All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/2] FUSE: Adaptive NFS-like readdirplus support
       [not found] <87mx1ngmip.fsf@tucsk.pomaz.szeredi.hu>
@ 2013-01-15  3:23 ` Feng Shuo
  2013-01-15  3:23   ` [PATCH v3 1/2] fuse: implement " Feng Shuo
  2013-01-15  3:23   ` [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns Feng Shuo
  0 siblings, 2 replies; 13+ messages in thread
From: Feng Shuo @ 2013-01-15  3:23 UTC (permalink / raw)
  To: fuse-devel, linux-fsdevel; +Cc: Feng Shuo

The original idea belows to Anand V. Avati:

http://sourceforge.net/mailarchive/message.php?msg_id=29562240

I did some benchmarking and add the adaptive mechanism as in NFS. For 
the detail of the testing, please refer to:

http://sourceforge.net/mailarchive/message.php?msg_id=30305348

In my setup, this patch set can give about 50% performance up with "ls -l"
and without much penalty with pure "ls" because of the second patch. 

Rebased to 3.8-rc3.

Feng Shuo (1):
  FUSE: Adapt readdirplus to application usage patterns

Miklos Szeredi (1):
  fuse: implement NFS-like readdirplus support

 fs/fuse/dev.c             |  19 +++++
 fs/fuse/dir.c             | 206 ++++++++++++++++++++++++++++++++++++++++++++--
 fs/fuse/fuse_i.h          |  16 ++++
 fs/fuse/inode.c           |   8 +-
 include/uapi/linux/fuse.h |  12 +++
 5 files changed, 254 insertions(+), 7 deletions(-)

-- 
1.7.12.4


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH v3 1/2] fuse: implement NFS-like readdirplus support
  2013-01-15  3:23 ` [PATCH v3 0/2] FUSE: Adaptive NFS-like readdirplus support Feng Shuo
@ 2013-01-15  3:23   ` Feng Shuo
  2013-01-15  3:23   ` [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns Feng Shuo
  1 sibling, 0 replies; 13+ messages in thread
From: Feng Shuo @ 2013-01-15  3:23 UTC (permalink / raw)
  To: fuse-devel, linux-fsdevel; +Cc: Miklos Szeredi, Feng Shuo

From: Miklos Szeredi <miklos@szeredi.hu>

Anand Avati <avati@redhat.com> writes:

> This version of the patch
>
> - incorporates review comments from the previous submission
> - fixes nlookup leak on entries in the first readdirplus
> - cleaner fuse_direntp structure

Anand,

Here's an updated version of the patch.  It fixes some issues (real and
cosmetic) with your latest patch.  Can you please look it over and give
it a test.

Thanks,
Miklos

Signed-off-by: Feng Shuo <steve.shuo.feng@gmail.com>
---
 fs/fuse/dev.c             |  19 ++++++
 fs/fuse/dir.c             | 160 ++++++++++++++++++++++++++++++++++++++++++++--
 fs/fuse/fuse_i.h          |   6 ++
 fs/fuse/inode.c           |   5 +-
 include/uapi/linux/fuse.h |  12 ++++
 5 files changed, 197 insertions(+), 5 deletions(-)

diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c
index c163353..8e8b216 100644
--- a/fs/fuse/dev.c
+++ b/fs/fuse/dev.c
@@ -491,6 +491,25 @@ void fuse_request_send_background_locked(struct fuse_conn *fc,
 	fuse_request_send_nowait_locked(fc, req);
 }
 
