|
|
|
@ -80,18 +80,32 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, |
|
|
|
|
struct inode *inode; |
|
|
|
|
struct super_block *sb = parent->d_sb; |
|
|
|
|
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); |
|
|
|
|
DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq); |
|
|
|
|
|
|
|
|
|
cifs_dbg(FYI, "%s: for %s\n", __func__, name->name); |
|
|
|
|
|
|
|
|
|
dentry = d_hash_and_lookup(parent, name); |
|
|
|
|
if (!dentry) { |
|
|
|
|
/*
|
|
|
|
|
* If we know that the inode will need to be revalidated |
|
|
|
|
* immediately, then don't create a new dentry for it. |
|
|
|
|
* We'll end up doing an on the wire call either way and |
|
|
|
|
* this spares us an invalidation. |
|
|
|
|
*/ |
|
|
|
|
if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) |
|
|
|
|
return; |
|
|
|
|
retry: |
|
|
|
|
dentry = d_alloc_parallel(parent, name, &wq); |
|
|
|
|
} |
|
|
|
|
if (IS_ERR(dentry)) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
if (dentry) { |
|
|
|
|
if (!d_in_lookup(dentry)) { |
|
|
|
|
inode = d_inode(dentry); |
|
|
|
|
if (inode) { |
|
|
|
|
if (d_mountpoint(dentry)) |
|
|
|
|
goto out; |
|
|
|
|
if (d_mountpoint(dentry)) { |
|
|
|
|
dput(dentry); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
* If we're generating inode numbers, then we don't |
|
|
|
|
* want to clobber the existing one with the one that |
|
|
|
@ -106,33 +120,22 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name, |
|
|
|
|
(inode->i_mode & S_IFMT) == |
|
|
|
|
(fattr->cf_mode & S_IFMT)) { |
|
|
|
|
cifs_fattr_to_inode(inode, fattr); |
|
|
|
|
goto out; |
|
|
|
|
dput(dentry); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
d_invalidate(dentry); |
|
|
|
|
dput(dentry); |
|
|
|
|
goto retry; |
|
|
|
|
} else { |
|
|
|
|
inode = cifs_iget(sb, fattr); |
|
|
|
|
if (!inode) |
|
|
|
|
inode = ERR_PTR(-ENOMEM); |
|
|
|
|
alias = d_splice_alias(inode, dentry); |
|
|
|
|
d_lookup_done(dentry); |
|
|
|
|
if (alias && !IS_ERR(alias)) |
|
|
|
|
dput(alias); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If we know that the inode will need to be revalidated immediately, |
|
|
|
|
* then don't create a new dentry for it. We'll end up doing an on |
|
|
|
|
* the wire call either way and this spares us an invalidation. |
|
|
|
|
*/ |
|
|
|
|
if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
dentry = d_alloc(parent, name); |
|
|
|
|
if (!dentry) |
|
|
|
|
return; |
|
|
|
|
|
|
|
|
|
inode = cifs_iget(sb, fattr); |
|
|
|
|
if (!inode) |
|
|
|
|
goto out; |
|
|
|
|
|
|
|
|
|
alias = d_splice_alias(inode, dentry); |
|
|
|
|
if (alias && !IS_ERR(alias)) |
|
|
|
|
dput(alias); |
|
|
|
|
out: |
|
|
|
|
dput(dentry); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|