All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Maxim V. Patlasov" <MPatlasov-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
To: miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org
Cc: dev-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org,
	xemul-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org,
	fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	jbottomley-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org,
	viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devel-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org
Subject: [PATCH 13/14] fuse: Turn writeback cache on
Date: Fri, 25 Jan 2013 22:27:47 +0400	[thread overview]
Message-ID: <20130125182711.10037.38176.stgit@maximpc.sw.ru> (raw)
In-Reply-To: <20130125181700.10037.29163.stgit-vWG5eQQidJHciZdyczg/7Q@public.gmane.org>

Introduce a bit kernel and userspace exchange between each-other on
the init stage and turn writeback on if the userspace want this and
mount option 'allow_wbcache' is present (controlled by fusermount).

Also add each writable file into per-inode write list and call the
generic_file_aio_write to make use of the Linux page cache engine.

Original patch by: Pavel Emelyanov <xemul-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org>
Signed-off-by: Maxim Patlasov <MPatlasov-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>
---
 fs/fuse/file.c            |   15 +++++++++++++++
 fs/fuse/fuse_i.h          |    4 ++++
 fs/fuse/inode.c           |   13 +++++++++++++
 include/uapi/linux/fuse.h |    2 ++
 4 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e6e064c..147e618 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -211,6 +211,8 @@ void fuse_finish_open(struct inode *inode, struct file *file)
 		spin_unlock(&fc->lock);
 		fuse_invalidate_attr(inode);
 	}
+	if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
+		fuse_link_write_file(file);
 }
 
 int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
@@ -1096,6 +1098,19 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	struct iov_iter i;
 	loff_t endbyte = 0;
 
+	if (get_fuse_conn(inode)->writeback_cache) {
+		if (!(file->f_flags & O_DIRECT)) {
+			struct fuse_conn *fc = get_fuse_conn(inode);
+			struct fuse_inode *fi = get_fuse_inode(inode);
+
+			spin_lock(&fc->lock);
+			inode->i_mtime = current_fs_time(inode->i_sb);
+			set_bit(FUSE_I_MTIME_UPDATED, &fi->state);
+			spin_unlock(&fc->lock);
+		}
+		return generic_file_aio_write(iocb, iov, nr_segs, pos);
+	}
+
 	WARN_ON(iocb->ki_pos != pos);
 
 	ocount = 0;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 86caa8c..a207744 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -44,6 +44,10 @@
     doing the mount will be allowed to access the filesystem */
 #define FUSE_ALLOW_OTHER         (1 << 1)
 
+/** If the FUSE_ALLOW_WBCACHE flag is given, the filesystem
+    module will enable support of writback cache */
+#define FUSE_ALLOW_WBCACHE       (1 << 2)
+
 /** Number of page pointers embedded in fuse_req */
 #define FUSE_REQ_INLINE_PAGES 1
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 3687daf..541fc4f 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -521,6 +521,7 @@ enum {
 	OPT_ALLOW_OTHER,
 	OPT_MAX_READ,
 	OPT_BLKSIZE,
+	OPT_ALLOW_WBCACHE,
 	OPT_ERR
 };
 
@@ -533,6 +534,7 @@ static const match_table_t tokens = {
 	{OPT_ALLOW_OTHER,		"allow_other"},
 	{OPT_MAX_READ,			"max_read=%u"},
 	{OPT_BLKSIZE,			"blksize=%u"},
+	{OPT_ALLOW_WBCACHE,		"allow_wbcache"},
 	{OPT_ERR,			NULL}
 };
 
@@ -606,6 +608,10 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 			d->blksize = value;
 			break;
 
+		case OPT_ALLOW_WBCACHE:
+			d->flags |= FUSE_ALLOW_WBCACHE;
+			break;
+
 		default:
 			return 0;
 		}
@@ -633,6 +639,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
 		seq_printf(m, ",max_read=%u", fc->max_read);
 	if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE)
 		seq_printf(m, ",blksize=%lu", sb->s_blocksize);
+	if (fc->flags & FUSE_ALLOW_WBCACHE)
+		seq_puts(m, ",allow_wbcache");
 	return 0;
 }
 
@@ -944,6 +952,9 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
 				fc->auto_inval_data = 1;
 			if (arg->flags & FUSE_DO_READDIRPLUS)
 				fc->do_readdirplus = 1;