+void fuse_force_forget(struct file *file, u64 nodeid)
+{
+	struct inode *inode = file->f_path.dentry->d_inode;
+	struct fuse_conn *fc = get_fuse_conn(inode);
+	struct fuse_req *req;
+	struct fuse_forget_in inarg;
+
+	memset(&inarg, 0, sizeof(inarg));
+	inarg.nlookup = 1;
+	req = fuse_get_req_nofail(fc, file);
+	req->in.h.opcode = FUSE_FORGET;
+	req->in.h.nodeid = nodeid;
+	req->in.numargs = 1;
+	req->in.args[0].size = sizeof(inarg);
+	req->in.args[0].value = &inarg;
+	req->isreply = 0;
+	fuse_request_send_nowait(fc, req);
+}
+
 /*
  * Lock the request.  Up to the next unlock_request() there mustn't be
  * anything that could cause a page-fault.  If the request was already
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index b7c09f9..dcc1e52 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1155,6 +1155,143 @@ static int parse_dirfile(char *buf, size_t nbytes, struct file *file,
 	return 0;
 }
 
+static int fuse_direntplus_link(struct file *file,
+				struct fuse_direntplus *direntplus,
+				u64 attr_version)
+{
+	int err;
+	struct fuse_entry_out *o = &direntplus->entry_out;
+	struct fuse_dirent *dirent = &direntplus->dirent;
+	struct dentry *parent = file->f_path.dentry;
+	struct qstr name = QSTR_INIT(dirent->name, dirent->namelen);
+	struct dentry *dentry;
+	struct dentry *alias;
+	struct inode *dir = parent->d_inode;
+	struct fuse_conn *fc;
+	struct inode *inode;
+
+	if (!o->nodeid) {
+		/*
+		 * Unlike in the case of fuse_lookup, zero nodeid does not mean
+		 * ENOENT. Instead, it only means the userspace filesystem did
+		 * not want to return attributes/handle for this entry.
+		 *
+		 * So do nothing.
+		 */
+		return 0;
+	}
+
+	if (name.name[0] == '.') {
+		/*
+		 * We could potentially refresh the attributes of the directory
+		 * and its parent?
+		 */
+		if (name.len == 1)
+			return 0;
+		if (name.name[1] == '.' && name.len == 2)
+			return 0;
+	}
+	fc = get_fuse_conn(dir);
+
+	name.hash = full_name_hash(name.name, name.len);
+	dentry = d_lookup(parent, &name);
+	if (dentry && dentry->d_inode) {
+		inode = dentry->d_inode;
+		if (get_node_id(inode) == o->nodeid) {
+			struct fuse_inode *fi;
+			fi = get_fuse_inode(inode);
+			spin_lock(&fc->lock);
+			fi->nlookup++;
+			spin_unlock(&fc->lock);
+
+			/*
+			 * The other branch to 'found' comes via fuse_iget()
+			 * which bumps nlookup inside
+			 */
+			goto found;
+		}
+		err = d_invalidate(dentry);
+		if (err)
+			goto out;
+		dput(dentry);
+		dentry = NULL;
+	}
+
+	dentry = d_alloc(parent, &name);
+	err = -ENOMEM;
+	if (!dentry)
+		goto out;
+
+	inode = fuse_iget(dir->i_sb, o->nodeid, o->generation,
+			  &o->attr, entry_attr_timeout(o), attr_version);
+	if (!inode)
+		goto out;
+
+	alias = d_materialise_unique(dentry, inode);
+	err = PTR_ERR(alias);
+	if (IS_ERR(alias))
+		goto out;
+	if (alias) {
+		dput(dentry);
+		dentry = alias;
+	}
+
+found:
+	fuse_change_attributes(inode, &o->attr, entry_attr_timeout(o),
+			       attr_version);
+
+	fuse_change_entry_timeout(dentry, o);
+
+	err = 0;
+out:
+	if (dentry)
+		dput(dentry);
+	return err;
+}
+
+static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
+			     void *dstbuf, filldir_t filldir, u64 attr_version)
+{
+	struct fuse_direntplus *direntplus;
+	struct fuse_dirent *dirent;
+	size_t reclen;
+	int over = 0;
+	int ret;
+
+	while (nbytes >= FUSE_NAME_OFFSET_DIRENTPLUS) {
+		direntplus = (struct fuse_direntplus *) buf;
+		dirent = &direntplus->dirent;
+		reclen = FUSE_DIRENTPLUS_SIZE(direntplus);
+
+		if (!dirent->namelen || dirent->namelen > FUSE_NAME_MAX)
+			return -EIO;
+		if (reclen > nbytes)
+			break;
+
+		if (!over) {
+			/* We fill entries into dstbuf only as much as
+			   it can hold. But we still continue iterating
+			   over remaining entries to link them. If not,
+			   we need to send a FORGET for each of those
+			   which we did not link.
+			*/
+			over = filldir(dstbuf, dirent->name, dirent->namelen,
+				       file->f_pos, dirent->ino,
+				       dirent->type);
+			file->f_pos = dirent->off;
+		}
+
+		buf += reclen;
+		nbytes -= reclen;
+
+		ret = fuse_direntplus_link(file, direntplus, attr_version);
+		if (ret)
+			fuse_force_forget(file, direntplus->entry_out.nodeid);
+	}
+
+	return 0;
+}
+
 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 {
 	int err;
@@ -1163,6 +1300,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 	struct inode *inode = file->f_path.dentry->d_inode;
 	struct fuse_conn *fc = get_fuse_conn(inode);
 	struct fuse_req *req;
+	u64 attr_version = 0;
 
 	if (is_bad_inode(inode))
 		return -EIO;
@@ -1179,14 +1317,28 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 	req->out.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
-	fuse_read_fill(req, file, file->f_pos, PAGE_SIZE, FUSE_READDIR);
+	if (fc->do_readdirplus) {
+		attr_version = fuse_get_attr_version(fc);
+		fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
+			       FUSE_READDIRPLUS);
+	} else {
+		fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
+			       FUSE_READDIR);
+	}
 	fuse_request_send(fc, req);
 	nbytes = req->out.args[0].size;
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
-	if (!err)
-		err = parse_dirfile(page_address(page), nbytes, file, dstbuf,
-				    filldir);
+	if (!err) {
+		if (fc->do_readdirplus) {
+			err = parse_dirplusfile(page_address(page), nbytes,
+						file, dstbuf, filldir,
+						attr_version);
+		} else {
+			err = parse_dirfile(page_address(page), nbytes, file,
+					    dstbuf, filldir);
+		}
+	}
 
 	__free_page(page);
 	fuse_invalidate_attr(inode); /* atime changed */
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index e105a53..5c50553 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -487,6 +487,9 @@ struct fuse_conn {
 	/** Use enhanced/automatic page cache invalidation. */
 	unsigned auto_inval_data:1;
 
+	/** Does the filesystem support readdir-plus? */
+	unsigned do_readdirplus:1;
+
 	/** The number of requests waiting for completion */
 	atomic_t num_waiting;
 
@@ -578,6 +581,9 @@ void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget,
 
 struct fuse_forget_link *fuse_alloc_forget(void);
 
+/* Used by READDIRPLUS */
+void fuse_force_forget(struct file *file, u64 nodeid);
+
 /**
  * Initialize READ or READDIR request
  */
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 73ca6b7..6f7d574 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -863,6 +863,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
 				fc->dont_mask = 1;
 			if (arg->flags & FUSE_AUTO_INVAL_DATA)
 				fc->auto_inval_data = 1;
+			if (arg->flags & FUSE_DO_READDIRPLUS)
+				fc->do_readdirplus = 1;
 		} else {
 			ra_pages = fc->max_read / PAGE_CACHE_SIZE;
 			fc->no_lock = 1;
@@ -889,7 +891,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req)
 	arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC |
 		FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK |
 		FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ |
