LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_imeta.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 335 494 67.8 %
Date: 2023-07-31 20:08:34 Functions: 25 33 75.8 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Copyright (C) 2018-2023 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <djwong@kernel.org>
       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_bit.h"
      13             : #include "xfs_sb.h"
      14             : #include "xfs_mount.h"
      15             : #include "xfs_defer.h"
      16             : #include "xfs_trans.h"
      17             : #include "xfs_imeta.h"
      18             : #include "xfs_trace.h"
      19             : #include "xfs_inode.h"
      20             : #include "xfs_quota.h"
      21             : #include "xfs_ialloc.h"
      22             : #include "xfs_bmap_btree.h"
      23             : #include "xfs_da_format.h"
      24             : #include "xfs_da_btree.h"
      25             : #include "xfs_trans_space.h"
      26             : #include "xfs_ag.h"
      27             : #include "xfs_dir2.h"
      28             : #include "xfs_dir2_priv.h"
      29             : #include "xfs_health.h"
      30             : #include "xfs_errortag.h"
      31             : #include "xfs_error.h"
      32             : #include "xfs_btree.h"
      33             : #include "xfs_alloc.h"
      34             : 
      35             : /*
      36             :  * Metadata File Management
      37             :  * ========================
      38             :  *
      39             :  * These functions provide an abstraction layer for looking up, creating, and
      40             :  * deleting metadata inodes.  These pointers live in the in-core superblock,
      41             :  * so the functions moderate access to those fields and take care of logging.
      42             :  *
      43             :  * For the five existing metadata inodes (real time bitmap & summary; and the
      44             :  * user, group, and quotas) we'll continue to maintain the in-core superblock
      45             :  * inodes for reads and only require xfs_imeta_create and xfs_imeta_unlink to
      46             :  * persist changes.  New metadata inode types must only use the xfs_imeta_*
      47             :  * functions.
      48             :  *
      49             :  * Callers wishing to create or unlink a metadata inode must pass in a
      50             :  * xfs_imeta_end structure.  After committing or cancelling the transaction,
      51             :  * this structure must be passed to xfs_imeta_end_update to free resources that
      52             :  * cannot be freed during the transaction.
      53             :  *
      54             :  * When the metadata directory tree (metadir) feature is enabled, we can create
      55             :  * a complex directory tree in which to store metadata inodes.  Inodes within
      56             :  * the metadata directory tree should have the "metadata" inode flag set to
      57             :  * prevent them from being exposed to the outside world.
      58             :  *
      59             :  * Callers are not expected to take the IOLOCK of metadata directories.  They
      60             :  * are expected to take the ILOCK of any inode in the metadata directory tree
      61             :  * (just like the regular to synchronize access to that inode.  It is not
      62             :  * necessary to take the MMAPLOCK since metadata inodes should never be exposed
      63             :  * to user space.
      64             :  */
      65             : 
      66             : /* Static metadata inode paths */
      67             : static const unsigned char *rtbitmap_path[]     = {"realtime", "bitmap"};
      68             : static const unsigned char *rtsummary_path[]    = {"realtime", "summary"};
      69             : static const unsigned char *usrquota_path[]     = {"quota", "user"};
      70             : static const unsigned char *grpquota_path[]     = {"quota", "group"};
      71             : static const unsigned char *prjquota_path[]     = {"quota", "project"};
      72             : 
      73             : XFS_IMETA_DEFINE_PATH(XFS_IMETA_RTBITMAP,       rtbitmap_path);
      74             : XFS_IMETA_DEFINE_PATH(XFS_IMETA_RTSUMMARY,      rtsummary_path);
      75             : XFS_IMETA_DEFINE_PATH(XFS_IMETA_USRQUOTA,       usrquota_path);
      76             : XFS_IMETA_DEFINE_PATH(XFS_IMETA_GRPQUOTA,       grpquota_path);
      77             : XFS_IMETA_DEFINE_PATH(XFS_IMETA_PRJQUOTA,       prjquota_path);
      78             : 
      79             : const struct xfs_imeta_path XFS_IMETA_METADIR = {
      80             :         .im_depth = 0,
      81             :         .im_ftype = XFS_DIR3_FT_DIR,
      82             : };
      83             : 
      84             : /* Are these two paths equal? */
      85             : STATIC bool
      86      845114 : xfs_imeta_path_compare(
      87             :         const struct xfs_imeta_path     *a,
      88             :         const struct xfs_imeta_path     *b)
      89             : {
      90      845114 :         unsigned int                    i;
      91             : 
      92      845114 :         if (a == b)
      93             :                 return true;
      94             : 
      95      805854 :         if (a->im_depth != b->im_depth)
      96             :                 return false;
      97             : 
      98      199652 :         for (i = 0; i < a->im_depth; i++)
      99      199652 :                 if (a->im_path[i] != b->im_path[i] &&
     100      160667 :                     strcmp(a->im_path[i], b->im_path[i]))
     101             :                         return false;
     102             : 
     103             :         return true;
     104             : }
     105             : 
     106             : /* Is this path ok? */
     107             : static inline bool
     108             : xfs_imeta_path_check(
     109             :         const struct xfs_imeta_path     *path)
     110             : {
     111      281473 :         return path->im_depth <= XFS_IMETA_MAX_DEPTH;
     112             : }
     113             : 
     114             : /* Functions for storing and retrieving superblock inode values. */
     115             : 
     116             : /* Mapping of metadata inode paths to in-core superblock values. */
     117             : static const struct xfs_imeta_sbmap {
     118             :         const struct xfs_imeta_path     *path;
     119             :         unsigned int                    offset;
     120             : } xfs_imeta_sbmaps[] = {
     121             :         {
     122             :                 .path   = &XFS_IMETA_RTBITMAP,
     123             :                 .offset = offsetof(struct xfs_sb, sb_rbmino),
     124             :         },
     125             :         {
     126             :                 .path   = &XFS_IMETA_RTSUMMARY,
     127             :                 .offset = offsetof(struct xfs_sb, sb_rsumino),
     128             :         },
     129             :         {
     130             :                 .path   = &XFS_IMETA_USRQUOTA,
     131             :                 .offset = offsetof(struct xfs_sb, sb_uquotino),
     132             :         },
     133             :         {
     134             :                 .path   = &XFS_IMETA_GRPQUOTA,
     135             :                 .offset = offsetof(struct xfs_sb, sb_gquotino),
     136             :         },
     137             :         {
     138             :                 .path   = &XFS_IMETA_PRJQUOTA,
     139             :                 .offset = offsetof(struct xfs_sb, sb_pquotino),
     140             :         },
     141             :         {
     142             :                 .path   = &XFS_IMETA_METADIR,
     143             :                 .offset = offsetof(struct xfs_sb, sb_metadirino),
     144             :         },
     145             :         { NULL, 0 },
     146             : };
     147             : 
     148             : /* Return a pointer to the in-core superblock inode value. */
     149             : static inline xfs_ino_t *
     150             : xfs_imeta_sbmap_to_inop(
     151             :         struct xfs_mount                *mp,
     152             :         const struct xfs_imeta_sbmap    *map)
     153             : {
     154 >51351*10^7 :         return (xfs_ino_t *)(((char *)&mp->m_sb) + map->offset);
     155             : }
     156             : 
     157             : /* Compute location of metadata inode pointer in the in-core superblock */
     158             : static inline xfs_ino_t *
     159       57423 : xfs_imeta_path_to_sb_inop(
     160             :         struct xfs_mount                *mp,
     161             :         const struct xfs_imeta_path     *path)
     162             : {
     163       57423 :         const struct xfs_imeta_sbmap    *p;
     164             : 
     165      283906 :         for (p = xfs_imeta_sbmaps; p->path; p++)
     166      265743 :                 if (xfs_imeta_path_compare(p->path, path))
     167       39260 :                         return xfs_imeta_sbmap_to_inop(mp, p);
     168             : 
     169             :         return NULL;
     170             : }
     171             : 
     172             : /* Look up a superblock metadata inode by its path. */
     173             : STATIC int
     174           0 : xfs_imeta_sb_lookup(
     175             :         struct xfs_mount                *mp,
     176             :         const struct xfs_imeta_path     *path,
     177             :         xfs_ino_t                       *inop)
     178             : {
     179           0 :         xfs_ino_t                       *sb_inop;
     180             : 
     181           0 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, path);
     182           0 :         if (!sb_inop)
     183             :                 return -EINVAL;
     184             : 
     185           0 :         trace_xfs_imeta_sb_lookup(mp, sb_inop);
     186           0 :         *inop = *sb_inop;
     187           0 :         return 0;
     188             : }
     189             : 
     190             : /* Update inode pointers in the superblock. */
     191             : static inline void
     192        4097 : xfs_imeta_log_sb(
     193             :         struct xfs_trans        *tp)
     194             : {
     195        4097 :         struct xfs_mount        *mp = tp->t_mountp;
     196        4097 :         struct xfs_buf          *bp = xfs_trans_getsb(tp);
     197             : 
     198             :         /*
     199             :          * Update the inode flags in the ondisk superblock without touching
     200             :          * the summary counters.  We have not quiesced inode chunk allocation,
     201             :          * so we cannot coordinate with updates to the icount and ifree percpu
     202             :          * counters.
     203             :          */
     204        4097 :         xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
     205        4097 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF);
     206        4097 :         xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb) - 1);
     207        4097 : }
     208             : 
     209             : /*
     210             :  * Create a new metadata inode and set a superblock pointer to this new inode.
     211             :  * The superblock field must not already be pointing to an inode.
     212             :  */
     213             : STATIC int
     214        4097 : xfs_imeta_sb_create(
     215             :         struct xfs_imeta_update         *upd,
     216             :         umode_t                         mode)
     217             : {
     218        8194 :         struct xfs_icreate_args         args = {
     219        4097 :                 .nlink                  = S_ISDIR(mode) ? 2 : 1,
     220             :         };
     221        4097 :         struct xfs_mount                *mp = upd->mp;
     222        4097 :         xfs_ino_t                       *sb_inop;
     223        4097 :         xfs_ino_t                       ino;
     224        4097 :         int                             error;
     225             : 
     226             :         /* Files rooted in the superblock do not have parents. */
     227        4097 :         xfs_icreate_args_rootfile(&args, mp, mode, false);
     228             : 
     229             :         /* Reject if the sb already points to some inode. */
     230        4097 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
     231        4097 :         if (!sb_inop)
     232             :                 return -EINVAL;
     233             : 
     234        4097 :         if (*sb_inop != NULLFSINO)
     235             :                 return -EEXIST;
     236             : 
     237             :         /* Create a new inode and set the sb pointer. */
     238        4097 :         error = xfs_dialloc(&upd->tp, NULL, mode, &ino);
     239        4097 :         if (error)
     240             :                 return error;
     241        4097 :         error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
     242        4097 :         if (error)
     243             :                 return error;
     244        4097 :         upd->ip_locked = true;
     245             : 
     246             :         /*
     247             :          * If we ever need the ability to create rt metadata files on a
     248             :          * pre-metadir filesystem, we'll need to dqattach the child here.
     249             :          * Currently we assume that mkfs will create the files and quotacheck
     250             :          * will account for them.
     251             :          */
     252             : 
     253             :         /* Update superblock pointer. */
     254        4097 :         *sb_inop = ino;
     255        4097 :         xfs_imeta_log_sb(upd->tp);
     256             : 
     257        4097 :         trace_xfs_imeta_sb_create(upd);
     258        4097 :         return 0;
     259             : }
     260             : 
     261             : /*
     262             :  * Clear the given inode pointer from the superblock and drop the link count
     263             :  * of the metadata inode.
     264             :  */
     265             : STATIC int
     266           0 : xfs_imeta_sb_unlink(
     267             :         struct xfs_imeta_update         *upd)
     268             : {
     269           0 :         struct xfs_mount                *mp = upd->mp;
     270           0 :         xfs_ino_t                       *sb_inop;
     271             : 
     272           0 :         ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
     273             : 
     274           0 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
     275           0 :         if (!sb_inop)
     276             :                 return -EINVAL;
     277             : 
     278             :         /* Reject if the sb doesn't point to the inode that was passed in. */
     279           0 :         if (*sb_inop != upd->ip->i_ino)
     280             :                 return -ENOENT;
     281             : 
     282           0 :         trace_xfs_imeta_sb_unlink(upd);
     283             : 
     284           0 :         *sb_inop = NULLFSINO;
     285           0 :         xfs_imeta_log_sb(upd->tp);
     286           0 :         return xfs_droplink(upd->tp, upd->ip);
     287             : }
     288             : 
     289             : /* Set the given inode pointer in the superblock. */
     290             : STATIC int
     291           0 : xfs_imeta_sb_link(
     292             :         struct xfs_imeta_update         *upd)
     293             : {
     294           0 :         struct xfs_mount                *mp = upd->mp;
     295           0 :         xfs_ino_t                       *sb_inop;
     296             : 
     297           0 :         ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
     298             : 
     299           0 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
     300           0 :         if (!sb_inop)
     301             :                 return -EINVAL;
     302           0 :         if (*sb_inop != NULLFSINO)
     303             :                 return -EEXIST;
     304             : 
     305           0 :         trace_xfs_imeta_sb_link(upd);
     306             : 
     307           0 :         xfs_bumplink(upd->tp, upd->ip);
     308           0 :         xfs_imeta_log_sb(upd->tp);
     309             : 
     310           0 :         *sb_inop = upd->ip->i_ino;
     311           0 :         return 0;
     312             : }
     313             : 
     314             : /* Functions for storing and retrieving metadata directory inode values. */
     315             : 
     316             : static inline void
     317     1060440 : xfs_imeta_set_xname(
     318             :         struct xfs_name                 *xname,
     319             :         const struct xfs_imeta_path     *path,
     320             :         unsigned int                    path_idx,
     321             :         unsigned char                   ftype)
     322             : {
     323     1060440 :         xname->name = (const unsigned char *)path->im_path[path_idx];
     324     1060440 :         xname->len = strlen(path->im_path[path_idx]);
     325     1060440 :         xname->type = ftype;
     326     1060440 : }
     327             : 
     328             : /*
     329             :  * Look up the inode number and filetype for an exact name in a directory.
     330             :  * Caller must hold ILOCK_EXCL.
     331             :  */
     332             : static inline int
     333     1060440 : xfs_imeta_dir_lookup(
     334             :         struct xfs_inode        *dp,
     335             :         struct xfs_name         *xname,
     336             :         xfs_ino_t               *ino)
     337             : {
     338     2120880 :         struct xfs_da_args      args = {
     339             :                 .dp             = dp,
     340     1060440 :                 .geo            = dp->i_mount->m_dir_geo,
     341     1060440 :                 .name           = xname->name,
     342     1060440 :                 .namelen        = xname->len,
     343     1060440 :                 .hashval        = xfs_dir2_hashname(dp->i_mount, xname),
     344             :                 .whichfork      = XFS_DATA_FORK,
     345             :                 .op_flags       = XFS_DA_OP_OKNOENT,
     346     1060440 :                 .owner          = dp->i_ino,
     347             :         };
     348     1060440 :         bool                    isblock, isleaf;
     349     1060440 :         int                     error;
     350             : 
     351     2120880 :         if (xfs_is_shutdown(dp->i_mount))
     352             :                 return -EIO;
     353             : 
     354     1060440 :         if (dp->i_df.if_format == XFS_DINODE_FMT_LOCAL) {
     355      828280 :                 error = xfs_dir2_sf_lookup(&args);
     356      828280 :                 goto out_unlock;
     357             :         }
     358             : 
     359             :         /* dir2 functions require that the data fork is loaded */
     360      232160 :         error = xfs_iread_extents(NULL, dp, XFS_DATA_FORK);
     361      232160 :         if (error)
     362           0 :                 goto out_unlock;
     363             : 
     364      232160 :         error = xfs_dir2_isblock(&args, &isblock);
     365      232160 :         if (error)
     366           0 :                 goto out_unlock;
     367             : 
     368      232160 :         if (isblock) {
     369      214063 :                 error = xfs_dir2_block_lookup(&args);
     370      214063 :                 goto out_unlock;
     371             :         }
     372             : 
     373       18097 :         error = xfs_dir2_isleaf(&args, &isleaf);
     374       18097 :         if (error)
     375           0 :                 goto out_unlock;
     376             : 
     377       18097 :         if (isleaf) {
     378        1880 :                 error = xfs_dir2_leaf_lookup(&args);
     379        1880 :                 goto out_unlock;
     380             :         }
     381             : 
     382       16217 :         error = xfs_dir2_node_lookup(&args);
     383             : 
     384     1060440 : out_unlock:
     385     1060440 :         if (error == -EEXIST)
     386             :                 error = 0;
     387      112526 :         if (error)
     388             :                 return error;
     389             : 
     390      947914 :         *ino = args.inumber;
     391      947914 :         xname->type = args.filetype;
     392      947914 :         return 0;
     393             : }
     394             : 
     395             : /*
     396             :  * Given a parent directory @dp and a metadata inode path component @xname,
     397             :  * Look up the inode number in the directory, returning it in @ino.
     398             :  * @xname.type must match the directory entry's ftype.
     399             :  *
     400             :  * Caller must hold ILOCK_EXCL.
     401             :  */
     402             : static inline int
     403     1060440 : xfs_imeta_dir_lookup_component(
     404             :         struct xfs_inode                *dp,
     405             :         struct xfs_name                 *xname,
     406             :         xfs_ino_t                       *ino)
     407             : {
     408     1060440 :         int                             type_wanted = xname->type;
     409     1060440 :         int                             error;
     410             : 
     411     1060440 :         if (!S_ISDIR(VFS_I(dp)->i_mode)) {
     412           0 :                 xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
     413           0 :                 return -EFSCORRUPTED;
     414             :         }
     415             : 
     416     1060440 :         error = xfs_imeta_dir_lookup(dp, xname, ino);
     417     1060440 :         if (error)
     418             :                 return error;
     419      947914 :         if (!xfs_verify_ino(dp->i_mount, *ino)) {
     420           0 :                 xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
     421           0 :                 return -EFSCORRUPTED;
     422             :         }
     423      947914 :         if (type_wanted != XFS_DIR3_FT_UNKNOWN && xname->type != type_wanted) {
     424           0 :                 xfs_fs_mark_sick(dp->i_mount, XFS_SICK_FS_METADIR);
     425           0 :                 return -EFSCORRUPTED;
     426             :         }
     427             : 
     428      947914 :         trace_xfs_imeta_dir_lookup(dp, xname, *ino);
     429      947914 :         return 0;
     430             : }
     431             : 
     432             : /*
     433             :  * Traverse a metadata directory tree path, returning the inode corresponding
     434             :  * to the parent of the last path component.  If any of the path components do
     435             :  * not exist, return -ENOENT.
     436             :  *
     437             :  * @dp is returned without any locks held.
     438             :  */
     439             : int
     440      579371 : xfs_imeta_dir_parent(
     441             :         struct xfs_mount                *mp,
     442             :         const struct xfs_imeta_path     *path,
     443             :         struct xfs_inode                **dpp)
     444             : {
     445      579371 :         struct xfs_name                 xname;
     446      579371 :         struct xfs_inode                *dp = NULL;
     447      579371 :         xfs_ino_t                       ino;
     448      579371 :         unsigned int                    i;
     449      579371 :         int                             error;
     450             : 
     451             :         /* Caller wanted the root, we're done! */
     452      579371 :         if (path->im_depth == 0)
     453           0 :                 goto out;
     454             : 
     455             :         /* No metadata directory means no parent. */
     456      579371 :         if (mp->m_metadirip == NULL)
     457             :                 return -ENOENT;
     458             : 
     459             :         /* Grab a new reference to the metadir root dir. */
     460      579371 :         error = xfs_imeta_iget(mp, mp->m_metadirip->i_ino, XFS_DIR3_FT_DIR,
     461             :                         &dp);
     462      579371 :         if (error)
     463             :                 return error;
     464             : 
     465     1060440 :         for (i = 0; i < path->im_depth - 1; i++) {
     466      538042 :                 struct xfs_inode        *ip = NULL;
     467             : 
     468      538042 :                 xfs_ilock(dp, XFS_ILOCK_EXCL);
     469             : 
     470             :                 /* Look up the name in the current directory. */
     471      538042 :                 xfs_imeta_set_xname(&xname, path, i, XFS_DIR3_FT_DIR);
     472      538042 :                 error = xfs_imeta_dir_lookup_component(dp, &xname, &ino);
     473      538042 :                 if (error)
     474       56973 :                         goto out_rele;
     475             : 
     476             :                 /*
     477             :                  * Grab the child inode while we still have the parent
     478             :                  * directory locked.
     479             :                  */
     480      481069 :                 error = xfs_imeta_iget(mp, ino, XFS_DIR3_FT_DIR, &ip);
     481      481069 :                 if (error)
     482           0 :                         goto out_rele;
     483             : 
     484      481069 :                 xfs_iunlock(dp, XFS_ILOCK_EXCL);
     485      481069 :                 xfs_imeta_irele(dp);
     486      481069 :                 dp = ip;
     487             :         }
     488             : 
     489      522398 : out:
     490      522398 :         *dpp = dp;
     491      522398 :         return 0;
     492             : 
     493             : out_rele:
     494       56973 :         xfs_iunlock(dp, XFS_ILOCK_EXCL);
     495       56973 :         xfs_imeta_irele(dp);
     496       56973 :         return error;
     497             : }
     498             : 
     499             : /*
     500             :  * Look up a metadata inode from the metadata directory.  If the last path
     501             :  * component doesn't exist, return NULLFSINO.  If any other part of the path
     502             :  * does not exist, return -ENOENT so we can distinguish the two.
     503             :  */
     504             : STATIC int
     505      496713 : xfs_imeta_dir_lookup_int(
     506             :         struct xfs_mount                *mp,
     507             :         const struct xfs_imeta_path     *path,
     508             :         xfs_ino_t                       *inop)
     509             : {
     510      496713 :         struct xfs_name                 xname;
     511      496713 :         struct xfs_inode                *dp = NULL;
     512      496713 :         xfs_ino_t                       ino;
     513      496713 :         int                             error;
     514             : 
     515             :         /* metadir ino is recorded in superblock */
     516      496713 :         if (xfs_imeta_path_compare(path, &XFS_IMETA_METADIR))
     517           0 :                 return xfs_imeta_sb_lookup(mp, path, inop);
     518             : 
     519      496713 :         ASSERT(path->im_depth > 0);
     520             : 
     521             :         /* Find the parent of the last path component. */
     522      496713 :         error = xfs_imeta_dir_parent(mp, path, &dp);
     523      496713 :         if (error)
     524             :                 return error;
     525             : 
     526      439740 :         xfs_ilock(dp, XFS_ILOCK_EXCL);
     527             : 
     528             :         /* Look up the name in the current directory. */
     529      439740 :         xfs_imeta_set_xname(&xname, path, path->im_depth - 1, path->im_ftype);
     530      439740 :         error = xfs_imeta_dir_lookup_component(dp, &xname, &ino);
     531      439740 :         switch (error) {
     532      437513 :         case 0:
     533      437513 :                 *inop = ino;
     534      437513 :                 break;
     535        2219 :         case -ENOENT:
     536        2219 :                 *inop = NULLFSINO;
     537        2219 :                 error = 0;
     538        2219 :                 break;
     539             :         }
     540             : 
     541      439740 :         xfs_iunlock(dp, XFS_ILOCK_EXCL);
     542      439740 :         xfs_imeta_irele(dp);
     543      439740 :         return error;
     544             : }
     545             : 
     546             : /*
     547             :  * Load all the metadata inode pointers that are cached in the in-core
     548             :  * superblock but live somewhere in the metadata directory tree.
     549             :  */
     550             : STATIC int
     551       60399 : xfs_imeta_dir_mount(
     552             :         struct xfs_mount                *mp)
     553             : {
     554       60399 :         const struct xfs_imeta_sbmap    *p;
     555       60399 :         xfs_ino_t                       *sb_inop;
     556       60399 :         int                             err2;
     557       60399 :         int                             error = 0;
     558             : 
     559      362394 :         for (p = xfs_imeta_sbmaps; p->path && p->path->im_depth > 0; p++) {
     560      301995 :                 if (p->path == &XFS_IMETA_METADIR)
     561           0 :                         continue;
     562      301995 :                 sb_inop = xfs_imeta_sbmap_to_inop(mp, p);
     563      301995 :                 err2 = xfs_imeta_dir_lookup_int(mp, p->path, sb_inop);
     564      301995 :                 if (err2 == -ENOENT) {
     565       56973 :                         *sb_inop = NULLFSINO;
     566       56973 :                         continue;
     567             :                 }
     568      245022 :                 if (!error && err2)
     569           4 :                         error = err2;
     570             :         }
     571             : 
     572       60399 :         return error;
     573             : }
     574             : 
     575             : /* Set up an inode to be recognized as a metadata inode. */
     576             : void
     577       53326 : xfs_imeta_set_iflag(
     578             :         struct xfs_trans        *tp,
     579             :         struct xfs_inode        *ip)
     580             : {
     581       53326 :         VFS_I(ip)->i_mode &= ~0777;
     582       53326 :         VFS_I(ip)->i_uid = GLOBAL_ROOT_UID;
     583       53326 :         VFS_I(ip)->i_gid = GLOBAL_ROOT_GID;
     584       53326 :         ip->i_projid = 0;
     585       53326 :         ip->i_diflags |= (XFS_DIFLAG_IMMUTABLE | XFS_DIFLAG_SYNC |
     586             :                           XFS_DIFLAG_NOATIME | XFS_DIFLAG_NODUMP |
     587             :                           XFS_DIFLAG_NODEFRAG);
     588       53326 :         if (S_ISDIR(VFS_I(ip)->i_mode))
     589       11997 :                 ip->i_diflags |= XFS_DIFLAG_NOSYMLINKS;
     590       53326 :         ip->i_diflags2 &= ~XFS_DIFLAG2_DAX;
     591       53326 :         ip->i_diflags2 |= XFS_DIFLAG2_METADIR;
     592       53326 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
     593       53326 : }
     594             : 
     595             : /*
     596             :  * Create a new metadata inode accessible via the given metadata directory path.
     597             :  * Callers must ensure that the directory entry does not already exist; a new
     598             :  * one will be created.
     599             :  */
     600             : STATIC int
     601       82658 : xfs_imeta_dir_create(
     602             :         struct xfs_imeta_update         *upd,
     603             :         umode_t                         mode)
     604             : {
     605      165316 :         struct xfs_icreate_args         args = {
     606       82658 :                 .pip                    = upd->dp,
     607       82658 :                 .nlink                  = S_ISDIR(mode) ? 2 : 1,
     608             :         };
     609       82658 :         struct xfs_name                 xname;
     610       82658 :         struct xfs_dir_update           du = {
     611             :                 .dp                     = upd->dp,
     612             :                 .name                   = &xname,
     613       82658 :                 .parent                 = upd->parent,
     614             :         };
     615       82658 :         struct xfs_mount                *mp = upd->mp;
     616       82658 :         xfs_ino_t                       *sb_inop;
     617       82658 :         xfs_ino_t                       ino;
     618       82658 :         unsigned int                    resblks;
     619       82658 :         int                             error;
     620             : 
     621       82658 :         ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
     622             : 
     623             :         /* metadir ino is recorded in superblock; only mkfs gets to do this */
     624       82658 :         if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
     625           0 :                 error = xfs_imeta_sb_create(upd, mode);
     626           0 :                 if (error)
     627             :                         return error;
     628             : 
     629             :                 /* Set the metadata iflag, initialize directory. */
     630           0 :                 xfs_imeta_set_iflag(upd->tp, upd->ip);
     631           0 :                 return xfs_dir_init(upd->tp, upd->ip, upd->ip);
     632             :         }
     633             : 
     634       82658 :         ASSERT(upd->path->im_depth > 0);
     635             : 
     636       82658 :         xfs_icreate_args_rootfile(&args, mp, mode, xfs_has_parent(mp));
     637             : 
     638             :         /* Check that the name does not already exist in the directory. */
     639       82658 :         xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
     640             :                         XFS_DIR3_FT_UNKNOWN);
     641       82658 :         error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
     642       82658 :         switch (error) {
     643             :         case -ENOENT:
     644       53326 :                 break;
     645       29332 :         case 0:
     646       29332 :                 error = -EEXIST;
     647             :                 fallthrough;
     648             :         default:
     649             :                 return error;
     650             :         }
     651             : 
     652             :         /*
     653             :          * A newly created regular or special file just has one directory
     654             :          * entry pointing to them, but a directory also the "." entry
     655             :          * pointing to itself.
     656             :          */
     657       53326 :         error = xfs_dialloc(&upd->tp, upd->dp, mode, &ino);
     658       53326 :         if (error)
     659             :                 return error;
     660       53326 :         error = xfs_icreate(upd->tp, ino, &args, &upd->ip);
     661       53326 :         if (error)
     662             :                 return error;
     663       53326 :         du.ip = upd->ip;
     664       53326 :         xfs_imeta_set_iflag(upd->tp, upd->ip);
     665       53326 :         upd->ip_locked = true;
     666             : 
     667             :         /*
     668             :          * Join the directory inode to the transaction.  We do not do it
     669             :          * earlier because xfs_dialloc rolls the transaction.
     670             :          */
     671       53326 :         xfs_trans_ijoin(upd->tp, upd->dp, 0);
     672             : 
     673             :         /* Create the entry. */
     674       53326 :         if (S_ISDIR(args.mode))
     675       11997 :                 resblks = xfs_mkdir_space_res(mp, xname.len);
     676             :         else
     677       41329 :                 resblks = xfs_create_space_res(mp, xname.len);
     678       53326 :         xname.type = xfs_mode_to_ftype(args.mode);
     679             : 
     680       53326 :         trace_xfs_imeta_dir_try_create(upd);
     681             : 
     682       53326 :         error = xfs_dir_create_child(upd->tp, resblks, &du);
     683       53326 :         if (error)
     684             :                 return error;
     685             : 
     686             :         /* Metadir files are not accounted to quota. */
     687             : 
     688       53326 :         trace_xfs_imeta_dir_create(upd);
     689             : 
     690             :         /* Update the in-core superblock value if there is one. */
     691       53326 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
     692       53326 :         if (sb_inop)
     693       35163 :                 *sb_inop = ino;
     694             :         return 0;
     695             : }
     696             : 
     697             : /*
     698             :  * Remove the given entry from the metadata directory and drop the link count
     699             :  * of the metadata inode.
     700             :  */
     701             : STATIC int
     702           0 : xfs_imeta_dir_unlink(
     703             :         struct xfs_imeta_update         *upd)
     704             : {
     705           0 :         struct xfs_name                 xname;
     706           0 :         struct xfs_dir_update           du = {
     707           0 :                 .dp                     = upd->dp,
     708             :                 .name                   = &xname,
     709           0 :                 .ip                     = upd->ip,
     710           0 :                 .parent                 = upd->parent,
     711             :         };
     712           0 :         struct xfs_mount                *mp = upd->mp;
     713           0 :         xfs_ino_t                       *sb_inop;
     714           0 :         xfs_ino_t                       ino;
     715           0 :         unsigned int                    resblks;
     716           0 :         int                             error;
     717             : 
     718           0 :         ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
     719           0 :         ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
     720             : 
     721             :         /* Metadata directory root cannot be unlinked. */
     722           0 :         if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
     723           0 :                 ASSERT(0);
     724           0 :                 xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
     725           0 :                 return -EFSCORRUPTED;
     726             :         }
     727             : 
     728           0 :         ASSERT(upd->path->im_depth > 0);
     729             : 
     730             :         /* Look up the name in the current directory. */
     731           0 :         xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
     732           0 :                         xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
     733           0 :         error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
     734           0 :         switch (error) {
     735           0 :         case 0:
     736           0 :                 if (ino != upd->ip->i_ino)
     737             :                         error = -ENOENT;
     738             :                 break;
     739           0 :         case -ENOENT:
     740           0 :                 xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
     741           0 :                 error = -EFSCORRUPTED;
     742           0 :                 break;
     743             :         }
     744           0 :         if (error)
     745           0 :                 return error;
     746             : 
     747           0 :         resblks = xfs_remove_space_res(mp, xname.len);
     748           0 :         error = xfs_dir_remove_child(upd->tp, resblks, &du);
     749           0 :         if (error)
     750             :                 return error;
     751             : 
     752           0 :         trace_xfs_imeta_dir_unlink(upd);
     753             : 
     754             :         /* Update the in-core superblock value if there is one. */
     755           0 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
     756           0 :         if (sb_inop)
     757           0 :                 *sb_inop = NULLFSINO;
     758             :         return 0;
     759             : }
     760             : 
     761             : /* Set the given path in the metadata directory to point to an inode. */
     762             : STATIC int
     763           0 : xfs_imeta_dir_link(
     764             :         struct xfs_imeta_update         *upd)
     765             : {
     766           0 :         struct xfs_name                 xname;
     767           0 :         struct xfs_dir_update           du = {
     768           0 :                 .dp                     = upd->dp,
     769             :                 .name                   = &xname,
     770           0 :                 .ip                     = upd->ip,
     771           0 :                 .parent                 = upd->parent,
     772             :         };
     773           0 :         struct xfs_mount                *mp = upd->mp;
     774           0 :         xfs_ino_t                       *sb_inop;
     775           0 :         xfs_ino_t                       ino;
     776           0 :         unsigned int                    resblks;
     777           0 :         int                             error;
     778             : 
     779           0 :         ASSERT(xfs_isilocked(upd->dp, XFS_ILOCK_EXCL));
     780           0 :         ASSERT(xfs_isilocked(upd->ip, XFS_ILOCK_EXCL));
     781             : 
     782             :         /* Metadata directory root cannot be linked. */
     783           0 :         if (xfs_imeta_path_compare(upd->path, &XFS_IMETA_METADIR)) {
     784           0 :                 ASSERT(0);
     785           0 :                 xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
     786           0 :                 return -EFSCORRUPTED;
     787             :         }
     788             : 
     789           0 :         ASSERT(upd->path->im_depth > 0);
     790             : 
     791             :         /* Look up the name in the current directory. */
     792           0 :         xfs_imeta_set_xname(&xname, upd->path, upd->path->im_depth - 1,
     793           0 :                         xfs_mode_to_ftype(VFS_I(upd->ip)->i_mode));
     794           0 :         error = xfs_imeta_dir_lookup_component(upd->dp, &xname, &ino);
     795           0 :         switch (error) {
     796             :         case -ENOENT:
     797           0 :                 break;
     798           0 :         case 0:
     799           0 :                 error = -EEXIST;
     800             :                 fallthrough;
     801             :         default:
     802             :                 return error;
     803             :         }
     804             : 
     805           0 :         resblks = xfs_link_space_res(mp, xname.len);
     806           0 :         error = xfs_dir_add_child(upd->tp, resblks, &du);
     807           0 :         if (error)
     808             :                 return error;
     809             : 
     810           0 :         trace_xfs_imeta_dir_link(upd);
     811             : 
     812             :         /* Update the in-core superblock value if there is one. */
     813           0 :         sb_inop = xfs_imeta_path_to_sb_inop(mp, upd->path);
     814           0 :         if (sb_inop)
     815           0 :                 *sb_inop = upd->ip->i_ino;
     816             :         return 0;
     817             : }
     818             : 
     819             : /* General functions for managing metadata inode pointers */
     820             : 
     821             : /*
     822             :  * Is this metadata inode pointer ok?  We allow the fields to be set to
     823             :  * NULLFSINO if the metadata structure isn't present, and we don't allow
     824             :  * obviously incorrect inode pointers.
     825             :  */
     826             : static inline bool
     827             : xfs_imeta_verify(
     828             :         struct xfs_mount        *mp,
     829             :         xfs_ino_t               ino)
     830             : {
     831      194718 :         if (ino == NULLFSINO)
     832             :                 return true;
     833      194718 :         return xfs_verify_ino(mp, ino);
     834             : }
     835             : 
     836             : /* Look up a metadata inode by its path. */
     837             : int
     838      194718 : xfs_imeta_lookup(
     839             :         struct xfs_mount                *mp,
     840             :         const struct xfs_imeta_path     *path,
     841             :         xfs_ino_t                       *inop)
     842             : {
     843      194718 :         xfs_ino_t                       ino;
     844      194718 :         int                             error;
     845             : 
     846      194718 :         ASSERT(xfs_imeta_path_check(path));
     847             : 
     848      194718 :         if (xfs_has_metadir(mp)) {
     849      194718 :                 error = xfs_imeta_dir_lookup_int(mp, path, &ino);
     850      194718 :                 if (error == -ENOENT) {
     851           0 :                         xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
     852           0 :                         return -EFSCORRUPTED;
     853             :                 }
     854             :         } else {
     855           0 :                 error = xfs_imeta_sb_lookup(mp, path, &ino);
     856             :         }
     857      194718 :         if (error)
     858             :                 return error;
     859             : 
     860      389436 :         if (!xfs_imeta_verify(mp, ino)) {
     861           0 :                 xfs_fs_mark_sick(mp, XFS_SICK_FS_METADIR);
     862           0 :                 return -EFSCORRUPTED;
     863             :         }
     864             : 
     865      194718 :         *inop = ino;
     866      194718 :         return 0;
     867             : }
     868             : 
     869             : /*
     870             :  * Create a metadata inode with the given @mode, and insert it into the
     871             :  * metadata directory tree at the given @path.  The path (up to the final
     872             :  * component) must already exist.
     873             :  *
     874             :  * The new metadata inode will be attached to the update structure @upd->ip,
     875             :  * with the ILOCK held until the caller releases it.  @ipp is set to upd->ip
     876             :  * as a convenience for callers.
     877             :  *
     878             :  * Callers must ensure that the root dquots are allocated, if applicable.
     879             :  *
     880             :  * NOTE: This function may return a new inode to the caller even if it returns
     881             :  * a negative error code.  If an inode is passed back, the caller must finish
     882             :  * setting up the inode before releasing it.
     883             :  */
     884             : int
     885       86755 : xfs_imeta_create(
     886             :         struct xfs_imeta_update         *upd,
     887             :         umode_t                         mode,
     888             :         struct xfs_inode                **ipp)
     889             : {
     890       86755 :         struct xfs_mount                *mp = upd->mp;
     891       86755 :         int                             error;
     892             : 
     893       86755 :         ASSERT(xfs_imeta_path_check(upd->path));
     894             : 
     895       86755 :         *ipp = NULL;
     896             : 
     897       86755 :         if (xfs_has_metadir(mp))
     898       82658 :                 error = xfs_imeta_dir_create(upd, mode);
     899             :         else
     900        4097 :                 error = xfs_imeta_sb_create(upd, mode);
     901       86755 :         *ipp = upd->ip;
     902       86755 :         return error;
     903             : }
     904             : 
     905             : /* Free a file from the metadata directory tree. */
     906             : STATIC int
     907           0 : xfs_imeta_ifree(
     908             :         struct xfs_trans        *tp,
     909             :         struct xfs_inode        *ip)
     910             : {
     911           0 :         struct xfs_mount        *mp = ip->i_mount;
     912           0 :         struct xfs_perag        *pag;
     913           0 :         struct xfs_icluster     xic = { 0 };
     914           0 :         int                     error;
     915             : 
     916           0 :         ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
     917           0 :         ASSERT(VFS_I(ip)->i_nlink == 0);
     918           0 :         ASSERT(ip->i_df.if_nextents == 0);
     919           0 :         ASSERT(ip->i_disk_size == 0 || !S_ISREG(VFS_I(ip)->i_mode));
     920           0 :         ASSERT(ip->i_nblocks == 0);
     921             : 
     922           0 :         pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
     923             : 
     924           0 :         error = xfs_dir_ifree(tp, pag, ip, &xic);
     925           0 :         if (error)
     926           0 :                 goto out;
     927             : 
     928             :         /* Metadata files do not support ownership changes or DMAPI. */
     929             : 
     930           0 :         if (xic.deleted)
     931           0 :                 error = xfs_ifree_cluster(tp, pag, ip, &xic);
     932           0 : out:
     933           0 :         xfs_perag_put(pag);
     934           0 :         return error;
     935             : }
     936             : 
     937             : /*
     938             :  * Unlink a metadata inode @upd->ip from the metadata directory given by @path.
     939             :  * The path must already exist.
     940             :  */
     941             : int
     942           0 : xfs_imeta_unlink(
     943             :         struct xfs_imeta_update         *upd)
     944             : {
     945           0 :         int                             error;
     946             : 
     947           0 :         ASSERT(xfs_imeta_path_check(upd->path));
     948           0 :         ASSERT(xfs_imeta_verify(upd->mp, upd->ip->i_ino));
     949             : 
     950           0 :         if (xfs_has_metadir(upd->mp))
     951           0 :                 error = xfs_imeta_dir_unlink(upd);
     952             :         else
     953           0 :                 error = xfs_imeta_sb_unlink(upd);
     954           0 :         if (error)
     955             :                 return error;
     956             : 
     957             :         /*
     958             :          * Metadata files require explicit resource cleanup.  In other words,
     959             :          * the inactivation system will not touch these files, so we must free
     960             :          * the ondisk inode by ourselves if warranted.
     961             :          */
     962           0 :         if (VFS_I(upd->ip)->i_nlink > 0)
     963             :                 return 0;
     964             : 
     965           0 :         return xfs_imeta_ifree(upd->tp, upd->ip);
     966             : }
     967             : 
     968             : /*
     969             :  * Link the metadata directory given by @path to the inode @upd->ip.
     970             :  * The path (up to the final component) must already exist, but the final
     971             :  * component must not already exist.
     972             :  */
     973             : int
     974           0 : xfs_imeta_link(
     975             :         struct xfs_imeta_update         *upd)
     976             : {
     977           0 :         ASSERT(xfs_imeta_path_check(upd->path));
     978             : 
     979           0 :         if (xfs_has_metadir(upd->mp))
     980           0 :                 return xfs_imeta_dir_link(upd);
     981           0 :         return xfs_imeta_sb_link(upd);
     982             : }
     983             : 
     984             : /* Does this inode number refer to a static metadata inode? */
     985             : bool
     986 86632174291 : xfs_is_static_meta_ino(
     987             :         struct xfs_mount                *mp,
     988             :         xfs_ino_t                       ino)
     989             : {
     990 86632174291 :         const struct xfs_imeta_sbmap    *p;
     991             : 
     992 86632174291 :         if (ino == NULLFSINO)
     993             :                 return false;
     994             : 
     995 >59993*10^7 :         for (p = xfs_imeta_sbmaps; p->path; p++)
     996 >51351*10^7 :                 if (ino == *xfs_imeta_sbmap_to_inop(mp, p))
     997             :                         return true;
     998             : 
     999             :         return false;
    1000             : }
    1001             : 
    1002             : /* Ensure that the in-core superblock has all the values that it should. */
    1003             : int
    1004       66795 : xfs_imeta_mount(
    1005             :         struct xfs_mount        *mp)
    1006             : {
    1007       66795 :         if (xfs_has_metadir(mp))
    1008       60399 :                 return xfs_imeta_dir_mount(mp);
    1009             : 
    1010             :         return 0;
    1011             : }
    1012             : 
    1013             : /* Clear the metadata iflag if we're unlinking this inode. */
    1014             : void
    1015    81092919 : xfs_imeta_droplink(
    1016             :         struct xfs_inode        *ip)
    1017             : {
    1018    81092919 :         if (VFS_I(ip)->i_nlink == 0 && xfs_is_metadir_inode(ip))
    1019           0 :                 ip->i_diflags2 &= ~XFS_DIFLAG2_METADIR;
    1020    81092919 : }
    1021             : 
    1022             : /* Create a path to a file within the metadata directory tree. */
    1023             : int
    1024      200884 : xfs_imeta_create_file_path(
    1025             :         struct xfs_mount        *mp,
    1026             :         unsigned int            nr_components,
    1027             :         struct xfs_imeta_path   **pathp)
    1028             : {
    1029      200884 :         struct xfs_imeta_path   *p;
    1030      200884 :         unsigned char           **components;
    1031             : 
    1032      200884 :         p = kmalloc(sizeof(struct xfs_imeta_path), GFP_KERNEL);
    1033      200884 :         if (!p)
    1034             :                 return -ENOMEM;
    1035             : 
    1036      200884 :         components = kvcalloc(nr_components, sizeof(unsigned char *),
    1037             :                         GFP_KERNEL);
    1038      200884 :         if (!components) {
    1039           0 :                 kfree(p);
    1040           0 :                 return -ENOMEM;
    1041             :         }
    1042             : 
    1043      200884 :         p->im_depth = nr_components;
    1044      200884 :         p->im_path = (const unsigned char **)components;
    1045      200884 :         p->im_ftype = XFS_DIR3_FT_REG_FILE;
    1046      200884 :         p->im_dynamicmask = 0;
    1047      200884 :         *pathp = p;
    1048      200884 :         return 0;
    1049             : }
    1050             : 
    1051             : /* Free a metadata directory tree path. */
    1052             : void
    1053      200884 : xfs_imeta_free_path(
    1054             :         struct xfs_imeta_path   *path)
    1055             : {
    1056      200884 :         unsigned int            i;
    1057             : 
    1058      602652 :         for (i = 0; i < path->im_depth; i++) {
    1059      401768 :                 if ((path->im_dynamicmask & (1ULL << i)) && path->im_path[i])
    1060      200884 :                         kfree(path->im_path[i]);
    1061             :         }
    1062      200884 :         kfree(path->im_path);
    1063      200884 :         kfree(path);
    1064      200884 : }
    1065             : 
    1066             : /*
    1067             :  * Is the amount of space that could be allocated towards a given metadata
    1068             :  * file at or beneath a certain threshold?
    1069             :  */
    1070             : static inline bool
    1071   240943538 : xfs_imeta_resv_can_cover(
    1072             :         struct xfs_inode        *ip,
    1073             :         int64_t                 rhs)
    1074             : {
    1075             :         /*
    1076             :          * The amount of space that can be allocated to this metadata file is
    1077             :          * the remaining reservation for the particular metadata file + the
    1078             :          * global free block count.  Take care of the first case to avoid
    1079             :          * touching the per-cpu counter.
    1080             :          */
    1081   240943538 :         if (ip->i_delayed_blks >= rhs)
    1082             :                 return true;
    1083             : 
    1084             :         /*
    1085             :          * There aren't enough blocks left in the inode's reservation, but it
    1086             :          * isn't critical unless there also isn't enough free space.
    1087             :          */
    1088    64215758 :         return __percpu_counter_compare(&ip->i_mount->m_fdblocks,
    1089    64215758 :                         rhs - ip->i_delayed_blks, 2048) >= 0;
    1090             : }
    1091             : 
    1092             : /*
    1093             :  * Is this metadata file critically low on blocks?  For now we'll define that
    1094             :  * as the number of blocks we can get our hands on being less than 10% of what
    1095             :  * we reserved or less than some arbitrary number (maximum btree height).
    1096             :  */
    1097             : bool
    1098   120471925 : xfs_imeta_resv_critical(
    1099             :         struct xfs_inode        *ip)
    1100             : {
    1101   120471925 :         uint64_t                asked_low_water;
    1102             : 
    1103   120471925 :         if (!ip)
    1104             :                 return false;
    1105             : 
    1106   120471925 :         ASSERT(xfs_is_metadir_inode(ip));
    1107   120471925 :         trace_xfs_imeta_resv_critical(ip, 0);
    1108             : 
    1109   120471956 :         if (!xfs_imeta_resv_can_cover(ip, ip->i_mount->m_rtbtree_maxlevels))
    1110             :                 return true;
    1111             : 
    1112   120471905 :         asked_low_water = div_u64(ip->i_meta_resv_asked, 10);
    1113   120471831 :         if (!xfs_imeta_resv_can_cover(ip, asked_low_water))
    1114             :                 return true;
    1115             : 
    1116   120471836 :         return XFS_TEST_ERROR(false, ip->i_mount,
    1117             :                         XFS_ERRTAG_IMETA_RESV_CRITICAL);
    1118             : }
    1119             : 
    1120             : /* Allocate a block from the metadata file's reservation. */
    1121             : void
    1122      726296 : xfs_imeta_resv_alloc_extent(
    1123             :         struct xfs_inode        *ip,
    1124             :         struct xfs_alloc_arg    *args)
    1125             : {
    1126      726296 :         int64_t                 len = args->len;
    1127             : 
    1128      726296 :         ASSERT(xfs_is_metadir_inode(ip));
    1129      726296 :         ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
    1130      726296 :         ASSERT(args->resv == XFS_AG_RESV_IMETA);
    1131             : 
    1132      726296 :         trace_xfs_imeta_resv_alloc_extent(ip, args->len);
    1133             : 
    1134             :         /*
    1135             :          * Allocate the blocks from the metadata inode's block reservation
    1136             :          * and update the ondisk sb counter.
    1137             :          */
    1138      726296 :         if (ip->i_delayed_blks > 0) {
    1139      522346 :                 int64_t         from_resv;
    1140             : 
    1141      522346 :                 from_resv = min_t(int64_t, len, ip->i_delayed_blks);
    1142      522346 :                 ip->i_delayed_blks -= from_resv;
    1143      522346 :                 xfs_mod_delalloc(ip->i_mount, -from_resv);
    1144      522346 :                 xfs_trans_mod_sb(args->tp, XFS_TRANS_SB_RES_FDBLOCKS,
    1145             :                                 -from_resv);
    1146      522346 :                 len -= from_resv;
    1147             :         }
    1148             : 
    1149             :         /*
    1150             :          * Any allocation in excess of the reservation requires in-core and
    1151             :          * on-disk fdblocks updates.
    1152             :          */
    1153      726296 :         if (len)
    1154      203950 :                 xfs_trans_mod_sb(args->tp, XFS_TRANS_SB_FDBLOCKS, -len);
    1155             : 
    1156      726296 :         ip->i_nblocks += args->len;
    1157      726296 :         xfs_trans_log_inode(args->tp, ip, XFS_ILOG_CORE);
    1158      726295 : }
    1159             : 
    1160             : /* Free a block to the metadata file's reservation. */
    1161             : void
    1162       88578 : xfs_imeta_resv_free_extent(
    1163             :         struct xfs_inode        *ip,
    1164             :         struct xfs_trans        *tp,
    1165             :         xfs_filblks_t           len)
    1166             : {
    1167       88578 :         int64_t                 to_resv;
    1168             : 
    1169       88578 :         ASSERT(xfs_is_metadir_inode(ip));
    1170       88578 :         ASSERT(XFS_IS_DQDETACHED(ip->i_mount, ip));
    1171       88578 :         trace_xfs_imeta_resv_free_extent(ip, len);
    1172             : 
    1173       88578 :         ip->i_nblocks -= len;
    1174       88578 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
    1175             : 
    1176             :         /*
    1177             :          * Add the freed blocks back into the inode's delalloc reservation
    1178             :          * until it reaches the maximum size.  Update the ondisk fdblocks only.
    1179             :          */
    1180       88578 :         to_resv = ip->i_meta_resv_asked - (ip->i_nblocks + ip->i_delayed_blks);
    1181       88578 :         if (to_resv > 0) {
    1182       88578 :                 to_resv = min_t(int64_t, to_resv, len);
    1183       88578 :                 ip->i_delayed_blks += to_resv;
    1184       88578 :                 xfs_mod_delalloc(ip->i_mount, to_resv);
    1185       88579 :                 xfs_trans_mod_sb(tp, XFS_TRANS_SB_RES_FDBLOCKS, to_resv);
    1186       88579 :                 len -= to_resv;
    1187             :         }
    1188             : 
    1189             :         /*
    1190             :          * Everything else goes back to the filesystem, so update the in-core
    1191             :          * and on-disk counters.
    1192             :          */
    1193       88579 :         if (len)
    1194           0 :                 xfs_trans_mod_sb(tp, XFS_TRANS_SB_FDBLOCKS, len);
    1195       88579 : }
    1196             : 
    1197             : /* Release a metadata file's space reservation. */
    1198             : void
    1199      403510 : xfs_imeta_resv_free_inode(
    1200             :         struct xfs_inode        *ip)
    1201             : {
    1202      403510 :         if (!ip)
    1203             :                 return;
    1204             : 
    1205      403190 :         ASSERT(xfs_is_metadir_inode(ip));
    1206      403190 :         trace_xfs_imeta_resv_free(ip, 0);
    1207             : 
    1208      403190 :         xfs_mod_delalloc(ip->i_mount, -ip->i_delayed_blks);
    1209      403190 :         xfs_mod_fdblocks(ip->i_mount, ip->i_delayed_blks, true);
    1210      403190 :         ip->i_delayed_blks = 0;
    1211      403190 :         ip->i_meta_resv_asked = 0;
    1212             : }
    1213             : 
    1214             : /* Set up a metadata file's space reservation. */
    1215             : int
    1216      396650 : xfs_imeta_resv_init_inode(
    1217             :         struct xfs_inode        *ip,
    1218             :         xfs_filblks_t           ask)
    1219             : {
    1220      396650 :         xfs_filblks_t           hidden_space;
    1221      396650 :         xfs_filblks_t           used;
    1222      396650 :         int                     error;
    1223             : 
    1224      396650 :         if (!ip || ip->i_meta_resv_asked > 0)
    1225             :                 return 0;
    1226             : 
    1227      396290 :         ASSERT(xfs_is_metadir_inode(ip));
    1228             : 
    1229             :         /*
    1230             :          * Space taken by all other metadata btrees are accounted on-disk as
    1231             :          * used space.  We therefore only hide the space that is reserved but
    1232             :          * not used by the trees.
    1233             :          */
    1234      396290 :         used = ip->i_nblocks;
    1235      396290 :         if (used > ask)
    1236             :                 ask = used;
    1237      396290 :         hidden_space = ask - used;
    1238             : 
    1239      396290 :         error = xfs_mod_fdblocks(ip->i_mount, -(int64_t)hidden_space, true);
    1240      396290 :         if (error) {
    1241           3 :                 trace_xfs_imeta_resv_init_error(ip, error, _RET_IP_);
    1242           3 :                 return error;
    1243             :         }
    1244             : 
    1245      396287 :         xfs_mod_delalloc(ip->i_mount, hidden_space);
    1246      396287 :         ip->i_delayed_blks = hidden_space;
    1247      396287 :         ip->i_meta_resv_asked = ask;
    1248             : 
    1249      396287 :         trace_xfs_imeta_resv_init(ip, ask);
    1250      396287 :         return 0;
    1251             : }

Generated by: LCOV version 1.14