All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/34] vfs: add the ability to retry lookup and operation to most path-based syscalls
@ 2012-11-05 15:21 ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

This patchset retrofits most of the path-based syscalls in the kernel to
retry the lookup and operation when the operation returns ESTALE. There
might be a few more that need similar changes afterward, but this should
cover most of the ones people are interested in.

The prerequisite patches for this set were merged in 3.7. I think that
these are appropriate for 3.8. There are some changes since I last
posted the set:

- the do_unlinkat patch has been respun to reorganize the function for
  greater clarity. It now uses a do-while loop and a comment has been
  added that points out the need to reset the "inode" variable on each
  pass through the loop.

- a few of the patches were not setting the "retry" arguments on some
  of the path lookup wrappers properly. Those have now been fixed so
  the code should now properly set LOOKUP_REVAL on lookup reattempts.

- I've also added a patches to ensure that lookups are making forward
  progress. This is necessary to prevent fruitless retries on a path
  based syscall when the process' cwd goes stale. We don't really
  need this though unless we plan to add the tunable to allow more
  retries.

- A patch to add a sliding backoff delay between timeouts has been
  added. This is a nice-to-have if we're planning to make the estale
  retries tunable.

I'm happy to report that with this set, I was able to run Peter
Staubach's reproducer program from 2008 for as long as I liked providing
I cranked up the estale_retries value to a large number. [1]

At the very least, I'd like to see the first 28 patches merged for 3.8.

The rest are not strictly needed unless we want to make the number of
retry attempts tunable. I've added them here since they demonstrate how
I tested these patches. It's too hard to verify that they actually do
what they're supposed to if you only retry once.

These patches are also available in the "estale" branch of my git tree
if that makes it easier to merge them:

    git://git.samba.org/jlayton/linux.git estale

[1]: Peter's test program is here: https://lkml.org/lkml/2008/1/18/265
     I commented out the inotify_test since I haven't patched those
     syscalls. The test was done by running this program on the server
     and the client at the same time in the same directory. If I
     cranked up estale_retries to a large value (10000000 or so), then
     it would run indefinitely.

Jeff Layton (34):
  vfs: add a retry_estale helper function to handle retries on ESTALE
  vfs: make fstatat retry on ESTALE errors from getattr call
  vfs: fix readlinkat to retry on ESTALE
  vfs: add new "reval" argument to kern_path_create and
    user_path_create
  vfs: fix mknodat to retry on ESTALE errors
  vfs: fix mkdir to retry on ESTALE errors
  vfs: fix symlinkat to retry on ESTALE errors
  vfs: fix linkat to retry on ESTALE errors
  vfs: add a reval argument to user_path_parent
  vfs: make rmdir retry on ESTALE errors
  vfs: make do_unlinkat retry on ESTALE errors
  vfs: fix renameat to retry on ESTALE errors
  vfs: have do_sys_truncate retry once on an ESTALE error
  vfs: have faccessat retry once on an ESTALE error
  vfs: have chdir retry lookup and call once on ESTALE error
  vfs: make chroot retry once on ESTALE error
  vfs: make fchmodat retry once on ESTALE errors
  vfs: make fchownat retry once on ESTALE errors
  vfs: fix user_statfs to retry once on ESTALE errors
  vfs: allow utimensat() calls to retry once on an ESTALE error
  vfs: allow setxattr to retry once on ESTALE errors
  vfs: allow lsetxattr() to retry once on ESTALE errors
  vfs: make getxattr retry once on an ESTALE error
  vfs: make lgetxattr retry once on ESTALE
  vfs: make listxattr retry once on ESTALE error
  vfs: make llistxattr retry once on ESTALE error
  vfs: make removexattr retry once on ESTALE
  vfs: make lremovexattr retry once on ESTALE error
  vfs: convert do_filp_open to use retry_estale helper
  vfs: convert do_file_open_root to use retry_estale helper
  vfs: convert filename_lookup to use retry_estale helper
  vfs: ensure that forward progress is being made on pathwalks
  vfs: make number of ESTALE retries tunable
  vfs: add a sliding backoff delay between ESTALE retries

 arch/powerpc/platforms/cell/spufs/syscalls.c |   2 +-
 drivers/base/devtmpfs.c                      |   7 +-
 fs/namei.c                                   | 404 ++++++++++++++++++---------
 fs/ocfs2/refcounttree.c                      |   3 +-
 fs/open.c                                    | 252 +++++++++--------
 fs/stat.c                                    |  32 ++-
 fs/statfs.c                                  |  14 +-
 fs/utimes.c                                  |  17 +-
 fs/xattr.c                                   | 152 ++++++----
 include/linux/fs.h                           |  22 ++
 include/linux/namei.h                        |   4 +-
 kernel/sysctl.c                              |   7 +
 net/unix/af_unix.c                           |   2 +-
 13 files changed, 582 insertions(+), 336 deletions(-)

-- 
1.7.11.7


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

* [PATCH v9 00/34] vfs: add the ability to retry lookup and operation to most path-based syscalls
@ 2012-11-05 15:21 ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
	pstaubach-83r9SdEf25FBDgjK7y7TUQ

This patchset retrofits most of the path-based syscalls in the kernel to
retry the lookup and operation when the operation returns ESTALE. There
might be a few more that need similar changes afterward, but this should
cover most of the ones people are interested in.

The prerequisite patches for this set were merged in 3.7. I think that
these are appropriate for 3.8. There are some changes since I last
posted the set:

- the do_unlinkat patch has been respun to reorganize the function for
  greater clarity. It now uses a do-while loop and a comment has been
  added that points out the need to reset the "inode" variable on each
  pass through the loop.

- a few of the patches were not setting the "retry" arguments on some
  of the path lookup wrappers properly. Those have now been fixed so
  the code should now properly set LOOKUP_REVAL on lookup reattempts.

- I've also added a patches to ensure that lookups are making forward
  progress. This is necessary to prevent fruitless retries on a path
  based syscall when the process' cwd goes stale. We don't really
  need this though unless we plan to add the tunable to allow more
  retries.

- A patch to add a sliding backoff delay between timeouts has been
  added. This is a nice-to-have if we're planning to make the estale
  retries tunable.

I'm happy to report that with this set, I was able to run Peter
Staubach's reproducer program from 2008 for as long as I liked providing
I cranked up the estale_retries value to a large number. [1]

At the very least, I'd like to see the first 28 patches merged for 3.8.

The rest are not strictly needed unless we want to make the number of
retry attempts tunable. I've added them here since they demonstrate how
I tested these patches. It's too hard to verify that they actually do
what they're supposed to if you only retry once.

These patches are also available in the "estale" branch of my git tree
if that makes it easier to merge them:

    git://git.samba.org/jlayton/linux.git estale

[1]: Peter's test program is here: https://lkml.org/lkml/2008/1/18/265
     I commented out the inotify_test since I haven't patched those
     syscalls. The test was done by running this program on the server
     and the client at the same time in the same directory. If I
     cranked up estale_retries to a large value (10000000 or so), then
     it would run indefinitely.

Jeff Layton (34):
  vfs: add a retry_estale helper function to handle retries on ESTALE
  vfs: make fstatat retry on ESTALE errors from getattr call
  vfs: fix readlinkat to retry on ESTALE
  vfs: add new "reval" argument to kern_path_create and
    user_path_create
  vfs: fix mknodat to retry on ESTALE errors
  vfs: fix mkdir to retry on ESTALE errors
  vfs: fix symlinkat to retry on ESTALE errors
  vfs: fix linkat to retry on ESTALE errors
  vfs: add a reval argument to user_path_parent
  vfs: make rmdir retry on ESTALE errors
  vfs: make do_unlinkat retry on ESTALE errors
  vfs: fix renameat to retry on ESTALE errors
  vfs: have do_sys_truncate retry once on an ESTALE error
  vfs: have faccessat retry once on an ESTALE error
  vfs: have chdir retry lookup and call once on ESTALE error
  vfs: make chroot retry once on ESTALE error
  vfs: make fchmodat retry once on ESTALE errors
  vfs: make fchownat retry once on ESTALE errors
  vfs: fix user_statfs to retry once on ESTALE errors
  vfs: allow utimensat() calls to retry once on an ESTALE error
  vfs: allow setxattr to retry once on ESTALE errors
  vfs: allow lsetxattr() to retry once on ESTALE errors
  vfs: make getxattr retry once on an ESTALE error
  vfs: make lgetxattr retry once on ESTALE
  vfs: make listxattr retry once on ESTALE error
  vfs: make llistxattr retry once on ESTALE error
  vfs: make removexattr retry once on ESTALE
  vfs: make lremovexattr retry once on ESTALE error
  vfs: convert do_filp_open to use retry_estale helper
  vfs: convert do_file_open_root to use retry_estale helper
  vfs: convert filename_lookup to use retry_estale helper
  vfs: ensure that forward progress is being made on pathwalks
  vfs: make number of ESTALE retries tunable
  vfs: add a sliding backoff delay between ESTALE retries

 arch/powerpc/platforms/cell/spufs/syscalls.c |   2 +-
 drivers/base/devtmpfs.c                      |   7 +-
 fs/namei.c                                   | 404 ++++++++++++++++++---------
 fs/ocfs2/refcounttree.c                      |   3 +-
 fs/open.c                                    | 252 +++++++++--------
 fs/stat.c                                    |  32 ++-
 fs/statfs.c                                  |  14 +-
 fs/utimes.c                                  |  17 +-
 fs/xattr.c                                   | 152 ++++++----
 include/linux/fs.h                           |  22 ++
 include/linux/namei.h                        |   4 +-
 kernel/sysctl.c                              |   7 +
 net/unix/af_unix.c                           |   2 +-
 13 files changed, 582 insertions(+), 336 deletions(-)

