cifs: switch to ->iterate_shared()
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
d9b3dbdcfd
commit
3125d2650c
|
@ -1083,7 +1083,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct file_operations cifs_dir_ops = {
|
const struct file_operations cifs_dir_ops = {
|
||||||
.iterate = cifs_readdir,
|
.iterate_shared = cifs_readdir,
|
||||||
.release = cifs_closedir,
|
.release = cifs_closedir,
|
||||||
.read = generic_read_dir,
|
.read = generic_read_dir,
|
||||||
.unlocked_ioctl = cifs_ioctl,
|
.unlocked_ioctl = cifs_ioctl,
|
||||||
|
|
|
@ -80,18 +80,32 @@ cifs_prime_dcache(struct dentry *parent, struct qstr *name,
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct super_block *sb = parent->d_sb;
|
struct super_block *sb = parent->d_sb;
|
||||||
struct cifs_sb_info *cifs_sb = CIFS_SB(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);
|
cifs_dbg(FYI, "%s: for %s\n", __func__, name->name);
|
||||||
|
|
||||||
dentry = d_hash_and_lookup(parent, 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))
|
if (IS_ERR(dentry))
|
||||||
return;
|
return;
|
||||||
|
if (!d_in_lookup(dentry)) {
|
||||||
if (dentry) {
|
|
||||||
inode = d_inode(dentry);
|
inode = d_inode(dentry);
|
||||||
if (inode) {
|
if (inode) {
|
||||||
if (d_mountpoint(dentry))
|
if (d_mountpoint(dentry)) {
|
||||||
goto out;
|
dput(dentry);
|
||||||
|
return;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* If we're generating inode numbers, then we don't
|
* If we're generating inode numbers, then we don't
|
||||||
* want to clobber the existing one with the one that
|
* 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) ==
|
(inode->i_mode & S_IFMT) ==
|
||||||
(fattr->cf_mode & S_IFMT)) {
|
(fattr->cf_mode & S_IFMT)) {
|
||||||
cifs_fattr_to_inode(inode, fattr);
|
cifs_fattr_to_inode(inode, fattr);
|
||||||
goto out;
|
dput(dentry);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d_invalidate(dentry);
|
d_invalidate(dentry);
|
||||||
dput(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);
|
dput(dentry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue