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