aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dir2.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_dir2.c')
-rw-r--r--fs/xfs/xfs_dir2.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/fs/xfs/xfs_dir2.c b/fs/xfs/xfs_dir2.c
index 3387acd3e471..882609c699c8 100644
--- a/fs/xfs/xfs_dir2.c
+++ b/fs/xfs/xfs_dir2.c
@@ -193,14 +193,43 @@ xfs_dir_createname(
193} 193}
194 194
195/* 195/*
196 * If doing a CI lookup and case-insensitive match, dup actual name into
197 * args.value. Return EEXIST for success (ie. name found) or an error.
198 */
199int
200xfs_dir_cilookup_result(
201 struct xfs_da_args *args,
202 const char *name,
203 int len)
204{
205 if (args->cmpresult == XFS_CMP_DIFFERENT)
206 return ENOENT;
207 if (args->cmpresult != XFS_CMP_CASE ||
208 !(args->op_flags & XFS_DA_OP_CILOOKUP))
209 return EEXIST;
210
211 args->value = kmem_alloc(len, KM_MAYFAIL);
212 if (!args->value)
213 return ENOMEM;
214
215 memcpy(args->value, name, len);
216 args->valuelen = len;
217 return EEXIST;
218}
219
220/*
196 * Lookup a name in a directory, give back the inode number. 221 * Lookup a name in a directory, give back the inode number.
222 * If ci_name is not NULL, returns the actual name in ci_name if it differs
223 * to name, or ci_name->name is set to NULL for an exact match.
197 */ 224 */
225
198int 226int
199xfs_dir_lookup( 227xfs_dir_lookup(
200 xfs_trans_t *tp, 228 xfs_trans_t *tp,
201 xfs_inode_t *dp, 229 xfs_inode_t *dp,
202 struct xfs_name *name, 230 struct xfs_name *name,
203 xfs_ino_t *inum) /* out: inode number */ 231 xfs_ino_t *inum, /* out: inode number */
232 struct xfs_name *ci_name) /* out: actual name if CI match */
204{ 233{
205 xfs_da_args_t args; 234 xfs_da_args_t args;
206 int rval; 235 int rval;
@@ -217,6 +246,8 @@ xfs_dir_lookup(
217 args.whichfork = XFS_DATA_FORK; 246 args.whichfork = XFS_DATA_FORK;
218 args.trans = tp; 247 args.trans = tp;
219 args.op_flags = XFS_DA_OP_OKNOENT; 248 args.op_flags = XFS_DA_OP_OKNOENT;
249 if (ci_name)
250 args.op_flags |= XFS_DA_OP_CILOOKUP;
220 args.cmpresult = XFS_CMP_DIFFERENT; 251 args.cmpresult = XFS_CMP_DIFFERENT;
221 252
222 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL) 253 if (dp->i_d.di_format == XFS_DINODE_FMT_LOCAL)
@@ -233,8 +264,13 @@ xfs_dir_lookup(
233 rval = xfs_dir2_node_lookup(&args); 264 rval = xfs_dir2_node_lookup(&args);
234 if (rval == EEXIST) 265 if (rval == EEXIST)
235 rval = 0; 266 rval = 0;
236 if (rval == 0) 267 if (!rval) {
237 *inum = args.inumber; 268 *inum = args.inumber;
269 if (ci_name) {
270 ci_name->name = args.value;
271 ci_name->len = args.valuelen;
272 }
273 }
238 return rval; 274 return rval;
239} 275}
240 276