All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: fuse-devel@lists.sourceforge.net, miklos@szeredi.hu,
	greg@kroah.com, linux-kernel@vger.kernel.org
Cc: Tejun Heo <tj@kernel.org>
Subject: [PATCH 4/7] FUSE: implement direct lseek support
Date: Fri, 29 Aug 2008 02:41:00 +0900	[thread overview]
Message-ID: <1219945263-21074-5-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1219945263-21074-1-git-send-email-tj@kernel.org>

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


  parent reply	other threads:[~2008-08-28 17:43 UTC|newest]

Thread overview: 82+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-28 17:40 [PATCHSET] FUSE: extend FUSE to support more operations Tejun Heo
2008-08-28 17:40 ` [PATCH 1/7] FUSE: add include protectors Tejun Heo
2008-08-28 17:40 ` [PATCH 2/7] FUSE: pass nonblock flag to client Tejun Heo
2008-08-28 17:40 ` [PATCH 3/7] FUSE: implement nonseekable open Tejun Heo
2008-08-28 17:41 ` Tejun Heo [this message]
2008-08-28 17:41 ` [PATCH 5/7] FUSE: implement ioctl support Tejun Heo
2008-08-28 17:51   ` Greg KH
2008-08-28 17:59     ` Tejun Heo
2008-08-28 18:01       ` Tejun Heo
2008-08-28 18:13         ` Miklos Szeredi
2008-08-28 18:17           ` Tejun Heo
2008-08-28 18:23             ` Miklos Szeredi
2008-08-28 18:34               ` Tejun Heo
2008-08-28 19:25                 ` Miklos Szeredi
2008-08-28 19:42                   ` Tejun Heo
2008-08-28 20:02                     ` Miklos Szeredi
2008-08-29  2:19                       ` Tejun Heo
2008-08-29  7:59                         ` Miklos Szeredi
2008-08-29  8:12                           ` Tejun Heo
2008-08-29  8:29                             ` Miklos Szeredi
2008-08-29  9:03                               ` Tejun Heo
2008-08-29 19:17                                 ` Eric W. Biederman
2008-08-29 19:47                                   ` Arnd Bergmann
2008-08-30 11:40                                   ` Tejun Heo
2008-09-01 11:57                                   ` Miklos Szeredi
2008-09-01 12:03                                     ` Tejun Heo
2008-09-03 14:32                                       ` Eric W. Biederman
2008-09-03 14:40                                         ` Tejun Heo
2008-09-03 21:51                                           ` Eric W. Biederman
2008-09-04  0:09                                             ` Tejun Heo
2008-08-29 11:31                         ` [fuse-devel] " Roger Willcocks
2008-08-29 11:54                           ` Tejun Heo
2008-08-28 20:48                 ` Alan Cox
2008-08-28 18:02       ` Tejun Heo
2008-08-28 18:14         ` Greg KH
2008-08-28 18:25           ` Tejun Heo
2008-08-28 18:20   ` H. Peter Anvin
2008-08-28 18:28     ` Tejun Heo
2008-08-28 19:08       ` H. Peter Anvin
2008-08-28 19:18         ` Miklos Szeredi
2008-08-28 20:21           ` H. Peter Anvin
2008-08-28 20:55             ` Miklos Szeredi
2008-08-28 21:27               ` H. Peter Anvin
2008-08-29  7:32                 ` Miklos Szeredi
2008-08-28 17:41 ` [PATCH 6/7] FUSE: implement unsolicited notification Tejun Heo
2008-08-28 17:41 ` [PATCH 7/7] FUSE: implement poll support Tejun Heo
2008-08-28 18:20 ` [PATCHSET] FUSE: extend FUSE to support more operations Miklos Szeredi
2008-08-28 18:23   ` Tejun Heo
2008-10-14  8:21 ` Tejun Heo
2008-10-14  9:37   ` Miklos Szeredi
2008-10-14 12:16     ` [fuse-devel] " Szabolcs Szakacsits
2008-10-14 12:43       ` Miklos Szeredi
     [not found]     ` <2cff7cb50810141032m5793a405h7425dfa122fb67ba@mail.gmail.com>
2008-10-14 21:04       ` Miklos Szeredi
2008-11-12  8:41     ` Tejun Heo
2008-11-12  9:14       ` Christoph Hellwig
2008-11-12  9:30         ` Tejun Heo
2008-11-12  9:36           ` Miklos Szeredi
2008-11-12  9:43             ` [fuse-devel] " Mike Hommey
2008-11-12 10:00       ` Miklos Szeredi
2008-11-13  5:54         ` Tejun Heo
2008-11-13  6:06       ` Tejun Heo
2008-11-13 11:19         ` Miklos Szeredi
2008-11-13 11:29           ` Tejun Heo
2008-11-13 11:57             ` Miklos Szeredi
2008-11-13 12:14               ` Tejun Heo
2008-11-13  6:26     ` Tejun Heo
2008-11-13 11:47       ` Miklos Szeredi
2008-11-13 11:54         ` Tejun Heo
2008-11-13 11:58           ` Miklos Szeredi
2008-11-13 12:34             ` Miklos Szeredi
2008-11-13 13:23               ` Tejun Heo
2008-11-13 13:42                 ` Miklos Szeredi
2008-11-13 14:29                   ` Tejun Heo
2008-11-13 14:48                     ` Miklos Szeredi
2008-11-13 15:10                       ` Tejun Heo
2008-11-13 15:52                         ` Miklos Szeredi
2008-11-13 16:00                           ` Tejun Heo
2008-11-17  9:17                           ` Tejun Heo
2008-11-17 10:16                             ` [fuse-devel] " Miklos Szeredi
2008-11-18  3:32                               ` Tejun Heo
2008-11-18  9:33                                 ` Miklos Szeredi
2008-11-18 10:30                                   ` Tejun Heo

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=1219945263-21074-5-git-send-email-tj@kernel.org \
    --to=tj@kernel.org \
    --cc=fuse-devel@lists.sourceforge.net \
    --cc=greg@kroah.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    /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.