From 5163f95a08cbf058ae16452c2242c5600fedc32e Mon Sep 17 00:00:00 2001 From: Barry Naujok Date: Wed, 21 May 2008 16:41:01 +1000 Subject: [XFS] Name operation vector for hash and compare Adds two pieces of functionality for the basis of case-insensitive support in XFS: 1. A comparison result enumerated type: xfs_dacmp. It represents an exact match, case-insensitive match or no match at all. This patch only implements different and exact results. 2. xfs_nameops vector for specifying how to perform the hash generation of filenames and comparision methods. In this patch the hash vector points to the existing xfs_da_hashname function and the comparison method does a length compare, and if the same, does a memcmp and return the xfs_dacmp result. All filename functions that use the hash (create, lookup remove, rename, etc) now use the xfs_nameops.hashname function and all directory lookup functions also use the xfs_nameops.compname function. The lookup functions also handle case-insensitive results even though the default comparison function cannot return that. And important aspect of the lookup functions is that an exact match always has precedence over a case-insensitive. So while a case-insensitive match is found, we have to keep looking just in case there is an exact match. In the meantime, the info for the first case-insensitive match is retained if no exact match is found. SGI-PV: 981519 SGI-Modid: xfs-linux-melb:xfs-kern:31205a Signed-off-by: Barry Naujok Signed-off-by: Christoph Hellwig --- fs/xfs/xfs_dir2.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'fs/xfs/xfs_dir2.c') diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c index 0284af1734bd..675899bb7048 100644 --- a/fs/xfs/xfs_dir2.c +++ b/fs/xfs/xfs_dir2.c @@ -65,6 +65,7 @@ xfs_dir_mount( (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) / (uint)sizeof(xfs_da_node_entry_t); mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; + mp->m_dirnameops = &xfs_default_nameops; } /* @@ -164,7 +165,7 @@ xfs_dir_createname( args.name = name->name; args.namelen = name->len; - args.hashval = xfs_da_hashname(name->name, name->len); + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -210,11 +211,12 @@ xfs_dir_lookup( args.name = name->name; args.namelen = name->len; - args.hashval = xfs_da_hashname(name->name, name->len); + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; args.oknoent = 1; + args.cmpresult = XFS_CMP_DIFFERENT; if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) rval = xfs_dir2_sf_lookup(&args); @@ -257,7 +259,7 @@ xfs_dir_removename( args.name = name->name; args.namelen = name->len; - args.hashval = xfs_da_hashname(name->name, name->len); + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = ino; args.dp = dp; args.firstblock = first; @@ -340,7 +342,7 @@ xfs_dir_replace( args.name = name->name; args.namelen = name->len; - args.hashval = xfs_da_hashname(name->name, name->len); + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.inumber = inum; args.dp = dp; args.firstblock = first; @@ -388,7 +390,7 @@ xfs_dir_canenter( args.name = name->name; args.namelen = name->len; - args.hashval = xfs_da_hashname(name->name, name->len); + args.hashval = dp->i_mount->m_dirnameops->hashname(name); args.dp = dp; args.whichfork = XFS_DATA_FORK; args.trans = tp; -- cgit v1.2.3-70-g09d2