* [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call
@ 2012-04-26 15:57 Jeff Layton
2012-04-26 15:57 ` [PATCH v1 03/12] vfs: fix readlinkat to retry on ESTALE Jeff Layton
` (9 more replies)
0 siblings, 10 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/stat.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/fs/stat.c b/fs/stat.c
index c733dc5..f3eef0d 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -73,7 +73,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)
@@ -84,12 +85,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.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 03/12] vfs: fix readlinkat to retry on ESTALE
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 04/12] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
` (8 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/stat.c | 16 ++++++++++++----
1 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/fs/stat.c b/fs/stat.c
index f3eef0d..f7904aa 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -299,14 +299,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);
@@ -317,7 +324,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.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 04/12] vfs: add new "reval" argument to kern_path_create and user_path_create
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
2012-04-26 15:57 ` [PATCH v1 03/12] vfs: fix readlinkat to retry on ESTALE Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 05/12] vfs: fix mknodat to retry on ESTALE errors Jeff Layton
` (7 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
...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 | 22 ++++++++++++++--------
fs/ocfs2/refcounttree.c | 3 ++-
include/linux/namei.h | 4 ++--
net/unix/af_unix.c | 3 ++-
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 5665dcc..3c222cc 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 8493536..70eb0b0 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, false, false);
if (IS_ERR(dentry))
return PTR_ERR(dentry);
@@ -195,10 +195,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 0062dd1..367b0f2 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2460,11 +2460,17 @@ 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 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);
@@ -2512,13 +2518,13 @@ out:
}
EXPORT_SYMBOL(kern_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)
{
char *tmp = getname(pathname);
struct dentry *res;
if (IS_ERR(tmp))
return ERR_CAST(tmp);
- res = kern_path_create(dfd, tmp, path, is_dir);
+ res = kern_path_create(dfd, tmp, path, is_dir, reval);
putname(tmp);
return res;
}
@@ -2579,7 +2585,7 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
if (S_ISDIR(mode))
return -EPERM;
- 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);
@@ -2652,7 +2658,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);
@@ -2939,7 +2945,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;
@@ -3048,7 +3054,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 9f32d7c..b52b24d 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 ffc0213..3e90dcd 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -76,8 +76,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 int kern_path_parent(const char *, struct nameidata *);
extern int vfs_path_lookup(struct dentry *, struct vfsmount *,
const char *, unsigned int, struct path *);
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index d510353..9951294 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -865,7 +865,8 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
* 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))
goto out_mknod_parent;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 05/12] vfs: fix mknodat to retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
2012-04-26 15:57 ` [PATCH v1 03/12] vfs: fix readlinkat to retry on ESTALE Jeff Layton
2012-04-26 15:57 ` [PATCH v1 04/12] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 06/12] vfs: fix mkdir " Jeff Layton
` (6 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 62 ++++++++++++++++++++++++++++++-----------------------------
1 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 367b0f2..9ee6b4e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2581,44 +2581,46 @@ SYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
struct dentry *dentry;
struct path path;
int error;
+ unsigned int try = 0;
if (S_ISDIR(mode))
return -EPERM;
- 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 = may_mknod(mode);
- if (error)
- goto out_dput;
- error = mnt_want_write(path.mnt);
- if (error)
- goto out_dput;
- error = security_path_mknod(&path, dentry, mode, dev);
- if (error)
- goto out_drop_write;
- switch (mode & S_IFMT) {
- case 0: case S_IFREG:
- error = vfs_create(path.dentry->d_inode,dentry,mode,NULL);
- break;
- 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);
+ if (!IS_POSIXACL(path.dentry->d_inode))
+ mode &= ~current_umask();
+ error = may_mknod(mode);
+ if (error)
+ goto out_dput;
+ error = mnt_want_write(path.mnt);
+ if (error)
+ goto out_dput;
+ error = security_path_mknod(&path, dentry, mode, dev);
+ if (error)
+ goto out_drop_write;
+ switch (mode & S_IFMT) {
+ case 0: case S_IFREG:
+ error = vfs_create(path.dentry->d_inode, dentry, mode, NULL);
+ break;
+ 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;
- }
+ }
out_drop_write:
- mnt_drop_write(path.mnt);
+ mnt_drop_write(path.mnt);
out_dput:
- dput(dentry);
- mutex_unlock(&path.dentry->d_inode->i_mutex);
- path_put(&path);
-
+ dput(dentry);
+ mutex_unlock(&path.dentry->d_inode->i_mutex);
+ path_put(&path);
+ } while (retry_estale(error, try++));
return error;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 06/12] vfs: fix mkdir to retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (2 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 05/12] vfs: fix mknodat to retry on ESTALE errors Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 07/12] vfs: add a "reval" flag to args for user_path_parent Jeff Layton
` (5 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 38 +++++++++++++++++++++-----------------
1 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 9ee6b4e..e9da40b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2659,26 +2659,30 @@ 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);
-
- if (!IS_POSIXACL(path.dentry->d_inode))
- mode &= ~current_umask();
- error = mnt_want_write(path.mnt);
- if (error)
- goto out_dput;
- error = security_path_mkdir(&path, dentry, mode);
- if (error)
- goto out_drop_write;
- error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
+ do {
+ dentry = user_path_create(dfd, pathname, &path, true, try);
+ if (IS_ERR(dentry)) {
+ error = PTR_ERR(dentry);
+ break;
+ }
+ if (!IS_POSIXACL(path.dentry->d_inode))
+ mode &= ~current_umask();
+ error = mnt_want_write(path.mnt);
+ if (error)
+ goto out_dput;
+ error = security_path_mkdir(&path, dentry, mode);
+ if (error)
+ goto out_drop_write;
+ error = vfs_mkdir(path.dentry->d_inode, dentry, mode);
out_drop_write:
- mnt_drop_write(path.mnt);
+ mnt_drop_write(path.mnt);
out_dput:
- dput(dentry);
- mutex_unlock(&path.dentry->d_inode->i_mutex);
- path_put(&path);
+ dput(dentry);
+ mutex_unlock(&path.dentry->d_inode->i_mutex);
+ path_put(&path);
+ } while (retry_estale(error, try++));
return error;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 07/12] vfs: add a "reval" flag to args for user_path_parent
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (3 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 06/12] vfs: fix mkdir " Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 08/12] vfs: make rmdir retry on ESTALE errors Jeff Layton
` (4 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
All of the current callers set this to "false" for now, but we'll fix
them later to set it to true when they retry on an ESTALE error.
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 16 ++++++++++------
1 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index e9da40b..b1b116b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1908,15 +1908,19 @@ int user_path_at(int dfd, const char __user *name, unsigned flags,
}
static int user_path_parent(int dfd, const char __user *path,
- struct nameidata *nd, char **name)
+ struct nameidata *nd, char **name, bool reval)
{
char *s = getname(path);
int error;
+ unsigned int lookup_flags = LOOKUP_PARENT;
if (IS_ERR(s))
return PTR_ERR(s);
- error = do_path_lookup(dfd, s, LOOKUP_PARENT, nd);
+ if (reval)
+ lookup_flags |= LOOKUP_REVAL;
+
+ error = do_path_lookup(dfd, s, lookup_flags, nd);
if (error)
putname(s);
else
@@ -2759,7 +2763,7 @@ static long do_rmdir(int dfd, const char __user *pathname)
struct dentry *dentry;
struct nameidata nd;
- error = user_path_parent(dfd, pathname, &nd, &name);
+ error = user_path_parent(dfd, pathname, &nd, &name, false);
if (error)
return error;
@@ -2856,7 +2860,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
struct nameidata nd;
struct inode *inode = NULL;
- error = user_path_parent(dfd, pathname, &nd, &name);
+ error = user_path_parent(dfd, pathname, &nd, &name, false);
if (error)
return error;
@@ -3255,11 +3259,11 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
char *to;
int error;
- error = user_path_parent(olddfd, oldname, &oldnd, &from);
+ error = user_path_parent(olddfd, oldname, &oldnd, &from, false);
if (error)
goto exit;
- error = user_path_parent(newdfd, newname, &newnd, &to);
+ error = user_path_parent(newdfd, newname, &newnd, &to, false);
if (error)
goto exit1;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 08/12] vfs: make rmdir retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (4 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 07/12] vfs: add a "reval" flag to args for user_path_parent Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 09/12] vfs: make do_unlinkat " Jeff Layton
` (3 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 76 +++++++++++++++++++++++++++++++----------------------------
1 files changed, 40 insertions(+), 36 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index b1b116b..d754460 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2762,50 +2762,54 @@ static long do_rmdir(int dfd, const char __user *pathname)
char * name;
struct dentry *dentry;
struct nameidata nd;
+ unsigned int try = 0;
- error = user_path_parent(dfd, pathname, &nd, &name, false);
- if (error)
- return error;
+ do {
+ error = user_path_parent(dfd, pathname, &nd, &name, try);
+ if (error)
+ break;
- 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;
- }
+ 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;
+ nd.flags &= ~LOOKUP_PARENT;
- 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 = mnt_want_write(nd.path.mnt);
- if (error)
- goto exit3;
- error = security_path_rmdir(&nd.path, dentry);
- if (error)
- goto exit4;
- 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);
+ error = PTR_ERR(dentry);
+ if (IS_ERR(dentry))
+ goto exit2;
+ if (!dentry->d_inode) {
+ error = -ENOENT;
+ goto exit3;
+ }
+ error = mnt_want_write(nd.path.mnt);
+ if (error)
+ goto exit3;
+ error = security_path_rmdir(&nd.path, dentry);
+ if (error)
+ goto exit4;
+ error = vfs_rmdir(nd.path.dentry->d_inode, dentry);
exit4:
- mnt_drop_write(nd.path.mnt);
+ mnt_drop_write(nd.path.mnt);
exit3:
- dput(dentry);
+ dput(dentry);
exit2:
- mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
exit1:
- path_put(&nd.path);
- putname(name);
+ path_put(&nd.path);
+ putname(name);
+ } while (retry_estale(error, try++));
return error;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 09/12] vfs: make do_unlinkat retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (5 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 08/12] vfs: make rmdir retry on ESTALE errors Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 10/12] vfs: fix symlinkat to " Jeff Layton
` (2 subsequent siblings)
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index d754460..3a8e5e4 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2863,8 +2863,9 @@ static long do_unlinkat(int dfd, const char __user *pathname)
struct dentry *dentry;
struct nameidata nd;
struct inode *inode = NULL;
-
- error = user_path_parent(dfd, pathname, &nd, &name, false);
+ unsigned int try = 0;
+retry:
+ error = user_path_parent(dfd, pathname, &nd, &name, try);
if (error)
return error;
@@ -2903,6 +2904,8 @@ exit3:
exit1:
path_put(&nd.path);
putname(name);
+ if (retry_estale(error, try++))
+ goto retry;
return error;
slashes:
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 10/12] vfs: fix symlinkat to retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (6 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 09/12] vfs: make do_unlinkat " Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 11/12] vfs: fix linkat " Jeff Layton
2012-04-26 15:57 ` [PATCH v1 12/12] vfs: fix renameat " Jeff Layton
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 3a8e5e4..b189dc5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2957,12 +2957,14 @@ SYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
char *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);
+retry:
+ dentry = user_path_create(newdfd, newname, &path, false, try);
error = PTR_ERR(dentry);
if (IS_ERR(dentry))
goto out_putname;
@@ -2980,6 +2982,8 @@ out_dput:
dput(dentry);
mutex_unlock(&path.dentry->d_inode->i_mutex);
path_put(&path);
+ if (retry_estale(error, try++))
+ goto retry;
out_putname:
putname(from);
return error;
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 11/12] vfs: fix linkat to retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (7 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 10/12] vfs: fix symlinkat to " Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
2012-04-26 15:57 ` [PATCH v1 12/12] vfs: fix renameat " Jeff Layton
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 9 +++++++--
1 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index b189dc5..0d54eb3 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3054,6 +3054,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;
@@ -3071,11 +3072,12 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
if (flags & AT_SYMLINK_FOLLOW)
how |= LOOKUP_FOLLOW;
+retry:
error = user_path_at(olddfd, oldname, how, &old_path);
if (error)
return error;
- new_dentry = user_path_create(newdfd, newname, &new_path, false, false);
+ new_dentry = user_path_create(newdfd, newname, &new_path, false, try);
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
goto out;
@@ -3098,7 +3100,10 @@ out_dput:
path_put(&new_path);
out:
path_put(&old_path);
-
+ if (retry_estale(error, try++)) {
+ how |= LOOKUP_REVAL;
+ goto retry;
+ }
return error;
}
--
1.7.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH v1 12/12] vfs: fix renameat to retry on ESTALE errors
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
` (8 preceding siblings ...)
2012-04-26 15:57 ` [PATCH v1 11/12] vfs: fix linkat " Jeff Layton
@ 2012-04-26 15:57 ` Jeff Layton
9 siblings, 0 replies; 11+ messages in thread
From: Jeff Layton @ 2012-04-26 15:57 UTC (permalink / raw)
To: viro
Cc: linux-fsdevel, linux-nfs, linux-kernel, miklos, hch, michael.brantley
...as always, rename is the messiest of the bunch...
Signed-off-by: Jeff Layton <jlayton@redhat.com>
---
fs/namei.c | 13 +++++++++++--
1 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 0d54eb3..1db2814 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3274,12 +3274,15 @@ SYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
char *from;
char *to;
int error;
+ unsigned int try = 0;
+ bool should_retry = false;
- error = user_path_parent(olddfd, oldname, &oldnd, &from, false);
+retry:
+ error = user_path_parent(olddfd, oldname, &oldnd, &from, try);
if (error)
goto exit;
- error = user_path_parent(newdfd, newname, &newnd, &to, false);
+ error = user_path_parent(newdfd, newname, &newnd, &to, try);
if (error)
goto exit1;
@@ -3348,12 +3351,18 @@ exit4:
dput(old_dentry);
exit3:
unlock_rename(new_dir, old_dir);
+ if (retry_estale(error, try++))
+ should_retry = true;
exit2:
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.7.6
^ permalink raw reply related [flat|nested] 11+ messages in thread
end of thread, other threads:[~2012-04-26 17:07 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-26 15:57 [PATCH v1 02/12] vfs: make fstatat retry on ESTALE errors from getattr call Jeff Layton
2012-04-26 15:57 ` [PATCH v1 03/12] vfs: fix readlinkat to retry on ESTALE Jeff Layton
2012-04-26 15:57 ` [PATCH v1 04/12] vfs: add new "reval" argument to kern_path_create and user_path_create Jeff Layton
2012-04-26 15:57 ` [PATCH v1 05/12] vfs: fix mknodat to retry on ESTALE errors Jeff Layton
2012-04-26 15:57 ` [PATCH v1 06/12] vfs: fix mkdir " Jeff Layton
2012-04-26 15:57 ` [PATCH v1 07/12] vfs: add a "reval" flag to args for user_path_parent Jeff Layton
2012-04-26 15:57 ` [PATCH v1 08/12] vfs: make rmdir retry on ESTALE errors Jeff Layton
2012-04-26 15:57 ` [PATCH v1 09/12] vfs: make do_unlinkat " Jeff Layton
2012-04-26 15:57 ` [PATCH v1 10/12] vfs: fix symlinkat to " Jeff Layton
2012-04-26 15:57 ` [PATCH v1 11/12] vfs: fix linkat " Jeff Layton
2012-04-26 15:57 ` [PATCH v1 12/12] vfs: fix renameat " 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).