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