This is a note to let you know that I've just added the patch titled
fuse: fix readdirplus Oops in fuse_dentry_revalidate
to the 3.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
fuse-fix-readdirplus-oops-in-fuse_dentry_revalidate.patch
and it can be found in the queue-3.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <[email protected]> know about it.
>From 28420dad233520811c0e0860e7fb4975ed863fc4 Mon Sep 17 00:00:00 2001
From: Miklos Szeredi <[email protected]>
Date: Mon, 3 Jun 2013 14:40:22 +0200
Subject: fuse: fix readdirplus Oops in fuse_dentry_revalidate
From: Miklos Szeredi <[email protected]>
commit 28420dad233520811c0e0860e7fb4975ed863fc4 upstream.
Fix bug introduced by commit 4582a4ab2a "FUSE: Adapt readdirplus to application
usage patterns".
We need to check for a positive dentry; negative dentries are not added by
readdirplus. Secondly we need to advise the use of readdirplus on the *parent*,
otherwise the whole thing is useless. Thirdly all this is only relevant if
"readdirplus_auto" mode is selected by the filesystem.
We advise the use of readdirplus only if the dentry was still valid. If we had
to redo the lookup then there was no use in doing the -plus version.
Reported-by: Bernd Schubert <[email protected]>
Signed-off-by: Miklos Szeredi <[email protected]>
CC: Feng Shuo <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
---
fs/fuse/dir.c | 12 +++++++++---
fs/fuse/inode.c | 7 ++++---
2 files changed, 13 insertions(+), 6 deletions(-)
--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -180,6 +180,8 @@ u64 fuse_get_attr_version(struct fuse_co
static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
{
struct inode *inode;
+ struct dentry *parent;
+ struct fuse_conn *fc;
inode = ACCESS_ONCE(entry->d_inode);
if (inode && is_bad_inode(inode))
@@ -187,10 +189,8 @@ static int fuse_dentry_revalidate(struct
else if (fuse_dentry_time(entry) < get_jiffies_64()) {
int err;
struct fuse_entry_out outarg;
- struct fuse_conn *fc;
struct fuse_req *req;
struct fuse_forget_link *forget;
- struct dentry *parent;
u64 attr_version;
/* For negative dentries, always do a fresh lookup */
@@ -241,8 +241,14 @@ static int fuse_dentry_revalidate(struct
entry_attr_timeout(&outarg),
attr_version);
fuse_change_entry_timeout(entry, &outarg);
+ } else if (inode) {
+ fc = get_fuse_conn(inode);
+ if (fc->readdirplus_auto) {
+ parent = dget_parent(entry);
+ fuse_advise_use_readdirplus(parent->d_inode);
+ dput(parent);
+ }
}
- fuse_advise_use_readdirplus(inode);
return 1;
}
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -864,10 +864,11 @@ static void process_init_reply(struct fu
fc->dont_mask = 1;
if (arg->flags & FUSE_AUTO_INVAL_DATA)
fc->auto_inval_data = 1;
- if (arg->flags & FUSE_DO_READDIRPLUS)
+ if (arg->flags & FUSE_DO_READDIRPLUS) {
fc->do_readdirplus = 1;
- if (arg->flags & FUSE_READDIRPLUS_AUTO)
- fc->readdirplus_auto = 1;
+ if (arg->flags & FUSE_READDIRPLUS_AUTO)
+ fc->readdirplus_auto = 1;
+ }
} else {
ra_pages = fc->max_read / PAGE_CACHE_SIZE;
fc->no_lock = 1;
Patches currently in stable-queue which might be from [email protected] are
queue-3.9/fuse-fix-readdirplus-oops-in-fuse_dentry_revalidate.patch
--
To unsubscribe from this list: send the line "unsubscribe stable" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html