aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2.c
diff options
context:
space:
mode:
authorBarry Naujok <bnaujok@sgi.com>2008-05-21 02:58:55 -0400
committerNiv Sardi <xaiki@debian.org>2008-07-28 02:58:42 -0400
commit189f4bf22bdc3c2402b038016d11fd3cb1c89f07 (patch)
tree98a168b063b87609fc28685ace7ce0fec589beff /fs/xfs/xfs_dir2.c
parent384f3ced07efdddf6838f6527366089d37843c94 (diff)
[XFS] XFS: ASCII case-insensitive support
Implement ASCII case-insensitive support. It's primary purpose is for supporting existing filesystems that already use this case-insensitive mode migrated from IRIX. But, if you only need ASCII-only case-insensitive support (ie. English only) and will never use another language, then this mode is perfectly adequate. ASCII-CI is implemented by generating hashes based on lower-case letters and doing lower-case compares. It implements a new xfs_nameops vector for doing the hashes and comparisons for all filename operations. To create a filesystem with this CI mode, use: # mkfs.xfs -n version=ci <device> SGI-PV: 981516 SGI-Modid: xfs-linux-melb:xfs-kern:31209a Signed-off-by: Barry Naujok <bnaujok@sgi.com> Signed-off-by: Christoph Hellwig <hch@infradead.org>
Diffstat (limited to 'fs/xfs/xfs_dir2.c')
-rw-r--r--fs/xfs/xfs_dir2.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 882609c699c8..b445ec314764 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -48,6 +48,52 @@ struct xfs_name xfs_name_dotdot = {"..", 2};
48 48
49extern const struct xfs_nameops xfs_default_nameops; 49extern const struct xfs_nameops xfs_default_nameops;
50 50
51/*
52 * ASCII case-insensitive (ie. A-Z) support for directories that was
53 * used in IRIX.
54 */
55STATIC xfs_dahash_t
56xfs_ascii_ci_hashname(
57 struct xfs_name *name)
58{
59 xfs_dahash_t hash;
60 int i;
61
62 for (i = 0, hash = 0; i < name->len; i++)
63 hash = tolower(name->name[i]) ^ rol32(hash, 7);
64
65 return hash;
66}
67
68STATIC enum xfs_dacmp
69xfs_ascii_ci_compname(
70 struct xfs_da_args *args,
71 const char *name,
72 int len)
73{
74 enum xfs_dacmp result;
75 int i;
76
77 if (args->namelen != len)
78 return XFS_CMP_DIFFERENT;
79
80 result = XFS_CMP_EXACT;
81 for (i = 0; i < len; i++) {
82 if (args->name[i] == name[i])
83 continue;
84 if (tolower(args->name[i]) != tolower(name[i]))
85 return XFS_CMP_DIFFERENT;
86 result = XFS_CMP_CASE;
87 }
88
89 return result;
90}
91
92static struct xfs_nameops xfs_ascii_ci_nameops = {
93 .hashname = xfs_ascii_ci_hashname,
94 .compname = xfs_ascii_ci_compname,
95};
96
51void 97void
52xfs_dir_mount( 98xfs_dir_mount(
53 xfs_mount_t *mp) 99 xfs_mount_t *mp)
@@ -67,7 +113,10 @@ xfs_dir_mount(
67 (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) / 113 (mp->m_dirblksize - (uint)sizeof(xfs_da_node_hdr_t)) /
68 (uint)sizeof(xfs_da_node_entry_t); 114 (uint)sizeof(xfs_da_node_entry_t);
69 mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100; 115 mp->m_dir_magicpct = (mp->m_dirblksize * 37) / 100;
70 mp->m_dirnameops = &xfs_default_nameops; 116 if (xfs_sb_version_hasasciici(&mp->m_sb))
117 mp->m_dirnameops = &xfs_ascii_ci_nameops;
118 else
119 mp->m_dirnameops = &xfs_default_nameops;
71} 120}
72 121
73/* 122/*