[PATCH 4/7] FUSE: implement direct lseek support

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: <fuse-devel@...>, <miklos@...>, <greg@...>, <linux-kernel@...>
Cc: Tejun Heo <tj@...>
Date: Thursday, August 28, 2008 - 1:41 pm

Allow clients to implement private lseek.  The feature is negotiated
using FUSE_DIRECT_LSEEK flag during INIT.  If the client doesn't
request direct lseek, the original implicit lseek is used.

Signed-off-by: Tejun Heo <tj@kernel.org>
---
 fs/fuse/file.c       |   52 ++++++++++++++++++++++++++++++++++++++++++-------
 fs/fuse/fuse_i.h     |    3 ++
 fs/fuse/inode.c      |    4 ++-
 include/linux/fuse.h |   14 +++++++++++++
 4 files changed, 64 insertions(+), 9 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 9c44f9c..fa27edb 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1448,18 +1448,53 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
 
 static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
 {
-	loff_t retval;
+	loff_t retval = -EINVAL;
 	struct inode *inode = file->f_path.dentry->d_inode;
+	struct fuse_conn *fc = get_fuse_conn(inode);
+
+	if (is_bad_inode(inode))
+		return -EIO;
 
 	mutex_lock(&inode->i_mutex);
-	switch (origin) {
-	case SEEK_END:
-		offset += i_size_read(inode);
-		break;
-	case SEEK_CUR:
-		offset += file->f_pos;
+
+	if (fc->direct_lseek) {
+		struct fuse_file *ff = file->private_data;
+		struct fuse_lseek_in inarg = { .fh = ff->fh, .pos = file->f_pos,
+					   .offset = offset, .origin = origin };
+		struct fuse_lseek_out outarg;
+		struct fuse_req *req;
+		int err;
+
+		req = fuse_get_req(fc);
+		if (IS_ERR(req))
+			return PTR_ERR(req);
+
+		req->in.h.opcode = FUSE_LSEEK;
+		req->in.h.nodeid = get_node_id(inode);
+		req->in.numargs = 1;
+		req->in.args[0].size = sizeof(inarg);
+		req->in.args[0].value = &inarg;
+		req->out.numargs = 1;
+		req->out.args[0].size = sizeof(outarg);
+		req->out.args[0].value = &outarg;
+		request_send(fc, req);
+		err = req->out.h.error;
+		fuse_put_request(fc, req);
+
+		if (err)
+			return err;
+
+		offset = outarg.pos;
+	} else {
+		switch (origin) {
+		case SEEK_END:
+			offset += i_size_read(inode);
+			break;
+		case SEEK_CUR:
+			offset += file->f_pos;
+		}
 	}
-	retval = -EINVAL;
+
 	if (offset >= 0 && offset <= inode->i_sb->s_maxbytes) {
 		if (offset != file->f_pos) {
 			file->f_pos = offset;
@@ -1467,6 +1502,7 @@ static loff_t fuse_file_llseek(struct file *file, loff_t offset, int origin)
 		}
 		retval = offset;
 	}
+
 	mutex_unlock(&inode->i_mutex);
 	return retval;
 }
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index e2b3b72..2bf2209 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -366,6 +366,9 @@ struct fuse_conn {
 	/** Do not send separate SETATTR request before open(O_TRUNC)  */
 	unsigned atomic_o_trunc : 1;
 
+	/** Do direct lseek */
+	unsigned direct_lseek : 1;
+
 	/** Filesystem supports NFS exporting.  Only set in INIT */
 	unsigned export_support : 1;
 
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index d2249f1..7693dfc 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -757,6 +757,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
 			}
 			if (arg->flags & FUSE_BIG_WRITES)
 				fc->big_writes = 1;
+			if (arg->flags & FUSE_DIRECT_LSEEK)
+				fc->direct_lseek = 1;
 		} else {
 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 			fc->no_lock = 1;
@@ -781,7 +783,7 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
 	arg->minor = FUSE_KERNEL_MINOR_VERSION;
 	arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE;
 	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
-		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES;
+		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DIRECT_LSEEK;
 	req->in.h.opcode = FUSE_INIT;
 	req->in.numargs = 1;
 	req->in.args[0].size = sizeof(*arg);
diff --git a/include/linux/fuse.h b/include/linux/fuse.h
index 431666e..508d54e 100644
--- a/include/linux/fuse.h
+++ b/include/linux/fuse.h
@@ -118,6 +118,7 @@ struct fuse_file_lock {
 #define FUSE_ATOMIC_O_TRUNC	(1 << 3)
 #define FUSE_EXPORT_SUPPORT	(1 << 4)
 #define FUSE_BIG_WRITES		(1 << 5)
+#define FUSE_DIRECT_LSEEK	(1 << 6)
 
 /**
  * Release flags
@@ -188,6 +189,7 @@ enum fuse_opcode {
 	FUSE_INTERRUPT     = 36,
 	FUSE_BMAP          = 37,
 	FUSE_DESTROY       = 38,
+	FUSE_LSEEK         = 39,
 };
 
 /* The read buffer is required to be at least 8k, but may be much larger */
@@ -388,6 +390,18 @@ struct fuse_bmap_out {
 	__u64	block;
 };
 
+struct fuse_lseek_in {
+	__u64	fh;
+	__u64	pos;			/* current file position */
+	__u64	offset;			/* seek offset */
+	__u32	origin;			/* SEEK_* */
+	__u32	padding;
+};
+
+struct fuse_lseek_out {
+	__u64	pos;			/* new position */
+};
+
 struct fuse_in_header {
 	__u32	len;
 	__u32	opcode;
-- 
1.5.4.5

--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [PATCHSET] FUSE: extend FUSE to support more operations, Miklos Szeredi, (Thu Nov 13, 10:48 am)
Re: [PATCHSET] FUSE: extend FUSE to support more operations, Miklos Szeredi, (Thu Nov 13, 11:52 am)
Re: [PATCHSET] FUSE: extend FUSE to support more operations, Christoph Hellwig, (Wed Nov 12, 5:14 am)
Re: [fuse-devel] [PATCHSET] FUSE: extend FUSE to support mor..., Szabolcs Szakacsits, (Tue Oct 14, 8:16 am)
[PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 1:41 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, H. Peter Anvin, (Thu Aug 28, 2:20 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 2:28 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, H. Peter Anvin, (Thu Aug 28, 3:08 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Thu Aug 28, 3:18 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, H. Peter Anvin, (Thu Aug 28, 4:21 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Thu Aug 28, 4:55 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, H. Peter Anvin, (Thu Aug 28, 5:27 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Fri Aug 29, 3:32 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Greg KH, (Thu Aug 28, 1:51 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 1:59 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 2:02 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Greg KH, (Thu Aug 28, 2:14 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 2:25 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 2:01 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Thu Aug 28, 2:13 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 2:17 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Thu Aug 28, 2:23 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 2:34 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Alan Cox, (Thu Aug 28, 4:48 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Thu Aug 28, 3:25 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 3:42 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Thu Aug 28, 4:02 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Thu Aug 28, 10:19 pm)
Re: [fuse-devel] [PATCH 5/7] FUSE: implement ioctl support, Roger Willcocks, (Fri Aug 29, 7:31 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Fri Aug 29, 3:59 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Fri Aug 29, 4:12 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Fri Aug 29, 4:29 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Fri Aug 29, 5:03 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Eric W. Biederman, (Fri Aug 29, 3:17 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Miklos Szeredi, (Mon Sep 1, 7:57 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Mon Sep 1, 8:03 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Eric W. Biederman, (Wed Sep 3, 10:32 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Wed Sep 3, 10:40 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Eric W. Biederman, (Wed Sep 3, 5:51 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Wed Sep 3, 8:09 pm)
Re: [PATCH 5/7] FUSE: implement ioctl support, Tejun Heo, (Sat Aug 30, 7:40 am)
Re: [PATCH 5/7] FUSE: implement ioctl support, Arnd Bergmann, (Fri Aug 29, 3:47 pm)
[PATCH 7/7] FUSE: implement poll support, Tejun Heo, (Thu Aug 28, 1:41 pm)
[PATCH 4/7] FUSE: implement direct lseek support, Tejun Heo, (Thu Aug 28, 1:41 pm)
[PATCH 1/7] FUSE: add include protectors, Tejun Heo, (Thu Aug 28, 1:40 pm)
[PATCH 3/7] FUSE: implement nonseekable open, Tejun Heo, (Thu Aug 28, 1:40 pm)
[PATCH 2/7] FUSE: pass nonblock flag to client, Tejun Heo, (Thu Aug 28, 1:40 pm)