* [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls
@ 2012-10-27 12:33 Jeff Layton
2012-10-27 12:33 ` [PATCH v8 01/32] vfs: add a retry_estale helper function to handle retries on ESTALE Jeff Layton
` (26 more replies)
0 siblings, 27 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 minor changes since I last
posted the set:
- a subtle bug in the do_unlinkat patch was fixed. It's necessary to set
"inode" to NULL on each pass through the function. This was causing a
"Busy inodes on umount" error in testing.
- a patch for user_statfs has been added
- patches for do_filp_open, do_file_open_root, and filename_lookup have
been added to make them use the retry_estale helper function. These
don't strictly need changing if we only ever want to make this code
retry once on an ESTALE error, but I still felt it was best to keep the
policy on retrying after an ESTALE error in a single function.
- a patch has been added to make the number of ESTALE retries tunable
via sysctl. The problem I encountered in working on this set was the
difficulty in testing these changes. By adding this tunable, I could
crank up the number of retries to a large value to make testing easier.
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 next three in the series I think also make sense for consistency's
sake. If we ever determined that a single retry was not enough, then
they will make changing that policy easier.
I include the final patch for completeness sake since it shows how I
tested the set. That said, since there is no well-defined value that
will work for all cases, allowing a tunable for this makes some sense to
me. [2]
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.
[2]: If we do want to allow a tunable however, we might consider "beefing
up" retry_estale() to add some of the earlier suggestions. For
instance, checking for fatal signals and an an exponential backoff
delay. We might also want to do some work to ensure that lookups are
making forward progress in the face of multiple retries. If we
do want those, then that's probably best done in a separate patchset.
Jeff Layton (32):
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: make number of ESTALE retries tunable
arch/powerpc/platforms/cell/spufs/syscalls.c | 2 +-
drivers/base/devtmpfs.c | 7 +-
fs/namei.c | 273 ++++++++++++++++-----------
fs/ocfs2/refcounttree.c | 3 +-
fs/open.c | 252 ++++++++++++++-----------
fs/stat.c | 32 +++-
fs/statfs.c | 14 +-
fs/utimes.c | 15 +-
fs/xattr.c | 152 +++++++++------
include/linux/fs.h | 23 +++
include/linux/namei.h | 4 +-
kernel/sysctl.c | 7 +
net/unix/af_unix.c | 2 +-
13 files changed, 484 insertions(+), 302 deletions(-)
--
1.7.11.7
^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH v8 01/32] vfs: add a retry_estale helper function to handle retries on ESTALE
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 02/32] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (25 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b33cfc9..01ff902 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2023,6 +2023,27 @@ 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 we'll be returning
+ * @try: number of retries already performed
+ *
+ * Check to see if the error code was -ESTALE, and then determine whether
+ * to retry the call based on the number of retries so far. Currently, we only
+ * retry the call once.
+ *
+ * Returns true if the caller should try 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] 37+ messages in thread
* [PATCH v8 02/32] vfs: make fstatat retry on ESTALE errors from getattr call
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
2012-10-27 12:33 ` [PATCH v8 01/32] vfs: add a retry_estale helper function to handle retries on ESTALE Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 03/32] vfs: fix readlinkat to retry on ESTALE Jeff Layton
` (24 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 03/32] vfs: fix readlinkat to retry on ESTALE
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
2012-10-27 12:33 ` [PATCH v8 01/32] vfs: add a retry_estale helper function to handle retries on ESTALE Jeff Layton
2012-10-27 12:33 ` [PATCH v8 02/32] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 04/32] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
` (23 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 04/32] vfs: add new "reval" argument to kern_path_create and user_path_create
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (2 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 03/32] vfs: fix readlinkat to retry on ESTALE Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 05/32] vfs: fix mknodat to retry on ESTALE errors Jeff Layton
` (22 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 d1895f3..a2bb283 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] 37+ messages in thread
* [PATCH v8 05/32] vfs: fix mknodat to retry on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (3 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 04/32] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (21 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 a2bb283..7b0ca39 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] 37+ messages in thread
* [PATCH v8 06/32] vfs: fix mkdir to retry on ESTALE errors
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 10/32] vfs: make rmdir " Jeff Layton
` (4 subsequent siblings)
5 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 | 21 ++++++++++++---------
1 file changed, 12 insertions(+), 9 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 7b0ca39..6e8db3d 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, false);
+ 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
--
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] 37+ messages in thread
* [PATCH v8 07/32] vfs: fix symlinkat to retry on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (5 preceding siblings ...)
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 08/32] vfs: fix linkat " Jeff Layton
` (19 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 6e8db3d..7def44b 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, false);
+ 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] 37+ messages in thread
* [PATCH v8 08/32] vfs: fix linkat to retry on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (6 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 07/32] vfs: fix symlinkat to retry on ESTALE errors Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 09/32] vfs: add a reval argument to user_path_parent Jeff Layton
` (18 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 7def44b..d542a19 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, false);
+ 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] 37+ messages in thread
* [PATCH v8 09/32] vfs: add a reval argument to user_path_parent
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (7 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 08/32] vfs: fix linkat " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors Jeff Layton
` (17 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 d542a19..47b6016 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] 37+ messages in thread
* [PATCH v8 10/32] vfs: make rmdir retry on ESTALE errors
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-10-27 12:33 ` [PATCH v8 06/32] vfs: fix mkdir " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 16/32] vfs: make chroot retry once on ESTALE error Jeff Layton
` (3 subsequent siblings)
5 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 | 81 ++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 44 insertions(+), 37 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 47b6016..7c9bb50 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3344,49 +3344,56 @@ static long do_rmdir(int dfd, const char __user *pathname)
struct filename *name;
struct dentry *dentry;
struct nameidata nd;
+ unsigned int try = 0;
+ unsigned int lookup_flags = LOOKUP_PARENT;
- 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);
+ lookup_flags |= LOOKUP_REVAL;
+ putname(name);
+ } while (retry_estale(error, try++));
return error;
}
--
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] 37+ messages in thread
* [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (8 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 09/32] vfs: add a reval argument to user_path_parent Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
[not found] ` <1351341219-17837-12-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-10-27 12:33 ` [PATCH v8 12/32] vfs: fix renameat to " Jeff Layton
` (16 subsequent siblings)
26 siblings, 1 reply; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 7c9bb50..467b9f1 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3446,9 +3446,13 @@ static long do_unlinkat(int dfd, const char __user *pathname)
struct filename *name;
struct dentry *dentry;
struct nameidata nd;
- struct inode *inode = NULL;
+ struct inode *inode;
+ unsigned int try = 0;
+ unsigned int lookup_flags = LOOKUP_PARENT;
- name = user_path_parent(dfd, pathname, &nd, 0);
+retry:
+ inode = NULL;
+ name = user_path_parent(dfd, pathname, &nd, try);
if (IS_ERR(name))
return PTR_ERR(name);
@@ -3486,6 +3490,10 @@ exit2:
exit1:
path_put(&nd.path);
putname(name);
+ if (retry_estale(error, try++)) {
+ lookup_flags |= LOOKUP_REVAL;
+ goto retry;
+ }
return error;
slashes:
--
1.7.11.7
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH v8 12/32] vfs: fix renameat to retry on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (9 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 13/32] vfs: have do_sys_truncate retry once on an ESTALE error Jeff Layton
` (15 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 467b9f1..27bff9b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3849,15 +3849,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;
@@ -3929,11 +3932,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] 37+ messages in thread
* [PATCH v8 13/32] vfs: have do_sys_truncate retry once on an ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (10 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 12/32] vfs: fix renameat to " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 14/32] vfs: have faccessat " Jeff Layton
` (14 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 14/32] vfs: have faccessat retry once on an ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (11 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 13/32] vfs: have do_sys_truncate retry once on an ESTALE error Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 15/32] vfs: have chdir retry lookup and call once on " Jeff Layton
` (13 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 15/32] vfs: have chdir retry lookup and call once on ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (12 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 14/32] vfs: have faccessat " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 17/32] vfs: make fchmodat retry once on ESTALE errors Jeff Layton
` (12 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 16/32] vfs: make chroot retry once on ESTALE error
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-10-27 12:33 ` [PATCH v8 06/32] vfs: fix mkdir " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 10/32] vfs: make rmdir " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 21/32] vfs: allow setxattr to retry once on ESTALE errors Jeff Layton
` (2 subsequent siblings)
5 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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/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
--
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] 37+ messages in thread
* [PATCH v8 17/32] vfs: make fchmodat retry once on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (13 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 15/32] vfs: have chdir retry lookup and call once on " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 18/32] vfs: make fchownat " Jeff Layton
` (11 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 18/32] vfs: make fchownat retry once on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (14 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 17/32] vfs: make fchmodat retry once on ESTALE errors Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 19/32] vfs: fix user_statfs to " Jeff Layton
` (10 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 19/32] vfs: fix user_statfs to retry once on ESTALE errors
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (15 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 18/32] vfs: make fchownat " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 20/32] vfs: allow utimensat() calls to retry once on an ESTALE error Jeff Layton
` (9 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 20/32] vfs: allow utimensat() calls to retry once on an ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (16 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 19/32] vfs: fix user_statfs to " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 23/32] vfs: make getxattr " Jeff Layton
` (8 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/fs/utimes.c b/fs/utimes.c
index bb0696a..2b91adc2 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -155,16 +155,21 @@ long do_utimes(int dfd, const char __user *filename, struct timespec *times,
} else {
struct path path;
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] 37+ messages in thread
* [PATCH v8 21/32] vfs: allow setxattr to retry once on ESTALE errors
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (2 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 16/32] vfs: make chroot retry once on ESTALE error Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 22/32] vfs: allow lsetxattr() " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 32/32] vfs: make number of ESTALE retries tunable Jeff Layton
5 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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/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
--
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] 37+ messages in thread
* [PATCH v8 22/32] vfs: allow lsetxattr() to retry once on ESTALE errors
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (3 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 21/32] vfs: allow setxattr to retry once on ESTALE errors Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 32/32] vfs: make number of ESTALE retries tunable Jeff Layton
5 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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/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
--
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] 37+ messages in thread
* [PATCH v8 23/32] vfs: make getxattr retry once on an ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (17 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 20/32] vfs: allow utimensat() calls to retry once on an ESTALE error Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 24/32] vfs: make lgetxattr retry once on ESTALE Jeff Layton
` (7 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 24/32] vfs: make lgetxattr retry once on ESTALE
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (18 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 23/32] vfs: make getxattr " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 25/32] vfs: make listxattr retry once on ESTALE error Jeff Layton
` (6 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 25/32] vfs: make listxattr retry once on ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (19 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 24/32] vfs: make lgetxattr retry once on ESTALE Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 26/32] vfs: make llistxattr " Jeff Layton
` (5 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 26/32] vfs: make llistxattr retry once on ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (20 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 25/32] vfs: make listxattr retry once on ESTALE error Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 27/32] vfs: make removexattr retry once on ESTALE Jeff Layton
` (4 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 27/32] vfs: make removexattr retry once on ESTALE
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (21 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 26/32] vfs: make llistxattr " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 28/32] vfs: make lremovexattr retry once on ESTALE error Jeff Layton
` (3 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 28/32] vfs: make lremovexattr retry once on ESTALE error
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (22 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 27/32] vfs: make removexattr retry once on ESTALE Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 29/32] vfs: convert do_filp_open to use retry_estale helper Jeff Layton
` (2 subsequent siblings)
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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] 37+ messages in thread
* [PATCH v8 29/32] vfs: convert do_filp_open to use retry_estale helper
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (23 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 28/32] vfs: make lremovexattr retry once on ESTALE error Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 30/32] vfs: convert do_file_open_root " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 31/32] vfs: convert filename_lookup " Jeff Layton
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 27bff9b..6930e91 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] 37+ messages in thread
* [PATCH v8 30/32] vfs: convert do_file_open_root to use retry_estale helper
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (24 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 29/32] vfs: convert do_filp_open to use retry_estale helper Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 31/32] vfs: convert filename_lookup " Jeff Layton
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 6930e91..c6173cc 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] 37+ messages in thread
* [PATCH v8 31/32] vfs: convert filename_lookup to use retry_estale helper
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
` (25 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 30/32] vfs: convert do_file_open_root " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
26 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 c6173cc..6886630 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] 37+ messages in thread
* [PATCH v8 32/32] vfs: make number of ESTALE retries tunable
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
` (4 preceding siblings ...)
2012-10-27 12:33 ` [PATCH v8 22/32] vfs: allow lsetxattr() " Jeff Layton
@ 2012-10-27 12:33 ` Jeff Layton
5 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-27 12:33 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 | 2 ++
include/linux/fs.h | 4 +++-
kernel/sysctl.c | 7 +++++++
3 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/fs/namei.c b/fs/namei.c
index 6886630..1ae2c06 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 01ff902..119a0f0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2023,6 +2023,8 @@ 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
*
@@ -2041,7 +2043,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
--
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] 37+ messages in thread
* Re: [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors
[not found] ` <1351341219-17837-12-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
@ 2012-10-30 16:14 ` J. Bruce Fields
[not found] ` <20121030161429.GD24618-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
0 siblings, 1 reply; 37+ messages in thread
From: J. Bruce Fields @ 2012-10-30 16:14 UTC (permalink / raw)
To: Jeff Layton
Cc: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
pstaubach-83r9SdEf25FBDgjK7y7TUQ
On Sat, Oct 27, 2012 at 08:33:18AM -0400, Jeff Layton wrote:
> Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> ---
> fs/namei.c | 12 ++++++++++--
> 1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/fs/namei.c b/fs/namei.c
> index 7c9bb50..467b9f1 100644
> --- a/fs/namei.c
> +++ b/fs/namei.c
> @@ -3446,9 +3446,13 @@ static long do_unlinkat(int dfd, const char __user *pathname)
> struct filename *name;
> struct dentry *dentry;
> struct nameidata nd;
> - struct inode *inode = NULL;
> + struct inode *inode;
> + unsigned int try = 0;
> + unsigned int lookup_flags = LOOKUP_PARENT;
>
> - name = user_path_parent(dfd, pathname, &nd, 0);
> +retry:
> + inode = NULL;
So, you fail after "inode" was set (say vfs_unlink returned an error)
the first time, then before "inode" was set (lookup_hash returns an
error), and you end up incorrectly doing another iput() the second time
through if you don't reset inode here?
(I think I made the same mistake in another patch, actually....)
--b.
> + name = user_path_parent(dfd, pathname, &nd, try);
> if (IS_ERR(name))
> return PTR_ERR(name);
>
> @@ -3486,6 +3490,10 @@ exit2:
> exit1:
> path_put(&nd.path);
> putname(name);
> + if (retry_estale(error, try++)) {
> + lookup_flags |= LOOKUP_REVAL;
> + goto retry;
> + }
> return error;
>
> slashes:
> --
> 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
--
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] 37+ messages in thread
* Re: [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors
[not found] ` <20121030161429.GD24618-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
@ 2012-10-30 16:33 ` Jeff Layton
[not found] ` <20121030123355.5c404373-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
0 siblings, 1 reply; 37+ messages in thread
From: Jeff Layton @ 2012-10-30 16:33 UTC (permalink / raw)
To: J. Bruce Fields
Cc: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
pstaubach-83r9SdEf25FBDgjK7y7TUQ
On Tue, 30 Oct 2012 12:14:29 -0400
"J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Sat, Oct 27, 2012 at 08:33:18AM -0400, Jeff Layton wrote:
> > Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > ---
> > fs/namei.c | 12 ++++++++++--
> > 1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/fs/namei.c b/fs/namei.c
> > index 7c9bb50..467b9f1 100644
> > --- a/fs/namei.c
> > +++ b/fs/namei.c
> > @@ -3446,9 +3446,13 @@ static long do_unlinkat(int dfd, const char __user *pathname)
> > struct filename *name;
> > struct dentry *dentry;
> > struct nameidata nd;
> > - struct inode *inode = NULL;
> > + struct inode *inode;
> > + unsigned int try = 0;
> > + unsigned int lookup_flags = LOOKUP_PARENT;
> >
> > - name = user_path_parent(dfd, pathname, &nd, 0);
> > +retry:
> > + inode = NULL;
>
> So, you fail after "inode" was set (say vfs_unlink returned an error)
> the first time, then before "inode" was set (lookup_hash returns an
> error), and you end up incorrectly doing another iput() the second time
> through if you don't reset inode here?
>
> (I think I made the same mistake in another patch, actually....)
>
> --b.
>
Correct. That's a new delta in this patch, btw. The original patch
didn't do that and it was causing a busy inodes on umount bug in
testing.
It would occasionally hit an ESTALE error in this function and
because "inode" wasn't reset to NULL, it would do a double-put of the
inode and cause the counter to underflow.
It might be good to restructure this code to make those sorts of bugs
less likely, but the error handling in here is already so hairy that I
decided to punt on that for now...
> > + name = user_path_parent(dfd, pathname, &nd, try);
> > if (IS_ERR(name))
> > return PTR_ERR(name);
> >
> > @@ -3486,6 +3490,10 @@ exit2:
> > exit1:
> > path_put(&nd.path);
> > putname(name);
> > + if (retry_estale(error, try++)) {
> > + lookup_flags |= LOOKUP_REVAL;
> > + goto retry;
> > + }
> > return error;
> >
> > slashes:
> > --
> > 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
--
Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
--
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] 37+ messages in thread
* Re: [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors
[not found] ` <20121030123355.5c404373-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
@ 2012-10-30 19:28 ` J. Bruce Fields
[not found] ` <20121030192809.GE24618-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
0 siblings, 1 reply; 37+ messages in thread
From: J. Bruce Fields @ 2012-10-30 19:28 UTC (permalink / raw)
To: Jeff Layton
Cc: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
pstaubach-83r9SdEf25FBDgjK7y7TUQ
On Tue, Oct 30, 2012 at 12:33:55PM -0400, Jeff Layton wrote:
> On Tue, 30 Oct 2012 12:14:29 -0400
> "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
>
> > On Sat, Oct 27, 2012 at 08:33:18AM -0400, Jeff Layton wrote:
> > > Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > > ---
> > > fs/namei.c | 12 ++++++++++--
> > > 1 file changed, 10 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/fs/namei.c b/fs/namei.c
> > > index 7c9bb50..467b9f1 100644
> > > --- a/fs/namei.c
> > > +++ b/fs/namei.c
> > > @@ -3446,9 +3446,13 @@ static long do_unlinkat(int dfd, const char __user *pathname)
> > > struct filename *name;
> > > struct dentry *dentry;
> > > struct nameidata nd;
> > > - struct inode *inode = NULL;
> > > + struct inode *inode;
> > > + unsigned int try = 0;
> > > + unsigned int lookup_flags = LOOKUP_PARENT;
> > >
> > > - name = user_path_parent(dfd, pathname, &nd, 0);
> > > +retry:
> > > + inode = NULL;
> >
> > So, you fail after "inode" was set (say vfs_unlink returned an error)
> > the first time, then before "inode" was set (lookup_hash returns an
> > error), and you end up incorrectly doing another iput() the second time
> > through if you don't reset inode here?
> >
> > (I think I made the same mistake in another patch, actually....)
> >
> > --b.
> >
>
> Correct. That's a new delta in this patch, btw. The original patch
> didn't do that and it was causing a busy inodes on umount bug in
> testing.
>
> It would occasionally hit an ESTALE error in this function and
> because "inode" wasn't reset to NULL, it would do a double-put of the
> inode and cause the counter to underflow.
>
> It might be good to restructure this code to make those sorts of bugs
> less likely, but the error handling in here is already so hairy that I
> decided to punt on that for now...
Understood. I might find it just a little more obvious why we're doing
this if the assignment was next to the final iput:
if (inode)
iput(inode);
inode = NULL;
...
--b.
>
> > > + name = user_path_parent(dfd, pathname, &nd, try);
> > > if (IS_ERR(name))
> > > return PTR_ERR(name);
> > >
> > > @@ -3486,6 +3490,10 @@ exit2:
> > > exit1:
> > > path_put(&nd.path);
> > > putname(name);
> > > + if (retry_estale(error, try++)) {
> > > + lookup_flags |= LOOKUP_REVAL;
> > > + goto retry;
> > > + }
> > > return error;
> > >
> > > slashes:
> > > --
> > > 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
>
>
> --
> Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
--
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] 37+ messages in thread
* Re: [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors
[not found] ` <20121030192809.GE24618-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
@ 2012-10-30 19:45 ` Jeff Layton
0 siblings, 0 replies; 37+ messages in thread
From: Jeff Layton @ 2012-10-30 19:45 UTC (permalink / raw)
To: J. Bruce Fields
Cc: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
michael.brantley-Iq/kdjr4a97QT0dZR+AlfA,
hch-wEGCiKHe2LqWVfeAwA7xHQ, miklos-sUDqSbJrdHQHWmgEVkV9KA,
pstaubach-83r9SdEf25FBDgjK7y7TUQ
On Tue, 30 Oct 2012 15:28:09 -0400
"J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> On Tue, Oct 30, 2012 at 12:33:55PM -0400, Jeff Layton wrote:
> > On Tue, 30 Oct 2012 12:14:29 -0400
> > "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org> wrote:
> >
> > > On Sat, Oct 27, 2012 at 08:33:18AM -0400, Jeff Layton wrote:
> > > > Signed-off-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
> > > > ---
> > > > fs/namei.c | 12 ++++++++++--
> > > > 1 file changed, 10 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/fs/namei.c b/fs/namei.c
> > > > index 7c9bb50..467b9f1 100644
> > > > --- a/fs/namei.c
> > > > +++ b/fs/namei.c
> > > > @@ -3446,9 +3446,13 @@ static long do_unlinkat(int dfd, const char __user *pathname)
> > > > struct filename *name;
> > > > struct dentry *dentry;
> > > > struct nameidata nd;
> > > > - struct inode *inode = NULL;
> > > > + struct inode *inode;
> > > > + unsigned int try = 0;
> > > > + unsigned int lookup_flags = LOOKUP_PARENT;
> > > >
> > > > - name = user_path_parent(dfd, pathname, &nd, 0);
> > > > +retry:
> > > > + inode = NULL;
> > >
> > > So, you fail after "inode" was set (say vfs_unlink returned an error)
> > > the first time, then before "inode" was set (lookup_hash returns an
> > > error), and you end up incorrectly doing another iput() the second time
> > > through if you don't reset inode here?
> > >
> > > (I think I made the same mistake in another patch, actually....)
> > >
> > > --b.
> > >
> >
> > Correct. That's a new delta in this patch, btw. The original patch
> > didn't do that and it was causing a busy inodes on umount bug in
> > testing.
> >
> > It would occasionally hit an ESTALE error in this function and
> > because "inode" wasn't reset to NULL, it would do a double-put of the
> > inode and cause the counter to underflow.
> >
> > It might be good to restructure this code to make those sorts of bugs
> > less likely, but the error handling in here is already so hairy that I
> > decided to punt on that for now...
>
> Understood. I might find it just a little more obvious why we're doing
> this if the assignment was next to the final iput:
>
> if (inode)
> iput(inode);
> inode = NULL;
> ...
>
Yeah, my initial patch did something similar (but inside the "if"
block). Ultimately, though I figured it was best to avoid setting
"inode" unless it was needed.
The patch I've got basically does that, but it's not as obvious as the
other way. Maybe I should just go ahead and try to clean up that logic
after all. Unrolling the error handling there is pretty nasty though.
--
Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
--
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] 37+ messages in thread
end of thread, other threads:[~2012-10-30 19:45 UTC | newest]
Thread overview: 37+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-10-27 12:33 [PATCH v8 00/32] vfs: add the ability to retry lookup and operation to most path-based syscalls Jeff Layton
2012-10-27 12:33 ` [PATCH v8 01/32] vfs: add a retry_estale helper function to handle retries on ESTALE Jeff Layton
2012-10-27 12:33 ` [PATCH v8 02/32] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
2012-10-27 12:33 ` [PATCH v8 03/32] vfs: fix readlinkat to retry on ESTALE Jeff Layton
2012-10-27 12:33 ` [PATCH v8 04/32] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
2012-10-27 12:33 ` [PATCH v8 05/32] vfs: fix mknodat to retry on ESTALE errors Jeff Layton
[not found] ` <1351341219-17837-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-10-27 12:33 ` [PATCH v8 06/32] vfs: fix mkdir " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 10/32] vfs: make rmdir " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 16/32] vfs: make chroot retry once on ESTALE error Jeff Layton
2012-10-27 12:33 ` [PATCH v8 21/32] vfs: allow setxattr to retry once on ESTALE errors Jeff Layton
2012-10-27 12:33 ` [PATCH v8 22/32] vfs: allow lsetxattr() " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 32/32] vfs: make number of ESTALE retries tunable Jeff Layton
2012-10-27 12:33 ` [PATCH v8 07/32] vfs: fix symlinkat to retry on ESTALE errors Jeff Layton
2012-10-27 12:33 ` [PATCH v8 08/32] vfs: fix linkat " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 09/32] vfs: add a reval argument to user_path_parent Jeff Layton
2012-10-27 12:33 ` [PATCH v8 11/32] vfs: make do_unlinkat retry on ESTALE errors Jeff Layton
[not found] ` <1351341219-17837-12-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-10-30 16:14 ` J. Bruce Fields
[not found] ` <20121030161429.GD24618-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
2012-10-30 16:33 ` Jeff Layton
[not found] ` <20121030123355.5c404373-9yPaYZwiELC+kQycOl6kW4xkIHaj4LzF@public.gmane.org>
2012-10-30 19:28 ` J. Bruce Fields
[not found] ` <20121030192809.GE24618-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
2012-10-30 19:45 ` Jeff Layton
2012-10-27 12:33 ` [PATCH v8 12/32] vfs: fix renameat to " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 13/32] vfs: have do_sys_truncate retry once on an ESTALE error Jeff Layton
2012-10-27 12:33 ` [PATCH v8 14/32] vfs: have faccessat " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 15/32] vfs: have chdir retry lookup and call once on " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 17/32] vfs: make fchmodat retry once on ESTALE errors Jeff Layton
2012-10-27 12:33 ` [PATCH v8 18/32] vfs: make fchownat " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 19/32] vfs: fix user_statfs to " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 20/32] vfs: allow utimensat() calls to retry once on an ESTALE error Jeff Layton
2012-10-27 12:33 ` [PATCH v8 23/32] vfs: make getxattr " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 24/32] vfs: make lgetxattr retry once on ESTALE Jeff Layton
2012-10-27 12:33 ` [PATCH v8 25/32] vfs: make listxattr retry once on ESTALE error Jeff Layton
2012-10-27 12:33 ` [PATCH v8 26/32] vfs: make llistxattr " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 27/32] vfs: make removexattr retry once on ESTALE Jeff Layton
2012-10-27 12:33 ` [PATCH v8 28/32] vfs: make lremovexattr retry once on ESTALE error Jeff Layton
2012-10-27 12:33 ` [PATCH v8 29/32] vfs: convert do_filp_open to use retry_estale helper Jeff Layton
2012-10-27 12:33 ` [PATCH v8 30/32] vfs: convert do_file_open_root " Jeff Layton
2012-10-27 12:33 ` [PATCH v8 31/32] vfs: convert filename_lookup " Jeff Layton
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).