-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v9 01/34] vfs: add a retry_estale helper function to handle retries on ESTALE
  2012-11-05 15:21 ` Jeff Layton
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

This function is expected to be called from path-based syscalls to help
them decide whether to try the lookup and call again in the event that
they got an -ESTALE return back on an earier try.

Currently, we only retry the call once on an ESTALE error, but in the
event that we decide that that's not enough in the future, we should be
able to change the logic in this helper without too much effort.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 include/linux/fs.h | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/include/linux/fs.h b/include/linux/fs.h
index b33cfc9..3e42289 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2023,6 +2023,26 @@ extern int finish_open(struct file *file, struct dentry *dentry,
 			int *opened);
 extern int finish_no_open(struct file *file, struct dentry *dentry);
 
+/**
+ * retry_estale - determine whether the caller should retry an operation
+ * @error: the error that would currently be returned
+ * @try: number of tries already performed
+ *
+ * Check to see if the error code was -ESTALE, and then determine whether
+ * to retry the call based on the number of tries so far. Currently, we only
+ * retry the call once.
+ *
+ * Returns true if the caller should try the operation again.
+ */
+static inline bool
+retry_estale(const long error, const unsigned int try)
+{
+	if (likely(error != -ESTALE))
+		return false;
+
+	return !try;
+}
+
 /* fs/ioctl.c */
 
 extern int ioctl_preallocate(struct file *filp, void __user *argp);
-- 
1.7.11.7


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

* [PATCH v9 02/34] vfs: make fstatat retry on ESTALE errors from getattr call
  2012-11-05 15:21 ` Jeff Layton
  (?)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/stat.c | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index eae4946..c97a17e 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -74,7 +74,8 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 {
 	struct path path;
 	int error = -EINVAL;
-	int lookup_flags = 0;
+	unsigned int try = 0;
+	unsigned int lookup_flags = 0;
 
 	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT |
 		      AT_EMPTY_PATH)) != 0)
@@ -85,12 +86,15 @@ int vfs_fstatat(int dfd, const char __user *filename, struct kstat *stat,
 	if (flag & AT_EMPTY_PATH)
 		lookup_flags |= LOOKUP_EMPTY;
 
-	error = user_path_at(dfd, filename, lookup_flags, &path);
-	if (error)
-		goto out;
+	do {
+		error = user_path_at(dfd, filename, lookup_flags, &path);
+		if (error)
+			break;
 
-	error = vfs_getattr(path.mnt, path.dentry, stat);
-	path_put(&path);
+		error = vfs_getattr(path.mnt, path.dentry, stat);
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 out:
 	return error;
 }
-- 
1.7.11.7


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

* [PATCH v9 03/34] vfs: fix readlinkat to retry on ESTALE
  2012-11-05 15:21 ` Jeff Layton
                   ` (2 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/stat.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/fs/stat.c b/fs/stat.c
index c97a17e..452ee93 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -300,14 +300,21 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
 	struct path path;
 	int error;
 	int empty = 0;
+	unsigned int try = 0;
+	unsigned int lookup_flags = LOOKUP_EMPTY;
 
 	if (bufsiz <= 0)
 		return -EINVAL;
 
-	error = user_path_at_empty(dfd, pathname, LOOKUP_EMPTY, &path, &empty);
-	if (!error) {
-		struct inode *inode = path.dentry->d_inode;
+	do {
+		struct inode *inode;
+
+		error = user_path_at_empty(dfd, pathname, lookup_flags,
+					   &path, &empty);
+		if (error)
+			break;
 
+		inode = path.dentry->d_inode;
 		error = empty ? -ENOENT : -EINVAL;
 		if (inode->i_op->readlink) {
 			error = security_inode_readlink(path.dentry);
@@ -318,7 +325,8 @@ SYSCALL_DEFINE4(readlinkat, int, dfd, const char __user *, pathname,
 			}
 		}
 		path_put(&path);
-	}
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 04/34] vfs: add new "reval" argument to kern_path_create and user_path_create
@ 2012-11-05 15:21   ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

...for now, all of the callers pass in "false". Eventually, we'll set
that to "true" when we retry the lookup after getting back an ESTALE on
a call.

While we're at it, change the is_dir arg to a bool since that's how it's
used currently.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 arch/powerpc/platforms/cell/spufs/syscalls.c |  2 +-
 drivers/base/devtmpfs.c                      |  7 ++++---
 fs/namei.c                                   | 23 +++++++++++++++--------
 fs/ocfs2/refcounttree.c                      |  3 ++-
 include/linux/namei.h                        |  4 ++--
 net/unix/af_unix.c                           |  2 +-
 6 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 5b7d8ff..cb4acc7 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -66,7 +66,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
 	struct dentry *dentry;
 	int ret;
 
-	dentry = user_path_create(AT_FDCWD, pathname, &path, 1);
+	dentry = user_path_create(AT_FDCWD, pathname, &path, true, false);
 	ret = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
 		ret = spufs_create(&path, dentry, flags, mode, neighbor);
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 147d1a4..128e156 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -148,7 +148,7 @@ static int dev_mkdir(const char *name, umode_t mode)
 	struct path path;
 	int err;
 
-	dentry = kern_path_create(AT_FDCWD, name, &path, 1);
+	dentry = kern_path_create(AT_FDCWD, name, &path, true, false);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -193,10 +193,11 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
 	struct path path;
 	int err;
 
-	dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
+	dentry = kern_path_create(AT_FDCWD, nodename, &path, false, false);
 	if (dentry == ERR_PTR(-ENOENT)) {
 		create_path(nodename);
-		dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
+		dentry = kern_path_create(AT_FDCWD, nodename, &path,
+								false, false);
 	}
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
diff --git a/fs/namei.c b/fs/namei.c
index 937f9d5..8618a47 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3039,12 +3039,18 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
 	return file;
 }
 
-struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, int is_dir)
+struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, bool is_dir, bool reval)
 {
 	struct dentry *dentry = ERR_PTR(-EEXIST);
 	struct nameidata nd;
 	int err2;
-	int error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
+	int error;
+	unsigned int lookup_flags = LOOKUP_PARENT;
+
+	if (reval)
+		lookup_flags |= LOOKUP_REVAL;
+
+	error = do_path_lookup(dfd, pathname, lookup_flags, &nd);
 	if (error)
 		return ERR_PTR(error);
 
@@ -3108,13 +3114,14 @@ void done_path_create(struct path *path, struct dentry *dentry)
 }
 EXPORT_SYMBOL(done_path_create);
 
-struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir)
+struct dentry *user_path_create(int dfd, const char __user *pathname,
+				struct path *path, bool is_dir, bool reval)
 {
 	struct filename *tmp = getname(pathname);
 	struct dentry *res;
 	if (IS_ERR(tmp))
 		return ERR_CAST(tmp);
-	res = kern_path_create(dfd, tmp->name, path, is_dir);
+	res = kern_path_create(dfd, tmp->name, path, is_dir, reval);
 	putname(tmp);
 	return res;
 }
@@ -3175,7 +3182,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 	if (error)
 		return error;
 
-	dentry = user_path_create(dfd, filename, &path, 0);
+	dentry = user_path_create(dfd, filename, &path, false, false);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -3237,7 +3244,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
 	struct path path;
 	int error;
 
-	dentry = user_path_create(dfd, pathname, &path, 1);
+	dentry = user_path_create(dfd, pathname, &path, true, false);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -3513,7 +3520,7 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
 	if (IS_ERR(from))
 		return PTR_ERR(from);
 
-	dentry = user_path_create(newdfd, newname, &path, 0);
+	dentry = user_path_create(newdfd, newname, &path, false, false);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto out_putname;
@@ -3613,7 +3620,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 	if (error)
 		return error;
 
-	new_dentry = user_path_create(newdfd, newname, &new_path, 0);
+	new_dentry = user_path_create(newdfd, newname, &new_path, false, false);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
 		goto out;
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 30a0550..645e225 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4453,7 +4453,8 @@ int ocfs2_reflink_ioctl(struct inode *inode,
 		return error;
 	}
 
