LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_dir2.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 579 595 97.3 %
Date: 2023-07-31 20:08:34 Functions: 30 31 96.8 %

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

Generated by: LCOV version 1.14