From: "J. Bruce Fields" <bfields-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
To: linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
samba-technical-w/Ol4Ecudpl8XjKLYN78aQ@public.gmane.org,
Christoph Hellwig <hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
Mimi Zohar
<zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org>,
Eric Paris <eparis-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH 2/2] locks: break lease on unlink
Date: Thu, 9 Jun 2011 20:11:35 -0400 [thread overview]
Message-ID: <20110610001135.GE22215@fieldses.org> (raw)
In-Reply-To: <20110610001011.GD22215-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
NFSv4 uses leases (delegations) to allow clients to do opens locally.
An open takes a component name, so to do a local open a client needs to
know that at least that last component name points at the same time as
long as they hold the delegation. For that reason, the NFSv4 spec
requires that delegations be broken on unlink.
Waiting for a lease to be broken may mean waiting for an nfs client or a
user process to give it up, so doing that while holding the i_mutex
would risk deadlocks. So instead we do a non-blocking lease break, then
drop the i_mutex and do a blocking lease break if necessary.
Signed-off-by: J. Bruce Fields <bfields-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
fs/namei.c | 32 ++++++++++++++++++++++++++++----
fs/nfsd/vfs.c | 6 +++++-
2 files changed, 33 insertions(+), 5 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index 079e68c..4661469 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2799,6 +2799,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
nd.flags &= ~LOOKUP_PARENT;
+retry:
mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
dentry = lookup_hash(&nd);
error = PTR_ERR(dentry);
@@ -2806,15 +2807,27 @@ static long do_unlinkat(int dfd, const char __user *pathname)
/* Why not before? Because we want correct error value */
if (nd.last.name[nd.last.len])
goto slashes;
- inode = dentry->d_inode;
- if (inode)
- ihold(inode);
+ if (inode && inode != dentry->d_inode) {
+ reallow_leases(inode, O_WRONLY);
+ iput(inode);
+ inode = NULL;
+ }
+ if (!inode) {
+ inode = dentry->d_inode;
+ if (inode)
+ ihold(inode);
+ disallow_leases(inode, O_WRONLY);
+ }
error = mnt_want_write(nd.path.mnt);
if (error)
goto exit2;
error = security_path_unlink(&nd.path, dentry);
if (error)
goto exit3;
+ if (inode)
+ error = break_lease(inode, O_WRONLY|O_NONBLOCK);
+ if (error)
+ goto exit3;
error = vfs_unlink(nd.path.dentry->d_inode, dentry);
exit3:
mnt_drop_write(nd.path.mnt);
@@ -2822,8 +2835,19 @@ exit3:
dput(dentry);
}
mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
- if (inode)
+ if (inode) {
+ /* XXX: safe to use EWOULDBLOCK==EAGAIN to do this?: */
+ if (error == -EWOULDBLOCK) {
+ /*
+ * Wait this time, then retry with leases left
+ * disabled:
+ */
+ break_lease(inode, O_WRONLY);
+ goto retry;
+ }
+ reallow_leases(inode, O_WRONLY);
iput(inode); /* truncate the inode here */
+ }
exit1:
path_put(&nd.path);
putname(name);
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index f4e056a..ef01b98 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -1826,13 +1826,17 @@ nfsd_unlink(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
if (host_err)
goto out_put;
+ disallow_leases(rdentry->d_inode, O_WRONLY);
host_err = nfsd_break_lease(rdentry->d_inode);
- if (host_err)
+ if (host_err) {
+ reallow_leases(rdentry->d_inode, O_WRONLY);
goto out_drop_write;
+ }
if (type != S_IFDIR)
host_err = vfs_unlink(dirp, rdentry);
else
host_err = vfs_rmdir(dirp, rdentry);
+ reallow_leases(rdentry->d_inode, O_WRONLY);
if (!host_err)
host_err = commit_metadata(fhp);
out_drop_write:
--
1.7.4.1
--
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
next prev parent reply other threads:[~2011-06-10 0:11 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-06-10 0:09 lease/delegation/oplock semantics J. Bruce Fields
2011-06-10 0:10 ` [PATCH 1/2] locks: introduce i_blockleases to close lease races J. Bruce Fields
[not found] ` <20110610001011.GD22215-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
2011-06-10 0:11 ` J. Bruce Fields [this message]
2011-06-10 20:24 ` Mimi Zohar
2011-06-10 21:34 ` J. Bruce Fields
2011-06-12 4:08 ` J. Bruce Fields
2011-06-12 19:10 ` Mimi Zohar
2011-06-12 19:12 ` J. Bruce Fields
[not found] ` <20110612191220.GK12149-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
2011-06-12 20:54 ` Mimi Zohar
2011-06-13 12:19 ` J. Bruce Fields
2011-06-13 20:37 ` Mimi Zohar
2011-06-14 0:35 ` J. Bruce Fields
[not found] ` <20110613121939.GL12149-uC3wQj2KruNg9hUCZPvPmw@public.gmane.org>
2011-06-15 15:47 ` J. Bruce Fields
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=20110610001135.GE22215@fieldses.org \
--to=bfields-uc3wqj2krung9huczpvpmw@public.gmane.org \
--cc=eparis-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=hch-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
--cc=linux-fsdevel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-nfs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=samba-technical-w/Ol4Ecudpl8XjKLYN78aQ@public.gmane.org \
--cc=zohar-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8@public.gmane.org \
/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 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).