mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
smb: client: short-circuit negative lookups when parent dir is fully cached
When the parent directory has a valid and complete cached enumeration we can assume that negative dentries are not present in the directory, thus we can return without issuing a request. This reduces traffic for common ENOENT when the directory entries are cached. Signed-off-by: Henrique Carvalho <henrique.carvalho@suse.com> Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
55580ad027
commit
316025335a
|
|
@ -683,6 +683,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
const char *full_path;
|
||||
void *page;
|
||||
int retry_count = 0;
|
||||
struct cached_fid *cfid = NULL;
|
||||
|
||||
xid = get_xid();
|
||||
|
||||
|
|
@ -722,6 +723,28 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
cifs_dbg(FYI, "non-NULL inode in lookup\n");
|
||||
} else {
|
||||
cifs_dbg(FYI, "NULL inode in lookup\n");
|
||||
|
||||
/*
|
||||
* We can only rely on negative dentries having the same
|
||||
* spelling as the cached dirent if case insensitivity is
|
||||
* forced on mount.
|
||||
*
|
||||
* XXX: if servers correctly announce Case Sensitivity Search
|
||||
* on GetInfo of FileFSAttributeInformation, then we can take
|
||||
* correct action even if case insensitive is not forced on
|
||||
* mount.
|
||||
*/
|
||||
if (pTcon->nocase && !open_cached_dir_by_dentry(pTcon, direntry->d_parent, &cfid)) {
|
||||
/*
|
||||
* dentry is negative and parent is fully cached:
|
||||
* we can assume file does not exist
|
||||
*/
|
||||
if (cfid->dirents.is_valid) {
|
||||
close_cached_dir(cfid);
|
||||
goto out;
|
||||
}
|
||||
close_cached_dir(cfid);
|
||||
}
|
||||
}
|
||||
cifs_dbg(FYI, "Full path: %s inode = 0x%p\n",
|
||||
full_path, d_inode(direntry));
|
||||
|
|
@ -755,6 +778,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
|
|||
}
|
||||
newInode = ERR_PTR(rc);
|
||||
}
|
||||
|
||||
out:
|
||||
free_dentry_path(page);
|
||||
cifs_put_tlink(tlink);
|
||||
free_xid(xid);
|
||||
|
|
@ -765,7 +790,8 @@ static int
|
|||
cifs_d_revalidate(struct inode *dir, const struct qstr *name,
|
||||
struct dentry *direntry, unsigned int flags)
|
||||
{
|
||||
struct inode *inode;
|
||||
struct inode *inode = NULL;
|
||||
struct cached_fid *cfid;
|
||||
int rc;
|
||||
|
||||
if (flags & LOOKUP_RCU)
|
||||
|
|
@ -812,6 +838,21 @@ cifs_d_revalidate(struct inode *dir, const struct qstr *name,
|
|||
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(dir->i_sb);
|
||||
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
|
||||
|
||||
if (!open_cached_dir_by_dentry(tcon, direntry->d_parent, &cfid)) {
|
||||
/*
|
||||
* dentry is negative and parent is fully cached:
|
||||
* we can assume file does not exist
|
||||
*/
|
||||
if (cfid->dirents.is_valid) {
|
||||
close_cached_dir(cfid);
|
||||
return 1;
|
||||
}
|
||||
close_cached_dir(cfid);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user