[XFS] Return case-insensitive match for dentry cache
This implements the code to store the actual filename found during a lookup in the dentry cache and to avoid multiple entries in the dcache pointing to the same inode. To avoid polluting the dcache, we implement a new directory inode operations for lookup. xfs_vn_ci_lookup() stores the correct case name in the dcache. The "actual name" is only allocated and returned for a case- insensitive match and not an actual match. Another unusual interaction with the dcache is not storing negative dentries like other filesystems doing a d_add(dentry, NULL) when an ENOENT is returned. During the VFS lookup, if a dentry returned has no inode, dput is called and ENOENT is returned. By not doing a d_add, this actually removes it completely from the dcache to be reused. create/rename have to be modified to support unhashed dentries being passed in. SGI-PV: 981521 SGI-Modid: xfs-linux-melb:xfs-kern:31208a Signed-off-by: Barry Naujok <bnaujok@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org>
This commit is contained in:
@@ -549,7 +549,7 @@ xfs_dir2_leafn_lookup_for_entry(
|
||||
xfs_dir2_data_entry_t *dep; /* data block entry */
|
||||
xfs_inode_t *dp; /* incore directory inode */
|
||||
int error; /* error return value */
|
||||
int di; /* data entry index */
|
||||
int di = -1; /* data entry index */
|
||||
int index; /* leaf entry index */
|
||||
xfs_dir2_leaf_t *leaf; /* leaf structure */
|
||||
xfs_dir2_leaf_entry_t *lep; /* leaf entry */
|
||||
@@ -577,6 +577,7 @@ xfs_dir2_leafn_lookup_for_entry(
|
||||
if (state->extravalid) {
|
||||
curbp = state->extrablk.bp;
|
||||
curdb = state->extrablk.blkno;
|
||||
di = state->extrablk.index;
|
||||
}
|
||||
/*
|
||||
* Loop over leaf entries with the right hash value.
|
||||
@@ -637,7 +638,6 @@ xfs_dir2_leafn_lookup_for_entry(
|
||||
}
|
||||
/* Didn't find an exact match. */
|
||||
error = ENOENT;
|
||||
di = -1;
|
||||
ASSERT(index == be16_to_cpu(leaf->hdr.count) ||
|
||||
(args->op_flags & XFS_DA_OP_OKNOENT));
|
||||
out:
|
||||
@@ -652,7 +652,7 @@ out:
|
||||
state->extravalid = 0;
|
||||
}
|
||||
/*
|
||||
* Return the index, that will be the insertion point.
|
||||
* Return the index, that will be the deletion point for remove/replace.
|
||||
*/
|
||||
*indexp = index;
|
||||
return XFS_ERROR(error);
|
||||
@@ -1820,8 +1820,14 @@ xfs_dir2_node_lookup(
|
||||
error = xfs_da_node_lookup_int(state, &rval);
|
||||
if (error)
|
||||
rval = error;
|
||||
else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE)
|
||||
rval = EEXIST; /* a case-insensitive match was found */
|
||||
else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) {
|
||||
/* If a CI match, dup the actual name and return EEXIST */
|
||||
xfs_dir2_data_entry_t *dep;
|
||||
|
||||
dep = (xfs_dir2_data_entry_t *)((char *)state->extrablk.bp->
|
||||
data + state->extrablk.index);
|
||||
rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
|
||||
}
|
||||
/*
|
||||
* Release the btree blocks and leaf block.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user