Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * Copyright (c) 2000-2001,2005 Silicon Graphics, Inc.
4 : * All Rights Reserved.
5 : */
6 : #include "xfs.h"
7 : #include "xfs_fs.h"
8 : #include "xfs_shared.h"
9 : #include "xfs_format.h"
10 : #include "xfs_log_format.h"
11 : #include "xfs_trans_resv.h"
12 : #include "xfs_mount.h"
13 : #include "xfs_inode.h"
14 : #include "xfs_trans.h"
15 : #include "xfs_bmap.h"
16 : #include "xfs_dir2.h"
17 : #include "xfs_dir2_priv.h"
18 : #include "xfs_errortag.h"
19 : #include "xfs_error.h"
20 : #include "xfs_trace.h"
21 : #include "xfs_health.h"
22 :
23 : const struct xfs_name xfs_name_dotdot = {
24 : .name = (const unsigned char *)"..",
25 : .len = 2,
26 : .type = XFS_DIR3_FT_DIR,
27 : };
28 :
29 : const struct xfs_name xfs_name_dot = {
30 : .name = (const unsigned char *)".",
31 : .len = 1,
32 : .type = XFS_DIR3_FT_DIR,
33 : };
34 :
35 : /*
36 : * Convert inode mode to directory entry filetype
37 : */
38 : unsigned char
39 1100489369 : xfs_mode_to_ftype(
40 : int mode)
41 : {
42 1100489369 : switch (mode & S_IFMT) {
43 : case S_IFREG:
44 : return XFS_DIR3_FT_REG_FILE;
45 129459318 : case S_IFDIR:
46 129459318 : return XFS_DIR3_FT_DIR;
47 242353028 : case S_IFCHR:
48 242353028 : return XFS_DIR3_FT_CHRDEV;
49 86 : case S_IFBLK:
50 86 : return XFS_DIR3_FT_BLKDEV;
51 1643 : case S_IFIFO:
52 1643 : return XFS_DIR3_FT_FIFO;
53 16 : case S_IFSOCK:
54 16 : return XFS_DIR3_FT_SOCK;
55 482608416 : case S_IFLNK:
56 482608416 : return XFS_DIR3_FT_SYMLINK;
57 21548438 : default:
58 21548438 : return XFS_DIR3_FT_UNKNOWN;
59 : }
60 : }
61 :
62 : /*
63 : * ASCII case-insensitive (ie. A-Z) support for directories that was
64 : * used in IRIX.
65 : */
66 : xfs_dahash_t
67 1681980 : xfs_ascii_ci_hashname(
68 : const struct xfs_name *name)
69 : {
70 1681980 : xfs_dahash_t hash;
71 1681980 : int i;
72 :
73 40372967 : for (i = 0, hash = 0; i < name->len; i++)
74 38690987 : hash = xfs_ascii_ci_xfrm(name->name[i]) ^ rol32(hash, 7);
75 :
76 1681980 : return hash;
77 : }
78 :
79 : enum xfs_dacmp
80 345835803 : xfs_ascii_ci_compname(
81 : struct xfs_da_args *args,
82 : const unsigned char *name,
83 : int len)
84 : {
85 345835803 : enum xfs_dacmp result;
86 345835803 : int i;
87 :
88 345835803 : if (args->namelen != len)
89 : return XFS_CMP_DIFFERENT;
90 :
91 : result = XFS_CMP_EXACT;
92 18599413 : for (i = 0; i < len; i++) {
93 18458208 : if (args->name[i] == name[i])
94 3858465 : continue;
95 14599743 : if (xfs_ascii_ci_xfrm(args->name[i]) !=
96 14599743 : xfs_ascii_ci_xfrm(name[i]))
97 : return XFS_CMP_DIFFERENT;
98 : result = XFS_CMP_CASE;
99 : }
100 :
101 : return result;
102 : }
103 :
104 : int
105 24115 : xfs_da_mount(
106 : struct xfs_mount *mp)
107 : {
108 24115 : struct xfs_da_geometry *dageo;
109 :
110 :
111 24115 : ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
112 24115 : ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
113 :
114 24115 : mp->m_dir_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
115 : KM_MAYFAIL);
116 24115 : mp->m_attr_geo = kmem_zalloc(sizeof(struct xfs_da_geometry),
117 : KM_MAYFAIL);
118 24115 : if (!mp->m_dir_geo || !mp->m_attr_geo) {
119 0 : kmem_free(mp->m_dir_geo);
120 0 : kmem_free(mp->m_attr_geo);
121 0 : return -ENOMEM;
122 : }
123 :
124 : /* set up directory geometry */
125 24115 : dageo = mp->m_dir_geo;
126 24115 : dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
127 24115 : dageo->fsblog = mp->m_sb.sb_blocklog;
128 24115 : dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
129 24115 : dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
130 24115 : if (xfs_has_crc(mp)) {
131 24073 : dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
132 24073 : dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
133 24073 : dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
134 24073 : dageo->data_entry_offset =
135 : sizeof(struct xfs_dir3_data_hdr);
136 : } else {
137 42 : dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
138 42 : dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
139 42 : dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
140 42 : dageo->data_entry_offset =
141 : sizeof(struct xfs_dir2_data_hdr);
142 : }
143 24115 : dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
144 : sizeof(struct xfs_dir2_leaf_entry);
145 24115 : dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
146 : sizeof(xfs_dir2_data_off_t);
147 :
148 24115 : dageo->data_first_offset = dageo->data_entry_offset +
149 24115 : xfs_dir2_data_entsize(mp, 1) +
150 : xfs_dir2_data_entsize(mp, 2);
151 :
152 : /*
153 : * Now we've set up the block conversion variables, we can calculate the
154 : * segment block constants using the geometry structure.
155 : */
156 24115 : dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
157 24115 : dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
158 24115 : dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
159 24115 : dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
160 : (uint)sizeof(xfs_da_node_entry_t);
161 24115 : dageo->max_extents = (XFS_DIR2_MAX_SPACES * XFS_DIR2_SPACE_SIZE) >>
162 24115 : mp->m_sb.sb_blocklog;
163 24115 : dageo->magicpct = (dageo->blksize * 37) / 100;
164 :
165 : /* set up attribute geometry - single fsb only */
166 24115 : dageo = mp->m_attr_geo;
167 24115 : dageo->blklog = mp->m_sb.sb_blocklog;
168 24115 : dageo->fsblog = mp->m_sb.sb_blocklog;
169 24115 : dageo->blksize = 1 << dageo->blklog;
170 24115 : dageo->fsbcount = 1;
171 24115 : dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size;
172 24115 : dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
173 : (uint)sizeof(xfs_da_node_entry_t);
174 :
175 24115 : if (xfs_has_large_extent_counts(mp))
176 24071 : dageo->max_extents = XFS_MAX_EXTCNT_ATTR_FORK_LARGE;
177 : else
178 44 : dageo->max_extents = XFS_MAX_EXTCNT_ATTR_FORK_SMALL;
179 :
180 24115 : dageo->magicpct = (dageo->blksize * 37) / 100;
181 24115 : return 0;
182 : }
183 :
184 : void
185 24122 : xfs_da_unmount(
186 : struct xfs_mount *mp)
187 : {
188 24122 : kmem_free(mp->m_dir_geo);
189 24122 : kmem_free(mp->m_attr_geo);
190 24122 : }
191 :
192 : /*
193 : * Return 1 if directory contains only "." and "..".
194 : */
195 : int
196 1061925 : xfs_dir_isempty(
197 : xfs_inode_t *dp)
198 : {
199 1061925 : xfs_dir2_sf_hdr_t *sfp;
200 :
201 1061925 : ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
202 1061925 : if (dp->i_disk_size == 0) /* might happen during shutdown. */
203 : return 1;
204 1061925 : if (dp->i_disk_size > xfs_inode_data_fork_size(dp))
205 : return 0;
206 1060318 : sfp = (xfs_dir2_sf_hdr_t *)dp->i_df.if_u1.if_data;
207 1060318 : return !sfp->count;
208 : }
209 :
210 : /*
211 : * Validate a given inode number.
212 : */
213 : int
214 845943313 : xfs_dir_ino_validate(
215 : xfs_mount_t *mp,
216 : xfs_ino_t ino)
217 : {
218 845943313 : bool ino_ok = xfs_verify_dir_ino(mp, ino);
219 :
220 1691907341 : if (XFS_IS_CORRUPT(mp, !ino_ok) ||
221 845948855 : XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DIR_INO_VALIDATE)) {
222 2 : xfs_warn(mp, "Invalid inode number 0x%Lx",
223 : (unsigned long long) ino);
224 2 : return -EFSCORRUPTED;
225 : }
226 : return 0;
227 : }
228 :
229 : /*
230 : * Initialize a directory with its "." and ".." entries.
231 : */
232 : int
233 6311429 : xfs_dir_init(
234 : xfs_trans_t *tp,
235 : xfs_inode_t *dp,
236 : xfs_inode_t *pdp)
237 : {
238 6311429 : struct xfs_da_args *args;
239 6311429 : int error;
240 :
241 6311429 : ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
242 6311429 : error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino);
243 6311406 : if (error)
244 : return error;
245 :
246 6311421 : args = kmem_zalloc(sizeof(*args), KM_NOFS);
247 6311411 : if (!args)
248 : return -ENOMEM;
249 :
250 6311411 : args->geo = dp->i_mount->m_dir_geo;
251 6311411 : args->dp = dp;
252 6311411 : args->trans = tp;
253 6311411 : args->owner = dp->i_ino;
254 6311411 : error = xfs_dir2_sf_create(args, pdp->i_ino);
255 6311289 : kmem_free(args);
256 6311289 : return error;
257 : }
258 :
259 : /*
260 : * Enter a name in a directory, or check for available space.
261 : * If inum is 0, only the available space test is performed.
262 : */
263 : int
264 85567532 : xfs_dir_createname(
265 : struct xfs_trans *tp,
266 : struct xfs_inode *dp,
267 : const struct xfs_name *name,
268 : xfs_ino_t inum, /* new entry inode number */
269 : xfs_extlen_t total) /* bmap's total block count */
270 : {
271 85567532 : struct xfs_da_args *args;
272 85567532 : int rval;
273 85567532 : bool v;
274 :
275 85567532 : ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
276 :
277 85567532 : if (inum) {
278 85567599 : rval = xfs_dir_ino_validate(tp->t_mountp, inum);
279 85568840 : if (rval)
280 : return rval;
281 85568840 : XFS_STATS_INC(dp->i_mount, xs_dir_create);
282 : }
283 :
284 85568773 : args = kmem_zalloc(sizeof(*args), KM_NOFS);
285 85566095 : if (!args)
286 : return -ENOMEM;
287 :
288 85566095 : args->geo = dp->i_mount->m_dir_geo;
289 85566095 : args->name = name->name;
290 85566095 : args->namelen = name->len;
291 85566095 : args->filetype = name->type;
292 85566095 : args->hashval = xfs_dir2_hashname(dp->i_mount, name);
293 85565015 : args->inumber = inum;
294 85565015 : args->dp = dp;
295 85565015 : args->total = total;
296 85565015 : args->whichfork = XFS_DATA_FORK;
297 85565015 : args->trans = tp;
298 85565015 : args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
299 85565015 : args->owner = dp->i_ino;
300 85565015 : if (!inum)
301 0 : args->op_flags |= XFS_DA_OP_JUSTCHECK;
302 :
303 85565015 : if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
304 46337384 : rval = xfs_dir2_sf_addname(args);
305 46339599 : goto out_free;
306 : }
307 :
308 39227631 : rval = xfs_dir2_isblock(args, &v);
309 39230831 : if (rval)
310 0 : goto out_free;
311 39230831 : if (v) {
312 2268982 : rval = xfs_dir2_block_addname(args);
313 2269183 : goto out_free;
314 : }
315 :
316 36961849 : rval = xfs_dir2_isleaf(args, &v);
317 36960537 : if (rval)
318 0 : goto out_free;
319 36960537 : if (v)
320 4704825 : rval = xfs_dir2_leaf_addname(args);
321 : else
322 32255712 : rval = xfs_dir2_node_addname(args);
323 :
324 85570353 : out_free:
325 85570353 : kmem_free(args);
326 85570353 : return rval;
327 : }
328 :
329 : /*
330 : * If doing a CI lookup and case-insensitive match, dup actual name into
331 : * args.value. Return EEXIST for success (ie. name found) or an error.
332 : */
333 : int
334 30400800 : xfs_dir_cilookup_result(
335 : struct xfs_da_args *args,
336 : const unsigned char *name,
337 : int len)
338 : {
339 30400800 : if (args->cmpresult == XFS_CMP_DIFFERENT)
340 : return -ENOENT;
341 30400800 : if (args->cmpresult != XFS_CMP_CASE ||
342 : !(args->op_flags & XFS_DA_OP_CILOOKUP))
343 : return -EEXIST;
344 :
345 88096 : args->value = kmem_alloc(len, KM_NOFS | KM_MAYFAIL);
346 88096 : if (!args->value)
347 : return -ENOMEM;
348 :
349 176192 : memcpy(args->value, name, len);
350 88096 : args->valuelen = len;
351 88096 : return -EEXIST;
352 : }
353 :
354 : /*
355 : * Lookup a name in a directory, give back the inode number.
356 : * If ci_name is not NULL, returns the actual name in ci_name if it differs
357 : * to name, or ci_name->name is set to NULL for an exact match.
358 : */
359 :
360 : int
361 192884765 : xfs_dir_lookup(
362 : struct xfs_trans *tp,
363 : struct xfs_inode *dp,
364 : const struct xfs_name *name,
365 : xfs_ino_t *inum, /* out: inode number */
366 : struct xfs_name *ci_name) /* out: actual name if CI match */
367 : {
368 192884765 : struct xfs_da_args *args;
369 192884765 : int rval;
370 192884765 : bool v;
371 192884765 : int lock_mode;
372 :
373 192884765 : ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
374 192884765 : XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
375 :
376 : /*
377 : * We need to use KM_NOFS here so that lockdep will not throw false
378 : * positive deadlock warnings on a non-transactional lookup path. It is
379 : * safe to recurse into inode recalim in that case, but lockdep can't
380 : * easily be taught about it. Hence KM_NOFS avoids having to add more
381 : * lockdep Doing this avoids having to add a bunch of lockdep class
382 : * annotations into the reclaim path for the ilock.
383 : */
384 192884765 : args = kmem_zalloc(sizeof(*args), KM_NOFS);
385 192874018 : args->geo = dp->i_mount->m_dir_geo;
386 192874018 : args->name = name->name;
387 192874018 : args->namelen = name->len;
388 192874018 : args->filetype = name->type;
389 192874018 : args->hashval = xfs_dir2_hashname(dp->i_mount, name);
390 192886249 : args->dp = dp;
391 192886249 : args->whichfork = XFS_DATA_FORK;
392 192886249 : args->trans = tp;
393 192886249 : args->op_flags = XFS_DA_OP_OKNOENT;
394 192886249 : args->owner = dp->i_ino;
395 192886249 : if (ci_name)
396 195894 : args->op_flags |= XFS_DA_OP_CILOOKUP;
397 :
398 192886249 : lock_mode = xfs_ilock_data_map_shared(dp);
399 192882964 : if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
400 150580160 : rval = xfs_dir2_sf_lookup(args);
401 150578869 : goto out_check_rval;
402 : }
403 :
404 42302804 : rval = xfs_dir2_isblock(args, &v);
405 42300856 : if (rval)
406 0 : goto out_free;
407 42300856 : if (v) {
408 21706858 : rval = xfs_dir2_block_lookup(args);
409 21706432 : goto out_check_rval;
410 : }
411 :
412 20593998 : rval = xfs_dir2_isleaf(args, &v);
413 20606131 : if (rval)
414 0 : goto out_free;
415 20606131 : if (v)
416 10015176 : rval = xfs_dir2_leaf_lookup(args);
417 : else
418 10590955 : rval = xfs_dir2_node_lookup(args);
419 :
420 192896283 : out_check_rval:
421 192896283 : if (rval == -EEXIST)
422 : rval = 0;
423 73164556 : if (!rval) {
424 119730073 : *inum = args->inumber;
425 119730073 : if (ci_name) {
426 103142 : ci_name->name = args->value;
427 103142 : ci_name->len = args->valuelen;
428 : }
429 : }
430 192793213 : out_free:
431 192896283 : xfs_iunlock(dp, lock_mode);
432 192893066 : kmem_free(args);
433 192895348 : return rval;
434 : }
435 :
436 : /*
437 : * Remove an entry from a directory.
438 : */
439 : int
440 60550358 : xfs_dir_removename(
441 : struct xfs_trans *tp,
442 : struct xfs_inode *dp,
443 : const struct xfs_name *name,
444 : xfs_ino_t ino,
445 : xfs_extlen_t total) /* bmap's total block count */
446 : {
447 60550358 : struct xfs_da_args *args;
448 60550358 : int rval;
449 60550358 : bool v;
450 :
451 60550358 : ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
452 60550358 : XFS_STATS_INC(dp->i_mount, xs_dir_remove);
453 :
454 60550358 : args = kmem_zalloc(sizeof(*args), KM_NOFS);
455 60551132 : if (!args)
456 : return -ENOMEM;
457 :
458 60551132 : args->geo = dp->i_mount->m_dir_geo;
459 60551132 : args->name = name->name;
460 60551132 : args->namelen = name->len;
461 60551132 : args->filetype = name->type;
462 60551132 : args->hashval = xfs_dir2_hashname(dp->i_mount, name);
463 60551309 : args->inumber = ino;
464 60551309 : args->dp = dp;
465 60551309 : args->total = total;
466 60551309 : args->whichfork = XFS_DATA_FORK;
467 60551309 : args->trans = tp;
468 60551309 : args->owner = dp->i_ino;
469 :
470 60551309 : if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
471 23954289 : rval = xfs_dir2_sf_removename(args);
472 23954556 : goto out_free;
473 : }
474 :
475 36597020 : rval = xfs_dir2_isblock(args, &v);
476 36597173 : if (rval)
477 0 : goto out_free;
478 36597173 : if (v) {
479 1690684 : rval = xfs_dir2_block_removename(args);
480 1690682 : goto out_free;
481 : }
482 :
483 34906489 : rval = xfs_dir2_isleaf(args, &v);
484 34906633 : if (rval)
485 0 : goto out_free;
486 34906633 : if (v)
487 4611384 : rval = xfs_dir2_leaf_removename(args);
488 : else
489 30295249 : rval = xfs_dir2_node_removename(args);
490 60552316 : out_free:
491 60552316 : kmem_free(args);
492 60552316 : return rval;
493 : }
494 :
495 : /*
496 : * Replace the inode number of a directory entry.
497 : */
498 : int
499 31401761 : xfs_dir_replace(
500 : struct xfs_trans *tp,
501 : struct xfs_inode *dp,
502 : const struct xfs_name *name, /* name of entry to replace */
503 : xfs_ino_t inum, /* new inode number */
504 : xfs_extlen_t total) /* bmap's total block count */
505 : {
506 31401761 : struct xfs_da_args *args;
507 31401761 : int rval;
508 31401761 : bool v;
509 :
510 31401761 : ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
511 :
512 31401761 : rval = xfs_dir_ino_validate(tp->t_mountp, inum);
513 31401760 : if (rval)
514 : return rval;
515 :
516 31401765 : args = kmem_zalloc(sizeof(*args), KM_NOFS);
517 31401759 : if (!args)
518 : return -ENOMEM;
519 :
520 31401759 : args->geo = dp->i_mount->m_dir_geo;
521 31401759 : args->name = name->name;
522 31401759 : args->namelen = name->len;
523 31401759 : args->filetype = name->type;
524 31401759 : args->hashval = xfs_dir2_hashname(dp->i_mount, name);
525 31401742 : args->inumber = inum;
526 31401742 : args->dp = dp;
527 31401742 : args->total = total;
528 31401742 : args->whichfork = XFS_DATA_FORK;
529 31401742 : args->trans = tp;
530 31401742 : args->owner = dp->i_ino;
531 :
532 31401742 : if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
533 29801173 : rval = xfs_dir2_sf_replace(args);
534 29801186 : goto out_free;
535 : }
536 :
537 1600569 : rval = xfs_dir2_isblock(args, &v);
538 1600573 : if (rval)
539 0 : goto out_free;
540 1600573 : if (v) {
541 881048 : rval = xfs_dir2_block_replace(args);
542 881047 : goto out_free;
543 : }
544 :
545 719525 : rval = xfs_dir2_isleaf(args, &v);
546 719524 : if (rval)
547 0 : goto out_free;
548 719524 : if (v)
549 210662 : rval = xfs_dir2_leaf_replace(args);
550 : else
551 508862 : rval = xfs_dir2_node_replace(args);
552 31401759 : out_free:
553 31401759 : kmem_free(args);
554 31401759 : return rval;
555 : }
556 :
557 : /*
558 : * See if this entry can be added to the directory without allocating space.
559 : */
560 : int
561 0 : xfs_dir_canenter(
562 : xfs_trans_t *tp,
563 : xfs_inode_t *dp,
564 : struct xfs_name *name) /* name of entry to add */
565 : {
566 0 : return xfs_dir_createname(tp, dp, name, 0, 0);
567 : }
568 :
569 : /*
570 : * Utility routines.
571 : */
572 :
573 : /*
574 : * Add a block to the directory.
575 : *
576 : * This routine is for data and free blocks, not leaf/node blocks which are
577 : * handled by xfs_da_grow_inode.
578 : */
579 : int
580 352968 : xfs_dir2_grow_inode(
581 : struct xfs_da_args *args,
582 : int space, /* v2 dir's space XFS_DIR2_xxx_SPACE */
583 : xfs_dir2_db_t *dbp) /* out: block number added */
584 : {
585 352968 : struct xfs_inode *dp = args->dp;
586 352968 : struct xfs_mount *mp = dp->i_mount;
587 352968 : xfs_fileoff_t bno; /* directory offset of new block */
588 352968 : int count; /* count of filesystem blocks */
589 352968 : int error;
590 :
591 352968 : trace_xfs_dir2_grow_inode(args, space);
592 :
593 : /*
594 : * Set lowest possible block in the space requested.
595 : */
596 352968 : bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
597 352968 : count = args->geo->fsbcount;
598 :
599 352968 : error = xfs_da_grow_inode_int(args, &bno, count);
600 352965 : if (error)
601 : return error;
602 :
603 352964 : *dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno);
604 :
605 : /*
606 : * Update file's size if this is the data space and it grew.
607 : */
608 352964 : if (space == XFS_DIR2_DATA_SPACE) {
609 351269 : xfs_fsize_t size; /* directory file (data) size */
610 :
611 351269 : size = XFS_FSB_TO_B(mp, bno + count);
612 351269 : if (size > dp->i_disk_size) {
613 350474 : dp->i_disk_size = size;
614 350474 : xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
615 : }
616 : }
617 : return 0;
618 : }
619 :
620 : /*
621 : * See if the directory is a single-block form directory.
622 : */
623 : int
624 233117176 : xfs_dir2_isblock(
625 : struct xfs_da_args *args,
626 : bool *isblock)
627 : {
628 233117176 : struct xfs_mount *mp = args->dp->i_mount;
629 233117176 : xfs_fileoff_t eof;
630 233117176 : int error;
631 :
632 233117176 : error = xfs_bmap_last_offset(args->dp, &eof, XFS_DATA_FORK);
633 233153620 : if (error)
634 : return error;
635 :
636 233153620 : *isblock = false;
637 233153620 : if (XFS_FSB_TO_B(mp, eof) != args->geo->blksize)
638 : return 0;
639 :
640 47410009 : *isblock = true;
641 47410009 : if (XFS_IS_CORRUPT(mp, args->dp->i_disk_size != args->geo->blksize)) {
642 0 : xfs_da_mark_sick(args);
643 0 : return -EFSCORRUPTED;
644 : }
645 : return 0;
646 : }
647 :
648 : /*
649 : * See if the directory is a single-leaf form directory.
650 : */
651 : int
652 165637381 : xfs_dir2_isleaf(
653 : struct xfs_da_args *args,
654 : bool *isleaf)
655 : {
656 165637381 : xfs_fileoff_t eof;
657 165637381 : int error;
658 :
659 165637381 : error = xfs_bmap_last_offset(args->dp, &eof, XFS_DATA_FORK);
660 165632136 : if (error)
661 : return error;
662 :
663 165632136 : *isleaf = false;
664 165632136 : if (eof != args->geo->leafblk + args->geo->fsbcount)
665 : return 0;
666 :
667 21582546 : *isleaf = true;
668 21582546 : return 0;
669 : }
670 :
671 : /*
672 : * Remove the given block from the directory.
673 : * This routine is used for data and free blocks, leaf/node are done
674 : * by xfs_da_shrink_inode.
675 : */
676 : int
677 240143 : xfs_dir2_shrink_inode(
678 : struct xfs_da_args *args,
679 : xfs_dir2_db_t db,
680 : struct xfs_buf *bp)
681 : {
682 240143 : xfs_fileoff_t bno; /* directory file offset */
683 240143 : xfs_dablk_t da; /* directory file offset */
684 240143 : int done; /* bunmap is finished */
685 240143 : struct xfs_inode *dp;
686 240143 : int error;
687 240143 : struct xfs_mount *mp;
688 240143 : struct xfs_trans *tp;
689 :
690 240143 : trace_xfs_dir2_shrink_inode(args, db);
691 :
692 240143 : dp = args->dp;
693 240143 : mp = dp->i_mount;
694 240143 : tp = args->trans;
695 240143 : da = xfs_dir2_db_to_da(args->geo, db);
696 :
697 : /* Unmap the fsblock(s). */
698 240143 : error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, &done);
699 240143 : if (error) {
700 : /*
701 : * ENOSPC actually can happen if we're in a removename with no
702 : * space reservation, and the resulting block removal would
703 : * cause a bmap btree split or conversion from extents to btree.
704 : * This can only happen for un-fragmented directory blocks,
705 : * since you need to be punching out the middle of an extent.
706 : * In this case we need to leave the block in the file, and not
707 : * binval it. So the block has to be in a consistent empty
708 : * state and appropriately logged. We don't free up the buffer,
709 : * the caller can tell it hasn't happened since it got an error
710 : * back.
711 : */
712 : return error;
713 : }
714 240143 : ASSERT(done);
715 : /*
716 : * Invalidate the buffer from the transaction.
717 : */
718 240143 : xfs_trans_binval(tp, bp);
719 : /*
720 : * If it's not a data block, we're done.
721 : */
722 240143 : if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET))
723 : return 0;
724 : /*
725 : * If the block isn't the last one in the directory, we're done.
726 : */
727 238906 : if (dp->i_disk_size > xfs_dir2_db_off_to_byte(args->geo, db + 1, 0))
728 : return 0;
729 219764 : bno = da;
730 219764 : if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
731 : /*
732 : * This can't really happen unless there's kernel corruption.
733 : */
734 : return error;
735 : }
736 219764 : if (db == args->geo->datablk)
737 217278 : ASSERT(bno == 0);
738 : else
739 2486 : ASSERT(bno > 0);
740 : /*
741 : * Set the size to the new last block.
742 : */
743 219764 : dp->i_disk_size = XFS_FSB_TO_B(mp, bno);
744 219764 : xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
745 219764 : return 0;
746 : }
747 :
748 : /* Returns true if the directory entry name is valid. */
749 : bool
750 28195914665 : xfs_dir2_namecheck(
751 : const void *name,
752 : size_t length)
753 : {
754 : /*
755 : * MAXNAMELEN includes the trailing null, but (name/length) leave it
756 : * out, so use >= for the length check.
757 : */
758 28195914665 : if (length >= MAXNAMELEN)
759 : return false;
760 :
761 : /* There shouldn't be any slashes or nulls here */
762 83140307551 : return !memchr(name, '/', length) && !memchr(name, 0, length);
763 : }
764 :
765 : xfs_dahash_t
766 2800934544 : xfs_dir2_hashname(
767 : struct xfs_mount *mp,
768 : const struct xfs_name *name)
769 : {
770 2800934544 : if (unlikely(xfs_has_asciici(mp)))
771 1680780 : return xfs_ascii_ci_hashname(name);
772 2799253764 : return xfs_da_hashname(name->name, name->len);
773 : }
774 :
775 : enum xfs_dacmp
776 1685463145 : xfs_dir2_compname(
777 : struct xfs_da_args *args,
778 : const unsigned char *name,
779 : int len)
780 : {
781 1685463145 : if (unlikely(xfs_has_asciici(args->dp->i_mount)))
782 345835803 : return xfs_ascii_ci_compname(args, name, len);
783 1339627342 : return xfs_da_compname(args, name, len);
784 : }
|