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