aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2_node.c
diff options
context:
space:
mode:
authorBarry Naujok <bnaujok@sgi.com>2008-05-21 02:58:22 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:58:40 -0400
commit384f3ced07efdddf6838f6527366089d37843c94 (patch)
tree13037bc99115f6f940b6fe924b75dc48e0577678 /fs/xfs/xfs_dir2_node.c
parent9403540c0653122ca34884a180439ddbfcbcb524 (diff)
[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>
Diffstat (limited to 'fs/xfs/xfs_dir2_node.c')
-rw-r--r--fs/xfs/xfs_dir2_node.c16
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/xfs/xfs_dir2_node.c b/fs/xfs/xfs_dir2_node.c
index c71cff85950c..1b5430223461 100644
--- a/fs/xfs/xfs_dir2_node.c
+++ b/fs/xfs/xfs_dir2_node.c
@@ -549,7 +549,7 @@ xfs_dir2_leafn_lookup_for_entry(
549 xfs_dir2_data_entry_t *dep; /* data block entry */ 549 xfs_dir2_data_entry_t *dep; /* data block entry */
550 xfs_inode_t *dp; /* incore directory inode */ 550 xfs_inode_t *dp; /* incore directory inode */
551 int error; /* error return value */ 551 int error; /* error return value */
552 int di; /* data entry index */ 552 int di = -1; /* data entry index */
553 int index; /* leaf entry index */ 553 int index; /* leaf entry index */
554 xfs_dir2_leaf_t *leaf; /* leaf structure */ 554 xfs_dir2_leaf_t *leaf; /* leaf structure */
555 xfs_dir2_leaf_entry_t *lep; /* leaf entry */ 555 xfs_dir2_leaf_entry_t *lep; /* leaf entry */
@@ -577,6 +577,7 @@ xfs_dir2_leafn_lookup_for_entry(
577 if (state->extravalid) { 577 if (state->extravalid) {
578 curbp = state->extrablk.bp; 578 curbp = state->extrablk.bp;
579 curdb = state->extrablk.blkno; 579 curdb = state->extrablk.blkno;
580 di = state->extrablk.index;
580 } 581 }
581 /* 582 /*
582 * Loop over leaf entries with the right hash value. 583 * Loop over leaf entries with the right hash value.
@@ -637,7 +638,6 @@ xfs_dir2_leafn_lookup_for_entry(
637 } 638 }
638 /* Didn't find an exact match. */ 639 /* Didn't find an exact match. */
639 error = ENOENT; 640 error = ENOENT;
640 di = -1;
641 ASSERT(index == be16_to_cpu(leaf->hdr.count) || 641 ASSERT(index == be16_to_cpu(leaf->hdr.count) ||
642 (args->op_flags & XFS_DA_OP_OKNOENT)); 642 (args->op_flags & XFS_DA_OP_OKNOENT));
643out: 643out:
@@ -652,7 +652,7 @@ out:
652 state->extravalid = 0; 652 state->extravalid = 0;
653 } 653 }
654 /* 654 /*
655 * Return the index, that will be the insertion point. 655 * Return the index, that will be the deletion point for remove/replace.
656 */ 656 */
657 *indexp = index; 657 *indexp = index;
658 return XFS_ERROR(error); 658 return XFS_ERROR(error);
@@ -1820,8 +1820,14 @@ xfs_dir2_node_lookup(
1820 error = xfs_da_node_lookup_int(state, &rval); 1820 error = xfs_da_node_lookup_int(state, &rval);
1821 if (error) 1821 if (error)
1822 rval = error; 1822 rval = error;
1823 else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) 1823 else if (rval == ENOENT && args->cmpresult == XFS_CMP_CASE) {
1824 rval = EEXIST; /* a case-insensitive match was found */ 1824 /* If a CI match, dup the actual name and return EEXIST */
1825 xfs_dir2_data_entry_t *dep;
1826
1827 dep = (xfs_dir2_data_entry_t *)((char *)state->extrablk.bp->
1828 data + state->extrablk.index);
1829 rval = xfs_dir_cilookup_result(args, dep->name, dep->namelen);
1830 }
1825 /* 1831 /*
1826 * Release the btree blocks and leaf block. 1832 * Release the btree blocks and leaf block.
1827 */ 1833 */