-		FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA;
+		FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA |
+		FUSE_DO_READDIRPLUS;
 	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 d8c713e..5dc1fea 100644
--- a/include/uapi/linux/fuse.h
+++ b/include/uapi/linux/fuse.h
@@ -193,6 +193,7 @@ struct fuse_file_lock {
 #define FUSE_FLOCK_LOCKS	(1 << 10)
 #define FUSE_HAS_IOCTL_DIR	(1 << 11)
 #define FUSE_AUTO_INVAL_DATA	(1 << 12)
+#define FUSE_DO_READDIRPLUS	(1 << 13)
 
 /**
  * CUSE INIT request/reply flags
@@ -299,6 +300,7 @@ enum fuse_opcode {
 	FUSE_NOTIFY_REPLY  = 41,
 	FUSE_BATCH_FORGET  = 42,
 	FUSE_FALLOCATE     = 43,
+	FUSE_READDIRPLUS   = 44,
 
 	/* CUSE specific operations */
 	CUSE_INIT          = 4096,
@@ -630,6 +632,16 @@ struct fuse_dirent {
 #define FUSE_DIRENT_SIZE(d) \
 	FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + (d)->namelen)
 
+struct fuse_direntplus {
+	struct fuse_entry_out entry_out;
+	struct fuse_dirent dirent;
+};
+
+#define FUSE_NAME_OFFSET_DIRENTPLUS \
+	offsetof(struct fuse_direntplus, dirent.name)
+#define FUSE_DIRENTPLUS_SIZE(d) \
+	FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET_DIRENTPLUS + (d)->dirent.namelen)
+
 struct fuse_notify_inval_inode_out {
 	__u64	ino;
 	__s64	off;
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
  2013-01-15  3:23 ` [PATCH v3 0/2] FUSE: Adaptive NFS-like readdirplus support Feng Shuo
  2013-01-15  3:23   ` [PATCH v3 1/2] fuse: implement " Feng Shuo
@ 2013-01-15  3:23   ` Feng Shuo
       [not found]     ` <1358220208-27131-3-git-send-email-steve.shuo.feng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
  2013-02-03  7:15     ` Eric Wong
  1 sibling, 2 replies; 13+ messages in thread
From: Feng Shuo @ 2013-01-15  3:23 UTC (permalink / raw)
  To: fuse-devel, linux-fsdevel; +Cc: Feng Shuo

Use the same adaptive readdirplus mechanism as NFS:

http://permalink.gmane.org/gmane.linux.nfs/49299

If the user space implementation wants to disable readdirplus
temporarily, it could just return ENOTSUPP. Then kernel will
recall it with readdir.

Signed-off-by: Feng Shuo <steve.shuo.feng@gmail.com>
---
 fs/fuse/dir.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
 fs/fuse/fuse_i.h | 10 ++++++++++
 fs/fuse/inode.c  |  3 +++
 3 files changed, 59 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index dcc1e52..b9975df 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -14,6 +14,34 @@
 #include <linux/namei.h>
 #include <linux/slab.h>
 
+static bool fuse_use_readdirplus(struct inode *dir, struct file *filp)
+{
+	struct fuse_conn *fc = get_fuse_conn(dir);
+	struct fuse_inode *fi = get_fuse_inode(dir);
+
+	if (!fc->do_readdirplus)
+		return false;
+	if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
+		return true;
+	if (filp->f_pos == 0)
+		return true;
+	return false;
+}
+
+static void fuse_advise_use_readdirplus(struct inode *dir)
+{
+	struct fuse_inode *fi = get_fuse_inode(dir);
+
+	set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
+}
+
+static void fuse_stop_use_readdirplus(struct inode *dir)
+{
+	struct fuse_inode *fi = get_fuse_inode(dir);
+
+	clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
+}
+
 #if BITS_PER_LONG >= 64
 static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
 {
@@ -219,6 +247,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
 				       attr_version);
 		fuse_change_entry_timeout(entry, &outarg);
 	}
+	fuse_advise_use_readdirplus(inode);
 	return 1;
 }
 
@@ -355,6 +384,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
 	else
 		fuse_invalidate_entry_cache(entry);
 
+	fuse_advise_use_readdirplus(dir);
 	return newent;
 
  out_iput:
@@ -1294,7 +1324,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
 
 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 {
-	int err;
+	int plus, err;
 	size_t nbytes;
 	struct page *page;
 	struct inode *inode = file->f_path.dentry->d_inode;
@@ -1314,10 +1344,13 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 		fuse_put_request(fc, req);
 		return -ENOMEM;
 	}
+
+	plus = fuse_use_readdirplus(inode, file);
+read_again:
 	req->out.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
-	if (fc->do_readdirplus) {
+	if (plus) {
 		attr_version = fuse_get_attr_version(fc);
 		fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
 			       FUSE_READDIRPLUS);
@@ -1329,8 +1362,17 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 	nbytes = req->out.args[0].size;
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
+	if ((err == -ENOTSUPP) && plus) {
+		fuse_stop_use_readdirplus(inode);
+		plus = 0;
+		req = fuse_get_req(fc);
+		if (!IS_ERR(req))
+			goto read_again;
+		err = PTR_ERR(req);
+		goto out;
+	}
 	if (!err) {
-		if (fc->do_readdirplus) {
+		if (plus) {
 			err = parse_dirplusfile(page_address(page), nbytes,
 						file, dstbuf, filldir,
 						attr_version);
@@ -1339,7 +1381,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 					    dstbuf, filldir);
 		}
 	}
-
+out:
 	__free_page(page);
 	fuse_invalidate_attr(inode); /* atime changed */
 	return err;
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 5c50553..e582603 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -103,6 +103,16 @@ struct fuse_inode {
 
 	/** List of writepage requestst (pending or sent) */
 	struct list_head writepages;
+
+	/** Miscellaneous bits describing inode state */
+	unsigned long state;
+};
+
+/** FUSE inode state bits */
+enum {
+	/** Advise readdirplus  */
+	FUSE_I_ADVISE_RDPLUS,
+	/* FUSE_I_MTIME_UPDATED, */
 };
 
 struct fuse_conn;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 6f7d574..4ba1cf5 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -255,6 +255,9 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
 				   new_decode_dev(attr->rdev));
 	} else
 		BUG();
+
+	/* The readdir_plus is disabled initially. */
+	get_fuse_inode(inode)->state = 0;
 }
 
 int fuse_inode_eq(struct inode *inode, void *_nodeidp)
-- 
1.7.12.4


^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
       [not found]     ` <1358220208-27131-3-git-send-email-steve.shuo.feng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-01-25 14:16       ` Miklos Szeredi
  0 siblings, 0 replies; 13+ messages in thread
From: Miklos Szeredi @ 2013-01-25 14:16 UTC (permalink / raw)
  To: Feng Shuo
  Cc: fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA

On Tue, Jan 15, 2013 at 4:23 AM, Feng Shuo <steve.shuo.feng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
> Use the same adaptive readdirplus mechanism as NFS:
>
> http://permalink.gmane.org/gmane.linux.nfs/49299

OK, applied with minor updates.

> If the user space implementation wants to disable readdirplus
> temporarily, it could just return ENOTSUPP. Then kernel will
> recall it with readdir.

I removed this part.  It may make sense, but it's not part of the
adaptive readdirplus algorithm, so I'd like to see this as a separate
patch.

Thanks,
Miklos



> Signed-off-by: Feng Shuo <steve.shuo.feng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>  fs/fuse/dir.c    | 50 ++++++++++++++++++++++++++++++++++++++++++++++----
>  fs/fuse/fuse_i.h | 10 ++++++++++
>  fs/fuse/inode.c  |  3 +++
>  3 files changed, 59 insertions(+), 4 deletions(-)
>
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index dcc1e52..b9975df 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -14,6 +14,34 @@
>  #include <linux/namei.h>
>  #include <linux/slab.h>
>
> +static bool fuse_use_readdirplus(struct inode *dir, struct file *filp)
> +{
> +       struct fuse_conn *fc = get_fuse_conn(dir);
> +       struct fuse_inode *fi = get_fuse_inode(dir);
> +
> +       if (!fc->do_readdirplus)
> +               return false;
> +       if (test_and_clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state))
> +               return true;
> +       if (filp->f_pos == 0)
> +               return true;
> +       return false;
> +}
> +
> +static void fuse_advise_use_readdirplus(struct inode *dir)
> +{
> +       struct fuse_inode *fi = get_fuse_inode(dir);
> +
> +       set_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
> +}
> +
> +static void fuse_stop_use_readdirplus(struct inode *dir)
> +{
> +       struct fuse_inode *fi = get_fuse_inode(dir);
> +
> +       clear_bit(FUSE_I_ADVISE_RDPLUS, &fi->state);
> +}
> +
>  #if BITS_PER_LONG >= 64
>  static inline void fuse_dentry_settime(struct dentry *entry, u64 time)
>  {
> @@ -219,6 +247,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
>                                        attr_version);
>                 fuse_change_entry_timeout(entry, &outarg);
>         }
> +       fuse_advise_use_readdirplus(inode);
>         return 1;
>  }
>
> @@ -355,6 +384,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
>         else
>                 fuse_invalidate_entry_cache(entry);
>
> +       fuse_advise_use_readdirplus(dir);
>         return newent;
>
>   out_iput:
> @@ -1294,7 +1324,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
>
>  static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>  {
> -       int err;
> +       int plus, err;
>         size_t nbytes;
>         struct page *page;
>         struct inode *inode = file->f_path.dentry->d_inode;
> @@ -1314,10 +1344,13 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>                 fuse_put_request(fc, req);
>                 return -ENOMEM;
>         }
> +
> +       plus = fuse_use_readdirplus(inode, file);
> +read_again:
>         req->out.argpages = 1;
>         req->num_pages = 1;
>         req->pages[0] = page;
> -       if (fc->do_readdirplus) {
> +       if (plus) {
>                 attr_version = fuse_get_attr_version(fc);
>                 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
>                                FUSE_READDIRPLUS);
> @@ -1329,8 +1362,17 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>         nbytes = req->out.args[0].size;
>         err = req->out.h.error;
>         fuse_put_request(fc, req);
> +       if ((err == -ENOTSUPP) && plus) {
> +               fuse_stop_use_readdirplus(inode);
> +               plus = 0;
> +               req = fuse_get_req(fc);
> +               if (!IS_ERR(req))
> +                       goto read_again;
> +               err = PTR_ERR(req);
> +               goto out;
> +       }
>         if (!err) {
> -               if (fc->do_readdirplus) {
> +               if (plus) {
>                         err = parse_dirplusfile(page_address(page), nbytes,
>                                                 file, dstbuf, filldir,
>                                                 attr_version);
> @@ -1339,7 +1381,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>                                             dstbuf, filldir);
>                 }
>         }
> -
> +out:
>         __free_page(page);
>         fuse_invalidate_attr(inode); /* atime changed */
>         return err;
> diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
> index 5c50553..e582603 100644
> --- a/fs/fuse/fuse_i.h
> +++ b/fs/fuse/fuse_i.h
> @@ -103,6 +103,16 @@ struct fuse_inode {
>
>         /** List of writepage requestst (pending or sent) */
>         struct list_head writepages;
> +
> +       /** Miscellaneous bits describing inode state */
> +       unsigned long state;
> +};
> +
> +/** FUSE inode state bits */
> +enum {
> +       /** Advise readdirplus  */
> +       FUSE_I_ADVISE_RDPLUS,
> +       /* FUSE_I_MTIME_UPDATED, */
>  };
>
>  struct fuse_conn;
> diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
> index 6f7d574..4ba1cf5 100644
> --- a/fs/fuse/inode.c
> +++ b/fs/fuse/inode.c
> @@ -255,6 +255,9 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
>                                    new_decode_dev(attr->rdev));
>         } else
>                 BUG();
> +
> +       /* The readdir_plus is disabled initially. */
> +       get_fuse_inode(inode)->state = 0;
>  }
>
>  int fuse_inode_eq(struct inode *inode, void *_nodeidp)
> --
> 1.7.12.4
>
>
> ------------------------------------------------------------------------------
> Master SQL Server Development, Administration, T-SQL, SSAS, SSIS, SSRS
> and more. Get SQL Server skills now (including 2012) with LearnDevNow -
> 200+ hours of step-by-step video tutorials by Microsoft MVPs and experts.
> SALE $99.99 this month only - learn more at:
> http://p.sf.net/sfu/learnmore_122512
> _______________________________________________
> fuse-devel mailing list
> fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
> https://lists.sourceforge.net/lists/listinfo/fuse-devel

------------------------------------------------------------------------------
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

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
  2013-01-15  3:23   ` [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns Feng Shuo
       [not found]     ` <1358220208-27131-3-git-send-email-steve.shuo.feng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
@ 2013-02-03  7:15     ` Eric Wong
  2013-02-03  8:10       ` Eric Wong
  1 sibling, 1 reply; 13+ messages in thread
From: Eric Wong @ 2013-02-03  7:15 UTC (permalink / raw)
  To: Feng Shuo; +Cc: fuse-devel, linux-fsdevel, Miklos Szeredi

Feng Shuo <steve.shuo.feng@gmail.com> wrote:
> Use the same adaptive readdirplus mechanism as NFS:
> 
> http://permalink.gmane.org/gmane.linux.nfs/49299
> 
> If the user space implementation wants to disable readdirplus
> temporarily, it could just return ENOTSUPP. Then kernel will
> recall it with readdir.

The version of this patch in "for-next" in
git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git
(commit 4582a4ab2a0e7218449fb2e895d0aae9ea753c94)
seems to be causing problems for me with "find -ls"
(I trivially backported all the for-next patches to 3.7.5)

I see getdents() returning a single d_name="" entry at the end of the
list, leading to infinite looping when combined with the userspace
patches I posted in
http://mid.gmane.org/20130202043316.GA19751@dcvr.yhbt.net

Normally getdents() returns 0 to indicate EOF on the directory;
but with this patch, I no longer get that...

This only seems to happen on large directories which require multiple
getdents() calls.  Sometimes "ls -l" will succeed and "find -ls" will
fail, and sometimes strace seems to make the problem go away...

It could be a bug in my end in userspace, too.  However, reverting the
version of this patch that landed in for-next seems to avoid the issue
for me.  I've also verified none of my userspace code is sending
dentries with an empty name.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
  2013-02-03  7:15     ` Eric Wong
@ 2013-02-03  8:10       ` Eric Wong
  2013-02-04 10:03         ` Feng Shuo
  0 siblings, 1 reply; 13+ messages in thread
From: Eric Wong @ 2013-02-03  8:10 UTC (permalink / raw)
  To: Feng Shuo; +Cc: fuse-devel, linux-fsdevel, Miklos Szeredi

Eric Wong <normalperson@yhbt.net> wrote:
> Feng Shuo <steve.shuo.feng@gmail.com> wrote:
> > Use the same adaptive readdirplus mechanism as NFS:
> > 
> > http://permalink.gmane.org/gmane.linux.nfs/49299
> 
> The version of this patch in "for-next" in
> git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git
> (commit 4582a4ab2a0e7218449fb2e895d0aae9ea753c94)

I can confirm this problem exists in Miklos's unmodified for-next,
too, and and reverting 4582a4ab2a0e7218449fb2e895d0aae9ea753c94
solves the problem for me.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
  2013-02-03  8:10       ` Eric Wong
@ 2013-02-04 10:03         ` Feng Shuo
  2013-02-04 10:10           ` Eric Wong
  0 siblings, 1 reply; 13+ messages in thread
From: Feng Shuo @ 2013-02-04 10:03 UTC (permalink / raw)
  To: Eric Wong, fuse-devel, linux-fsdevel, Miklos Szeredi

Thank you. I will check this soon. BTW. Do you think this is related
to the stack issue you mentioned in another thread?

2013/2/3, Eric Wong <normalperson@yhbt.net>:
> Eric Wong <normalperson@yhbt.net> wrote:
>> Feng Shuo <steve.shuo.feng@gmail.com> wrote:
>> > Use the same adaptive readdirplus mechanism as NFS:
>> >
>> > http://permalink.gmane.org/gmane.linux.nfs/49299
>>
>> The version of this patch in "for-next" in
>> git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git
>> (commit 4582a4ab2a0e7218449fb2e895d0aae9ea753c94)
>
> I can confirm this problem exists in Miklos's unmodified for-next,
> too, and and reverting 4582a4ab2a0e7218449fb2e895d0aae9ea753c94
> solves the problem for me.
>

-- 
从我的移动设备发送

Feng Shuo
Tel: (86)10-59851155-2116
Fax: (86)10-59851155-2008
Tianjin Zhongke Blue Whale Information Technologies Co., Ltd
10th Floor, Tower A, The GATE building, No. 19 Zhong-guan-cun Avenue
Haidian District, Beijing, China
Postcode 100080
--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
  2013-02-04 10:03         ` Feng Shuo
@ 2013-02-04 10:10           ` Eric Wong
  2013-02-04 12:46             ` [fuse-devel] " Miklos Szeredi
  0 siblings, 1 reply; 13+ messages in thread
From: Eric Wong @ 2013-02-04 10:10 UTC (permalink / raw)
  To: Feng Shuo; +Cc: fuse-devel, linux-fsdevel, Miklos Szeredi

Feng Shuo <steve.shuo.feng@gmail.com> wrote:
> Thank you. I will check this soon. BTW. Do you think this is related
> to the stack issue you mentioned in another thread?

I initially thought it was related, but no, I don't think I trigger
fuse_force_forget()...  I need to take a closer look later.

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [fuse-devel] [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
  2013-02-04 10:10           ` Eric Wong
@ 2013-02-04 12:46             ` Miklos Szeredi
       [not found]               ` <CAJfpegtKM6jsegxV+Jx0QkOEP6MhO6en6nEq7bCEJHxAAfMKHw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
  2013-02-05  3:12               ` [RFC] fuse: consistently use readdirplus offsets Eric Wong
  0 siblings, 2 replies; 13+ messages in thread
From: Miklos Szeredi @ 2013-02-04 12:46 UTC (permalink / raw)
  To: Eric Wong; +Cc: Feng Shuo, fuse-devel, linux-fsdevel, Miklos Szeredi

I think the problem is that directory offsets are not consistent
between readdir and readdirplus.  The solution is that userspace
should always use the same offsets.  This makes the readdirplus
implementation more complex but that's really the only sane thing to
do.

Thanks,
Miklos

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns
       [not found]               ` <CAJfpegtKM6jsegxV+Jx0QkOEP6MhO6en6nEq7bCEJHxAAfMKHw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-02-04 13:20                 ` Eric Wong
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Wong @ 2013-02-04 13:20 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Miklos Szeredi

Miklos Szeredi <miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org> wrote:
> I think the problem is that directory offsets are not consistent
> between readdir and readdirplus.  The solution is that userspace
> should always use the same offsets.  This makes the readdirplus
> implementation more complex but that's really the only sane thing to
> do.

I figured as much.  Will update the userspace lib tomorrow (or wait
for Feng Shuo to do it :>)

------------------------------------------------------------------------------
Everyone hates slow websites. So do we.
Make your web apps faster with AppDynamics
Download AppDynamics Lite for free today:
http://p.sf.net/sfu/appdyn_d2d_jan

^ permalink raw reply	[flat|nested] 13+ messages in thread

* [RFC] fuse: consistently use readdirplus offsets
  2013-02-04 12:46             ` [fuse-devel] " Miklos Szeredi
       [not found]               ` <CAJfpegtKM6jsegxV+Jx0QkOEP6MhO6en6nEq7bCEJHxAAfMKHw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
@ 2013-02-05  3:12               ` Eric Wong
       [not found]                 ` <20130205031202.GA9062-yBiyF41qdooeIZ0/mPfg9Q@public.gmane.org>
  1 sibling, 1 reply; 13+ messages in thread
From: Eric Wong @ 2013-02-05  3:12 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: Feng Shuo, fuse-devel, linux-fsdevel, Miklos Szeredi, Anand Avati

Miklos Szeredi <miklos@szeredi.hu> wrote:
> I think the problem is that directory offsets are not consistent
> between readdir and readdirplus.  The solution is that userspace
> should always use the same offsets.  This makes the readdirplus
> implementation more complex but that's really the only sane thing to
> do.

I think something like the following is necessary in the kernel, too.
(Userspace patch coming)

------------------------------- 8< --------------------------------
>From ed52619fda61c8f2b723ef72666e7acdd8885a1c Mon Sep 17 00:00:00 2001
From: Eric Wong <normalperson@yhbt.net>
Date: Tue, 5 Feb 2013 02:54:28 +0000
Subject: [PATCH] fuse: consistently use readdirplus offsets

With adaptive readdirplus, filesystems may switch between normal
readdir or readdirplus requests.  However, directory offsets
must be maintained consistently to prevent the kernel from
misinterpreting the offsets between different requests which
may use the same buffer.

Signed-off-by: Eric Wong <normalperson@yhbt.net>
---
 fs/fuse/dir.c |    7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
index dc5e648..a8e4abb 100644
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -1313,7 +1313,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
 
 static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 {
-	int plus, err;
+	int err;
 	size_t nbytes;
 	struct page *page;
 	struct inode *inode = file->f_path.dentry->d_inode;
@@ -1334,12 +1334,11 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 		return -ENOMEM;
 	}
 
-	plus = fuse_use_readdirplus(inode, file);
 	req->out.argpages = 1;
 	req->num_pages = 1;
 	req->pages[0] = page;
 	req->page_descs[0].length = PAGE_SIZE;
-	if (plus) {
+	if (fuse_use_readdirplus(inode, file)) {
 		attr_version = fuse_get_attr_version(fc);
 		fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
 			       FUSE_READDIRPLUS);
@@ -1352,7 +1351,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
 	err = req->out.h.error;
 	fuse_put_request(fc, req);
 	if (!err) {
-		if (plus) {
+		if (fc->do_readdirplus) {
 			err = parse_dirplusfile(page_address(page), nbytes,
 						file, dstbuf, filldir,
 						attr_version);
-- 
Eric Wong

^ permalink raw reply related	[flat|nested] 13+ messages in thread

* Re: [RFC] fuse: consistently use readdirplus offsets
       [not found]                 ` <20130205031202.GA9062-yBiyF41qdooeIZ0/mPfg9Q@public.gmane.org>
@ 2013-02-06 17:55                   ` Miklos Szeredi
  2013-02-06 21:40                     ` Eric Wong
  0 siblings, 1 reply; 13+ messages in thread
From: Miklos Szeredi @ 2013-02-06 17:55 UTC (permalink / raw)
  To: Eric Wong
  Cc: fuse-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
	linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Miklos Szeredi

On Tue, Feb 5, 2013 at 4:12 AM, Eric Wong <normalperson-rMlxZR9MS24@public.gmane.org> wrote:
> Miklos Szeredi <miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org> wrote:
>> I think the problem is that directory offsets are not consistent
>> between readdir and readdirplus.  The solution is that userspace
>> should always use the same offsets.  This makes the readdirplus
>> implementation more complex but that's really the only sane thing to
>> do.
>
> I think something like the following is necessary in the kernel, too.
> (Userspace patch coming)

Can you please explain what this patch is trying to do?  Because I
think it's not doing what it wants ;)

Thanks,
Miklos

>
> ------------------------------- 8< --------------------------------
> From ed52619fda61c8f2b723ef72666e7acdd8885a1c Mon Sep 17 00:00:00 2001
> From: Eric Wong <normalperson-rMlxZR9MS24@public.gmane.org>
> Date: Tue, 5 Feb 2013 02:54:28 +0000
> Subject: [PATCH] fuse: consistently use readdirplus offsets
>
> With adaptive readdirplus, filesystems may switch between normal
> readdir or readdirplus requests.  However, directory offsets
> must be maintained consistently to prevent the kernel from
> misinterpreting the offsets between different requests which
> may use the same buffer.
>
> Signed-off-by: Eric Wong <normalperson-rMlxZR9MS24@public.gmane.org>
> ---
>  fs/fuse/dir.c |    7 +++----
>  1 file changed, 3 insertions(+), 4 deletions(-)
>
> diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c
> index dc5e648..a8e4abb 100644
> --- a/fs/fuse/dir.c
> +++ b/fs/fuse/dir.c
> @@ -1313,7 +1313,7 @@ static int parse_dirplusfile(char *buf, size_t nbytes, struct file *file,
>
>  static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>  {
> -       int plus, err;
> +       int err;
>         size_t nbytes;
>         struct page *page;
>         struct inode *inode = file->f_path.dentry->d_inode;
> @@ -1334,12 +1334,11 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>                 return -ENOMEM;
>         }
>
> -       plus = fuse_use_readdirplus(inode, file);
>         req->out.argpages = 1;
>         req->num_pages = 1;
>         req->pages[0] = page;
>         req->page_descs[0].length = PAGE_SIZE;
> -       if (plus) {
> +       if (fuse_use_readdirplus(inode, file)) {
>                 attr_version = fuse_get_attr_version(fc);
>                 fuse_read_fill(req, file, file->f_pos, PAGE_SIZE,
>                                FUSE_READDIRPLUS);
> @@ -1352,7 +1351,7 @@ static int fuse_readdir(struct file *file, void *dstbuf, filldir_t filldir)
>         err = req->out.h.error;
>         fuse_put_request(fc, req);
>         if (!err) {
> -               if (plus) {
> +               if (fc->do_readdirplus) {
>                         err = parse_dirplusfile(page_address(page), nbytes,
>                                                 file, dstbuf, filldir,
>                                                 attr_version);
> --
> Eric Wong

------------------------------------------------------------------------------
Free Next-Gen Firewall Hardware Offer
Buy your Sophos next-gen firewall before the end March 2013 
and get the hardware for free! Learn more.
http://p.sf.net/sfu/sophos-d2d-feb

^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [RFC] fuse: consistently use readdirplus offsets
  2013-02-06 17:55                   ` Miklos Szeredi
@ 2013-02-06 21:40                     ` Eric Wong
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Wong @ 2013-02-06 21:40 UTC (permalink / raw)
  To: Miklos Szeredi
  Cc: Feng Shuo, fuse-devel, linux-fsdevel, Miklos Szeredi, Anand Avati

Miklos Szeredi <miklos@szeredi.hu> wrote:
> On Tue, Feb 5, 2013 at 4:12 AM, Eric Wong <normalperson@yhbt.net> wrote:
> > Miklos Szeredi <miklos@szeredi.hu> wrote:
> >> I think the problem is that directory offsets are not consistent
> >> between readdir and readdirplus.  The solution is that userspace
> >> should always use the same offsets.  This makes the readdirplus
> >> implementation more complex but that's really the only sane thing to
> >> do.
> >
> > I think something like the following is necessary in the kernel, too.
> > (Userspace patch coming)
> 
> Can you please explain what this patch is trying to do?  Because I
> think it's not doing what it wants ;)

I admit I'm not sure why your original email only said:

	userspace should always use the same offsets

instead of:

	kernel and userspace should always use the same offsets

This patch makes the kernel always use the same offsets, as does
v2 of my high-level userspace patch.

Anyways, I've tested this patch together with my v2 userspace patch and
got the results I expected with adaptive readdirplus.

Perhaps I have two bugs nullifying each other?

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2013-02-06 21:40 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <87mx1ngmip.fsf@tucsk.pomaz.szeredi.hu>
2013-01-15  3:23 ` [PATCH v3 0/2] FUSE: Adaptive NFS-like readdirplus support Feng Shuo
2013-01-15  3:23   ` [PATCH v3 1/2] fuse: implement " Feng Shuo
2013-01-15  3:23   ` [PATCH v3 2/2] FUSE: Adapt readdirplus to application usage patterns Feng Shuo
     [not found]     ` <1358220208-27131-3-git-send-email-steve.shuo.feng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-01-25 14:16       ` Miklos Szeredi
2013-02-03  7:15     ` Eric Wong
2013-02-03  8:10       ` Eric Wong
2013-02-04 10:03         ` Feng Shuo
2013-02-04 10:10           ` Eric Wong
2013-02-04 12:46             ` [fuse-devel] " Miklos Szeredi
     [not found]               ` <CAJfpegtKM6jsegxV+Jx0QkOEP6MhO6en6nEq7bCEJHxAAfMKHw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-02-04 13:20                 ` Eric Wong
2013-02-05  3:12               ` [RFC] fuse: consistently use readdirplus offsets Eric Wong
     [not found]                 ` <20130205031202.GA9062-yBiyF41qdooeIZ0/mPfg9Q@public.gmane.org>
2013-02-06 17:55                   ` Miklos Szeredi
2013-02-06 21:40                     ` Eric Wong

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.