mirror of https://lore.kernel.org/lkml/
 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

Powered by JetHome