Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1435919
| From | Al Viro <viro@ZenIV.linux.org.uk> |
|---|---|
| Newsgroups | linux.kernel |
| Subject | Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. |
| Date | 2016-07-03 08:40 +0200 |
| Message-ID | <rQJep-5my-5@gated-at.bofh.it> (permalink) |
| References | <rKTgu-1Aj-5@gated-at.bofh.it> <rKTzP-1Kz-1@gated-at.bofh.it> <rNYMF-7KV-7@gated-at.bofh.it> |
| Organization | linux.* mail to news gateway |
On Sat, Jun 25, 2016 at 12:38:40PM -0400, Oleg Drokin wrote:
> Sorry to nag you about this, but did any of those pan out?
>
> d_alloc_parallel() sounds like a bit too heavy there, esp. considering we came in with
> a dentry already (though a potentially shared one, I understand).
> Would not it be better to try and establish some dentry locking rule for calling into
> d_splice_alias() instead? At least then the callers can make sure the dentry does
> not change under them?
> Though I guess if there's dentry locking like that, we might as well do all the
> checking in d_splice_alias(), but that means the unhashed dentries would no
> longer be disallowed which is a change of semantic from now.--
FWIW, the only interesting case here is this:
* no O_CREAT in flags (otherwise the parent is held exclusive).
* dentry is found in hash
* dentry is negative
* dentry has passed ->d_revalidate() (i.e. in case of
NFS it had nfs_neg_need_reval() return false).
Only two instances are non-trivial in that respect - NFS and Lustre.
Everything else will simply fail open() with ENOENT in that case.
And at least for NFS we could bloody well do d_drop + d_alloc_parallel +
finish_no_open and bugger off in case it's not in_lookup, otherwise do
pretty much what we do in case we'd got in_lookup from the very beginning.
Some adjustments are needed for that case (basically, we need to make
sure we hit d_lookup_done() matching that d_alloc_parallel() and deal
with refcounting correctly).
Tentative NFS patch follows; I don't understand Lustre well enough, but it
looks like a plausible strategy there as well.
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d8015a03..5474e39 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1485,11 +1485,13 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
struct file *file, unsigned open_flags,
umode_t mode, int *opened)
{
+ DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
struct nfs_open_context *ctx;
struct dentry *res;
struct iattr attr = { .ia_valid = ATTR_OPEN };
struct inode *inode;
unsigned int lookup_flags = 0;
+ bool switched = false;
int err;
/* Expect a negative dentry */
@@ -1528,6 +1530,17 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
attr.ia_size = 0;
}
+ if (!(open_flags & O_CREAT) && !d_unhashed(dentry)) {
+ d_drop(dentry);
+ switched = true;
+ dentry = d_alloc_parallel(dentry->d_parent,
+ &dentry->d_name, &wq);
+ if (IS_ERR(dentry))
+ return PTR_ERR(dentry);
+ if (unlikely(!d_in_lookup(dentry)))
+ return finish_no_open(file, dentry);
+ }
+
ctx = create_nfs_open_context(dentry, open_flags);
err = PTR_ERR(ctx);
if (IS_ERR(ctx))
@@ -1563,14 +1576,23 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
trace_nfs_atomic_open_exit(dir, ctx, open_flags, err);
put_nfs_open_context(ctx);
out:
+ if (unlikely(switched)) {
+ d_lookup_done(dentry);
+ dput(dentry);
+ }
return err;
no_open:
res = nfs_lookup(dir, dentry, lookup_flags);
- err = PTR_ERR(res);
+ if (switched) {
+ d_lookup_done(dentry);
+ if (!res)
+ res = dentry;
+ else
+ dput(dentry);
+ }
if (IS_ERR(res))
- goto out;
-
+ return PTR_ERR(res);
return finish_no_open(file, res);
}
EXPORT_SYMBOL_GPL(nfs_atomic_open);
Back to linux.kernel | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-06-25 18:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-03 08:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-04 02:10 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-04 02:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-04 05:10 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-04 06:00 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-05 04:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 04:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 04:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 06:50 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 08:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-05 14:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-05 16:00 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 17:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-05 19:50 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 20:20 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 18:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-05 20:10 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 21:20 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-05 22:10 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-05 22:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-06 02:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Al Viro <viro@ZenIV.linux.org.uk> - 2016-07-06 05:30 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-06 06:10 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-06 06:40 +0200
Re: More parallel atomic_open/d_splice_alias fun with NFS and possibly more FSes. Oleg Drokin <green@linuxhacker.ru> - 2016-07-06 18:30 +0200
csiph-web