All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@redhat.com>
To: viro@zeniv.linux.org.uk
Cc: linux-fsdevel@vger.kernel.org, linux-nfs@vger.kernel.org,
	linux-kernel@vger.kernel.org, michael.brantley@deshaw.com,
	hch@infradead.org, miklos@szeredi.hu, pstaubach@exagrid.com
Subject: [PATCH v9 11/34] vfs: make do_unlinkat retry on ESTALE errors
Date: Mon,  5 Nov 2012 10:21:50 -0500	[thread overview]
Message-ID: <1352128933-28526-12-git-send-email-jlayton@redhat.com> (raw)
In-Reply-To: <1352128933-28526-1-git-send-email-jlayton@redhat.com>

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

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


WARNING: multiple messages have this Message-ID (diff)
From: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: viro-RmSDqhL/yNMiFSDQTTA3OLVCufUGDwFn@public.gmane.org
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	michael.brantley-Iq/kdjr4a97QT0dZR+AlfA@public.gmane.org,
	hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org,
	miklos-sUDqSbJrdHQHWmgEVkV9KA@public.gmane.org,
	pstaubach-83r9SdEf25FBDgjK7y7TUQ@public.gmane.org
Subject: [PATCH v9 11/34] vfs: make do_unlinkat retry on ESTALE errors
Date: Mon,  5 Nov 2012 10:21:50 -0500	[thread overview]
Message-ID: <1352128933-28526-12-git-send-email-jlayton@redhat.com> (raw)
In-Reply-To: <1352128933-28526-1-git-send-email-jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

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

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

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

  parent reply	other threads:[~2012-11-05 15:33 UTC|newest]

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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1352128933-28526-12-git-send-email-jlayton@redhat.com \
    --to=jlayton@redhat.com \
    --cc=hch@infradead.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    --cc=michael.brantley@deshaw.com \
    --cc=miklos@szeredi.hu \
    --cc=pstaubach@exagrid.com \
    --cc=viro@zeniv.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.