-	new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0);
+	new_dentry = user_path_create(AT_FDCWD, newname, &new_path,
+					false, false);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry)) {
 		mlog_errno(error);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 4bf19d8..2202740 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -65,8 +65,8 @@ extern int user_path_at_empty(int, const char __user *, unsigned, struct path *,
 
 extern int kern_path(const char *, unsigned, struct path *);
 
-extern struct dentry *kern_path_create(int, const char *, struct path *, int);
-extern struct dentry *user_path_create(int, const char __user *, struct path *, int);
+extern struct dentry *kern_path_create(int, const char *, struct path *, bool, bool);
+extern struct dentry *user_path_create(int, const char __user *, struct path *, bool, bool);
 extern void done_path_create(struct path *, struct dentry *);
 extern struct dentry *kern_path_locked(const char *, struct path *);
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 5b5c876..8ce6209 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -829,7 +829,7 @@ static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
 	 * Get the parent directory, calculate the hash for last
 	 * component.
 	 */
-	dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
+	dentry = kern_path_create(AT_FDCWD, sun_path, &path, false, false);
 	err = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		return err;
-- 
1.7.11.7


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

* [PATCH v9 04/34] vfs: add new "reval" argument to kern_path_create and user_path_create
@ 2012-11-05 15:21   ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
	pstaubach-83r9SdEf25FBDgjK7y7TUQ

...for now, all of the callers pass in "false". Eventually, we'll set
that to "true" when we retry the lookup after getting back an ESTALE on
a call.

While we're at it, change the is_dir arg to a bool since that's how it's
used currently.

Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 arch/powerpc/platforms/cell/spufs/syscalls.c |  2 +-
 drivers/base/devtmpfs.c                      |  7 ++++---
 fs/namei.c                                   | 23 +++++++++++++++--------
 fs/ocfs2/refcounttree.c                      |  3 ++-
 include/linux/namei.h                        |  4 ++--
 net/unix/af_unix.c                           |  2 +-
 6 files changed, 25 insertions(+), 16 deletions(-)

diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 5b7d8ff..cb4acc7 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -66,7 +66,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
 	struct dentry *dentry;
 	int ret;
 
-	dentry = user_path_create(AT_FDCWD, pathname, &path, 1);
+	dentry = user_path_create(AT_FDCWD, pathname, &path, true, false);
 	ret = PTR_ERR(dentry);
 	if (!IS_ERR(dentry)) {
 		ret = spufs_create(&path, dentry, flags, mode, neighbor);
diff --git a/drivers/base/devtmpfs.c b/drivers/base/devtmpfs.c
index 147d1a4..128e156 100644
--- a/drivers/base/devtmpfs.c
+++ b/drivers/base/devtmpfs.c
@@ -148,7 +148,7 @@ static int dev_mkdir(const char *name, umode_t mode)
 	struct path path;
 	int err;
 
-	dentry = kern_path_create(AT_FDCWD, name, &path, 1);
+	dentry = kern_path_create(AT_FDCWD, name, &path, true, false);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -193,10 +193,11 @@ static int handle_create(const char *nodename, umode_t mode, struct device *dev)
 	struct path path;
 	int err;
 
-	dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
+	dentry = kern_path_create(AT_FDCWD, nodename, &path, false, false);
 	if (dentry == ERR_PTR(-ENOENT)) {
 		create_path(nodename);
-		dentry = kern_path_create(AT_FDCWD, nodename, &path, 0);
+		dentry = kern_path_create(AT_FDCWD, nodename, &path,
+								false, false);
 	}
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
diff --git a/fs/namei.c b/fs/namei.c
index 937f9d5..8618a47 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3039,12 +3039,18 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
 	return file;
 }
 
-struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, int is_dir)
+struct dentry *kern_path_create(int dfd, const char *pathname, struct path *path, bool is_dir, bool reval)
 {
 	struct dentry *dentry = ERR_PTR(-EEXIST);
 	struct nameidata nd;
 	int err2;
-	int error = do_path_lookup(dfd, pathname, LOOKUP_PARENT, &nd);
+	int error;
+	unsigned int lookup_flags = LOOKUP_PARENT;
+
+	if (reval)
+		lookup_flags |= LOOKUP_REVAL;
+
+	error = do_path_lookup(dfd, pathname, lookup_flags, &nd);
 	if (error)
 		return ERR_PTR(error);
 
@@ -3108,13 +3114,14 @@ void done_path_create(struct path *path, struct dentry *dentry)
 }
 EXPORT_SYMBOL(done_path_create);
 
-struct dentry *user_path_create(int dfd, const char __user *pathname, struct path *path, int is_dir)
+struct dentry *user_path_create(int dfd, const char __user *pathname,
+				struct path *path, bool is_dir, bool reval)
 {
 	struct filename *tmp = getname(pathname);
 	struct dentry *res;
 	if (IS_ERR(tmp))
 		return ERR_CAST(tmp);
-	res = kern_path_create(dfd, tmp->name, path, is_dir);
+	res = kern_path_create(dfd, tmp->name, path, is_dir, reval);
 	putname(tmp);
 	return res;
 }
@@ -3175,7 +3182,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 	if (error)
 		return error;
 
-	dentry = user_path_create(dfd, filename, &path, 0);
+	dentry = user_path_create(dfd, filename, &path, false, false);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -3237,7 +3244,7 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
 	struct path path;
 	int error;
 
-	dentry = user_path_create(dfd, pathname, &path, 1);
+	dentry = user_path_create(dfd, pathname, &path, true, false);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
@@ -3513,7 +3520,7 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
 	if (IS_ERR(from))
 		return PTR_ERR(from);
 
-	dentry = user_path_create(newdfd, newname, &path, 0);
+	dentry = user_path_create(newdfd, newname, &path, false, false);
 	error = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		goto out_putname;
@@ -3613,7 +3620,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 	if (error)
 		return error;
 
-	new_dentry = user_path_create(newdfd, newname, &new_path, 0);
+	new_dentry = user_path_create(newdfd, newname, &new_path, false, false);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry))
 		goto out;
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c
index 30a0550..645e225 100644
--- a/fs/ocfs2/refcounttree.c
+++ b/fs/ocfs2/refcounttree.c
@@ -4453,7 +4453,8 @@ int ocfs2_reflink_ioctl(struct inode *inode,
 		return error;
 	}
 