+			if (arg->flags & FUSE_WRITEBACK_CACHE &&
+			    fc->flags & FUSE_ALLOW_WBCACHE)
+				fc->writeback_cache = 1;
 		} else {
 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 			fc->no_lock = 1;
@@ -972,6 +983,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
 		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
 		FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
 		FUSE_DO_READDIRPLUS;
+	if (fc->flags & FUSE_ALLOW_WBCACHE)
+		arg->flags |= FUSE_WRITEBACK_CACHE;
 	req->in.h.opcode = FUSE_INIT;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(*arg);
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 5dc1fea..20a9553 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -179,6 +179,7 @@ struct fuse_file_lock {
  * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
  * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
  * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
+ * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
  */
 #define FUSE_ASYNC_READ		(1 << 0)
 #define FUSE_POSIX_LOCKS	(1 << 1)
@@ -194,6 +195,7 @@ struct fuse_file_lock {
 #define FUSE_HAS_IOCTL_DIR	(1 << 11)
 #define FUSE_AUTO_INVAL_DATA	(1 << 12)
 #define FUSE_DO_READDIRPLUS	(1 << 13)
+#define FUSE_WRITEBACK_CACHE	(1 << 14)
 
 /**
  * CUSE INIT request/reply flags


------------------------------------------------------------------------------
Master Visual Studio, SharePoint, SQL, ASP.NET, C# 2012, HTML5, CSS,
MVC, Windows 8 Apps, JavaScript and much more. Keep your skills current
with LearnDevNow - 3,200 step-by-step video tutorials by Microsoft
MVPs and experts. ON SALE this month only -- learn more at:
http://p.sf.net/sfu/learnnow-d2d

WARNING: multiple messages have this Message-ID (diff)
From: "Maxim V. Patlasov" <MPatlasov@parallels.com>
To: miklos@szeredi.hu
Cc: dev@parallels.com, xemul@parallels.com,
	fuse-devel@lists.sourceforge.net, linux-kernel@vger.kernel.org,
	jbottomley@parallels.com, viro@zeniv.linux.org.uk,
	linux-fsdevel@vger.kernel.org, devel@openvz.org
Subject: [PATCH 13/14] fuse: Turn writeback cache on
Date: Fri, 25 Jan 2013 22:27:47 +0400	[thread overview]
Message-ID: <20130125182711.10037.38176.stgit@maximpc.sw.ru> (raw)
In-Reply-To: <20130125181700.10037.29163.stgit@maximpc.sw.ru>

Introduce a bit kernel and userspace exchange between each-other on
the init stage and turn writeback on if the userspace want this and
mount option 'allow_wbcache' is present (controlled by fusermount).

Also add each writable file into per-inode write list and call the
generic_file_aio_write to make use of the Linux page cache engine.

Original patch by: Pavel Emelyanov <xemul@openvz.org>
Signed-off-by: Maxim Patlasov <MPatlasov@parallels.com>
---
 fs/fuse/file.c            |   15 +++++++++++++++
 fs/fuse/fuse_i.h          |    4 ++++
 fs/fuse/inode.c           |   13 +++++++++++++
 include/uapi/linux/fuse.h |    2 ++
 4 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index e6e064c..147e618 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -211,6 +211,8 @@ void fuse_finish_open(struct inode *inode, struct file *file)
 		spin_unlock(&fc->lock);
 		fuse_invalidate_attr(inode);
 	}
+	if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache)
+		fuse_link_write_file(file);
 }
 
 int fuse_open_common(struct inode *inode, struct file *file, bool isdir)
@@ -1096,6 +1098,19 @@ static ssize_t fuse_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
 	struct iov_iter i;
 	loff_t endbyte = 0;
 
+	if (get_fuse_conn(inode)->writeback_cache) {
+		if (!(file->f_flags & O_DIRECT)) {
+			struct fuse_conn *fc = get_fuse_conn(inode);
+			struct fuse_inode *fi = get_fuse_inode(inode);
+
+			spin_lock(&fc->lock);
+			inode->i_mtime = current_fs_time(inode->i_sb);
+			set_bit(FUSE_I_MTIME_UPDATED, &fi->state);
+			spin_unlock(&fc->lock);
+		}
+		return generic_file_aio_write(iocb, iov, nr_segs, pos);
+	}
+
 	WARN_ON(iocb->ki_pos != pos);
 
 	ocount = 0;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 86caa8c..a207744 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -44,6 +44,10 @@
     doing the mount will be allowed to access the filesystem */
 #define FUSE_ALLOW_OTHER         (1 << 1)
 
+/** If the FUSE_ALLOW_WBCACHE flag is given, the filesystem
+    module will enable support of writback cache */
+#define FUSE_ALLOW_WBCACHE       (1 << 2)
+
 /** Number of page pointers embedded in fuse_req */
 #define FUSE_REQ_INLINE_PAGES 1
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 3687daf..541fc4f 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -521,6 +521,7 @@ enum {
 	OPT_ALLOW_OTHER,
 	OPT_MAX_READ,
 	OPT_BLKSIZE,
+	OPT_ALLOW_WBCACHE,
 	OPT_ERR
 };
 
@@ -533,6 +534,7 @@ static const match_table_t tokens = {
 	{OPT_ALLOW_OTHER,		"allow_other"},
 	{OPT_MAX_READ,			"max_read=%u"},
 	{OPT_BLKSIZE,			"blksize=%u"},
+	{OPT_ALLOW_WBCACHE,		"allow_wbcache"},
 	{OPT_ERR,			NULL}
 };
 
@@ -606,6 +608,10 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev)
 			d->blksize = value;
 			break;
 
+		case OPT_ALLOW_WBCACHE:
+			d->flags |= FUSE_ALLOW_WBCACHE;
+			break;
+
 		default:
 			return 0;
 		}
@@ -633,6 +639,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root)
 		seq_printf(m, ",max_read=%u", fc->max_read);
 	if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE)
 		seq_printf(m, ",blksize=%lu", sb->s_blocksize);
+	if (fc->flags & FUSE_ALLOW_WBCACHE)
+		seq_puts(m, ",allow_wbcache");
 	return 0;
 }
 
@@ -944,6 +952,9 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
 				fc->auto_inval_data = 1;
 			if (arg->flags & FUSE_DO_READDIRPLUS)
 				fc->do_readdirplus = 1;
+			if (arg->flags & FUSE_WRITEBACK_CACHE &&
+			    fc->flags & FUSE_ALLOW_WBCACHE)
+				fc->writeback_cache = 1;
 		} else {
 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 			fc->no_lock = 1;
@@ -972,6 +983,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
 		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
 		FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
 		FUSE_DO_READDIRPLUS;
+	if (fc->flags & FUSE_ALLOW_WBCACHE)
+		arg->flags |= FUSE_WRITEBACK_CACHE;
 	req->in.h.opcode = FUSE_INIT;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(*arg);
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h
index 5dc1fea..20a9553 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -179,6 +179,7 @@ struct fuse_file_lock {
  * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks
  * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories
  * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages
+ * FUSE_WRITEBACK_CACHE: use writeback cache for buffered writes
  */
 #define FUSE_ASYNC_READ		(1 << 0)
 #define FUSE_POSIX_LOCKS	(1 << 1)
@@ -194,6 +195,7 @@ struct fuse_file_lock {
 #define FUSE_HAS_IOCTL_DIR	(1 << 11)
 #define FUSE_AUTO_INVAL_DATA	(1 << 12)
 #define FUSE_DO_READDIRPLUS	(1 << 13)
+#define FUSE_WRITEBACK_CACHE	(1 << 14)
 
 /**
  * CUSE INIT request/reply flags


  parent reply	other threads:[~2013-01-25 18:27 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-25 18:20 [PATCH v3 00/14] fuse: An attempt to implement a write-back cache policy Maxim V. Patlasov
2013-01-25 18:20 ` Maxim V. Patlasov
2013-01-25 18:21 ` [PATCH 03/14] fuse: Prepare to handle short reads Maxim V. Patlasov
2013-01-25 18:24 ` [PATCH 07/14] fuse: Update i_mtime on buffered writes Maxim V. Patlasov
2013-01-29 22:19   ` Miklos Szeredi
2013-03-26  9:55     ` Maxim V. Patlasov
     [not found] ` <20130125181700.10037.29163.stgit-vWG5eQQidJHciZdyczg/7Q@public.gmane.org>
2013-01-25 18:20   ` [PATCH 01/14] fuse: Linking file to inode helper Maxim V. Patlasov
2013-01-25 18:20     ` Maxim V. Patlasov
2013-01-25 18:21   ` [PATCH 02/14] fuse: Getting file for writeback helper Maxim V. Patlasov
2013-01-25 18:21     ` Maxim V. Patlasov
2013-01-25 18:21   ` [PATCH 04/14] fuse: Prepare to handle multiple pages in writeback Maxim V. Patlasov
2013-01-25 18:21     ` Maxim V. Patlasov
2013-01-25 18:22   ` [PATCH 05/14] fuse: Connection bit for enabling writeback Maxim V. Patlasov
2013-01-25 18:22     ` Maxim V. Patlasov
2013-01-25 18:22   ` [PATCH 06/14] fuse: Trust kernel i_size only - v2 Maxim V. Patlasov
2013-01-25 18:22     ` Maxim V. Patlasov
2013-01-29 10:18     ` Miklos Szeredi
2013-03-25 12:29       ` Maxim V. Patlasov
2013-01-25 18:24   ` [PATCH 08/14] fuse: Flush files on wb close Maxim V. Patlasov
2013-01-25 18:24     ` Maxim V. Patlasov
2013-01-29 22:58     ` Miklos Szeredi
2013-03-26 11:24       ` Maxim V. Patlasov
2013-03-26 11:24         ` Maxim V. Patlasov
2013-01-25 18:25   ` [PATCH 09/14] fuse: Implement writepages and write_begin/write_end callbacks - v2 Maxim V. Patlasov
2013-01-25 18:25     ` Maxim V. Patlasov
2013-01-29 23:08     ` Miklos Szeredi
2013-03-27 12:39       ` Maxim V. Patlasov
2013-03-27 12:39         ` Maxim V. Patlasov
2013-01-25 18:25   ` [PATCH 10/14] fuse: fuse_writepage_locked() should wait on writeback Maxim V. Patlasov
2013-01-25 18:25     ` Maxim V. Patlasov
2013-01-25 18:26   ` [PATCH 11/14] fuse: fuse_flush() " Maxim V. Patlasov
2013-01-25 18:26     ` Maxim V. Patlasov
2013-01-25 18:27   ` Maxim V. Patlasov [this message]
2013-01-25 18:27     ` [PATCH 13/14] fuse: Turn writeback cache on Maxim V. Patlasov
2013-01-25 18:28   ` [PATCH 14/14] mm: Account for WRITEBACK_TEMP in balance_dirty_pages Maxim V. Patlasov
2013-01-25 18:28     ` Maxim V. Patlasov
2013-01-25 18:27 ` [PATCH 12/14] fuse: Fix O_DIRECT operations vs cached writeback misorder - v2 Maxim V. Patlasov
  -- strict thread matches above, loose matches on Subject: below --
2013-04-01 10:40 [PATCH v4 00/14] fuse: An attempt to implement a write-back cache policy Maxim V. Patlasov
     [not found] ` <20130401103749.19027.89833.stgit-vWG5eQQidJHciZdyczg/7Q@public.gmane.org>
2013-04-01 10:42   ` [PATCH 13/14] fuse: Turn writeback cache on Maxim V. Patlasov
2013-04-01 10:42     ` Maxim V. Patlasov
2012-11-16 17:04 [PATCH v2 00/14] fuse: An attempt to implement a write-back cache policy Maxim Patlasov
     [not found] ` <20121116170123.3196.93431.stgit-vWG5eQQidJHciZdyczg/7Q@public.gmane.org>
2012-11-16 17:10   ` [PATCH 13/14] fuse: Turn writeback cache on Maxim Patlasov
2012-11-16 17:10     ` Maxim Patlasov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130125182711.10037.38176.stgit@maximpc.sw.ru \
    --to=mpatlasov-bzqdu9zft3wakbo8gow8eq@public.gmane.org \
    --cc=dev-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org \
    --cc=devel-GEFAQzZX7r8dnm+yROfE0A@public.gmane.org \
    --cc=fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    --cc=jbottomley-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org \
    --cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org \
    --cc=viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org \
    --cc=xemul-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.