]> Git Repo - J-linux.git/blob - fs/xfs/libxfs/xfs_dir2.c
Merge tag 'vfs-6.13-rc7.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
[J-linux.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 #include "xfs_health.h"
22 #include "xfs_bmap_btree.h"
23 #include "xfs_trans_space.h"
24 #include "xfs_parent.h"
25 #include "xfs_ag.h"
26 #include "xfs_ialloc.h"
27
28 const struct xfs_name xfs_name_dotdot = {
29         .name   = (const unsigned char *)"..",
30         .len    = 2,
31         .type   = XFS_DIR3_FT_DIR,
32 };
33
34 const struct xfs_name xfs_name_dot = {
35         .name   = (const unsigned char *)".",
36         .len    = 1,
37         .type   = XFS_DIR3_FT_DIR,
38 };
39
40 /*
41  * Convert inode mode to directory entry filetype
42  */
43 unsigned char
44 xfs_mode_to_ftype(
45         int             mode)
46 {
47         switch (mode & S_IFMT) {
48         case S_IFREG:
49                 return XFS_DIR3_FT_REG_FILE;
50         case S_IFDIR:
51                 return XFS_DIR3_FT_DIR;
52         case S_IFCHR:
53                 return XFS_DIR3_FT_CHRDEV;
54         case S_IFBLK:
55                 return XFS_DIR3_FT_BLKDEV;
56         case S_IFIFO:
57                 return XFS_DIR3_FT_FIFO;
58         case S_IFSOCK:
59                 return XFS_DIR3_FT_SOCK;
60         case S_IFLNK:
61                 return XFS_DIR3_FT_SYMLINK;
62         default:
63                 return XFS_DIR3_FT_UNKNOWN;
64         }
65 }
66
67 /*
68  * ASCII case-insensitive (ie. A-Z) support for directories that was
69  * used in IRIX.
70  */
71 xfs_dahash_t
72 xfs_ascii_ci_hashname(
73         const struct xfs_name   *name)
74 {
75         xfs_dahash_t            hash;
76         int                     i;
77
78         for (i = 0, hash = 0; i < name->len; i++)
79                 hash = xfs_ascii_ci_xfrm(name->name[i]) ^ rol32(hash, 7);
80
81         return hash;
82 }
83
84 enum xfs_dacmp
85 xfs_ascii_ci_compname(
86         struct xfs_da_args      *args,
87         const unsigned char     *name,
88         int                     len)
89 {
90         enum xfs_dacmp          result;
91         int                     i;
92
93         if (args->namelen != len)
94                 return XFS_CMP_DIFFERENT;
95
96         result = XFS_CMP_EXACT;
97         for (i = 0; i < len; i++) {
98                 if (args->name[i] == name[i])
99                         continue;
100                 if (xfs_ascii_ci_xfrm(args->name[i]) !=
101                     xfs_ascii_ci_xfrm(name[i]))
102                         return XFS_CMP_DIFFERENT;
103                 result = XFS_CMP_CASE;
104         }
105
106         return result;
107 }
108
109 int
110 xfs_da_mount(
111         struct xfs_mount        *mp)
112 {
113         struct xfs_da_geometry  *dageo;
114
115
116         ASSERT(mp->m_sb.sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
117         ASSERT(xfs_dir2_dirblock_bytes(&mp->m_sb) <= XFS_MAX_BLOCKSIZE);
118
119         mp->m_dir_geo = kzalloc(sizeof(struct xfs_da_geometry),
120                                 GFP_KERNEL | __GFP_RETRY_MAYFAIL);
121         mp->m_attr_geo = kzalloc(sizeof(struct xfs_da_geometry),
122                                 GFP_KERNEL | __GFP_RETRY_MAYFAIL);
123         if (!mp->m_dir_geo || !mp->m_attr_geo) {
124                 kfree(mp->m_dir_geo);
125                 kfree(mp->m_attr_geo);
126                 return -ENOMEM;
127         }
128
129         /* set up directory geometry */
130         dageo = mp->m_dir_geo;
131         dageo->blklog = mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog;
132         dageo->fsblog = mp->m_sb.sb_blocklog;
133         dageo->blksize = xfs_dir2_dirblock_bytes(&mp->m_sb);
134         dageo->fsbcount = 1 << mp->m_sb.sb_dirblklog;
135         if (xfs_has_crc(mp)) {
136                 dageo->node_hdr_size = sizeof(struct xfs_da3_node_hdr);
137                 dageo->leaf_hdr_size = sizeof(struct xfs_dir3_leaf_hdr);
138                 dageo->free_hdr_size = sizeof(struct xfs_dir3_free_hdr);
139                 dageo->data_entry_offset =
140                                 sizeof(struct xfs_dir3_data_hdr);
141         } else {
142                 dageo->node_hdr_size = sizeof(struct xfs_da_node_hdr);
143                 dageo->leaf_hdr_size = sizeof(struct xfs_dir2_leaf_hdr);
144                 dageo->free_hdr_size = sizeof(struct xfs_dir2_free_hdr);
145                 dageo->data_entry_offset =
146                                 sizeof(struct xfs_dir2_data_hdr);
147         }
148         dageo->leaf_max_ents = (dageo->blksize - dageo->leaf_hdr_size) /
149                         sizeof(struct xfs_dir2_leaf_entry);
150         dageo->free_max_bests = (dageo->blksize - dageo->free_hdr_size) /
151                         sizeof(xfs_dir2_data_off_t);
152
153         dageo->data_first_offset = dageo->data_entry_offset +
154                         xfs_dir2_data_entsize(mp, 1) +
155                         xfs_dir2_data_entsize(mp, 2);
156
157         /*
158          * Now we've set up the block conversion variables, we can calculate the
159          * segment block constants using the geometry structure.
160          */
161         dageo->datablk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_DATA_OFFSET);
162         dageo->leafblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_LEAF_OFFSET);
163         dageo->freeblk = xfs_dir2_byte_to_da(dageo, XFS_DIR2_FREE_OFFSET);
164         dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
165                                 (uint)sizeof(xfs_da_node_entry_t);
166         dageo->max_extents = (XFS_DIR2_MAX_SPACES * XFS_DIR2_SPACE_SIZE) >>
167                                         mp->m_sb.sb_blocklog;
168         dageo->magicpct = (dageo->blksize * 37) / 100;
169
170         /* set up attribute geometry - single fsb only */
171         dageo = mp->m_attr_geo;
172         dageo->blklog = mp->m_sb.sb_blocklog;
173         dageo->fsblog = mp->m_sb.sb_blocklog;
174         dageo->blksize = 1 << dageo->blklog;
175         dageo->fsbcount = 1;
176         dageo->node_hdr_size = mp->m_dir_geo->node_hdr_size;
177         dageo->node_ents = (dageo->blksize - dageo->node_hdr_size) /
178                                 (uint)sizeof(xfs_da_node_entry_t);
179
180         if (xfs_has_large_extent_counts(mp))
181                 dageo->max_extents = XFS_MAX_EXTCNT_ATTR_FORK_LARGE;
182         else
183                 dageo->max_extents = XFS_MAX_EXTCNT_ATTR_FORK_SMALL;
184
185         dageo->magicpct = (dageo->blksize * 37) / 100;
186         return 0;
187 }
188
189 void
190 xfs_da_unmount(
191         struct xfs_mount        *mp)
192 {
193         kfree(mp->m_dir_geo);
194         kfree(mp->m_attr_geo);
195 }
196
197 /*
198  * Return 1 if directory contains only "." and "..".
199  */
200 int
201 xfs_dir_isempty(
202         xfs_inode_t     *dp)
203 {
204         xfs_dir2_sf_hdr_t       *sfp;
205
206         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
207         if (dp->i_disk_size == 0)       /* might happen during shutdown. */
208                 return 1;
209         if (dp->i_disk_size > xfs_inode_data_fork_size(dp))
210                 return 0;
211         sfp = dp->i_df.if_data;
212         return !sfp->count;
213 }
214
215 /*
216  * Validate a given inode number.
217  */
218 int
219 xfs_dir_ino_validate(
220         xfs_mount_t     *mp,
221         xfs_ino_t       ino)
222 {
223         bool            ino_ok = xfs_verify_dir_ino(mp, ino);
224
225         if (XFS_IS_CORRUPT(mp, !ino_ok) ||
226             XFS_TEST_ERROR(false, mp, XFS_ERRTAG_DIR_INO_VALIDATE)) {
227                 xfs_warn(mp, "Invalid inode number 0x%Lx",
228                                 (unsigned long long) ino);
229                 return -EFSCORRUPTED;
230         }
231         return 0;
232 }
233
234 /*
235  * Initialize a directory with its "." and ".." entries.
236  */
237 int
238 xfs_dir_init(
239         xfs_trans_t     *tp,
240         xfs_inode_t     *dp,
241         xfs_inode_t     *pdp)
242 {
243         struct xfs_da_args *args;
244         int             error;
245
246         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
247         error = xfs_dir_ino_validate(tp->t_mountp, pdp->i_ino);
248         if (error)
249                 return error;
250
251         args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
252         if (!args)
253                 return -ENOMEM;
254
255         args->geo = dp->i_mount->m_dir_geo;
256         args->dp = dp;
257         args->trans = tp;
258         args->owner = dp->i_ino;
259         error = xfs_dir2_sf_create(args, pdp->i_ino);
260         kfree(args);
261         return error;
262 }
263
264 enum xfs_dir2_fmt
265 xfs_dir2_format(
266         struct xfs_da_args      *args,
267         int                     *error)
268 {
269         struct xfs_inode        *dp = args->dp;
270         struct xfs_mount        *mp = dp->i_mount;
271         struct xfs_da_geometry  *geo = mp->m_dir_geo;
272         xfs_fileoff_t           eof;
273
274         xfs_assert_ilocked(dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL);
275
276         *error = 0;
277         if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL)
278                 return XFS_DIR2_FMT_SF;
279
280         *error = xfs_bmap_last_offset(dp, &eof, XFS_DATA_FORK);
281         if (*error)
282                 return XFS_DIR2_FMT_ERROR;
283
284         if (eof == XFS_B_TO_FSB(mp, geo->blksize)) {
285                 if (XFS_IS_CORRUPT(mp, dp->i_disk_size != geo->blksize)) {
286                         xfs_da_mark_sick(args);
287                         *error = -EFSCORRUPTED;
288                         return XFS_DIR2_FMT_ERROR;
289                 }
290                 return XFS_DIR2_FMT_BLOCK;
291         }
292         if (eof == geo->leafblk + geo->fsbcount)
293                 return XFS_DIR2_FMT_LEAF;
294         return XFS_DIR2_FMT_NODE;
295 }
296
297 int
298 xfs_dir_createname_args(
299         struct xfs_da_args      *args)
300 {
301         int                     error;
302
303         if (!args->inumber)
304                 args->op_flags |= XFS_DA_OP_JUSTCHECK;
305
306         switch (xfs_dir2_format(args, &error)) {
307         case XFS_DIR2_FMT_SF:
308                 return xfs_dir2_sf_addname(args);
309         case XFS_DIR2_FMT_BLOCK:
310                 return xfs_dir2_block_addname(args);
311         case XFS_DIR2_FMT_LEAF:
312                 return xfs_dir2_leaf_addname(args);
313         case XFS_DIR2_FMT_NODE:
314                 return xfs_dir2_node_addname(args);
315         default:
316                 return error;
317         }
318 }
319
320 /*
321  * Enter a name in a directory, or check for available space.
322  * If inum is 0, only the available space test is performed.
323  */
324 int
325 xfs_dir_createname(
326         struct xfs_trans        *tp,
327         struct xfs_inode        *dp,
328         const struct xfs_name   *name,
329         xfs_ino_t               inum,           /* new entry inode number */
330         xfs_extlen_t            total)          /* bmap's total block count */
331 {
332         struct xfs_da_args      *args;
333         int                     rval;
334
335         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
336
337         if (inum) {
338                 rval = xfs_dir_ino_validate(tp->t_mountp, inum);
339                 if (rval)
340                         return rval;
341                 XFS_STATS_INC(dp->i_mount, xs_dir_create);
342         }
343
344         args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
345         if (!args)
346                 return -ENOMEM;
347
348         args->geo = dp->i_mount->m_dir_geo;
349         args->name = name->name;
350         args->namelen = name->len;
351         args->filetype = name->type;
352         args->hashval = xfs_dir2_hashname(dp->i_mount, name);
353         args->inumber = inum;
354         args->dp = dp;
355         args->total = total;
356         args->whichfork = XFS_DATA_FORK;
357         args->trans = tp;
358         args->op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
359         args->owner = dp->i_ino;
360
361         rval = xfs_dir_createname_args(args);
362         kfree(args);
363         return rval;
364 }
365
366 /*
367  * If doing a CI lookup and case-insensitive match, dup actual name into
368  * args.value. Return EEXIST for success (ie. name found) or an error.
369  */
370 int
371 xfs_dir_cilookup_result(
372         struct xfs_da_args *args,
373         const unsigned char *name,
374         int             len)
375 {
376         if (args->cmpresult == XFS_CMP_DIFFERENT)
377                 return -ENOENT;
378         if (args->cmpresult != XFS_CMP_CASE ||
379                                         !(args->op_flags & XFS_DA_OP_CILOOKUP))
380                 return -EEXIST;
381
382         args->value = kmalloc(len,
383                         GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_RETRY_MAYFAIL);
384         if (!args->value)
385                 return -ENOMEM;
386
387         memcpy(args->value, name, len);
388         args->valuelen = len;
389         return -EEXIST;
390 }
391
392 int
393 xfs_dir_lookup_args(
394         struct xfs_da_args      *args)
395 {
396         int                     error;
397
398         switch (xfs_dir2_format(args, &error)) {
399         case XFS_DIR2_FMT_SF:
400                 error = xfs_dir2_sf_lookup(args);
401                 break;
402         case XFS_DIR2_FMT_BLOCK:
403                 error = xfs_dir2_block_lookup(args);
404                 break;
405         case XFS_DIR2_FMT_LEAF:
406                 error = xfs_dir2_leaf_lookup(args);
407                 break;
408         case XFS_DIR2_FMT_NODE:
409                 error = xfs_dir2_node_lookup(args);
410                 break;
411         default:
412                 break;
413         }
414
415         if (error != -EEXIST)
416                 return error;
417         return 0;
418 }
419
420 /*
421  * Lookup a name in a directory, give back the inode number.
422  * If ci_name is not NULL, returns the actual name in ci_name if it differs
423  * to name, or ci_name->name is set to NULL for an exact match.
424  */
425
426 int
427 xfs_dir_lookup(
428         struct xfs_trans        *tp,
429         struct xfs_inode        *dp,
430         const struct xfs_name   *name,
431         xfs_ino_t               *inum,    /* out: inode number */
432         struct xfs_name         *ci_name) /* out: actual name if CI match */
433 {
434         struct xfs_da_args      *args;
435         int                     rval;
436         int                     lock_mode;
437
438         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
439         XFS_STATS_INC(dp->i_mount, xs_dir_lookup);
440
441         args = kzalloc(sizeof(*args),
442                         GFP_KERNEL | __GFP_NOLOCKDEP | __GFP_NOFAIL);
443         args->geo = dp->i_mount->m_dir_geo;
444         args->name = name->name;
445         args->namelen = name->len;
446         args->filetype = name->type;
447         args->hashval = xfs_dir2_hashname(dp->i_mount, name);
448         args->dp = dp;
449         args->whichfork = XFS_DATA_FORK;
450         args->trans = tp;
451         args->op_flags = XFS_DA_OP_OKNOENT;
452         args->owner = dp->i_ino;
453         if (ci_name)
454                 args->op_flags |= XFS_DA_OP_CILOOKUP;
455
456         lock_mode = xfs_ilock_data_map_shared(dp);
457         rval = xfs_dir_lookup_args(args);
458         if (!rval) {
459                 *inum = args->inumber;
460                 if (ci_name) {
461                         ci_name->name = args->value;
462                         ci_name->len = args->valuelen;
463                 }
464         }
465         xfs_iunlock(dp, lock_mode);
466         kfree(args);
467         return rval;
468 }
469
470 int
471 xfs_dir_removename_args(
472         struct xfs_da_args      *args)
473 {
474         int                     error;
475
476         switch (xfs_dir2_format(args, &error)) {
477         case XFS_DIR2_FMT_SF:
478                 return xfs_dir2_sf_removename(args);
479         case XFS_DIR2_FMT_BLOCK:
480                 return xfs_dir2_block_removename(args);
481         case XFS_DIR2_FMT_LEAF:
482                 return xfs_dir2_leaf_removename(args);
483         case XFS_DIR2_FMT_NODE:
484                 return xfs_dir2_node_removename(args);
485         default:
486                 return error;
487         }
488 }
489
490 /*
491  * Remove an entry from a directory.
492  */
493 int
494 xfs_dir_removename(
495         struct xfs_trans        *tp,
496         struct xfs_inode        *dp,
497         const struct xfs_name   *name,
498         xfs_ino_t               ino,
499         xfs_extlen_t            total)          /* bmap's total block count */
500 {
501         struct xfs_da_args      *args;
502         int                     rval;
503
504         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
505         XFS_STATS_INC(dp->i_mount, xs_dir_remove);
506
507         args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
508         if (!args)
509                 return -ENOMEM;
510
511         args->geo = dp->i_mount->m_dir_geo;
512         args->name = name->name;
513         args->namelen = name->len;
514         args->filetype = name->type;
515         args->hashval = xfs_dir2_hashname(dp->i_mount, name);
516         args->inumber = ino;
517         args->dp = dp;
518         args->total = total;
519         args->whichfork = XFS_DATA_FORK;
520         args->trans = tp;
521         args->owner = dp->i_ino;
522         rval = xfs_dir_removename_args(args);
523         kfree(args);
524         return rval;
525 }
526
527 int
528 xfs_dir_replace_args(
529         struct xfs_da_args      *args)
530 {
531         int                     error;
532
533         switch (xfs_dir2_format(args, &error)) {
534         case XFS_DIR2_FMT_SF:
535                 return xfs_dir2_sf_replace(args);
536         case XFS_DIR2_FMT_BLOCK:
537                 return xfs_dir2_block_replace(args);
538         case XFS_DIR2_FMT_LEAF:
539                 return xfs_dir2_leaf_replace(args);
540         case XFS_DIR2_FMT_NODE:
541                 return xfs_dir2_node_replace(args);
542         default:
543                 return error;
544         }
545 }
546
547 /*
548  * Replace the inode number of a directory entry.
549  */
550 int
551 xfs_dir_replace(
552         struct xfs_trans        *tp,
553         struct xfs_inode        *dp,
554         const struct xfs_name   *name,          /* name of entry to replace */
555         xfs_ino_t               inum,           /* new inode number */
556         xfs_extlen_t            total)          /* bmap's total block count */
557 {
558         struct xfs_da_args      *args;
559         int                     rval;
560
561         ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
562
563         rval = xfs_dir_ino_validate(tp->t_mountp, inum);
564         if (rval)
565                 return rval;
566
567         args = kzalloc(sizeof(*args), GFP_KERNEL | __GFP_NOFAIL);
568         if (!args)
569                 return -ENOMEM;
570
571         args->geo = dp->i_mount->m_dir_geo;
572         args->name = name->name;
573         args->namelen = name->len;
574         args->filetype = name->type;
575         args->hashval = xfs_dir2_hashname(dp->i_mount, name);
576         args->inumber = inum;
577         args->dp = dp;
578         args->total = total;
579         args->whichfork = XFS_DATA_FORK;
580         args->trans = tp;
581         args->owner = dp->i_ino;
582         rval = xfs_dir_replace_args(args);
583         kfree(args);
584         return rval;
585 }
586
587 /*
588  * See if this entry can be added to the directory without allocating space.
589  */
590 int
591 xfs_dir_canenter(
592         struct xfs_trans        *tp,
593         struct xfs_inode        *dp,
594         const struct xfs_name   *name)          /* name of entry to add */
595 {
596         return xfs_dir_createname(tp, dp, name, 0, 0);
597 }
598
599 /*
600  * Utility routines.
601  */
602
603 /*
604  * Add a block to the directory.
605  *
606  * This routine is for data and free blocks, not leaf/node blocks which are
607  * handled by xfs_da_grow_inode.
608  */
609 int
610 xfs_dir2_grow_inode(
611         struct xfs_da_args      *args,
612         int                     space,  /* v2 dir's space XFS_DIR2_xxx_SPACE */
613         xfs_dir2_db_t           *dbp)   /* out: block number added */
614 {
615         struct xfs_inode        *dp = args->dp;
616         struct xfs_mount        *mp = dp->i_mount;
617         xfs_fileoff_t           bno;    /* directory offset of new block */
618         int                     count;  /* count of filesystem blocks */
619         int                     error;
620
621         trace_xfs_dir2_grow_inode(args, space);
622
623         /*
624          * Set lowest possible block in the space requested.
625          */
626         bno = XFS_B_TO_FSBT(mp, space * XFS_DIR2_SPACE_SIZE);
627         count = args->geo->fsbcount;
628
629         error = xfs_da_grow_inode_int(args, &bno, count);
630         if (error)
631                 return error;
632
633         *dbp = xfs_dir2_da_to_db(args->geo, (xfs_dablk_t)bno);
634
635         /*
636          * Update file's size if this is the data space and it grew.
637          */
638         if (space == XFS_DIR2_DATA_SPACE) {
639                 xfs_fsize_t     size;           /* directory file (data) size */
640
641                 size = XFS_FSB_TO_B(mp, bno + count);
642                 if (size > dp->i_disk_size) {
643                         dp->i_disk_size = size;
644                         xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
645                 }
646         }
647         return 0;
648 }
649
650 /*
651  * Remove the given block from the directory.
652  * This routine is used for data and free blocks, leaf/node are done
653  * by xfs_da_shrink_inode.
654  */
655 int
656 xfs_dir2_shrink_inode(
657         struct xfs_da_args      *args,
658         xfs_dir2_db_t           db,
659         struct xfs_buf          *bp)
660 {
661         xfs_fileoff_t           bno;            /* directory file offset */
662         xfs_dablk_t             da;             /* directory file offset */
663         int                     done;           /* bunmap is finished */
664         struct xfs_inode        *dp;
665         int                     error;
666         struct xfs_mount        *mp;
667         struct xfs_trans        *tp;
668
669         trace_xfs_dir2_shrink_inode(args, db);
670
671         dp = args->dp;
672         mp = dp->i_mount;
673         tp = args->trans;
674         da = xfs_dir2_db_to_da(args->geo, db);
675
676         /* Unmap the fsblock(s). */
677         error = xfs_bunmapi(tp, dp, da, args->geo->fsbcount, 0, 0, &done);
678         if (error) {
679                 /*
680                  * ENOSPC actually can happen if we're in a removename with no
681                  * space reservation, and the resulting block removal would
682                  * cause a bmap btree split or conversion from extents to btree.
683                  * This can only happen for un-fragmented directory blocks,
684                  * since you need to be punching out the middle of an extent.
685                  * In this case we need to leave the block in the file, and not
686                  * binval it.  So the block has to be in a consistent empty
687                  * state and appropriately logged.  We don't free up the buffer,
688                  * the caller can tell it hasn't happened since it got an error
689                  * back.
690                  */
691                 return error;
692         }
693         ASSERT(done);
694         /*
695          * Invalidate the buffer from the transaction.
696          */
697         xfs_trans_binval(tp, bp);
698         /*
699          * If it's not a data block, we're done.
700          */
701         if (db >= xfs_dir2_byte_to_db(args->geo, XFS_DIR2_LEAF_OFFSET))
702                 return 0;
703         /*
704          * If the block isn't the last one in the directory, we're done.
705          */
706         if (dp->i_disk_size > xfs_dir2_db_off_to_byte(args->geo, db + 1, 0))
707                 return 0;
708         bno = da;
709         if ((error = xfs_bmap_last_before(tp, dp, &bno, XFS_DATA_FORK))) {
710                 /*
711                  * This can't really happen unless there's kernel corruption.
712                  */
713                 return error;
714         }
715         if (db == args->geo->datablk)
716                 ASSERT(bno == 0);
717         else
718                 ASSERT(bno > 0);
719         /*
720          * Set the size to the new last block.
721          */
722         dp->i_disk_size = XFS_FSB_TO_B(mp, bno);
723         xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
724         return 0;
725 }
726
727 /* Returns true if the directory entry name is valid. */
728 bool
729 xfs_dir2_namecheck(
730         const void      *name,
731         size_t          length)
732 {
733         /*
734          * MAXNAMELEN includes the trailing null, but (name/length) leave it
735          * out, so use >= for the length check.
736          */
737         if (length >= MAXNAMELEN)
738                 return false;
739
740         /* There shouldn't be any slashes or nulls here */
741         return !memchr(name, '/', length) && !memchr(name, 0, length);
742 }
743
744 xfs_dahash_t
745 xfs_dir2_hashname(
746         struct xfs_mount        *mp,
747         const struct xfs_name   *name)
748 {
749         if (unlikely(xfs_has_asciici(mp)))
750                 return xfs_ascii_ci_hashname(name);
751         return xfs_da_hashname(name->name, name->len);
752 }
753
754 enum xfs_dacmp
755 xfs_dir2_compname(
756         struct xfs_da_args      *args,
757         const unsigned char     *name,
758         int                     len)
759 {
760         if (unlikely(xfs_has_asciici(args->dp->i_mount)))
761                 return xfs_ascii_ci_compname(args, name, len);
762         return xfs_da_compname(args, name, len);
763 }
764
765 #ifdef CONFIG_XFS_LIVE_HOOKS
766 /*
767  * Use a static key here to reduce the overhead of directory live update hooks.
768  * If the compiler supports jump labels, the static branch will be replaced by
769  * a nop sled when there are no hook users.  Online fsck is currently the only
770  * caller, so this is a reasonable tradeoff.
771  *
772  * Note: Patching the kernel code requires taking the cpu hotplug lock.  Other
773  * parts of the kernel allocate memory with that lock held, which means that
774  * XFS callers cannot hold any locks that might be used by memory reclaim or
775  * writeback when calling the static_branch_{inc,dec} functions.
776  */
777 DEFINE_STATIC_XFS_HOOK_SWITCH(xfs_dir_hooks_switch);
778
779 void
780 xfs_dir_hook_disable(void)
781 {
782         xfs_hooks_switch_off(&xfs_dir_hooks_switch);
783 }
784
785 void
786 xfs_dir_hook_enable(void)
787 {
788         xfs_hooks_switch_on(&xfs_dir_hooks_switch);
789 }
790
791 /* Call hooks for a directory update relating to a child dirent update. */
792 inline void
793 xfs_dir_update_hook(
794         struct xfs_inode                *dp,
795         struct xfs_inode                *ip,
796         int                             delta,
797         const struct xfs_name           *name)
798 {
799         if (xfs_hooks_switched_on(&xfs_dir_hooks_switch)) {
800                 struct xfs_dir_update_params    p = {
801                         .dp             = dp,
802                         .ip             = ip,
803                         .delta          = delta,
804                         .name           = name,
805                 };
806                 struct xfs_mount        *mp = ip->i_mount;
807
808                 xfs_hooks_call(&mp->m_dir_update_hooks, 0, &p);
809         }
810 }
811
812 /* Call the specified function during a directory update. */
813 int
814 xfs_dir_hook_add(
815         struct xfs_mount        *mp,
816         struct xfs_dir_hook     *hook)
817 {
818         return xfs_hooks_add(&mp->m_dir_update_hooks, &hook->dirent_hook);
819 }
820
821 /* Stop calling the specified function during a directory update. */
822 void
823 xfs_dir_hook_del(
824         struct xfs_mount        *mp,
825         struct xfs_dir_hook     *hook)
826 {
827         xfs_hooks_del(&mp->m_dir_update_hooks, &hook->dirent_hook);
828 }
829
830 /* Configure directory update hook functions. */
831 void
832 xfs_dir_hook_setup(
833         struct xfs_dir_hook     *hook,
834         notifier_fn_t           mod_fn)
835 {
836         xfs_hook_setup(&hook->dirent_hook, mod_fn);
837 }
838 #endif /* CONFIG_XFS_LIVE_HOOKS */
839
840 /*
841  * Given a directory @dp, a newly allocated inode @ip, and a @name, link @ip
842  * into @dp under the given @name.  If @ip is a directory, it will be
843  * initialized.  Both inodes must have the ILOCK held and the transaction must
844  * have sufficient blocks reserved.
845  */
846 int
847 xfs_dir_create_child(
848         struct xfs_trans        *tp,
849         unsigned int            resblks,
850         struct xfs_dir_update   *du)
851 {
852         struct xfs_inode        *dp = du->dp;
853         const struct xfs_name   *name = du->name;
854         struct xfs_inode        *ip = du->ip;
855         int                     error;
856
857         xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
858         xfs_assert_ilocked(dp, XFS_ILOCK_EXCL);
859
860         error = xfs_dir_createname(tp, dp, name, ip->i_ino, resblks);
861         if (error) {
862                 ASSERT(error != -ENOSPC);
863                 return error;
864         }
865
866         xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
867         xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
868
869         if (S_ISDIR(VFS_I(ip)->i_mode)) {
870                 error = xfs_dir_init(tp, ip, dp);
871                 if (error)
872                         return error;
873
874                 xfs_bumplink(tp, dp);
875         }
876
877         /*
878          * If we have parent pointers, we need to add the attribute containing
879          * the parent information now.
880          */
881         if (du->ppargs) {
882                 error = xfs_parent_addname(tp, du->ppargs, dp, name, ip);
883                 if (error)
884                         return error;
885         }
886
887         xfs_dir_update_hook(dp, ip, 1, name);
888         return 0;
889 }
890
891 /*
892  * Given a directory @dp, an existing non-directory inode @ip, and a @name,
893  * link @ip into @dp under the given @name.  Both inodes must have the ILOCK
894  * held.
895  */
896 int
897 xfs_dir_add_child(
898         struct xfs_trans        *tp,
899         unsigned int            resblks,
900         struct xfs_dir_update   *du)
901 {
902         struct xfs_inode        *dp = du->dp;
903         const struct xfs_name   *name = du->name;
904         struct xfs_inode        *ip = du->ip;
905         struct xfs_mount        *mp = tp->t_mountp;
906         int                     error;
907
908         xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
909         xfs_assert_ilocked(dp, XFS_ILOCK_EXCL);
910         ASSERT(!S_ISDIR(VFS_I(ip)->i_mode));
911
912         if (!resblks) {
913                 error = xfs_dir_canenter(tp, dp, name);
914                 if (error)
915                         return error;
916         }
917
918         /*
919          * Handle initial link state of O_TMPFILE inode
920          */
921         if (VFS_I(ip)->i_nlink == 0) {
922                 struct xfs_perag        *pag;
923
924                 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
925                 error = xfs_iunlink_remove(tp, pag, ip);
926                 xfs_perag_put(pag);
927                 if (error)
928                         return error;
929         }
930
931         error = xfs_dir_createname(tp, dp, name, ip->i_ino, resblks);
932         if (error)
933                 return error;
934
935         xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
936         xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
937
938         xfs_bumplink(tp, ip);
939
940         /*
941          * If we have parent pointers, we now need to add the parent record to
942          * the attribute fork of the inode. If this is the initial parent
943          * attribute, we need to create it correctly, otherwise we can just add
944          * the parent to the inode.
945          */
946         if (du->ppargs) {
947                 error = xfs_parent_addname(tp, du->ppargs, dp, name, ip);
948                 if (error)
949                         return error;
950         }
951
952         xfs_dir_update_hook(dp, ip, 1, name);
953         return 0;
954 }
955
956 /*
957  * Given a directory @dp, a child @ip, and a @name, remove the (@name, @ip)
958  * entry from the directory.  Both inodes must have the ILOCK held.
959  */
960 int
961 xfs_dir_remove_child(
962         struct xfs_trans        *tp,
963         unsigned int            resblks,
964         struct xfs_dir_update   *du)
965 {
966         struct xfs_inode        *dp = du->dp;
967         const struct xfs_name   *name = du->name;
968         struct xfs_inode        *ip = du->ip;
969         int                     error;
970
971         xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
972         xfs_assert_ilocked(dp, XFS_ILOCK_EXCL);
973
974         /*
975          * If we're removing a directory perform some additional validation.
976          */
977         if (S_ISDIR(VFS_I(ip)->i_mode)) {
978                 ASSERT(VFS_I(ip)->i_nlink >= 2);
979                 if (VFS_I(ip)->i_nlink != 2)
980                         return -ENOTEMPTY;
981                 if (!xfs_dir_isempty(ip))
982                         return -ENOTEMPTY;
983
984                 /* Drop the link from ip's "..".  */
985                 error = xfs_droplink(tp, dp);
986                 if (error)
987                         return error;
988
989                 /* Drop the "." link from ip to self.  */
990                 error = xfs_droplink(tp, ip);
991                 if (error)
992                         return error;
993
994                 /*
995                  * Point the unlinked child directory's ".." entry to the root
996                  * directory to eliminate back-references to inodes that may
997                  * get freed before the child directory is closed.  If the fs
998                  * gets shrunk, this can lead to dirent inode validation errors.
999                  */
1000                 if (dp->i_ino != tp->t_mountp->m_sb.sb_rootino) {
1001                         error = xfs_dir_replace(tp, ip, &xfs_name_dotdot,
1002                                         tp->t_mountp->m_sb.sb_rootino, 0);
1003                         if (error)
1004                                 return error;
1005                 }
1006         } else {
1007                 /*
1008                  * When removing a non-directory we need to log the parent
1009                  * inode here.  For a directory this is done implicitly
1010                  * by the xfs_droplink call for the ".." entry.
1011                  */
1012                 xfs_trans_log_inode(tp, dp, XFS_ILOG_CORE);
1013         }
1014         xfs_trans_ichgtime(tp, dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1015
1016         /* Drop the link from dp to ip. */
1017         error = xfs_droplink(tp, ip);
1018         if (error)
1019                 return error;
1020
1021         error = xfs_dir_removename(tp, dp, name, ip->i_ino, resblks);
1022         if (error) {
1023                 ASSERT(error != -ENOENT);
1024                 return error;
1025         }
1026
1027         /* Remove parent pointer. */
1028         if (du->ppargs) {
1029                 error = xfs_parent_removename(tp, du->ppargs, dp, name, ip);
1030                 if (error)
1031                         return error;
1032         }
1033
1034         xfs_dir_update_hook(dp, ip, -1, name);
1035         return 0;
1036 }
1037
1038 /*
1039  * Exchange the entry (@name1, @ip1) in directory @dp1 with the entry (@name2,
1040  * @ip2) in directory @dp2, and update '..' @ip1 and @ip2's entries as needed.
1041  * @ip1 and @ip2 need not be of the same type.
1042  *
1043  * All inodes must have the ILOCK held, and both entries must already exist.
1044  */
1045 int
1046 xfs_dir_exchange_children(
1047         struct xfs_trans        *tp,
1048         struct xfs_dir_update   *du1,
1049         struct xfs_dir_update   *du2,
1050         unsigned int            spaceres)
1051 {
1052         struct xfs_inode        *dp1 = du1->dp;
1053         const struct xfs_name   *name1 = du1->name;
1054         struct xfs_inode        *ip1 = du1->ip;
1055         struct xfs_inode        *dp2 = du2->dp;
1056         const struct xfs_name   *name2 = du2->name;
1057         struct xfs_inode        *ip2 = du2->ip;
1058         int                     ip1_flags = 0;
1059         int                     ip2_flags = 0;
1060         int                     dp2_flags = 0;
1061         int                     error;
1062
1063         /* Swap inode number for dirent in first parent */
1064         error = xfs_dir_replace(tp, dp1, name1, ip2->i_ino, spaceres);
1065         if (error)
1066                 return error;
1067
1068         /* Swap inode number for dirent in second parent */
1069         error = xfs_dir_replace(tp, dp2, name2, ip1->i_ino, spaceres);
1070         if (error)
1071                 return error;
1072
1073         /*
1074          * If we're renaming one or more directories across different parents,
1075          * update the respective ".." entries (and link counts) to match the new
1076          * parents.
1077          */
1078         if (dp1 != dp2) {
1079                 dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
1080
1081                 if (S_ISDIR(VFS_I(ip2)->i_mode)) {
1082                         error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot,
1083                                                 dp1->i_ino, spaceres);
1084                         if (error)
1085                                 return error;
1086
1087                         /* transfer ip2 ".." reference to dp1 */
1088                         if (!S_ISDIR(VFS_I(ip1)->i_mode)) {
1089                                 error = xfs_droplink(tp, dp2);
1090                                 if (error)
1091                                         return error;
1092                                 xfs_bumplink(tp, dp1);
1093                         }
1094
1095                         /*
1096                          * Although ip1 isn't changed here, userspace needs
1097                          * to be warned about the change, so that applications
1098                          * relying on it (like backup ones), will properly
1099                          * notify the change
1100                          */
1101                         ip1_flags |= XFS_ICHGTIME_CHG;
1102                         ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
1103                 }
1104
1105                 if (S_ISDIR(VFS_I(ip1)->i_mode)) {
1106                         error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot,
1107                                                 dp2->i_ino, spaceres);
1108                         if (error)
1109                                 return error;
1110
1111                         /* transfer ip1 ".." reference to dp2 */
1112                         if (!S_ISDIR(VFS_I(ip2)->i_mode)) {
1113                                 error = xfs_droplink(tp, dp1);
1114                                 if (error)
1115                                         return error;
1116                                 xfs_bumplink(tp, dp2);
1117                         }
1118
1119                         /*
1120                          * Although ip2 isn't changed here, userspace needs
1121                          * to be warned about the change, so that applications
1122                          * relying on it (like backup ones), will properly
1123                          * notify the change
1124                          */
1125                         ip1_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG;
1126                         ip2_flags |= XFS_ICHGTIME_CHG;
1127                 }
1128         }
1129
1130         if (ip1_flags) {
1131                 xfs_trans_ichgtime(tp, ip1, ip1_flags);
1132                 xfs_trans_log_inode(tp, ip1, XFS_ILOG_CORE);
1133         }
1134         if (ip2_flags) {
1135                 xfs_trans_ichgtime(tp, ip2, ip2_flags);
1136                 xfs_trans_log_inode(tp, ip2, XFS_ILOG_CORE);
1137         }
1138         if (dp2_flags) {
1139                 xfs_trans_ichgtime(tp, dp2, dp2_flags);
1140                 xfs_trans_log_inode(tp, dp2, XFS_ILOG_CORE);
1141         }
1142         xfs_trans_ichgtime(tp, dp1, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1143         xfs_trans_log_inode(tp, dp1, XFS_ILOG_CORE);
1144
1145         /* Schedule parent pointer replacements */
1146         if (du1->ppargs) {
1147                 error = xfs_parent_replacename(tp, du1->ppargs, dp1, name1,
1148                                 dp2, name2, ip1);
1149                 if (error)
1150                         return error;
1151         }
1152
1153         if (du2->ppargs) {
1154                 error = xfs_parent_replacename(tp, du2->ppargs, dp2, name2,
1155                                 dp1, name1, ip2);
1156                 if (error)
1157                         return error;
1158         }
1159
1160         /*
1161          * Inform our hook clients that we've finished an exchange operation as
1162          * follows: removed the source and target files from their directories;
1163          * added the target to the source directory; and added the source to
1164          * the target directory.  All inodes are locked, so it's ok to model a
1165          * rename this way so long as we say we deleted entries before we add
1166          * new ones.
1167          */
1168         xfs_dir_update_hook(dp1, ip1, -1, name1);
1169         xfs_dir_update_hook(dp2, ip2, -1, name2);
1170         xfs_dir_update_hook(dp1, ip2, 1, name1);
1171         xfs_dir_update_hook(dp2, ip1, 1, name2);
1172         return 0;
1173 }
1174
1175 /*
1176  * Given an entry (@src_name, @src_ip) in directory @src_dp, make the entry
1177  * @target_name in directory @target_dp point to @src_ip and remove the
1178  * original entry, cleaning up everything left behind.
1179  *
1180  * Cleanup involves dropping a link count on @target_ip, and either removing
1181  * the (@src_name, @src_ip) entry from @src_dp or simply replacing the entry
1182  * with (@src_name, @wip) if a whiteout inode @wip is supplied.
1183  *
1184  * All inodes must have the ILOCK held.  We assume that if @src_ip is a
1185  * directory then its '..' doesn't already point to @target_dp, and that @wip
1186  * is a freshly allocated whiteout.
1187  */
1188 int
1189 xfs_dir_rename_children(
1190         struct xfs_trans        *tp,
1191         struct xfs_dir_update   *du_src,
1192         struct xfs_dir_update   *du_tgt,
1193         unsigned int            spaceres,
1194         struct xfs_dir_update   *du_wip)
1195 {
1196         struct xfs_mount        *mp = tp->t_mountp;
1197         struct xfs_inode        *src_dp = du_src->dp;
1198         const struct xfs_name   *src_name = du_src->name;
1199         struct xfs_inode        *src_ip = du_src->ip;
1200         struct xfs_inode        *target_dp = du_tgt->dp;
1201         const struct xfs_name   *target_name = du_tgt->name;
1202         struct xfs_inode        *target_ip = du_tgt->ip;
1203         bool                    new_parent = (src_dp != target_dp);
1204         bool                    src_is_directory;
1205         int                     error;
1206
1207         src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode);
1208
1209         /*
1210          * Check for expected errors before we dirty the transaction
1211          * so we can return an error without a transaction abort.
1212          */
1213         if (target_ip == NULL) {
1214                 /*
1215                  * If there's no space reservation, check the entry will
1216                  * fit before actually inserting it.
1217                  */
1218                 if (!spaceres) {
1219                         error = xfs_dir_canenter(tp, target_dp, target_name);
1220                         if (error)
1221                                 return error;
1222                 }
1223         } else {
1224                 /*
1225                  * If target exists and it's a directory, check that whether
1226                  * it can be destroyed.
1227                  */
1228                 if (S_ISDIR(VFS_I(target_ip)->i_mode) &&
1229                     (!xfs_dir_isempty(target_ip) ||
1230                      (VFS_I(target_ip)->i_nlink > 2)))
1231                         return -EEXIST;
1232         }
1233
1234         /*
1235          * Directory entry creation below may acquire the AGF. Remove
1236          * the whiteout from the unlinked list first to preserve correct
1237          * AGI/AGF locking order. This dirties the transaction so failures
1238          * after this point will abort and log recovery will clean up the
1239          * mess.
1240          *
1241          * For whiteouts, we need to bump the link count on the whiteout
1242          * inode. After this point, we have a real link, clear the tmpfile
1243          * state flag from the inode so it doesn't accidentally get misused
1244          * in future.
1245          */
1246         if (du_wip->ip) {
1247                 struct xfs_perag        *pag;
1248
1249                 ASSERT(VFS_I(du_wip->ip)->i_nlink == 0);
1250
1251                 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, du_wip->ip->i_ino));
1252                 error = xfs_iunlink_remove(tp, pag, du_wip->ip);
1253                 xfs_perag_put(pag);
1254                 if (error)
1255                         return error;
1256
1257                 xfs_bumplink(tp, du_wip->ip);
1258         }
1259
1260         /*
1261          * Set up the target.
1262          */
1263         if (target_ip == NULL) {
1264                 /*
1265                  * If target does not exist and the rename crosses
1266                  * directories, adjust the target directory link count
1267                  * to account for the ".." reference from the new entry.
1268                  */
1269                 error = xfs_dir_createname(tp, target_dp, target_name,
1270                                            src_ip->i_ino, spaceres);
1271                 if (error)
1272                         return error;
1273
1274                 xfs_trans_ichgtime(tp, target_dp,
1275                                         XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1276
1277                 if (new_parent && src_is_directory) {
1278                         xfs_bumplink(tp, target_dp);
1279                 }
1280         } else { /* target_ip != NULL */
1281                 /*
1282                  * Link the source inode under the target name.
1283                  * If the source inode is a directory and we are moving
1284                  * it across directories, its ".." entry will be
1285                  * inconsistent until we replace that down below.
1286                  *
1287                  * In case there is already an entry with the same
1288                  * name at the destination directory, remove it first.
1289                  */
1290                 error = xfs_dir_replace(tp, target_dp, target_name,
1291                                         src_ip->i_ino, spaceres);
1292                 if (error)
1293                         return error;
1294
1295                 xfs_trans_ichgtime(tp, target_dp,
1296                                         XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1297
1298                 /*
1299                  * Decrement the link count on the target since the target
1300                  * dir no longer points to it.
1301                  */
1302                 error = xfs_droplink(tp, target_ip);
1303                 if (error)
1304                         return error;
1305
1306                 if (src_is_directory) {
1307                         /*
1308                          * Drop the link from the old "." entry.
1309                          */
1310                         error = xfs_droplink(tp, target_ip);
1311                         if (error)
1312                                 return error;
1313                 }
1314         } /* target_ip != NULL */
1315
1316         /*
1317          * Remove the source.
1318          */
1319         if (new_parent && src_is_directory) {
1320                 /*
1321                  * Rewrite the ".." entry to point to the new
1322                  * directory.
1323                  */
1324                 error = xfs_dir_replace(tp, src_ip, &xfs_name_dotdot,
1325                                         target_dp->i_ino, spaceres);
1326                 ASSERT(error != -EEXIST);
1327                 if (error)
1328                         return error;
1329         }
1330
1331         /*
1332          * We always want to hit the ctime on the source inode.
1333          *
1334          * This isn't strictly required by the standards since the source
1335          * inode isn't really being changed, but old unix file systems did
1336          * it and some incremental backup programs won't work without it.
1337          */
1338         xfs_trans_ichgtime(tp, src_ip, XFS_ICHGTIME_CHG);
1339         xfs_trans_log_inode(tp, src_ip, XFS_ILOG_CORE);
1340
1341         /*
1342          * Adjust the link count on src_dp.  This is necessary when
1343          * renaming a directory, either within one parent when
1344          * the target existed, or across two parent directories.
1345          */
1346         if (src_is_directory && (new_parent || target_ip != NULL)) {
1347
1348                 /*
1349                  * Decrement link count on src_directory since the
1350                  * entry that's moved no longer points to it.
1351                  */
1352                 error = xfs_droplink(tp, src_dp);
1353                 if (error)
1354                         return error;
1355         }
1356
1357         /*
1358          * For whiteouts, we only need to update the source dirent with the
1359          * inode number of the whiteout inode rather than removing it
1360          * altogether.
1361          */
1362         if (du_wip->ip)
1363                 error = xfs_dir_replace(tp, src_dp, src_name, du_wip->ip->i_ino,
1364                                         spaceres);
1365         else
1366                 error = xfs_dir_removename(tp, src_dp, src_name, src_ip->i_ino,
1367                                            spaceres);
1368         if (error)
1369                 return error;
1370
1371         xfs_trans_ichgtime(tp, src_dp, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
1372         xfs_trans_log_inode(tp, src_dp, XFS_ILOG_CORE);
1373         if (new_parent)
1374                 xfs_trans_log_inode(tp, target_dp, XFS_ILOG_CORE);
1375
1376         /* Schedule parent pointer updates. */
1377         if (du_wip->ppargs) {
1378                 error = xfs_parent_addname(tp, du_wip->ppargs, src_dp,
1379                                 src_name, du_wip->ip);
1380                 if (error)
1381                         return error;
1382         }
1383
1384         if (du_src->ppargs) {
1385                 error = xfs_parent_replacename(tp, du_src->ppargs, src_dp,
1386                                 src_name, target_dp, target_name, src_ip);
1387                 if (error)
1388                         return error;
1389         }
1390
1391         if (du_tgt->ppargs) {
1392                 error = xfs_parent_removename(tp, du_tgt->ppargs, target_dp,
1393                                 target_name, target_ip);
1394                 if (error)
1395                         return error;
1396         }
1397
1398         /*
1399          * Inform our hook clients that we've finished a rename operation as
1400          * follows: removed the source and target files from their directories;
1401          * that we've added the source to the target directory; and finally
1402          * that we've added the whiteout, if there was one.  All inodes are
1403          * locked, so it's ok to model a rename this way so long as we say we
1404          * deleted entries before we add new ones.
1405          */
1406         if (target_ip)
1407                 xfs_dir_update_hook(target_dp, target_ip, -1, target_name);
1408         xfs_dir_update_hook(src_dp, src_ip, -1, src_name);
1409         xfs_dir_update_hook(target_dp, src_ip, 1, target_name);
1410         if (du_wip->ip)
1411                 xfs_dir_update_hook(src_dp, du_wip->ip, 1, src_name);
1412         return 0;
1413 }
This page took 0.118886 seconds and 4 git commands to generate.