-	new_dentry = user_path_create(AT_FDCWD, newname, &new_path, 0);
+	new_dentry = user_path_create(AT_FDCWD, newname, &new_path,
+					false, false);
 	error = PTR_ERR(new_dentry);
 	if (IS_ERR(new_dentry)) {
 		mlog_errno(error);
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 4bf19d8..2202740 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -65,8 +65,8 @@ extern int user_path_at_empty(int, const char __user *, unsigned, struct path *,
 
 extern int kern_path(const char *, unsigned, struct path *);
 
-extern struct dentry *kern_path_create(int, const char *, struct path *, int);
-extern struct dentry *user_path_create(int, const char __user *, struct path *, int);
+extern struct dentry *kern_path_create(int, const char *, struct path *, bool, bool);
+extern struct dentry *user_path_create(int, const char __user *, struct path *, bool, bool);
 extern void done_path_create(struct path *, struct dentry *);
 extern struct dentry *kern_path_locked(const char *, struct path *);
 extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 5b5c876..8ce6209 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -829,7 +829,7 @@ static int unix_mknod(const char *sun_path, umode_t mode, struct path *res)
 	 * Get the parent directory, calculate the hash for last
 	 * component.
 	 */
-	dentry = kern_path_create(AT_FDCWD, sun_path, &path, 0);
+	dentry = kern_path_create(AT_FDCWD, sun_path, &path, false, false);
 	err = PTR_ERR(dentry);
 	if (IS_ERR(dentry))
 		return err;
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v9 05/34] vfs: fix mknodat to retry on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (4 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 43 +++++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 8618a47..7311968 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3177,34 +3177,41 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
 	struct dentry *dentry;
 	struct path path;
 	int error;
+	unsigned int try = 0;
 
 	error = may_mknod(mode);
 	if (error)
 		return error;
 
-	dentry = user_path_create(dfd, filename, &path, false, false);
-	if (IS_ERR(dentry))
-		return PTR_ERR(dentry);
+	do {
+		dentry = user_path_create(dfd, filename, &path, false, try);
+		if (IS_ERR(dentry))
+			return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
-		mode &= ~current_umask();
-	error = security_path_mknod(&path, dentry, mode, dev);
-	if (error)
-		goto out;
-	switch (mode & S_IFMT) {
-		case 0: case S_IFREG:
-			error = vfs_create(path.dentry->d_inode,dentry,mode,true);
+		if (!IS_POSIXACL(path.dentry->d_inode))
+			mode &= ~current_umask();
+		error = security_path_mknod(&path, dentry, mode, dev);
+		if (error)
+			goto out;
+		switch (mode & S_IFMT) {
+		case 0:
+		case S_IFREG:
+			error = vfs_create(path.dentry->d_inode, dentry,
+					mode, true);
 			break;
-		case S_IFCHR: case S_IFBLK:
-			error = vfs_mknod(path.dentry->d_inode,dentry,mode,
+		case S_IFCHR:
+		case S_IFBLK:
+			error = vfs_mknod(path.dentry->d_inode, dentry, mode,
 					new_decode_dev(dev));
 			break;
-		case S_IFIFO: case S_IFSOCK:
-			error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
-			break;
-	}
+		case S_IFIFO:
+		case S_IFSOCK:
+			error = vfs_mknod(path.dentry->d_inode, dentry,
+					mode, 0);
+		}
 out:
-	done_path_create(&path, dentry);
+		done_path_create(&path, dentry);
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 06/34] vfs: fix mkdir to retry on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (5 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 7311968..04e4851 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3250,17 +3250,20 @@ SYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
 	struct dentry *dentry;
 	struct path path;
 	int error;
+	unsigned int try = 0;
 
-	dentry = user_path_create(dfd, pathname, &path, true, false);
-	if (IS_ERR(dentry))
-		return PTR_ERR(dentry);
+	do {
+		dentry = user_path_create(dfd, pathname, &path, true, try);
+		if (IS_ERR(dentry))
+			return PTR_ERR(dentry);
 
-	if (!IS_POSIXACL(path.dentry->d_inode))
-		mode &= ~current_umask();
-	error = security_path_mkdir(&path, dentry, mode);
-	if (!error)
-		error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
-	done_path_create(&path, dentry);
+		if (!IS_POSIXACL(path.dentry->d_inode))
+			mode &= ~current_umask();
+		error = security_path_mkdir(&path, dentry, mode);
+		if (!error)
+			error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
+		done_path_create(&path, dentry);
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 07/34] vfs: fix symlinkat to retry on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (6 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 22 +++++++++++++---------
 1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 04e4851..af1b473 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3525,21 +3525,25 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
 	struct filename *from;
 	struct dentry *dentry;
 	struct path path;
+	unsigned int try = 0;
 
 	from = getname(oldname);
 	if (IS_ERR(from))
 		return PTR_ERR(from);
 
-	dentry = user_path_create(newdfd, newname, &path, false, false);
-	error = PTR_ERR(dentry);
-	if (IS_ERR(dentry))
-		goto out_putname;
+	do {
+		dentry = user_path_create(newdfd, newname, &path, false, try);
+		if (IS_ERR(dentry)) {
+			error = PTR_ERR(dentry);
+			break;
+		}
 
-	error = security_path_symlink(&path, dentry, from->name);
-	if (!error)
-		error = vfs_symlink(path.dentry->d_inode, dentry, from->name);
-	done_path_create(&path, dentry);
-out_putname:
+		error = security_path_symlink(&path, dentry, from->name);
+		if (!error)
+			error = vfs_symlink(path.dentry->d_inode, dentry,
+						from->name);
+		done_path_create(&path, dentry);
+	} while (retry_estale(error, try++));
 	putname(from);
 	return error;
 }
-- 
1.7.11.7


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

* [PATCH v9 08/34] vfs: fix linkat to retry on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (7 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 46 ++++++++++++++++++++++++++--------------------
 1 file changed, 26 insertions(+), 20 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index af1b473..28d70cd 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3613,6 +3613,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 	struct path old_path, new_path;
 	int how = 0;
 	int error;
+	unsigned int try = 0;
 
 	if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0)
 		return -EINVAL;
@@ -3630,30 +3631,35 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
 	if (flags & AT_SYMLINK_FOLLOW)
 		how |= LOOKUP_FOLLOW;
 
-	error = user_path_at(olddfd, oldname, how, &old_path);
-	if (error)
-		return error;
+	do {
+		error = user_path_at(olddfd, oldname, how, &old_path);
+		if (error)
+			break;
 
-	new_dentry = user_path_create(newdfd, newname, &new_path, false, false);
-	error = PTR_ERR(new_dentry);
-	if (IS_ERR(new_dentry))
-		goto out;
+		new_dentry = user_path_create(newdfd, newname, &new_path,
+						false, try);
+		error = PTR_ERR(new_dentry);
+		if (IS_ERR(new_dentry))
+			goto out;
 
-	error = -EXDEV;
-	if (old_path.mnt != new_path.mnt)
-		goto out_dput;
-	error = may_linkat(&old_path);
-	if (unlikely(error))
-		goto out_dput;
-	error = security_path_link(old_path.dentry, &new_path, new_dentry);
-	if (error)
-		goto out_dput;
-	error = vfs_link(old_path.dentry, new_path.dentry->d_inode, new_dentry);
+		error = -EXDEV;
+		if (old_path.mnt != new_path.mnt)
+			goto out_dput;
+		error = may_linkat(&old_path);
+		if (unlikely(error))
+			goto out_dput;
+		error = security_path_link(old_path.dentry, &new_path,
+						new_dentry);
+		if (error)
+			goto out_dput;
+		error = vfs_link(old_path.dentry, new_path.dentry->d_inode,
+						new_dentry);
 out_dput:
-	done_path_create(&new_path, new_dentry);
+		done_path_create(&new_path, new_dentry);
 out:
-	path_put(&old_path);
-
+		path_put(&old_path);
+		how |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 09/34] vfs: add a reval argument to user_path_parent
  2012-11-05 15:21 ` Jeff Layton
                   ` (8 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

...so we can tell it when to set LOOKUP_REVAL.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 28d70cd..1569ccd 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2184,15 +2184,20 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
  *     path-walking is complete.
  */
 static struct filename *
-user_path_parent(int dfd, const char __user *path, struct nameidata *nd)
+user_path_parent(int dfd, const char __user *path, struct nameidata *nd,
+		 unsigned int reval)
 {
 	struct filename *s = getname(path);
 	int error;
+	unsigned int flags = LOOKUP_PARENT;
+
+	if (reval)
+		flags |= LOOKUP_REVAL;
 
 	if (IS_ERR(s))
 		return s;
 
-	error = filename_lookup(dfd, s, LOOKUP_PARENT, nd);
+	error = filename_lookup(dfd, s, flags, nd);
 	if (error) {
 		putname(s);
 		return ERR_PTR(error);
@@ -3340,7 +3345,7 @@ static long do_rmdir(int dfd, const char __user *pathname)
 	struct dentry *dentry;
 	struct nameidata nd;
 
-	name = user_path_parent(dfd, pathname, &nd);
+	name = user_path_parent(dfd, pathname, &nd, 0);
 	if (IS_ERR(name))
 		return PTR_ERR(name);
 
@@ -3436,7 +3441,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
 	struct nameidata nd;
 	struct inode *inode = NULL;
 
-	name = user_path_parent(dfd, pathname, &nd);
+	name = user_path_parent(dfd, pathname, &nd, 0);
 	if (IS_ERR(name))
 		return PTR_ERR(name);
 
@@ -3831,13 +3836,13 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
 	struct filename *to;
 	int error;
 
-	from = user_path_parent(olddfd, oldname, &oldnd);
+	from = user_path_parent(olddfd, oldname, &oldnd, 0);
 	if (IS_ERR(from)) {
 		error = PTR_ERR(from);
 		goto exit;
 	}
 
-	to = user_path_parent(newdfd, newname, &newnd);
+	to = user_path_parent(newdfd, newname, &newnd, 0);
 	if (IS_ERR(to)) {
 		error = PTR_ERR(to);
 		goto exit1;
-- 
1.7.11.7


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

* [PATCH v9 10/34] vfs: make rmdir retry on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (9 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 79 +++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 42 insertions(+), 37 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 1569ccd..0b70e6d 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3344,49 +3344,54 @@ static long do_rmdir(int dfd, const char __user *pathname)
 	struct filename *name;
 	struct dentry *dentry;
 	struct nameidata nd;
+	unsigned int try = 0;
 
-	name = user_path_parent(dfd, pathname, &nd, 0);
-	if (IS_ERR(name))
-		return PTR_ERR(name);
-
-	switch(nd.last_type) {
-	case LAST_DOTDOT:
-		error = -ENOTEMPTY;
-		goto exit1;
-	case LAST_DOT:
-		error = -EINVAL;
-		goto exit1;
-	case LAST_ROOT:
-		error = -EBUSY;
-		goto exit1;
-	}
+	do {
+		name = user_path_parent(dfd, pathname, &nd, try);
+		if (IS_ERR(name))
+			return PTR_ERR(name);
+
+		switch (nd.last_type) {
+		case LAST_DOTDOT:
+			error = -ENOTEMPTY;
+			goto exit1;
+		case LAST_DOT:
+			error = -EINVAL;
+			goto exit1;
+		case LAST_ROOT:
+			error = -EBUSY;
+			goto exit1;
+		}
 
-	nd.flags &= ~LOOKUP_PARENT;
-	error = mnt_want_write(nd.path.mnt);
-	if (error)
-		goto exit1;
+		nd.flags &= ~LOOKUP_PARENT;
+		error = mnt_want_write(nd.path.mnt);
+		if (error)
+			goto exit1;
 
-	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
-	dentry = lookup_hash(&nd);
-	error = PTR_ERR(dentry);
-	if (IS_ERR(dentry))
-		goto exit2;
-	if (!dentry->d_inode) {
-		error = -ENOENT;
-		goto exit3;
-	}
-	error = security_path_rmdir(&nd.path, dentry);
-	if (error)
-		goto exit3;
-	error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
+		mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex,
+					I_MUTEX_PARENT);
+		dentry = lookup_hash(&nd);
+		if (IS_ERR(dentry)) {
+			error = PTR_ERR(dentry);
+			goto exit2;
+		}
+		if (!dentry->d_inode) {
+			error = -ENOENT;
+			goto exit3;
+		}
+		error = security_path_rmdir(&nd.path, dentry);
+		if (error)
+			goto exit3;
+		error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
 exit3:
-	dput(dentry);
+		dput(dentry);
 exit2:
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
-	mnt_drop_write(nd.path.mnt);
+		mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+		mnt_drop_write(nd.path.mnt);
 exit1:
-	path_put(&nd.path);
-	putname(name);
+		path_put(&nd.path);
+		putname(name);
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 11/34] vfs: make do_unlinkat retry on ESTALE errors
@ 2012-11-05 15:21   ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 87 +++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 52 insertions(+), 35 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 0b70e6d..fb5a084 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3432,6 +3432,13 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
 	return error;
 }
 
+/* Return an appropriate error code for unlink, based on the inode */
+static inline int
+unlinkat_slashes(struct inode *inode)
+{
+	return !inode ? -ENOENT : S_ISDIR(inode->i_mode) ? -EISDIR : -ENOTDIR;
+}
+
 /*
  * Make sure that the actual truncation of the file will occur outside its
  * directory's i_mutex.  Truncate can take a long time if there is a lot of
@@ -3444,52 +3451,62 @@ static long do_unlinkat(int dfd, const char __user *pathname)
 	struct filename *name;
 	struct dentry *dentry;
 	struct nameidata nd;
-	struct inode *inode = NULL;
+	unsigned int try = 0;
 
-	name = user_path_parent(dfd, pathname, &nd, 0);
-	if (IS_ERR(name))
-		return PTR_ERR(name);
+	do {
+		/* Must ensure that this is reset on each pass */
+		struct inode *inode = NULL;
 
-	error = -EISDIR;
-	if (nd.last_type != LAST_NORM)
-		goto exit1;
+		name = user_path_parent(dfd, pathname, &nd, try);
+		if (IS_ERR(name)) {
+			error = PTR_ERR(name);
+			break;
+		}
 
-	nd.flags &= ~LOOKUP_PARENT;
-	error = mnt_want_write(nd.path.mnt);
-	if (error)
-		goto exit1;
+		error = -EISDIR;
+		if (nd.last_type != LAST_NORM)
+			goto exit1;
+
+		nd.flags &= ~LOOKUP_PARENT;
+		error = mnt_want_write(nd.path.mnt);
+		if (error)
+			goto exit1;
+
+		mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex,
+							I_MUTEX_PARENT);
+		dentry = lookup_hash(&nd);
+		error = PTR_ERR(dentry);
+		if (IS_ERR(dentry))
+			goto exit2;
 
-	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
-	dentry = lookup_hash(&nd);
-	error = PTR_ERR(dentry);
-	if (!IS_ERR(dentry)) {
 		/* Why not before? Because we want correct error value */
-		if (nd.last.name[nd.last.len])
-			goto slashes;
+		if (nd.last.name[nd.last.len]) {
+			error = unlinkat_slashes(dentry->d_inode);
+			goto exit3;
+		}
+
 		inode = dentry->d_inode;
-		if (!inode)
-			goto slashes;
+		if (!inode) {
+			error = -ENOENT;
+			goto exit3;
+		}
 		ihold(inode);
+
 		error = security_path_unlink(&nd.path, dentry);
-		if (error)
-			goto exit2;
-		error = vfs_unlink(nd.path.dentry->d_inode, dentry);
-exit2:
+		if (!error)
+			error = vfs_unlink(nd.path.dentry->d_inode, dentry);
+exit3:
 		dput(dentry);
-	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
-	if (inode)
-		iput(inode);	/* truncate the inode here */
-	mnt_drop_write(nd.path.mnt);
+exit2:
+		mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+		if (inode)
+			iput(inode);	/* truncate the inode here */
+		mnt_drop_write(nd.path.mnt);
 exit1:
-	path_put(&nd.path);
-	putname(name);
+		path_put(&nd.path);
+		putname(name);
+	} while (retry_estale(error, try++));
 	return error;
-
-slashes:
-	error = !dentry->d_inode ? -ENOENT :
-		S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
-	goto exit2;
 }
 
 SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
-- 
1.7.11.7


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

* [PATCH v9 11/34] vfs: make do_unlinkat retry on ESTALE errors
@ 2012-11-05 15:21   ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
	pstaubach-83r9SdEf25FBDgjK7y7TUQ

Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 fs/namei.c | 87 +++++++++++++++++++++++++++++++++++++-------------------------
 1 file changed, 52 insertions(+), 35 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 0b70e6d..fb5a084 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3432,6 +3432,13 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
 	return error;
 }
 
+/* Return an appropriate error code for unlink, based on the inode */
+static inline int
+unlinkat_slashes(struct inode *inode)
+{
+	return !inode ? -ENOENT : S_ISDIR(inode->i_mode) ? -EISDIR : -ENOTDIR;
+}
+
 /*
  * Make sure that the actual truncation of the file will occur outside its
  * directory's i_mutex.  Truncate can take a long time if there is a lot of
@@ -3444,52 +3451,62 @@ static long do_unlinkat(int dfd, const char __user *pathname)
 	struct filename *name;
 	struct dentry *dentry;
 	struct nameidata nd;
-	struct inode *inode = NULL;
+	unsigned int try = 0;
 
-	name = user_path_parent(dfd, pathname, &nd, 0);
-	if (IS_ERR(name))
-		return PTR_ERR(name);
+	do {
+		/* Must ensure that this is reset on each pass */
+		struct inode *inode = NULL;
 
-	error = -EISDIR;
-	if (nd.last_type != LAST_NORM)
-		goto exit1;
+		name = user_path_parent(dfd, pathname, &nd, try);
+		if (IS_ERR(name)) {
+			error = PTR_ERR(name);
+			break;
+		}
 
-	nd.flags &= ~LOOKUP_PARENT;
-	error = mnt_want_write(nd.path.mnt);
-	if (error)
-		goto exit1;
+		error = -EISDIR;
+		if (nd.last_type != LAST_NORM)
+			goto exit1;
+
+		nd.flags &= ~LOOKUP_PARENT;
+		error = mnt_want_write(nd.path.mnt);
+		if (error)
+			goto exit1;
+
+		mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex,
+							I_MUTEX_PARENT);
+		dentry = lookup_hash(&nd);
+		error = PTR_ERR(dentry);
+		if (IS_ERR(dentry))
+			goto exit2;
 
-	mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
-	dentry = lookup_hash(&nd);
-	error = PTR_ERR(dentry);
-	if (!IS_ERR(dentry)) {
 		/* Why not before? Because we want correct error value */
-		if (nd.last.name[nd.last.len])
-			goto slashes;
+		if (nd.last.name[nd.last.len]) {
+			error = unlinkat_slashes(dentry->d_inode);
+			goto exit3;
+		}
+
 		inode = dentry->d_inode;
-		if (!inode)
-			goto slashes;
+		if (!inode) {
+			error = -ENOENT;
+			goto exit3;
+		}
 		ihold(inode);
+
 		error = security_path_unlink(&nd.path, dentry);
-		if (error)
-			goto exit2;
-		error = vfs_unlink(nd.path.dentry->d_inode, dentry);
-exit2:
+		if (!error)
+			error = vfs_unlink(nd.path.dentry->d_inode, dentry);
+exit3:
 		dput(dentry);
-	}
-	mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
-	if (inode)
-		iput(inode);	/* truncate the inode here */
-	mnt_drop_write(nd.path.mnt);
+exit2:
+		mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+		if (inode)
+			iput(inode);	/* truncate the inode here */
+		mnt_drop_write(nd.path.mnt);
 exit1:
-	path_put(&nd.path);
-	putname(name);
+		path_put(&nd.path);
+		putname(name);
+	} while (retry_estale(error, try++));
 	return error;
-
-slashes:
-	error = !dentry->d_inode ? -ENOENT :
-		S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR;
-	goto exit2;
 }
 
 SYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCH v9 12/34] vfs: fix renameat to retry on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (11 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

...as always, rename is the messiest of the bunch. We have to track
whether to retry or not via a separate flag since the error handling
is already quite complex.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index fb5a084..39adf1b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3856,15 +3856,18 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
 	struct nameidata oldnd, newnd;
 	struct filename *from;
 	struct filename *to;
+	unsigned int try = 0;
+	bool should_retry = false;
 	int error;
 
-	from = user_path_parent(olddfd, oldname, &oldnd, 0);
+retry:
+	from = user_path_parent(olddfd, oldname, &oldnd, try);
 	if (IS_ERR(from)) {
 		error = PTR_ERR(from);
 		goto exit;
 	}
 
-	to = user_path_parent(newdfd, newname, &newnd, 0);
+	to = user_path_parent(newdfd, newname, &newnd, try);
 	if (IS_ERR(to)) {
 		error = PTR_ERR(to);
 		goto exit1;
@@ -3936,11 +3939,17 @@ exit3:
 	unlock_rename(new_dir, old_dir);
 	mnt_drop_write(oldnd.path.mnt);
 exit2:
+	if (retry_estale(error, try++))
+		should_retry = true;
 	path_put(&newnd.path);
 	putname(to);
 exit1:
 	path_put(&oldnd.path);
 	putname(from);
+	if (should_retry) {
+		should_retry = false;
+		goto retry;
+	}
 exit:
 	return error;
 }
-- 
1.7.11.7


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

* [PATCH v9 13/34] vfs: have do_sys_truncate retry once on an ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (12 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/open.c | 86 +++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 45 insertions(+), 41 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 94d5649..2a32d5c 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -66,62 +66,66 @@ static long do_sys_truncate(const char __user *pathname, loff_t length)
 	struct path path;
 	struct inode *inode;
 	int error;
+	unsigned int lookup_flags = LOOKUP_FOLLOW;
+	unsigned int try = 0;
 
-	error = -EINVAL;
 	if (length < 0)	/* sorry, but loff_t says... */
-		goto out;
+		return -EINVAL;
 
-	error = user_path(pathname, &path);
-	if (error)
-		goto out;
-	inode = path.dentry->d_inode;
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		inode = path.dentry->d_inode;
 
-	/* For directories it's -EISDIR, for other non-regulars - -EINVAL */
-	error = -EISDIR;
-	if (S_ISDIR(inode->i_mode))
-		goto dput_and_out;
+		/* For dirs, -EISDIR. For other non-regulars, -EINVAL */
+		error = -EISDIR;
+		if (S_ISDIR(inode->i_mode))
+			goto dput_and_out;
 
-	error = -EINVAL;
-	if (!S_ISREG(inode->i_mode))
-		goto dput_and_out;
+		error = -EINVAL;
+		if (!S_ISREG(inode->i_mode))
+			goto dput_and_out;
 
-	error = mnt_want_write(path.mnt);
-	if (error)
-		goto dput_and_out;
+		error = mnt_want_write(path.mnt);
+		if (error)
+			goto dput_and_out;
 
-	error = inode_permission(inode, MAY_WRITE);
-	if (error)
-		goto mnt_drop_write_and_out;
+		error = inode_permission(inode, MAY_WRITE);
+		if (error)
+			goto mnt_drop_write_and_out;
 
-	error = -EPERM;
-	if (IS_APPEND(inode))
-		goto mnt_drop_write_and_out;
+		error = -EPERM;
+		if (IS_APPEND(inode))
+			goto mnt_drop_write_and_out;
 
-	error = get_write_access(inode);
-	if (error)
-		goto mnt_drop_write_and_out;
+		error = get_write_access(inode);
+		if (error)
+			goto mnt_drop_write_and_out;
 
-	/*
-	 * Make sure that there are no leases.  get_write_access() protects
-	 * against the truncate racing with a lease-granting setlease().
-	 */
-	error = break_lease(inode, O_WRONLY);
-	if (error)
-		goto put_write_and_out;
+		/*
+		 * Make sure that there are no leases. get_write_access()
+		 * protects against the truncate racing with a lease-granting
+		 * setlease().
+		 */
+		error = break_lease(inode, O_WRONLY);
+		if (error)
+			goto put_write_and_out;
 
-	error = locks_verify_truncate(inode, NULL, length);
-	if (!error)
-		error = security_path_truncate(&path);
-	if (!error)
-		error = do_truncate(path.dentry, length, 0, NULL);
+		error = locks_verify_truncate(inode, NULL, length);
+		if (!error)
+			error = security_path_truncate(&path);
+		if (!error)
+			error = do_truncate(path.dentry, length, 0, NULL);
 
 put_write_and_out:
-	put_write_access(inode);
+		put_write_access(inode);
 mnt_drop_write_and_out:
-	mnt_drop_write(path.mnt);
+		mnt_drop_write(path.mnt);
 dput_and_out:
-	path_put(&path);
-out:
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 14/34] vfs: have faccessat retry once on an ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (13 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/open.c | 64 +++++++++++++++++++++++++++++++++------------------------------
 1 file changed, 34 insertions(+), 30 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 2a32d5c..9cd0a50 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -310,6 +310,8 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
 	struct path path;
 	struct inode *inode;
 	int res;
+	unsigned int lookup_flags = LOOKUP_FOLLOW;
+	unsigned int try = 0;
 
 	if (mode & ~S_IRWXO)	/* where's F_OK, X_OK, W_OK, R_OK? */
 		return -EINVAL;
@@ -333,42 +335,44 @@ SYSCALL_DEFINE3(faccessat, int, dfd, const char __user *, filename, int, mode)
 
 	old_cred = override_creds(override_cred);
 
-	res = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
-	if (res)
-		goto out;
+	do {
+		res = user_path_at(dfd, filename, lookup_flags, &path);
+		if (res)
+			break;
 
-	inode = path.dentry->d_inode;
+		inode = path.dentry->d_inode;
+
+		if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) {
+			/*
+			 * MAY_EXEC on regular files is denied if the fs is
+			 * mounted with the "noexec" flag.
+			 */
+			res = -EACCES;
+			if (path.mnt->mnt_flags & MNT_NOEXEC)
+				goto out_path_release;
+		}
 
-	if ((mode & MAY_EXEC) && S_ISREG(inode->i_mode)) {
+		res = inode_permission(inode, mode | MAY_ACCESS);
+		/* SuS v2 requires we report a read only fs too */
+		if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
+			goto out_path_release;
 		/*
-		 * MAY_EXEC on regular files is denied if the fs is mounted
-		 * with the "noexec" flag.
+		 * This is a rare case where using __mnt_is_readonly()
+		 * is OK without a mnt_want/drop_write() pair.  Since
+		 * no actual write to the fs is performed here, we do
+		 * not need to telegraph to that to anyone.
+		 *
+		 * By doing this, we accept that this access is
+		 * inherently racy and know that the fs may change
+		 * state before we even see this result.
 		 */
-		res = -EACCES;
-		if (path.mnt->mnt_flags & MNT_NOEXEC)
-			goto out_path_release;
-	}
-
-	res = inode_permission(inode, mode | MAY_ACCESS);
-	/* SuS v2 requires we report a read only fs too */
-	if (res || !(mode & S_IWOTH) || special_file(inode->i_mode))
-		goto out_path_release;
-	/*
-	 * This is a rare case where using __mnt_is_readonly()
-	 * is OK without a mnt_want/drop_write() pair.  Since
-	 * no actual write to the fs is performed here, we do
-	 * not need to telegraph to that to anyone.
-	 *
-	 * By doing this, we accept that this access is
-	 * inherently racy and know that the fs may change
-	 * state before we even see this result.
-	 */
-	if (__mnt_is_readonly(path.mnt))
-		res = -EROFS;
+		if (__mnt_is_readonly(path.mnt))
+			res = -EROFS;
 
 out_path_release:
-	path_put(&path);
-out:
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(res, try++));
 	revert_creds(old_cred);
 	put_cred(override_cred);
 	return res;
-- 
1.7.11.7


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

* [PATCH v9 15/34] vfs: have chdir retry lookup and call once on ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (14 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/open.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 9cd0a50..5c2a973 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -387,20 +387,21 @@ SYSCALL_DEFINE1(chdir, const char __user *, filename)
 {
 	struct path path;
 	int error;
+	int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
+	unsigned int try = 0;
 
-	error = user_path_dir(filename, &path);
-	if (error)
-		goto out;
-
-	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
-	if (error)
-		goto dput_and_out;
-
-	set_fs_pwd(current->fs, &path);
+	do {
+		error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
+		if (error)
+			break;
 
-dput_and_out:
-	path_put(&path);
-out:
+		error = inode_permission(path.dentry->d_inode,
+					 MAY_EXEC | MAY_CHDIR);
+		if (!error)
+			set_fs_pwd(current->fs, &path);
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 16/34] vfs: make chroot retry once on ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (15 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/open.c | 37 +++++++++++++++++++++----------------
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 5c2a973..a1331f1 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -434,27 +434,32 @@ SYSCALL_DEFINE1(chroot, const char __user *, filename)
 {
 	struct path path;
 	int error;
+	int lookup_flags = LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
+	unsigned int try = 0;
 
-	error = user_path_dir(filename, &path);
-	if (error)
-		goto out;
+	do {
+		error = user_path_at(AT_FDCWD, filename, lookup_flags, &path);
+		if (error)
+			break;
 
-	error = inode_permission(path.dentry->d_inode, MAY_EXEC | MAY_CHDIR);
-	if (error)
-		goto dput_and_out;
+		error = inode_permission(path.dentry->d_inode,
+					 MAY_EXEC | MAY_CHDIR);
+		if (error)
+			goto dput_and_out;
 
-	error = -EPERM;
-	if (!capable(CAP_SYS_CHROOT))
-		goto dput_and_out;
-	error = security_path_chroot(&path);
-	if (error)
-		goto dput_and_out;
+		error = -EPERM;
+		if (!capable(CAP_SYS_CHROOT))
+			goto dput_and_out;
+		error = security_path_chroot(&path);
+		if (error)
+			goto dput_and_out;
 
-	set_fs_root(current->fs, &path);
-	error = 0;
+		set_fs_root(current->fs, &path);
+		error = 0;
 dput_and_out:
-	path_put(&path);
-out:
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 17/34] vfs: make fchmodat retry once on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (16 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/open.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index a1331f1..06f04bd 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -503,12 +503,17 @@ SYSCALL_DEFINE3(fchmodat, int, dfd, const char __user *, filename, umode_t, mode
 {
 	struct path path;
 	int error;
+	unsigned int try = 0;
+	int lookup_flags = LOOKUP_FOLLOW;
 
-	error = user_path_at(dfd, filename, LOOKUP_FOLLOW, &path);
-	if (!error) {
+	do {
+		error = user_path_at(dfd, filename, lookup_flags, &path);
+		if (error)
+			break;
 		error = chmod_common(&path, mode);
 		path_put(&path);
-	}
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 18/34] vfs: make fchownat retry once on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (17 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/open.c | 29 +++++++++++++++++------------
 1 file changed, 17 insertions(+), 12 deletions(-)

diff --git a/fs/open.c b/fs/open.c
index 06f04bd..abb52b9 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -564,24 +564,29 @@ SYSCALL_DEFINE5(fchownat, int, dfd, const char __user *, filename, uid_t, user,
 	struct path path;
 	int error = -EINVAL;
 	int lookup_flags;
+	unsigned int try = 0;
 
 	if ((flag & ~(AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH)) != 0)
-		goto out;
+		return error;
 
 	lookup_flags = (flag & AT_SYMLINK_NOFOLLOW) ? 0 : LOOKUP_FOLLOW;
 	if (flag & AT_EMPTY_PATH)
 		lookup_flags |= LOOKUP_EMPTY;
-	error = user_path_at(dfd, filename, lookup_flags, &path);
-	if (error)
-		goto out;
-	error = mnt_want_write(path.mnt);
-	if (error)
-		goto out_release;
-	error = chown_common(&path, user, group);
-	mnt_drop_write(path.mnt);
-out_release:
-	path_put(&path);
-out:
+
+	do {
+		error = user_path_at(dfd, filename, lookup_flags, &path);
+		if (error)
+			break;
+
+		error = mnt_want_write(path.mnt);
+		if (!error) {
+			error = chown_common(&path, user, group);
+			mnt_drop_write(path.mnt);
+		}
+
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 19/34] vfs: fix user_statfs to retry once on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (18 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/statfs.c | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/statfs.c b/fs/statfs.c
index f8e832e..7b42ca3 100644
--- a/fs/statfs.c
+++ b/fs/statfs.c
@@ -77,11 +77,19 @@ EXPORT_SYMBOL(vfs_statfs);
 int user_statfs(const char __user *pathname, struct kstatfs *st)
 {
 	struct path path;
-	int error = user_path_at(AT_FDCWD, pathname, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
-	if (!error) {
+	int error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT;
+
+	do {
+		error  = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+
 		error = vfs_statfs(&path, st);
 		path_put(&path);
-	}
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 20/34] vfs: allow utimensat() calls to retry once on an ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (19 preceding siblings ...)
  (?)
@ 2012-11-05 15:21 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:21 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Clearly, we can't handle the NULL filename case, but we can deal with
the case where there's a real pathname.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/utimes.c | 17 +++++++++++------
 1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/fs/utimes.c b/fs/utimes.c
index bb0696a..c9ce931 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -154,17 +154,22 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
 		fdput(f);
 	} else {
 		struct path path;
-		int lookup_flags = 0;
+		unsigned int lookup_flags = 0;
+		unsigned int try = 0;
 
 		if (!(flags & AT_SYMLINK_NOFOLLOW))
 			lookup_flags |= LOOKUP_FOLLOW;
 
-		error = user_path_at(dfd, filename, lookup_flags, &path);
-		if (error)
-			goto out;
+		do {
+			error = user_path_at(dfd, filename,
+						lookup_flags, &path);
+			if (error)
+				break;
 
-		error = utimes_common(&path, times);
-		path_put(&path);
+			error = utimes_common(&path, times);
+			path_put(&path);
+			lookup_flags |= LOOKUP_REVAL;
+		} while (retry_estale(error, try++));
 	}
 
 out:
-- 
1.7.11.7


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

* [PATCH v9 21/34] vfs: allow setxattr to retry once on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (20 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index f3a2ffa..5b6e48d 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -370,16 +370,21 @@ SYSCALL_DEFINE5(setxattr, const char __user *, pathname,
 {
 	struct path path;
 	int error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = LOOKUP_FOLLOW;
 
-	error = user_path(pathname, &path);
-	if (error)
-		return error;
-	error = mnt_want_write(path.mnt);
-	if (!error) {
-		error = setxattr(path.dentry, name, value, size, flags);
-		mnt_drop_write(path.mnt);
-	}
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = mnt_want_write(path.mnt);
+		if (!error) {
+			error = setxattr(path.dentry, name, value, size, flags);
+			mnt_drop_write(path.mnt);
+		}
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 22/34] vfs: allow lsetxattr() to retry once on ESTALE errors
  2012-11-05 15:21 ` Jeff Layton
                   ` (21 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 5b6e48d..5a9ddba 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -394,16 +394,21 @@ SYSCALL_DEFINE5(lsetxattr, const char __user *, pathname,
 {
 	struct path path;
 	int error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = 0;
 
-	error = user_lpath(pathname, &path);
-	if (error)
-		return error;
-	error = mnt_want_write(path.mnt);
-	if (!error) {
-		error = setxattr(path.dentry, name, value, size, flags);
-		mnt_drop_write(path.mnt);
-	}
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = mnt_want_write(path.mnt);
+		if (!error) {
+			error = setxattr(path.dentry, name, value, size, flags);
+			mnt_drop_write(path.mnt);
+		}
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 23/34] vfs: make getxattr retry once on an ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (22 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 5a9ddba..42284fc 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -486,12 +486,17 @@ SYSCALL_DEFINE4(getxattr, const char __user *, pathname,
 {
 	struct path path;
 	ssize_t error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = LOOKUP_FOLLOW;
 
-	error = user_path(pathname, &path);
-	if (error)
-		return error;
-	error = getxattr(path.dentry, name, value, size);
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = getxattr(path.dentry, name, value, size);
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 24/34] vfs: make lgetxattr retry once on ESTALE
  2012-11-05 15:21 ` Jeff Layton
                   ` (23 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 42284fc..3a5e3ff 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -505,12 +505,17 @@ SYSCALL_DEFINE4(lgetxattr, const char __user *, pathname,
 {
 	struct path path;
 	ssize_t error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = 0;
 
-	error = user_lpath(pathname, &path);
-	if (error)
-		return error;
-	error = getxattr(path.dentry, name, value, size);
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = getxattr(path.dentry, name, value, size);
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 25/34] vfs: make listxattr retry once on ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (24 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 3a5e3ff..8a318a4 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -576,12 +576,17 @@ SYSCALL_DEFINE3(listxattr, const char __user *, pathname, char __user *, list,
 {
 	struct path path;
 	ssize_t error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = LOOKUP_FOLLOW;
 
-	error = user_path(pathname, &path);
-	if (error)
-		return error;
-	error = listxattr(path.dentry, list, size);
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = listxattr(path.dentry, list, size);
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 26/34] vfs: make llistxattr retry once on ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (25 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 8a318a4..8a30ef0 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -595,12 +595,17 @@ SYSCALL_DEFINE3(llistxattr, const char __user *, pathname, char __user *, list,
 {
 	struct path path;
 	ssize_t error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = 0;
 
-	error = user_lpath(pathname, &path);
-	if (error)
-		return error;
-	error = listxattr(path.dentry, list, size);
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = listxattr(path.dentry, list, size);
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 27/34] vfs: make removexattr retry once on ESTALE
  2012-11-05 15:21 ` Jeff Layton
                   ` (26 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index 8a30ef0..e2071ed 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -645,16 +645,21 @@ SYSCALL_DEFINE2(removexattr, const char __user *, pathname,
 {
 	struct path path;
 	int error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = LOOKUP_FOLLOW;
 
-	error = user_path(pathname, &path);
-	if (error)
-		return error;
-	error = mnt_want_write(path.mnt);
-	if (!error) {
-		error = removexattr(path.dentry, name);
-		mnt_drop_write(path.mnt);
-	}
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = mnt_want_write(path.mnt);
+		if (!error) {
+			error = removexattr(path.dentry, name);
+			mnt_drop_write(path.mnt);
+		}
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 28/34] vfs: make lremovexattr retry once on ESTALE error
  2012-11-05 15:21 ` Jeff Layton
                   ` (27 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/xattr.c | 23 ++++++++++++++---------
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/fs/xattr.c b/fs/xattr.c
index e2071ed..17d5135 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -668,16 +668,21 @@ SYSCALL_DEFINE2(lremovexattr, const char __user *, pathname,
 {
 	struct path path;
 	int error;
+	unsigned int try = 0;
+	unsigned int lookup_flags = 0;
 
-	error = user_lpath(pathname, &path);
-	if (error)
-		return error;
-	error = mnt_want_write(path.mnt);
-	if (!error) {
-		error = removexattr(path.dentry, name);
-		mnt_drop_write(path.mnt);
-	}
-	path_put(&path);
+	do {
+		error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path);
+		if (error)
+			break;
+		error = mnt_want_write(path.mnt);
+		if (!error) {
+			error = removexattr(path.dentry, name);
+			mnt_drop_write(path.mnt);
+		}
+		path_put(&path);
+		lookup_flags |= LOOKUP_REVAL;
+	} while (retry_estale(error, try++));
 	return error;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 29/34] vfs: convert do_filp_open to use retry_estale helper
  2012-11-05 15:21 ` Jeff Layton
                   ` (28 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 39adf1b..45a45d7 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3012,11 +3012,12 @@ struct file *do_filp_open(int dfd, struct filename *pathname,
 {
 	struct nameidata nd;
 	struct file *filp;
+	unsigned int try = 0;
 
 	filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
 	if (unlikely(filp == ERR_PTR(-ECHILD)))
 		filp = path_openat(dfd, pathname, &nd, op, flags);
-	if (unlikely(filp == ERR_PTR(-ESTALE)))
+	while (retry_estale(PTR_ERR(filp), try++))
 		filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_REVAL);
 	return filp;
 }
-- 
1.7.11.7


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

* [PATCH v9 30/34] vfs: convert do_file_open_root to use retry_estale helper
  2012-11-05 15:21 ` Jeff Layton
                   ` (29 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index 45a45d7..fbfeb88 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3028,6 +3028,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
 	struct nameidata nd;
 	struct file *file;
 	struct filename filename = { .name = name };
+	unsigned int try = 0;
 
 	nd.root.mnt = mnt;
 	nd.root.dentry = dentry;
@@ -3040,7 +3041,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
 	file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
 	if (unlikely(file == ERR_PTR(-ECHILD)))
 		file = path_openat(-1, &filename, &nd, op, flags);
-	if (unlikely(file == ERR_PTR(-ESTALE)))
+	while (retry_estale(PTR_ERR(file), try++))
 		file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL);
 	return file;
 }
-- 
1.7.11.7


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

* [PATCH v9 31/34] vfs: convert filename_lookup to use retry_estale helper
  2012-11-05 15:21 ` Jeff Layton
                   ` (30 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/fs/namei.c b/fs/namei.c
index fbfeb88..c3582d4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2020,10 +2020,11 @@ static int path_lookupat(int dfd, const char *name,
 static int filename_lookup(int dfd, struct filename *name,
 				unsigned int flags, struct nameidata *nd)
 {
+	unsigned int try = 0;
 	int retval = path_lookupat(dfd, name->name, flags | LOOKUP_RCU, nd);
 	if (unlikely(retval == -ECHILD))
 		retval = path_lookupat(dfd, name->name, flags, nd);
-	if (unlikely(retval == -ESTALE))
+	while (retry_estale(retval, try++))
 		retval = path_lookupat(dfd, name->name,
 						flags | LOOKUP_REVAL, nd);
 
-- 
1.7.11.7


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

* [PATCH v9 32/34] vfs: ensure that forward progress is being made on pathwalks
  2012-11-05 15:21 ` Jeff Layton
                   ` (31 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

In operations that involve pathwalks (lookups and atomic opens), ensure
that the operations are making forward progress. Save a copy of the
current nd.path.dentry when retrying on an estale and ensure that it's
changing on each pass through the loop. If it isn't, then we're stuck.
Just return -ENOENT in that case.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c | 31 ++++++++++++++++++++++++++++---
 1 file changed, 28 insertions(+), 3 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index c3582d4..f0916e6 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2021,12 +2021,21 @@ static int filename_lookup(int dfd, struct filename *name,
 				unsigned int flags, struct nameidata *nd)
 {
 	unsigned int try = 0;
+	struct dentry *save = NULL;
 	int retval = path_lookupat(dfd, name->name, flags | LOOKUP_RCU, nd);
+
 	if (unlikely(retval == -ECHILD))
 		retval = path_lookupat(dfd, name->name, flags, nd);
-	while (retry_estale(retval, try++))
+
+	while (retry_estale(retval, try++)) {
+		if (nd->path.dentry == save) {
+			retval = -ENOENT;
+			break;
+		}
+		save = nd->path.dentry;
 		retval = path_lookupat(dfd, name->name,
 						flags | LOOKUP_REVAL, nd);
+	}
 
 	if (likely(!retval))
 		audit_inode(name, nd->path.dentry, flags & LOOKUP_PARENT);
@@ -3014,12 +3023,20 @@ struct file *do_filp_open(int dfd, struct filename *pathname,
 	struct nameidata nd;
 	struct file *filp;
 	unsigned int try = 0;
+	struct dentry *save = NULL;
 
 	filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_RCU);
 	if (unlikely(filp == ERR_PTR(-ECHILD)))
 		filp = path_openat(dfd, pathname, &nd, op, flags);
-	while (retry_estale(PTR_ERR(filp), try++))
+
+	while (retry_estale(PTR_ERR(filp), try++)) {
+		if (nd.path.dentry == save) {
+			filp = ERR_PTR(-ENOENT);
+			break;
+		}
+		save = nd.path.dentry;
 		filp = path_openat(dfd, pathname, &nd, op, flags | LOOKUP_REVAL);
+	}
 	return filp;
 }
 
@@ -3030,6 +3047,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
 	struct file *file;
 	struct filename filename = { .name = name };
 	unsigned int try = 0;
+	struct dentry *save = NULL;
 
 	nd.root.mnt = mnt;
 	nd.root.dentry = dentry;
@@ -3042,8 +3060,15 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
 	file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
 	if (unlikely(file == ERR_PTR(-ECHILD)))
 		file = path_openat(-1, &filename, &nd, op, flags);
-	while (retry_estale(PTR_ERR(file), try++))
+
+	while (retry_estale(PTR_ERR(file), try++)) {
+		if (nd.path.dentry == save) {
+			file = ERR_PTR(-ENOENT);
+			break;
+		}
+		save = nd.path.dentry;
 		file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_REVAL);
+	}
 	return file;
 }
 
-- 
1.7.11.7


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

* [PATCH v9 33/34] vfs: make number of ESTALE retries tunable
  2012-11-05 15:21 ` Jeff Layton
                   ` (32 preceding siblings ...)
  (?)
@ 2012-11-05 15:22 ` Jeff Layton
  -1 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

In some situations, when there is a lot of "churn", a single retry is
simply not enough. Since there is no single correct value for the
number of times that these retries should occur, it makes some sense
to allow the admin to tune that value.

This patch adds a sysctl to allow the admin to tune the number of
times to retry these operations before giving up.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c         | 2 ++
 include/linux/fs.h | 7 ++++---
 kernel/sysctl.c    | 7 +++++++
 3 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index f0916e6..70592ec 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -110,6 +110,8 @@
  * any extra contention...
  */
 
+unsigned int estale_retries __read_mostly = 1;
+
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 3e42289..1789199 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2023,14 +2023,15 @@ extern int finish_open(struct file *file, struct dentry *dentry,
 			int *opened);
 extern int finish_no_open(struct file *file, struct dentry *dentry);
 
+extern unsigned int estale_retries;
+
 /**
  * retry_estale - determine whether the caller should retry an operation
  * @error: the error that would currently be returned
  * @try: number of tries already performed
  *
  * Check to see if the error code was -ESTALE, and then determine whether
- * to retry the call based on the number of tries so far. Currently, we only
- * retry the call once.
+ * to retry the call based on the number of tries so far.
  *
  * Returns true if the caller should try the operation again.
  */
@@ -2040,7 +2041,7 @@ retry_estale(const long error, const unsigned int try)
 	if (likely(error != -ESTALE))
 		return false;
 
-	return !try;
+	return (try <= estale_retries);
 }
 
 /* fs/ioctl.c */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 26f65ea..24735db 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1545,6 +1545,13 @@ static struct ctl_table fs_table[] = {
 		.proc_handler	= &pipe_proc_fn,
 		.extra1		= &pipe_min_size,
 	},
+	{
+		.procname	= "estale_retries",
+		.data		= &estale_retries,
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+	},
 	{ }
 };
 
-- 
1.7.11.7


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

* [PATCH v9 34/34] vfs: add a sliding backoff delay between ESTALE retries
@ 2012-11-05 15:22   ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro
  Cc: linux-fsdevel, linux-nfs, linux-kernel, michael.brantley, hch,
	miklos, pstaubach

...with a hard, arbitrary cap on the amount of time that it will sleep
between tries. If we have a case where we're doing a lot of retries on
an ESTALE, then this should help keep us from hammering the fs as badly.

With this change, retry_estale has probably outgrown being an inline.
Make the check for ESTALE error an inline, and turn the rest of the
actual handling into a regular function.

Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
 fs/namei.c         | 33 +++++++++++++++++++++++++++++++++
 include/linux/fs.h |  7 ++++---
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 70592ec..ae61487 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -112,6 +112,39 @@
 
 unsigned int estale_retries __read_mostly = 1;
 
+/**
+ * __retry_estale - determine whether the caller should retry an operation
+ * @try: number of tries already performed
+ *
+ * Determine whether to retry a call based on the number of retries so far.
+ * It's expected that the caller has already determined that the error is
+ * estale.
+ *
+ * In the event that we're retrying multiple times, we also add an exponential
+ * backoff to allow things to stabilize before trying again. We do however add
+ * an arbitrary cap to that sleep.
+ *
+ * Returns true if the caller should try again.
+ */
+#define MAX_RETRY_ESTALE_DELAY	(3 * HZ)
+bool
+__retry_estale(const unsigned int try)
+{
+	bool should_retry = (try <= estale_retries);
+
+	/*
+	 * If we're retrying multiple times, then do a small, sliding delay to
+	 * cut down on the amount that we hammer the fs with requests. In
+	 * principle this gives things time to "settle down" before retrying.
+	 */
+	if (should_retry) {
+		long timeout = min_t(long, try * 2, MAX_RETRY_ESTALE_DELAY);
+		if (timeout)
+			schedule_timeout_killable(timeout);
+	}
+	return should_retry;
+}
+
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1789199..6a16b09 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2024,14 +2024,15 @@ extern int finish_open(struct file *file, struct dentry *dentry,
 extern int finish_no_open(struct file *file, struct dentry *dentry);
 
 extern unsigned int estale_retries;
+extern bool __retry_estale(const unsigned int try);
 
 /**
  * retry_estale - determine whether the caller should retry an operation
  * @error: the error that would currently be returned
  * @try: number of tries already performed
  *
- * Check to see if the error code was -ESTALE, and then determine whether
- * to retry the call based on the number of tries so far.
+ * Check to see if the error code was -ESTALE, and then call a separate routine
+ * to handle the situation if it is.
  *
  * Returns true if the caller should try the operation again.
  */
@@ -2041,7 +2042,7 @@ retry_estale(const long error, const unsigned int try)
 	if (likely(error != -ESTALE))
 		return false;
 
-	return (try <= estale_retries);
+	return __retry_estale(try);
 }
 
 /* fs/ioctl.c */
-- 
1.7.11.7


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

* [PATCH v9 34/34] vfs: add a sliding backoff delay between ESTALE retries
@ 2012-11-05 15:22   ` Jeff Layton
  0 siblings, 0 replies; 39+ messages in thread
From: Jeff Layton @ 2012-11-05 15:22 UTC (permalink / raw)
  To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn
  Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
	hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
	pstaubach-83r9SdEf25FBDgjK7y7TUQ

...with a hard, arbitrary cap on the amount of time that it will sleep
between tries. If we have a case where we're doing a lot of retries on
an ESTALE, then this should help keep us from hammering the fs as badly.

With this change, retry_estale has probably outgrown being an inline.
Make the check for ESTALE error an inline, and turn the rest of the
actual handling into a regular function.

Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
 fs/namei.c         | 33 +++++++++++++++++++++++++++++++++
 include/linux/fs.h |  7 ++++---
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index 70592ec..ae61487 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -112,6 +112,39 @@
 
 unsigned int estale_retries __read_mostly = 1;
 
+/**
+ * __retry_estale - determine whether the caller should retry an operation
+ * @try: number of tries already performed
+ *
+ * Determine whether to retry a call based on the number of retries so far.
+ * It's expected that the caller has already determined that the error is
+ * estale.
+ *
+ * In the event that we're retrying multiple times, we also add an exponential
+ * backoff to allow things to stabilize before trying again. We do however add
+ * an arbitrary cap to that sleep.
+ *
+ * Returns true if the caller should try again.
+ */
+#define MAX_RETRY_ESTALE_DELAY	(3 * HZ)
+bool
+__retry_estale(const unsigned int try)
+{
+	bool should_retry = (try <= estale_retries);
+
+	/*
+	 * If we're retrying multiple times, then do a small, sliding delay to
+	 * cut down on the amount that we hammer the fs with requests. In
+	 * principle this gives things time to "settle down" before retrying.
+	 */
+	if (should_retry) {
+		long timeout = min_t(long, try * 2, MAX_RETRY_ESTALE_DELAY);
+		if (timeout)
+			schedule_timeout_killable(timeout);
+	}
+	return should_retry;
+}
+
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
  * kernel data space before using them..
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1789199..6a16b09 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2024,14 +2024,15 @@ extern int finish_open(struct file *file, struct dentry *dentry,
 extern int finish_no_open(struct file *file, struct dentry *dentry);
 
 extern unsigned int estale_retries;
+extern bool __retry_estale(const unsigned int try);
 
 /**
  * retry_estale - determine whether the caller should retry an operation
  * @error: the error that would currently be returned
  * @try: number of tries already performed
  *
- * Check to see if the error code was -ESTALE, and then determine whether
- * to retry the call based on the number of tries so far.
+ * Check to see if the error code was -ESTALE, and then call a separate routine
+ * to handle the situation if it is.
  *
  * Returns true if the caller should try the operation again.
  */
@@ -2041,7 +2042,7 @@ retry_estale(const long error, const unsigned int try)
 	if (likely(error != -ESTALE))
 		return false;
 
-	return (try <= estale_retries);
+	return __retry_estale(try);
 }
 
 /* fs/ioctl.c */
-- 
1.7.11.7

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

end of thread, other threads:[~2012-11-05 15:36 UTC | newest]

Thread overview: 39+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-05 15:21 [PATCH v9 00/34] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
2012-11-05 15:21 ` Jeff Layton
2012-11-05 15:21 ` [PATCH v9 01/34] vfs: add a retry_estale helper function to handle retries on ESTALE Jeff Layton
2012-11-05 15:21 ` [PATCH v9 02/34] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
2012-11-05 15:21 ` [PATCH v9 03/34] vfs: fix readlinkat to retry on ESTALE Jeff Layton
2012-11-05 15:21 ` [PATCH v9 04/34] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
2012-11-05 15:21   ` Jeff Layton
2012-11-05 15:21 ` [PATCH v9 05/34] vfs: fix mknodat to retry on ESTALE errors Jeff Layton
2012-11-05 15:21 ` [PATCH v9 06/34] vfs: fix mkdir " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 07/34] vfs: fix symlinkat " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 08/34] vfs: fix linkat " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 09/34] vfs: add a reval argument to user_path_parent Jeff Layton
2012-11-05 15:21 ` [PATCH v9 10/34] vfs: make rmdir retry on ESTALE errors Jeff Layton
2012-11-05 15:21 ` [PATCH v9 11/34] vfs: make do_unlinkat " Jeff Layton
2012-11-05 15:21   ` Jeff Layton
2012-11-05 15:21 ` [PATCH v9 12/34] vfs: fix renameat to " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 13/34] vfs: have do_sys_truncate retry once on an ESTALE error Jeff Layton
2012-11-05 15:21 ` [PATCH v9 14/34] vfs: have faccessat " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 15/34] vfs: have chdir retry lookup and call once on " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 16/34] vfs: make chroot retry " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 17/34] vfs: make fchmodat retry once on ESTALE errors Jeff Layton
2012-11-05 15:21 ` [PATCH v9 18/34] vfs: make fchownat " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 19/34] vfs: fix user_statfs to " Jeff Layton
2012-11-05 15:21 ` [PATCH v9 20/34] vfs: allow utimensat() calls to retry once on an ESTALE error Jeff Layton
2012-11-05 15:22 ` [PATCH v9 21/34] vfs: allow setxattr to retry once on ESTALE errors Jeff Layton
2012-11-05 15:22 ` [PATCH v9 22/34] vfs: allow lsetxattr() " Jeff Layton
2012-11-05 15:22 ` [PATCH v9 23/34] vfs: make getxattr retry once on an ESTALE error Jeff Layton
2012-11-05 15:22 ` [PATCH v9 24/34] vfs: make lgetxattr retry once on ESTALE Jeff Layton
2012-11-05 15:22 ` [PATCH v9 25/34] vfs: make listxattr retry once on ESTALE error Jeff Layton
2012-11-05 15:22 ` [PATCH v9 26/34] vfs: make llistxattr " Jeff Layton
2012-11-05 15:22 ` [PATCH v9 27/34] vfs: make removexattr retry once on ESTALE Jeff Layton
2012-11-05 15:22 ` [PATCH v9 28/34] vfs: make lremovexattr retry once on ESTALE error Jeff Layton
2012-11-05 15:22 ` [PATCH v9 29/34] vfs: convert do_filp_open to use retry_estale helper Jeff Layton
2012-11-05 15:22 ` [PATCH v9 30/34] vfs: convert do_file_open_root " Jeff Layton
2012-11-05 15:22 ` [PATCH v9 31/34] vfs: convert filename_lookup " Jeff Layton
2012-11-05 15:22 ` [PATCH v9 32/34] vfs: ensure that forward progress is being made on pathwalks Jeff Layton
2012-11-05 15:22 ` [PATCH v9 33/34] vfs: make number of ESTALE retries tunable Jeff Layton
2012-11-05 15:22 ` [PATCH v9 34/34] vfs: add a sliding backoff delay between ESTALE retries Jeff Layton
2012-11-05 15:22   ` Jeff Layton

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.