linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).