LCOV - code coverage report
Current view: top level - fs/xfs/libxfs - xfs_inode_fork.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsa @ Mon Jul 31 20:08:27 PDT 2023 Lines: 298 356 83.7 %
Date: 2023-07-31 20:08:27 Functions: 23 23 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2006 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : 
       7             : #include "xfs.h"
       8             : #include "xfs_fs.h"
       9             : #include "xfs_shared.h"
      10             : #include "xfs_format.h"
      11             : #include "xfs_log_format.h"
      12             : #include "xfs_trans_resv.h"
      13             : #include "xfs_mount.h"
      14             : #include "xfs_inode.h"
      15             : #include "xfs_trans.h"
      16             : #include "xfs_inode_item.h"
      17             : #include "xfs_btree.h"
      18             : #include "xfs_bmap_btree.h"
      19             : #include "xfs_bmap.h"
      20             : #include "xfs_error.h"
      21             : #include "xfs_trace.h"
      22             : #include "xfs_da_format.h"
      23             : #include "xfs_da_btree.h"
      24             : #include "xfs_dir2_priv.h"
      25             : #include "xfs_attr_leaf.h"
      26             : #include "xfs_types.h"
      27             : #include "xfs_errortag.h"
      28             : #include "xfs_health.h"
      29             : #include "xfs_symlink_remote.h"
      30             : #include "xfs_rtrmap_btree.h"
      31             : #include "xfs_rtrefcount_btree.h"
      32             : 
      33             : struct kmem_cache *xfs_ifork_cache;
      34             : 
      35             : void
      36   560170369 : xfs_init_local_fork(
      37             :         struct xfs_inode        *ip,
      38             :         int                     whichfork,
      39             :         const void              *data,
      40             :         int64_t                 size)
      41             : {
      42   560170369 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
      43   560181755 :         int                     mem_size = size;
      44   560181755 :         bool                    zero_terminate;
      45             : 
      46             :         /*
      47             :          * If we are using the local fork to store a symlink body we need to
      48             :          * zero-terminate it so that we can pass it back to the VFS directly.
      49             :          * Overallocate the in-memory fork by one for that and add a zero
      50             :          * to terminate it below.
      51             :          */
      52   560181755 :         zero_terminate = S_ISLNK(VFS_I(ip)->i_mode);
      53   560181755 :         if (zero_terminate)
      54    39977293 :                 mem_size++;
      55             : 
      56   560181755 :         if (size) {
      57   560181755 :                 ifp->if_u1.if_data = kmem_alloc(mem_size, KM_NOFS);
      58  1120372466 :                 memcpy(ifp->if_u1.if_data, data, size);
      59   560186233 :                 if (zero_terminate)
      60    39977294 :                         ifp->if_u1.if_data[size] = '\0';
      61             :         } else {
      62           0 :                 ifp->if_u1.if_data = NULL;
      63             :         }
      64             : 
      65   560186233 :         ifp->if_bytes = size;
      66   560186233 : }
      67             : 
      68             : /*
      69             :  * The file is in-lined in the on-disk inode.
      70             :  */
      71             : STATIC int
      72   554502992 : xfs_iformat_local(
      73             :         struct xfs_inode        *ip,
      74             :         struct xfs_dinode       *dip,
      75             :         int                     whichfork,
      76             :         int                     size)
      77             : {
      78             :         /*
      79             :          * If the size is unreasonable, then something
      80             :          * is wrong and we just bail out rather than crash in
      81             :          * kmem_alloc() or memcpy() below.
      82             :          */
      83   554503038 :         if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
      84           0 :                 xfs_warn(ip->i_mount,
      85             :         "corrupt inode %llu (bad size %d for local fork, size = %zd).",
      86             :                         (unsigned long long) ip->i_ino, size,
      87             :                         XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
      88           0 :                 xfs_inode_verifier_error(ip, -EFSCORRUPTED,
      89             :                                 "xfs_iformat_local", dip, sizeof(*dip),
      90           0 :                                 __this_address);
      91           0 :                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
      92           0 :                 return -EFSCORRUPTED;
      93             :         }
      94             : 
      95  1109000813 :         xfs_init_local_fork(ip, whichfork, XFS_DFORK_PTR(dip, whichfork), size);
      96   554502992 :         return 0;
      97             : }
      98             : 
      99             : /*
     100             :  * The file consists of a set of extents all of which fit into the on-disk
     101             :  * inode.
     102             :  */
     103             : STATIC int
     104   184028314 : xfs_iformat_extents(
     105             :         struct xfs_inode        *ip,
     106             :         struct xfs_dinode       *dip,
     107             :         int                     whichfork)
     108             : {
     109   184028314 :         struct xfs_mount        *mp = ip->i_mount;
     110   184028314 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
     111   184024951 :         int                     state = xfs_bmap_fork_to_state(whichfork);
     112   184024951 :         xfs_extnum_t            nex = xfs_dfork_nextents(dip, whichfork);
     113   184028465 :         int                     size = nex * sizeof(xfs_bmbt_rec_t);
     114   184028465 :         struct xfs_iext_cursor  icur;
     115   184028465 :         struct xfs_bmbt_rec     *dp;
     116   184028465 :         struct xfs_bmbt_irec    new;
     117   184028465 :         int                     i;
     118             : 
     119             :         /*
     120             :          * If the number of extents is unreasonable, then something is wrong and
     121             :          * we just bail out rather than crash in kmem_alloc() or memcpy() below.
     122             :          */
     123   184028575 :         if (unlikely(size < 0 || size > XFS_DFORK_SIZE(dip, mp, whichfork))) {
     124           0 :                 xfs_warn(ip->i_mount, "corrupt inode %llu ((a)extents = %llu).",
     125             :                         ip->i_ino, nex);
     126           0 :                 xfs_inode_verifier_error(ip, -EFSCORRUPTED,
     127             :                                 "xfs_iformat_extents(1)", dip, sizeof(*dip),
     128           0 :                                 __this_address);
     129           0 :                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     130           0 :                 return -EFSCORRUPTED;
     131             :         }
     132             : 
     133   184028465 :         ifp->if_bytes = 0;
     134   184028465 :         ifp->if_u1.if_root = NULL;
     135   184028465 :         ifp->if_height = 0;
     136   184028465 :         if (size) {
     137   252345625 :                 dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork);
     138             : 
     139   126173060 :                 xfs_iext_first(ifp, &icur);
     140   675454470 :                 for (i = 0; i < nex; i++, dp++) {
     141   423108253 :                         xfs_failaddr_t  fa;
     142             : 
     143   423108253 :                         xfs_bmbt_disk_get_all(dp, &new);
     144   423105926 :                         fa = xfs_bmap_validate_extent(ip, whichfork, &new);
     145   423106888 :                         if (fa) {
     146           0 :                                 xfs_inode_verifier_error(ip, -EFSCORRUPTED,
     147             :                                                 "xfs_iformat_extents(2)",
     148             :                                                 dp, sizeof(*dp), fa);
     149           0 :                                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     150           0 :                                 return xfs_bmap_complain_bad_rec(ip, whichfork,
     151             :                                                 fa, &new);
     152             :                         }
     153             : 
     154   423106888 :                         xfs_iext_insert(ip, &icur, &new, state);
     155   423105386 :                         trace_xfs_read_extent(ip, &icur, state, _THIS_IP_);
     156   423107593 :                         xfs_iext_next(ifp, &icur);
     157             :                 }
     158             :         }
     159             :         return 0;
     160             : }
     161             : 
     162             : /*
     163             :  * The file has too many extents to fit into
     164             :  * the inode, so they are in B-tree format.
     165             :  * Allocate a buffer for the root of the B-tree
     166             :  * and copy the root into it.  The i_extents
     167             :  * field will remain NULL until all of the
     168             :  * extents are read in (when they are needed).
     169             :  */
     170             : STATIC int
     171    12629490 : xfs_iformat_btree(
     172             :         struct xfs_inode        *ip,
     173             :         struct xfs_dinode       *dip,
     174             :         int                     whichfork)
     175             : {
     176    12629490 :         struct xfs_mount        *mp = ip->i_mount;
     177    12629490 :         xfs_bmdr_block_t        *dfp;
     178    12629490 :         struct xfs_ifork        *ifp;
     179             :         /* REFERENCED */
     180    12629490 :         int                     nrecs;
     181    12629490 :         int                     size;
     182    12629490 :         int                     level;
     183             : 
     184    12629490 :         ifp = xfs_ifork_ptr(ip, whichfork);
     185    25258983 :         dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork);
     186    12629493 :         size = xfs_bmap_broot_space(mp, dfp);
     187    12629491 :         nrecs = be16_to_cpu(dfp->bb_numrecs);
     188    12629491 :         level = be16_to_cpu(dfp->bb_level);
     189             : 
     190             :         /*
     191             :          * blow out if -- fork has less extents than can fit in
     192             :          * fork (fork shouldn't be a btree format), root btree
     193             :          * block has more records than can fit into the fork,
     194             :          * or the number of extents is greater than the number of
     195             :          * blocks.
     196             :          */
     197    25258982 :         if (unlikely(ifp->if_nextents <= XFS_IFORK_MAXEXT(ip, whichfork) ||
     198             :                      nrecs == 0 ||
     199             :                      xfs_bmdr_space_calc(nrecs) >
     200             :                                         XFS_DFORK_SIZE(dip, mp, whichfork) ||
     201    12629491 :                      ifp->if_nextents > ip->i_nblocks) ||
     202    12629491 :                      level == 0 || level > XFS_BM_MAXLEVELS(mp, whichfork)) {
     203           0 :                 xfs_warn(mp, "corrupt inode %llu (btree).",
     204             :                                         (unsigned long long) ip->i_ino);
     205           0 :                 xfs_inode_verifier_error(ip, -EFSCORRUPTED,
     206             :                                 "xfs_iformat_btree", dfp, size,
     207           0 :                                 __this_address);
     208           0 :                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     209           0 :                 return -EFSCORRUPTED;
     210             :         }
     211             : 
     212    12629491 :         xfs_iroot_alloc(ip, whichfork, size);
     213    12629493 :         ASSERT(ifp->if_broot != NULL);
     214             :         /*
     215             :          * Copy and convert from the on-disk structure
     216             :          * to the in-memory structure.
     217             :          */
     218    12629493 :         xfs_bmdr_to_bmbt(ip, dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork),
     219             :                          ifp->if_broot, size);
     220             : 
     221    12629488 :         ifp->if_bytes = 0;
     222    12629488 :         ifp->if_u1.if_root = NULL;
     223    12629488 :         ifp->if_height = 0;
     224    12629488 :         return 0;
     225             : }
     226             : 
     227             : int
     228   479347048 : xfs_iformat_data_fork(
     229             :         struct xfs_inode        *ip,
     230             :         struct xfs_dinode       *dip)
     231             : {
     232   479347048 :         struct inode            *inode = VFS_I(ip);
     233   479347048 :         int                     error;
     234             : 
     235             :         /*
     236             :          * Initialize the extent count early, as the per-format routines may
     237             :          * depend on it.  Use release semantics to set needextents /after/ we
     238             :          * set the format. This ensures that we can use acquire semantics on
     239             :          * needextents in xfs_need_iread_extents() and be guaranteed to see a
     240             :          * valid format value after that load.
     241             :          */
     242   479347048 :         ip->i_df.if_format = dip->di_format;
     243   479347048 :         ip->i_df.if_nextents = xfs_dfork_data_extents(dip);
     244   946064640 :         smp_store_release(&ip->i_df.if_needextents,
     245             :                            ip->i_df.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);
     246             : 
     247   479355909 :         switch (inode->i_mode & S_IFMT) {
     248   207418207 :         case S_IFIFO:
     249             :         case S_IFCHR:
     250             :         case S_IFBLK:
     251             :         case S_IFSOCK:
     252   207418207 :                 ip->i_disk_size = 0;
     253   207418207 :                 inode->i_rdev = xfs_to_linux_dev_t(xfs_dinode_get_rdev(dip));
     254   207418207 :                 return 0;
     255   271937702 :         case S_IFREG:
     256             :         case S_IFLNK:
     257             :         case S_IFDIR:
     258   271937702 :                 switch (ip->i_df.if_format) {
     259    76756682 :                 case XFS_DINODE_FMT_LOCAL:
     260    76756682 :                         error = xfs_iformat_local(ip, dip, XFS_DATA_FORK,
     261    76756682 :                                         be64_to_cpu(dip->di_size));
     262    76756975 :                         if (!error)
     263    76756993 :                                 error = xfs_ifork_verify_local_data(ip);
     264             :                         return error;
     265   182549149 :                 case XFS_DINODE_FMT_EXTENTS:
     266   182549149 :                         return xfs_iformat_extents(ip, dip, XFS_DATA_FORK);
     267    12629449 :                 case XFS_DINODE_FMT_BTREE:
     268    12629449 :                         return xfs_iformat_btree(ip, dip, XFS_DATA_FORK);
     269        1211 :                 case XFS_DINODE_FMT_RMAP:
     270        1211 :                         if (!xfs_has_rtrmapbt(ip->i_mount)) {
     271           0 :                                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     272           0 :                                 return -EFSCORRUPTED;
     273             :                         }
     274        1211 :                         return xfs_iformat_rtrmap(ip, dip);
     275        1211 :                 case XFS_DINODE_FMT_REFCOUNT:
     276        1211 :                         if (!xfs_has_rtreflink(ip->i_mount)) {
     277           0 :                                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     278           0 :                                 return -EFSCORRUPTED;
     279             :                         }
     280        1211 :                         return xfs_iformat_rtrefcount(ip, dip);
     281             :                 default:
     282           0 :                         xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__,
     283           0 :                                         dip, sizeof(*dip), __this_address);
     284           0 :                         xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     285           0 :                         return -EFSCORRUPTED;
     286             :                 }
     287           0 :                 break;
     288             :         default:
     289           0 :                 xfs_inode_verifier_error(ip, -EFSCORRUPTED, __func__, dip,
     290           0 :                                 sizeof(*dip), __this_address);
     291           0 :                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     292           0 :                 return -EFSCORRUPTED;
     293             :         }
     294             : }
     295             : 
     296             : static uint16_t
     297   477735737 : xfs_dfork_attr_shortform_size(
     298             :         struct xfs_dinode               *dip)
     299             : {
     300   955471474 :         struct xfs_attr_shortform       *atp =
     301   477735737 :                 (struct xfs_attr_shortform *)XFS_DFORK_APTR(dip);
     302             : 
     303   477735737 :         return be16_to_cpu(atp->hdr.totsize);
     304             : }
     305             : 
     306             : void
     307    63966178 : xfs_ifork_init_attr(
     308             :         struct xfs_inode        *ip,
     309             :         enum xfs_dinode_fmt     format,
     310             :         xfs_extnum_t            nextents)
     311             : {
     312             :         /*
     313             :          * Initialize the extent count early, as the per-format routines may
     314             :          * depend on it.  Use release semantics to set needextents /after/ we
     315             :          * set the format. This ensures that we can use acquire semantics on
     316             :          * needextents in xfs_need_iread_extents() and be guaranteed to see a
     317             :          * valid format value after that load.
     318             :          */
     319   543183905 :         ip->i_af.if_format = format;
     320   543183905 :         ip->i_af.if_nextents = nextents;
     321   607150083 :         smp_store_release(&ip->i_af.if_needextents,
     322             :                            ip->i_af.if_format == XFS_DINODE_FMT_BTREE ? 1 : 0);
     323    63967017 : }
     324             : 
     325             : void
     326   545638265 : xfs_ifork_zap_attr(
     327             :         struct xfs_inode        *ip)
     328             : {
     329   545638265 :         xfs_idestroy_fork(&ip->i_af);
     330   546378873 :         memset(&ip->i_af, 0, sizeof(struct xfs_ifork));
     331   546378873 :         ip->i_af.if_format = XFS_DINODE_FMT_EXTENTS;
     332   546378873 : }
     333             : 
     334             : int
     335   479217727 : xfs_iformat_attr_fork(
     336             :         struct xfs_inode        *ip,
     337             :         struct xfs_dinode       *dip)
     338             : {
     339   479217727 :         xfs_extnum_t            naextents = xfs_dfork_attr_extents(dip);
     340   479217727 :         int                     error = 0;
     341             : 
     342             :         /*
     343             :          * Initialize the extent count early, as the per-format routines may
     344             :          * depend on it.
     345             :          */
     346   479217727 :         xfs_ifork_init_attr(ip, dip->di_aformat, naextents);
     347             : 
     348   479228271 :         switch (ip->i_af.if_format) {
     349   477749093 :         case XFS_DINODE_FMT_LOCAL:
     350   477749093 :                 error = xfs_iformat_local(ip, dip, XFS_ATTR_FORK,
     351   477749093 :                                 xfs_dfork_attr_shortform_size(dip));
     352   477752239 :                 if (!error)
     353   477751723 :                         error = xfs_ifork_verify_local_attr(ip);
     354             :                 break;
     355     1479136 :         case XFS_DINODE_FMT_EXTENTS:
     356     1479136 :                 error = xfs_iformat_extents(ip, dip, XFS_ATTR_FORK);
     357     1479136 :                 break;
     358          42 :         case XFS_DINODE_FMT_BTREE:
     359          42 :                 error = xfs_iformat_btree(ip, dip, XFS_ATTR_FORK);
     360          42 :                 break;
     361             :         default:
     362           0 :                 xfs_inode_verifier_error(ip, error, __func__, dip,
     363           0 :                                 sizeof(*dip), __this_address);
     364           0 :                 xfs_inode_mark_sick(ip, XFS_SICK_INO_CORE);
     365           0 :                 error = -EFSCORRUPTED;
     366           0 :                 break;
     367             :         }
     368             : 
     369   479238320 :         if (error)
     370           0 :                 xfs_ifork_zap_attr(ip);
     371   479238320 :         return error;
     372             : }
     373             : 
     374             : /* Allocate a new incore ifork btree root. */
     375             : void
     376    14227459 : xfs_iroot_alloc(
     377             :         struct xfs_inode        *ip,
     378             :         int                     whichfork,
     379             :         size_t                  bytes)
     380             : {
     381    14227459 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
     382             : 
     383    14227537 :         ifp->if_broot = kmem_alloc(bytes, KM_NOFS);
     384    14227545 :         ifp->if_broot_bytes = bytes;
     385    14227545 : }
     386             : 
     387             : /* Free all the memory and state associated with an incore ifork btree root. */
     388             : void
     389      792254 : xfs_iroot_free(
     390             :         struct xfs_inode        *ip,
     391             :         int                     whichfork)
     392             : {
     393      792254 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
     394             : 
     395      792254 :         ifp->if_broot_bytes = 0;
     396      792254 :         kmem_free(ifp->if_broot);
     397      792254 :         ifp->if_broot = NULL;
     398      792254 : }
     399             : 
     400             : /*
     401             :  * Reallocate the space for if_broot based on the number of records
     402             :  * being added or deleted as indicated in rec_diff.  Move the records
     403             :  * and pointers in if_broot to fit the new size.  When shrinking this
     404             :  * will eliminate holes between the records and pointers created by
     405             :  * the caller.  When growing this will create holes to be filled in
     406             :  * by the caller.
     407             :  *
     408             :  * The caller must not request to add more records than would fit in
     409             :  * the on-disk inode root.  If the if_broot is currently NULL, then
     410             :  * if we are adding records, one will be allocated.  The caller must also
     411             :  * not request that the number of records go below zero, although
     412             :  * it can go to zero.
     413             :  */
     414             : void
     415     1196433 : xfs_iroot_realloc(
     416             :         struct xfs_inode                *ip,
     417             :         int                             whichfork,
     418             :         const struct xfs_ifork_broot_ops *ops,
     419             :         int                             rec_diff)
     420             : {
     421     1196433 :         struct xfs_mount                *mp = ip->i_mount;
     422     1196433 :         struct xfs_ifork                *ifp = xfs_ifork_ptr(ip, whichfork);
     423     1196433 :         struct xfs_btree_block          *new_broot;
     424     1196433 :         size_t                          new_size;
     425     1196433 :         size_t                          old_size = ifp->if_broot_bytes;
     426     1196433 :         unsigned int                    level;
     427     1196433 :         int                             cur_max;
     428     1196433 :         int                             new_max;
     429             : 
     430             :         /* Handle degenerate cases. */
     431     1196433 :         if (rec_diff == 0)
     432             :                 return;
     433             : 
     434             :         /*
     435             :          * If there wasn't any memory allocated before, just allocate it now
     436             :          * and get out.
     437             :          */
     438     1196433 :         if (old_size == 0) {
     439           0 :                 ASSERT(rec_diff > 0);
     440             : 
     441           0 :                 new_size = ops->size(mp, 0, rec_diff);
     442           0 :                 xfs_iroot_alloc(ip, whichfork, new_size);
     443           0 :                 return;
     444             :         }
     445             : 
     446             :         /* Compute the new and old record count and space requirements. */
     447     1196433 :         level = be16_to_cpu(ifp->if_broot->bb_level);
     448     1196433 :         cur_max = ops->maxrecs(mp, old_size, level == 0);
     449     1196433 :         new_max = cur_max + rec_diff;
     450     1196433 :         ASSERT(new_max >= 0);
     451     1196433 :         new_size = ops->size(mp, level, new_max);
     452             : 
     453     1196433 :         if (rec_diff > 0) {
     454             :                 /*
     455             :                  * If there is already an existing if_broot, then we need
     456             :                  * to realloc() it and shift the pointers to their new
     457             :                  * location.
     458             :                  */
     459      633207 :                 ifp->if_broot = krealloc(ifp->if_broot, new_size,
     460             :                                          GFP_NOFS | __GFP_NOFAIL);
     461      633207 :                 ifp->if_broot_bytes = new_size;
     462      633207 :                 ops->move(ip, whichfork, ifp->if_broot, new_size,
     463             :                                 ifp->if_broot, old_size, level, cur_max);
     464      633207 :                 return;
     465             :         }
     466             : 
     467             :         /*
     468             :          * rec_diff is less than 0.  In this case, we are shrinking the
     469             :          * if_broot buffer.  It must already exist.  If we go to zero
     470             :          * bytes, just get rid of the root and clear the status bit.
     471             :          */
     472      563226 :         if (new_size == 0) {
     473           0 :                 xfs_iroot_free(ip, whichfork);
     474           0 :                 return;
     475             :         }
     476             : 
     477             :         /* Reallocate the btree root and move the contents. */
     478      563226 :         new_broot = kmem_alloc(new_size, KM_NOFS);
     479      563226 :         ops->move(ip, whichfork, new_broot, new_size, ifp->if_broot,
     480      563226 :                         ifp->if_broot_bytes, level, new_max);
     481             : 
     482      563226 :         kmem_free(ifp->if_broot);
     483      563226 :         ifp->if_broot = new_broot;
     484      563226 :         ifp->if_broot_bytes = new_size;
     485             : }
     486             : 
     487             : /*
     488             :  * This is called when the amount of space needed for if_data
     489             :  * is increased or decreased.  The change in size is indicated by
     490             :  * the number of bytes that need to be added or deleted in the
     491             :  * byte_diff parameter.
     492             :  *
     493             :  * If the amount of space needed has decreased below the size of the
     494             :  * inline buffer, then switch to using the inline buffer.  Otherwise,
     495             :  * use kmem_realloc() or kmem_alloc() to adjust the size of the buffer
     496             :  * to what is needed.
     497             :  *
     498             :  * ip -- the inode whose if_data area is changing
     499             :  * byte_diff -- the change in the number of bytes, positive or negative,
     500             :  *       requested for the if_data array.
     501             :  */
     502             : void
     503   441372451 : xfs_idata_realloc(
     504             :         struct xfs_inode        *ip,
     505             :         int64_t                 byte_diff,
     506             :         int                     whichfork)
     507             : {
     508   441372451 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
     509   441379731 :         int64_t                 new_size = ifp->if_bytes + byte_diff;
     510             : 
     511   441379731 :         ASSERT(new_size >= 0);
     512   441379731 :         ASSERT(new_size <= xfs_inode_fork_size(ip, whichfork));
     513             : 
     514   441379731 :         if (byte_diff == 0)
     515             :                 return;
     516             : 
     517   441379731 :         if (new_size == 0) {
     518     8987603 :                 kmem_free(ifp->if_u1.if_data);
     519     8987644 :                 ifp->if_u1.if_data = NULL;
     520     8987644 :                 ifp->if_bytes = 0;
     521     8987644 :                 return;
     522             :         }
     523             : 
     524   432392128 :         ifp->if_u1.if_data = krealloc(ifp->if_u1.if_data, new_size,
     525             :                                       GFP_NOFS | __GFP_NOFAIL);
     526   432400733 :         ifp->if_bytes = new_size;
     527             : }
     528             : 
     529             : /* Free all memory and reset a fork back to its initial state. */
     530             : void
     531   937735258 : xfs_idestroy_fork(
     532             :         struct xfs_ifork        *ifp)
     533             : {
     534   937735258 :         if (ifp->if_broot != NULL) {
     535    13487362 :                 kmem_free(ifp->if_broot);
     536    13487946 :                 ifp->if_broot = NULL;
     537             :         }
     538             : 
     539   937735842 :         switch (ifp->if_format) {
     540   617235428 :         case XFS_DINODE_FMT_LOCAL:
     541   617235428 :                 kmem_free(ifp->if_u1.if_data);
     542   618665441 :                 ifp->if_u1.if_data = NULL;
     543   618665441 :                 break;
     544   320479523 :         case XFS_DINODE_FMT_EXTENTS:
     545             :         case XFS_DINODE_FMT_BTREE:
     546   320479523 :                 if (ifp->if_height)
     547   134715052 :                         xfs_iext_destroy(ifp);
     548             :                 break;
     549             :         }
     550   939265394 : }
     551             : 
     552             : /*
     553             :  * Convert in-core extents to on-disk form
     554             :  *
     555             :  * In the case of the data fork, the in-core and on-disk fork sizes can be
     556             :  * different due to delayed allocation extents. We only copy on-disk extents
     557             :  * here, so callers must always use the physical fork size to determine the
     558             :  * size of the buffer passed to this routine.  We will return the size actually
     559             :  * used.
     560             :  */
     561             : int
     562   386726338 : xfs_iextents_copy(
     563             :         struct xfs_inode        *ip,
     564             :         struct xfs_bmbt_rec     *dp,
     565             :         int                     whichfork)
     566             : {
     567   386726338 :         int                     state = xfs_bmap_fork_to_state(whichfork);
     568   386726338 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
     569   386729451 :         struct xfs_iext_cursor  icur;
     570   386729451 :         struct xfs_bmbt_irec    rec;
     571   386729451 :         int64_t                 copied = 0;
     572             : 
     573   386729451 :         ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL | XFS_ILOCK_SHARED));
     574   386730774 :         ASSERT(ifp->if_bytes > 0);
     575             : 
     576  1716250247 :         for_each_xfs_iext(ifp, &icur, &rec) {
     577  1329483893 :                 if (isnullstartblock(rec.br_startblock))
     578    16372821 :                         continue;
     579  1313111072 :                 ASSERT(xfs_bmap_validate_extent(ip, whichfork, &rec) == NULL);
     580  1313119525 :                 xfs_bmbt_disk_set_all(dp, &rec);
     581  1313140180 :                 trace_xfs_write_extent(ip, &icur, state, _RET_IP_);
     582  1313146652 :                 copied += sizeof(struct xfs_bmbt_rec);
     583  1313146652 :                 dp++;
     584             :         }
     585             : 
     586   386736676 :         ASSERT(copied > 0);
     587   386736676 :         ASSERT(copied <= ifp->if_bytes);
     588   386736676 :         return copied;
     589             : }
     590             : 
     591             : /*
     592             :  * Each of the following cases stores data into the same region
     593             :  * of the on-disk inode, so only one of them can be valid at
     594             :  * any given time. While it is possible to have conflicting formats
     595             :  * and log flags, e.g. having XFS_ILOG_?DATA set when the fork is
     596             :  * in EXTENTS format, this can only happen when the fork has
     597             :  * changed formats after being modified but before being flushed.
     598             :  * In these cases, the format always takes precedence, because the
     599             :  * format indicates the current state of the fork.
     600             :  */
     601             : void
     602   569059058 : xfs_iflush_fork(
     603             :         struct xfs_inode        *ip,
     604             :         struct xfs_dinode       *dip,
     605             :         struct xfs_inode_log_item *iip,
     606             :         int                     whichfork)
     607             : {
     608   569059058 :         char                    *cp;
     609   569059058 :         struct xfs_ifork        *ifp;
     610   569059058 :         xfs_mount_t             *mp;
     611   569059058 :         static const short      brootflag[2] =
     612             :                 { XFS_ILOG_DBROOT, XFS_ILOG_ABROOT };
     613   569059058 :         static const short      dataflag[2] =
     614             :                 { XFS_ILOG_DDATA, XFS_ILOG_ADATA };
     615   569059058 :         static const short      extflag[2] =
     616             :                 { XFS_ILOG_DEXT, XFS_ILOG_AEXT };
     617             : 
     618   569059058 :         if (!iip)
     619             :                 return;
     620   569059058 :         ifp = xfs_ifork_ptr(ip, whichfork);
     621             :         /*
     622             :          * This can happen if we gave up in iformat in an error path,
     623             :          * for the attribute fork.
     624             :          */
     625   569059058 :         if (!ifp) {
     626           0 :                 ASSERT(whichfork == XFS_ATTR_FORK);
     627           0 :                 return;
     628             :         }
     629  1138117872 :         cp = XFS_DFORK_PTR(dip, whichfork);
     630   569059058 :         mp = ip->i_mount;
     631   569059058 :         switch (ifp->if_format) {
     632   247163754 :         case XFS_DINODE_FMT_LOCAL:
     633   247163754 :                 if ((iip->ili_fields & dataflag[whichfork]) &&
     634   148786838 :                     (ifp->if_bytes > 0)) {
     635   148786838 :                         ASSERT(ifp->if_u1.if_data != NULL);
     636   148786838 :                         ASSERT(ifp->if_bytes <= xfs_inode_fork_size(ip, whichfork));
     637   297573676 :                         memcpy(cp, ifp->if_u1.if_data, ifp->if_bytes);
     638             :                 }
     639             :                 break;
     640             : 
     641   286297225 :         case XFS_DINODE_FMT_EXTENTS:
     642   286297225 :                 if ((iip->ili_fields & extflag[whichfork]) &&
     643    32422579 :                     (ifp->if_bytes > 0)) {
     644    32422579 :                         ASSERT(ifp->if_nextents > 0);
     645    32422579 :                         (void)xfs_iextents_copy(ip, (xfs_bmbt_rec_t *)cp,
     646             :                                 whichfork);
     647             :                 }
     648             :                 break;
     649             : 
     650    16242012 :         case XFS_DINODE_FMT_BTREE:
     651    16242012 :                 if ((iip->ili_fields & brootflag[whichfork]) &&
     652     1734477 :                     (ifp->if_broot_bytes > 0)) {
     653     1734477 :                         ASSERT(ifp->if_broot != NULL);
     654     1734477 :                         ASSERT(xfs_bmap_bmdr_space(ifp->if_broot) <=
     655             :                                 xfs_inode_fork_size(ip, whichfork));
     656     3468954 :                         xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes,
     657             :                                 (xfs_bmdr_block_t *)cp,
     658     1734477 :                                 XFS_DFORK_SIZE(dip, mp, whichfork));
     659             :                 }
     660             :                 break;
     661             : 
     662    19291062 :         case XFS_DINODE_FMT_DEV:
     663    19291062 :                 if (iip->ili_fields & XFS_ILOG_DEV) {
     664     8638042 :                         ASSERT(whichfork == XFS_DATA_FORK);
     665     8638042 :                         xfs_dinode_put_rdev(dip,
     666             :                                         linux_to_xfs_dev_t(VFS_I(ip)->i_rdev));
     667             :                 }
     668             :                 break;
     669             : 
     670       36728 :         case XFS_DINODE_FMT_RMAP:
     671       36728 :                 ASSERT(whichfork == XFS_DATA_FORK);
     672       36728 :                 if (iip->ili_fields & brootflag[whichfork])
     673       18095 :                         xfs_iflush_rtrmap(ip, dip);
     674             :                 break;
     675             : 
     676       28277 :         case XFS_DINODE_FMT_REFCOUNT:
     677       28277 :                 ASSERT(whichfork == XFS_DATA_FORK);
     678       28277 :                 if (iip->ili_fields & brootflag[whichfork])
     679       27922 :                         xfs_iflush_rtrefcount(ip, dip);
     680             :                 break;
     681             : 
     682           0 :         default:
     683           0 :                 ASSERT(0);
     684           0 :                 break;
     685             :         }
     686             : }
     687             : 
     688             : /* Convert bmap state flags to an inode fork. */
     689             : struct xfs_ifork *
     690  1799800349 : xfs_iext_state_to_fork(
     691             :         struct xfs_inode        *ip,
     692             :         int                     state)
     693             : {
     694  1799800349 :         if (state & BMAP_COWFORK)
     695     8527200 :                 return ip->i_cowfp;
     696  1791273149 :         else if (state & BMAP_ATTRFORK)
     697    16958324 :                 return &ip->i_af;
     698  1774314825 :         return &ip->i_df;
     699             : }
     700             : 
     701             : /*
     702             :  * Initialize an inode's copy-on-write fork.
     703             :  */
     704             : void
     705   104001173 : xfs_ifork_init_cow(
     706             :         struct xfs_inode        *ip)
     707             : {
     708   104001173 :         if (ip->i_cowfp)
     709             :                 return;
     710             : 
     711   102976068 :         ip->i_cowfp = kmem_cache_zalloc(xfs_ifork_cache,
     712             :                                        GFP_NOFS | __GFP_NOFAIL);
     713   102976336 :         ip->i_cowfp->if_format = XFS_DINODE_FMT_EXTENTS;
     714             : }
     715             : 
     716             : /* Verify the inline contents of the data fork of an inode. */
     717             : int
     718   135413994 : xfs_ifork_verify_local_data(
     719             :         struct xfs_inode        *ip)
     720             : {
     721   135413994 :         xfs_failaddr_t          fa = NULL;
     722             : 
     723   135413994 :         switch (VFS_I(ip)->i_mode & S_IFMT) {
     724   128794189 :         case S_IFDIR:
     725   128794189 :                 fa = xfs_dir2_sf_verify(ip);
     726   128794189 :                 break;
     727     6619805 :         case S_IFLNK:
     728     6619805 :                 fa = xfs_symlink_shortform_verify(ip);
     729     6619805 :                 break;
     730             :         default:
     731             :                 break;
     732             :         }
     733             : 
     734   135414713 :         if (fa) {
     735           4 :                 xfs_inode_verifier_error(ip, -EFSCORRUPTED, "data fork",
     736           4 :                                 ip->i_df.if_u1.if_data, ip->i_df.if_bytes, fa);
     737           4 :                 return -EFSCORRUPTED;
     738             :         }
     739             : 
     740             :         return 0;
     741             : }
     742             : 
     743             : /* Verify the inline contents of the attr fork of an inode. */
     744             : int
     745   666211757 : xfs_ifork_verify_local_attr(
     746             :         struct xfs_inode        *ip)
     747             : {
     748   666211757 :         struct xfs_ifork        *ifp = &ip->i_af;
     749   666211757 :         xfs_failaddr_t          fa;
     750             : 
     751   666211757 :         if (!xfs_inode_has_attr_fork(ip))
     752           0 :                 fa = __this_address;
     753             :         else
     754   666211757 :                 fa = xfs_attr_shortform_verify(ip);
     755             : 
     756   666208501 :         if (fa) {
     757           0 :                 xfs_inode_verifier_error(ip, -EFSCORRUPTED, "attr fork",
     758           0 :                                 ifp->if_u1.if_data, ifp->if_bytes, fa);
     759           0 :                 return -EFSCORRUPTED;
     760             :         }
     761             : 
     762             :         return 0;
     763             : }
     764             : 
     765             : int
     766   532117924 : xfs_iext_count_may_overflow(
     767             :         struct xfs_inode        *ip,
     768             :         int                     whichfork,
     769             :         int                     nr_to_add)
     770             : {
     771   532117924 :         struct xfs_ifork        *ifp = xfs_ifork_ptr(ip, whichfork);
     772   532140152 :         uint64_t                max_exts;
     773   532140152 :         uint64_t                nr_exts;
     774             : 
     775   532140152 :         if (whichfork == XFS_COW_FORK)
     776             :                 return 0;
     777             : 
     778   531535599 :         max_exts = xfs_iext_max_nextents(xfs_inode_has_large_extent_counts(ip),
     779             :                                 whichfork);
     780             : 
     781   531554661 :         if (XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
     782         411 :                 max_exts = 10;
     783             : 
     784   531556495 :         nr_exts = ifp->if_nextents + nr_to_add;
     785   531556495 :         if (nr_exts < ifp->if_nextents || nr_exts > max_exts)
     786          55 :                 return -EFBIG;
     787             : 
     788             :         return 0;
     789             : }
     790             : 
     791             : /*
     792             :  * Upgrade this inode's extent counter fields to be able to handle a potential
     793             :  * increase in the extent count by nr_to_add.  Normally this is the same
     794             :  * quantity that caused xfs_iext_count_may_overflow() to return -EFBIG.
     795             :  */
     796             : int
     797          55 : xfs_iext_count_upgrade(
     798             :         struct xfs_trans        *tp,
     799             :         struct xfs_inode        *ip,
     800             :         uint                    nr_to_add)
     801             : {
     802          55 :         ASSERT(nr_to_add <= XFS_MAX_EXTCNT_UPGRADE_NR);
     803             : 
     804          55 :         if (!xfs_has_large_extent_counts(ip->i_mount) ||
     805           0 :             xfs_inode_has_large_extent_counts(ip) ||
     806           0 :             XFS_TEST_ERROR(false, ip->i_mount, XFS_ERRTAG_REDUCE_MAX_IEXTENTS))
     807          55 :                 return -EFBIG;
     808             : 
     809           0 :         ip->i_diflags2 |= XFS_DIFLAG2_NREXT64;
     810           0 :         xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
     811             : 
     812           0 :         return 0;
     813             : }
     814             : 
     815             : /* Decide if a file mapping is on the realtime device or not. */
     816             : bool
     817  1563254812 : xfs_ifork_is_realtime(
     818             :         struct xfs_inode        *ip,
     819             :         int                     whichfork)
     820             : {
     821  1563254812 :         return XFS_IS_REALTIME_INODE(ip) && whichfork != XFS_ATTR_FORK;
     822             : }

Generated by: LCOV version 1.14