LCOV - code coverage report
Current view: top level - fs/xfs - xfs_trans_buf.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 277 298 93.0 %
Date: 2023-07-31 20:08:34 Functions: 22 23 95.7 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc.
       4             :  * All Rights Reserved.
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_log_format.h"
      11             : #include "xfs_trans_resv.h"
      12             : #include "xfs_mount.h"
      13             : #include "xfs_trans.h"
      14             : #include "xfs_buf_item.h"
      15             : #include "xfs_trans_priv.h"
      16             : #include "xfs_trace.h"
      17             : 
      18             : /*
      19             :  * Check to see if a buffer matching the given parameters is already
      20             :  * a part of the given transaction.
      21             :  */
      22             : STATIC struct xfs_buf *
      23 36721925601 : xfs_trans_buf_item_match(
      24             :         struct xfs_trans        *tp,
      25             :         struct xfs_buftarg      *target,
      26             :         struct xfs_buf_map      *map,
      27             :         int                     nmaps)
      28             : {
      29 36721925601 :         struct xfs_log_item     *lip;
      30 36721925601 :         struct xfs_buf_log_item *blip;
      31 36721925601 :         int                     len = 0;
      32 36721925601 :         int                     i;
      33             : 
      34 73434706324 :         for (i = 0; i < nmaps; i++)
      35 36712780723 :                 len += map[i].bm_len;
      36             : 
      37 >15722*10^7 :         list_for_each_entry(lip, &tp->t_items, li_trans) {
      38 >12206*10^7 :                 blip = (struct xfs_buf_log_item *)lip;
      39 >12206*10^7 :                 if (blip->bli_item.li_type == XFS_LI_BUF &&
      40 98630671852 :                     blip->bli_buf->b_target == target &&
      41 88869010566 :                     xfs_buf_daddr(blip->bli_buf) == map[0].bm_bn &&
      42  1557276663 :                     blip->bli_buf->b_length == len) {
      43  1557260941 :                         ASSERT(blip->bli_buf->b_map_count == nmaps);
      44  1557260941 :                         return blip->bli_buf;
      45             :                 }
      46             :         }
      47             : 
      48             :         return NULL;
      49             : }
      50             : 
      51             : /*
      52             :  * Add the locked buffer to the transaction.
      53             :  *
      54             :  * The buffer must be locked, and it cannot be associated with any
      55             :  * transaction.
      56             :  *
      57             :  * If the buffer does not yet have a buf log item associated with it,
      58             :  * then allocate one for it.  Then add the buf item to the transaction.
      59             :  */
      60             : STATIC void
      61 35185304143 : _xfs_trans_bjoin(
      62             :         struct xfs_trans        *tp,
      63             :         struct xfs_buf          *bp,
      64             :         int                     reset_recur)
      65             : {
      66 35185304143 :         struct xfs_buf_log_item *bip;
      67             : 
      68 35185304143 :         ASSERT(bp->b_transp == NULL);
      69             : 
      70             :         /*
      71             :          * The xfs_buf_log_item pointer is stored in b_log_item.  If
      72             :          * it doesn't have one yet, then allocate one and initialize it.
      73             :          * The checks to see if one is there are in xfs_buf_item_init().
      74             :          */
      75 35185304143 :         xfs_buf_item_init(bp, tp->t_mountp);
      76 35205078688 :         bip = bp->b_log_item;
      77 35205078688 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
      78 35205078688 :         ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
      79 35205078688 :         ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
      80 35205078688 :         if (reset_recur)
      81 35184281669 :                 bip->bli_recur = 0;
      82             : 
      83             :         /*
      84             :          * Take a reference for this transaction on the buf item.
      85             :          */
      86 35205078688 :         atomic_inc(&bip->bli_refcount);
      87             : 
      88             :         /*
      89             :          * Attach the item to the transaction so we can find it in
      90             :          * xfs_trans_get_buf() and friends.
      91             :          */
      92 35226675764 :         xfs_trans_add_item(tp, &bip->bli_item);
      93 35193791656 :         bp->b_transp = tp;
      94             : 
      95 35193791656 : }
      96             : 
      97             : void
      98    16666526 : xfs_trans_bjoin(
      99             :         struct xfs_trans        *tp,
     100             :         struct xfs_buf          *bp)
     101             : {
     102    16666526 :         _xfs_trans_bjoin(tp, bp, 0);
     103    16672669 :         trace_xfs_trans_bjoin(bp->b_log_item);
     104    16670860 : }
     105             : 
     106             : /*
     107             :  * Get and lock the buffer for the caller if it is not already
     108             :  * locked within the given transaction.  If it is already locked
     109             :  * within the transaction, just increment its lock recursion count
     110             :  * and return a pointer to it.
     111             :  *
     112             :  * If the transaction pointer is NULL, make this just a normal
     113             :  * get_buf() call.
     114             :  */
     115             : int
     116    82565888 : xfs_trans_get_buf_map(
     117             :         struct xfs_trans        *tp,
     118             :         struct xfs_buftarg      *target,
     119             :         struct xfs_buf_map      *map,
     120             :         int                     nmaps,
     121             :         xfs_buf_flags_t         flags,
     122             :         struct xfs_buf          **bpp)
     123             : {
     124    82565888 :         struct xfs_buf          *bp;
     125    82565888 :         struct xfs_buf_log_item *bip;
     126    82565888 :         int                     error;
     127             : 
     128    82565888 :         *bpp = NULL;
     129    82565888 :         if (!tp)
     130     2564262 :                 return xfs_buf_get_map(target, map, nmaps, flags, bpp);
     131             : 
     132             :         /*
     133             :          * If we find the buffer in the cache with this transaction
     134             :          * pointer in its b_fsprivate2 field, then we know we already
     135             :          * have it locked.  In this case we just increment the lock
     136             :          * recursion count and return the buffer to the caller.
     137             :          */
     138    80001626 :         bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
     139    80057608 :         if (bp != NULL) {
     140      366162 :                 ASSERT(xfs_buf_islocked(bp));
     141      732324 :                 if (xfs_is_shutdown(tp->t_mountp)) {
     142           0 :                         xfs_buf_stale(bp);
     143           0 :                         bp->b_flags |= XBF_DONE;
     144             :                 }
     145             : 
     146      366162 :                 ASSERT(bp->b_transp == tp);
     147      366162 :                 bip = bp->b_log_item;
     148      366162 :                 ASSERT(bip != NULL);
     149      366162 :                 ASSERT(atomic_read(&bip->bli_refcount) > 0);
     150      366162 :                 bip->bli_recur++;
     151      366162 :                 trace_xfs_trans_get_buf_recur(bip);
     152      366100 :                 *bpp = bp;
     153      366100 :                 return 0;
     154             :         }
     155             : 
     156    79691446 :         error = xfs_buf_get_map(target, map, nmaps, flags, &bp);
     157    79696639 :         if (error)
     158             :                 return error;
     159             : 
     160    79696639 :         ASSERT(!bp->b_error);
     161             : 
     162    79696639 :         _xfs_trans_bjoin(tp, bp, 1);
     163    79814240 :         trace_xfs_trans_get_buf(bp->b_log_item);
     164    79788964 :         *bpp = bp;
     165    79788964 :         return 0;
     166             : }
     167             : 
     168             : /*
     169             :  * Get and lock the superblock buffer for the given transaction.
     170             :  */
     171             : static struct xfs_buf *
     172    20306373 : __xfs_trans_getsb(
     173             :         struct xfs_trans        *tp,
     174             :         struct xfs_buf          *bp)
     175             : {
     176             :         /*
     177             :          * Just increment the lock recursion count if the buffer is already
     178             :          * attached to this transaction.
     179             :          */
     180    20306373 :         if (bp->b_transp == tp) {
     181        5172 :                 struct xfs_buf_log_item *bip = bp->b_log_item;
     182             : 
     183        5172 :                 ASSERT(bip != NULL);
     184        5172 :                 ASSERT(atomic_read(&bip->bli_refcount) > 0);
     185        5172 :                 bip->bli_recur++;
     186             : 
     187        5172 :                 trace_xfs_trans_getsb_recur(bip);
     188             :         } else {
     189    20301201 :                 xfs_buf_lock(bp);
     190    20301201 :                 xfs_buf_hold(bp);
     191    20301201 :                 _xfs_trans_bjoin(tp, bp, 1);
     192             : 
     193    20301201 :                 trace_xfs_trans_getsb(bp->b_log_item);
     194             :         }
     195             : 
     196    20306373 :         return bp;
     197             : }
     198             : 
     199             : struct xfs_buf *
     200    20098330 : xfs_trans_getsb(
     201             :         struct xfs_trans        *tp)
     202             : {
     203    20098330 :         return __xfs_trans_getsb(tp, tp->t_mountp->m_sb_bp);
     204             : }
     205             : 
     206             : struct xfs_buf *
     207      471713 : xfs_trans_getrtsb(
     208             :         struct xfs_trans        *tp)
     209             : {
     210      471713 :         if (!tp->t_mountp->m_rtsb_bp)
     211             :                 return NULL;
     212      208043 :         return __xfs_trans_getsb(tp, tp->t_mountp->m_rtsb_bp);
     213             : }
     214             : 
     215             : /*
     216             :  * Get and lock the buffer for the caller if it is not already
     217             :  * locked within the given transaction.  If it has not yet been
     218             :  * read in, read it from disk. If it is already locked
     219             :  * within the transaction and already read in, just increment its
     220             :  * lock recursion count and return a pointer to it.
     221             :  *
     222             :  * If the transaction pointer is NULL, make this just a normal
     223             :  * read_buf() call.
     224             :  */
     225             : int
     226 38459844498 : xfs_trans_read_buf_map(
     227             :         struct xfs_mount        *mp,
     228             :         struct xfs_trans        *tp,
     229             :         struct xfs_buftarg      *target,
     230             :         struct xfs_buf_map      *map,
     231             :         int                     nmaps,
     232             :         xfs_buf_flags_t         flags,
     233             :         struct xfs_buf          **bpp,
     234             :         const struct xfs_buf_ops *ops)
     235             : {
     236 38459844498 :         struct xfs_buf          *bp = NULL;
     237 38459844498 :         struct xfs_buf_log_item *bip;
     238 38459844498 :         int                     error;
     239             : 
     240 38459844498 :         *bpp = NULL;
     241             :         /*
     242             :          * If we find the buffer in the cache with this transaction
     243             :          * pointer in its b_fsprivate2 field, then we know we already
     244             :          * have it locked.  If it is already read in we just increment
     245             :          * the lock recursion count and return the buffer to the caller.
     246             :          * If the buffer is not yet read in, then we read it in, increment
     247             :          * the lock recursion count, and return it to the caller.
     248             :          */
     249 38459844498 :         if (tp)
     250 36652626458 :                 bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
     251 38456200045 :         if (bp) {
     252  1556443537 :                 ASSERT(xfs_buf_islocked(bp));
     253  1556443537 :                 ASSERT(bp->b_transp == tp);
     254  1556443537 :                 ASSERT(bp->b_log_item != NULL);
     255  1556443537 :                 ASSERT(!bp->b_error);
     256  1556443537 :                 ASSERT(bp->b_flags & XBF_DONE);
     257             : 
     258             :                 /*
     259             :                  * We never locked this buf ourselves, so we shouldn't
     260             :                  * brelse it either. Just get out.
     261             :                  */
     262  3112887074 :                 if (xfs_is_shutdown(mp)) {
     263         197 :                         trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
     264         197 :                         return -EIO;
     265             :                 }
     266             : 
     267             :                 /*
     268             :                  * Check if the caller is trying to read a buffer that is
     269             :                  * already attached to the transaction yet has no buffer ops
     270             :                  * assigned.  Ops are usually attached when the buffer is
     271             :                  * attached to the transaction, or by the read caller if
     272             :                  * special circumstances.  That didn't happen, which is not
     273             :                  * how this is supposed to go.
     274             :                  *
     275             :                  * If the buffer passes verification we'll let this go, but if
     276             :                  * not we have to shut down.  Let the transaction cleanup code
     277             :                  * release this buffer when it kills the tranaction.
     278             :                  */
     279  1556443340 :                 ASSERT(bp->b_ops != NULL);
     280  1556443340 :                 error = xfs_buf_reverify(bp, ops);
     281  1555953251 :                 if (error) {
     282           0 :                         xfs_buf_ioerror_alert(bp, __return_address);
     283             : 
     284           0 :                         if (tp->t_flags & XFS_TRANS_DIRTY)
     285           0 :                                 xfs_force_shutdown(tp->t_mountp,
     286             :                                                 SHUTDOWN_META_IO_ERROR);
     287             : 
     288             :                         /* bad CRC means corrupted metadata */
     289           0 :                         if (error == -EFSBADCRC)
     290           0 :                                 error = -EFSCORRUPTED;
     291           0 :                         return error;
     292             :                 }
     293             : 
     294  1555953251 :                 bip = bp->b_log_item;
     295  1555953251 :                 bip->bli_recur++;
     296             : 
     297  1555953251 :                 ASSERT(atomic_read(&bip->bli_refcount) > 0);
     298  1555953251 :                 trace_xfs_trans_read_buf_recur(bip);
     299  1555584293 :                 ASSERT(bp->b_ops != NULL || ops == NULL);
     300  1555584293 :                 *bpp = bp;
     301  1555584293 :                 return 0;
     302             :         }
     303             : 
     304 36899756508 :         error = xfs_buf_read_map(target, map, nmaps, flags, &bp, ops,
     305             :                         __return_address);
     306 36886133542 :         switch (error) {
     307             :         case 0:
     308 36878079238 :                 break;
     309       36355 :         default:
     310       36355 :                 if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
     311        2086 :                         xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
     312             :                 fallthrough;
     313             :         case -ENOMEM:
     314             :         case -EAGAIN:
     315             :                 return error;
     316             :         }
     317             : 
     318 73756158476 :         if (xfs_is_shutdown(mp)) {
     319     1584951 :                 xfs_buf_relse(bp);
     320     1584951 :                 trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
     321     1584951 :                 return -EIO;
     322             :         }
     323             : 
     324 36876494287 :         if (tp) {
     325 35071600340 :                 _xfs_trans_bjoin(tp, bp, 1);
     326 35075294550 :                 trace_xfs_trans_read_buf(bp->b_log_item);
     327             :         }
     328 36878125916 :         ASSERT(bp->b_ops != NULL || ops == NULL);
     329 36878125916 :         *bpp = bp;
     330 36878125916 :         return 0;
     331             : 
     332             : }
     333             : 
     334             : /* Has this buffer been dirtied by anyone? */
     335             : bool
     336           0 : xfs_trans_buf_is_dirty(
     337             :         struct xfs_buf          *bp)
     338             : {
     339           0 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     340             : 
     341           0 :         if (!bip)
     342             :                 return false;
     343           0 :         ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
     344           0 :         return test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
     345             : }
     346             : 
     347             : /*
     348             :  * Release a buffer previously joined to the transaction. If the buffer is
     349             :  * modified within this transaction, decrement the recursion count but do not
     350             :  * release the buffer even if the count goes to 0. If the buffer is not modified
     351             :  * within the transaction, decrement the recursion count and release the buffer
     352             :  * if the recursion count goes to 0.
     353             :  *
     354             :  * If the buffer is to be released and it was not already dirty before this
     355             :  * transaction began, then also free the buf_log_item associated with it.
     356             :  *
     357             :  * If the transaction pointer is NULL, this is a normal xfs_buf_relse() call.
     358             :  */
     359             : void
     360 35822288380 : xfs_trans_brelse(
     361             :         struct xfs_trans        *tp,
     362             :         struct xfs_buf          *bp)
     363             : {
     364 35822288380 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     365             : 
     366 35822288380 :         ASSERT(bp->b_transp == tp);
     367             : 
     368 35822288380 :         if (!tp) {
     369  1731499709 :                 xfs_buf_relse(bp);
     370  1731507127 :                 return;
     371             :         }
     372             : 
     373 34090788671 :         trace_xfs_trans_brelse(bip);
     374 34090737803 :         ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
     375 34090737803 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     376             : 
     377             :         /*
     378             :          * If the release is for a recursive lookup, then decrement the count
     379             :          * and return.
     380             :          */
     381 34090737803 :         if (bip->bli_recur > 0) {
     382  1394911326 :                 bip->bli_recur--;
     383  1394911326 :                 return;
     384             :         }
     385             : 
     386             :         /*
     387             :          * If the buffer is invalidated or dirty in this transaction, we can't
     388             :          * release it until we commit.
     389             :          */
     390 65391652954 :         if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags))
     391             :                 return;
     392 29347885765 :         if (bip->bli_flags & XFS_BLI_STALE)
     393             :                 return;
     394             : 
     395             :         /*
     396             :          * Unlink the log item from the transaction and clear the hold flag, if
     397             :          * set. We wouldn't want the next user of the buffer to get confused.
     398             :          */
     399 29347885765 :         ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
     400 29347885765 :         xfs_trans_del_item(&bip->bli_item);
     401 29366550297 :         bip->bli_flags &= ~XFS_BLI_HOLD;
     402             : 
     403             :         /* drop the reference to the bli */
     404 29366550297 :         xfs_buf_item_put(bip);
     405             : 
     406 29366933114 :         bp->b_transp = NULL;
     407 29366933114 :         xfs_buf_relse(bp);
     408             : }
     409             : 
     410             : /*
     411             :  * Forcibly detach a buffer previously joined to the transaction.  The caller
     412             :  * will retain its locked reference to the buffer after this function returns.
     413             :  * The buffer must be completely clean and must not be held to the transaction.
     414             :  */
     415             : void
     416  1044302061 : xfs_trans_bdetach(
     417             :         struct xfs_trans        *tp,
     418             :         struct xfs_buf          *bp)
     419             : {
     420  1044302061 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     421             : 
     422  1044302061 :         ASSERT(tp != NULL);
     423  1044302061 :         ASSERT(bp->b_transp == tp);
     424  1044302061 :         ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
     425  1044302061 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     426             : 
     427  1044302061 :         trace_xfs_trans_bdetach(bip);
     428             : 
     429             :         /*
     430             :          * Erase all recursion count, since we're removing this buffer from the
     431             :          * transaction.
     432             :          */
     433  1044293872 :         bip->bli_recur = 0;
     434             : 
     435             :         /*
     436             :          * The buffer must be completely clean.  Specifically, it had better
     437             :          * not be dirty, stale, logged, ordered, or held to the transaction.
     438             :          */
     439  1044293872 :         ASSERT(!test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
     440  1044293872 :         ASSERT(!(bip->bli_flags & XFS_BLI_DIRTY));
     441  1044293872 :         ASSERT(!(bip->bli_flags & XFS_BLI_HOLD));
     442  1044293872 :         ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
     443  1044293872 :         ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
     444  1044293872 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
     445             : 
     446             :         /* Unlink the log item from the transaction and drop the log item. */
     447  1044293872 :         xfs_trans_del_item(&bip->bli_item);
     448  1044296543 :         xfs_buf_item_put(bip);
     449  1044291632 :         bp->b_transp = NULL;
     450  1044291632 : }
     451             : 
     452             : /*
     453             :  * Mark the buffer as not needing to be unlocked when the buf item's
     454             :  * iop_committing() routine is called.  The buffer must already be locked
     455             :  * and associated with the given transaction.
     456             :  */
     457             : /* ARGSUSED */
     458             : void
     459    19172457 : xfs_trans_bhold(
     460             :         xfs_trans_t             *tp,
     461             :         struct xfs_buf          *bp)
     462             : {
     463    19172457 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     464             : 
     465    19172457 :         ASSERT(bp->b_transp == tp);
     466    19172457 :         ASSERT(bip != NULL);
     467    19172457 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
     468    19172457 :         ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
     469    19172457 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     470             : 
     471    19172457 :         bip->bli_flags |= XFS_BLI_HOLD;
     472    19172457 :         trace_xfs_trans_bhold(bip);
     473    19170892 : }
     474             : 
     475             : /*
     476             :  * Cancel the previous buffer hold request made on this buffer
     477             :  * for this transaction.
     478             :  */
     479             : void
     480     1700681 : xfs_trans_bhold_release(
     481             :         xfs_trans_t             *tp,
     482             :         struct xfs_buf          *bp)
     483             : {
     484     1700681 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     485             : 
     486     1700681 :         ASSERT(bp->b_transp == tp);
     487     1700681 :         ASSERT(bip != NULL);
     488     1700681 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
     489     1700681 :         ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
     490     1700681 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     491     1700681 :         ASSERT(bip->bli_flags & XFS_BLI_HOLD);
     492             : 
     493     1700681 :         bip->bli_flags &= ~XFS_BLI_HOLD;
     494     1700681 :         trace_xfs_trans_bhold_release(bip);
     495     1700154 : }
     496             : 
     497             : /*
     498             :  * Mark a buffer dirty in the transaction.
     499             :  */
     500             : void
     501 10421397410 : xfs_trans_dirty_buf(
     502             :         struct xfs_trans        *tp,
     503             :         struct xfs_buf          *bp)
     504             : {
     505 10421397410 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     506             : 
     507 10421397410 :         ASSERT(bp->b_transp == tp);
     508 10421397410 :         ASSERT(bip != NULL);
     509             : 
     510             :         /*
     511             :          * Mark the buffer as needing to be written out eventually,
     512             :          * and set its iodone function to remove the buffer's buf log
     513             :          * item from the AIL and free it when the buffer is flushed
     514             :          * to disk.
     515             :          */
     516 10421397410 :         bp->b_flags |= XBF_DONE;
     517             : 
     518 10421397410 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     519             : 
     520             :         /*
     521             :          * If we invalidated the buffer within this transaction, then
     522             :          * cancel the invalidation now that we're dirtying the buffer
     523             :          * again.  There are no races with the code in xfs_buf_item_unpin(),
     524             :          * because we have a reference to the buffer this entire time.
     525             :          */
     526 10421397410 :         if (bip->bli_flags & XFS_BLI_STALE) {
     527           3 :                 bip->bli_flags &= ~XFS_BLI_STALE;
     528           3 :                 ASSERT(bp->b_flags & XBF_STALE);
     529           3 :                 bp->b_flags &= ~XBF_STALE;
     530           3 :                 bip->__bli_format.blf_flags &= ~XFS_BLF_CANCEL;
     531             :         }
     532 10421397410 :         bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED;
     533             : 
     534 10421397410 :         tp->t_flags |= XFS_TRANS_DIRTY;
     535 10421397410 :         set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
     536 10430730800 : }
     537             : 
     538             : /*
     539             :  * This is called to mark bytes first through last inclusive of the given
     540             :  * buffer as needing to be logged when the transaction is committed.
     541             :  * The buffer must already be associated with the given transaction.
     542             :  *
     543             :  * First and last are numbers relative to the beginning of this buffer,
     544             :  * so the first byte in the buffer is numbered 0 regardless of the
     545             :  * value of b_blkno.
     546             :  */
     547             : void
     548 10410053856 : xfs_trans_log_buf(
     549             :         struct xfs_trans        *tp,
     550             :         struct xfs_buf          *bp,
     551             :         uint                    first,
     552             :         uint                    last)
     553             : {
     554 10410053856 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     555             : 
     556 10410053856 :         ASSERT(first <= last && last < BBTOB(bp->b_length));
     557 10410053856 :         ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
     558             : 
     559 10410053856 :         xfs_trans_dirty_buf(tp, bp);
     560             : 
     561 10418492419 :         trace_xfs_trans_log_buf(bip);
     562 10417794566 :         xfs_buf_item_log(bip, first, last);
     563 10415042176 : }
     564             : 
     565             : 
     566             : /*
     567             :  * Invalidate a buffer that is being used within a transaction.
     568             :  *
     569             :  * Typically this is because the blocks in the buffer are being freed, so we
     570             :  * need to prevent it from being written out when we're done.  Allowing it
     571             :  * to be written again might overwrite data in the free blocks if they are
     572             :  * reallocated to a file.
     573             :  *
     574             :  * We prevent the buffer from being written out by marking it stale.  We can't
     575             :  * get rid of the buf log item at this point because the buffer may still be
     576             :  * pinned by another transaction.  If that is the case, then we'll wait until
     577             :  * the buffer is committed to disk for the last time (we can tell by the ref
     578             :  * count) and free it in xfs_buf_item_unpin().  Until that happens we will
     579             :  * keep the buffer locked so that the buffer and buf log item are not reused.
     580             :  *
     581             :  * We also set the XFS_BLF_CANCEL flag in the buf log format structure and log
     582             :  * the buf item.  This will be used at recovery time to determine that copies
     583             :  * of the buffer in the log before this should not be replayed.
     584             :  *
     585             :  * We mark the item descriptor and the transaction dirty so that we'll hold
     586             :  * the buffer until after the commit.
     587             :  *
     588             :  * Since we're invalidating the buffer, we also clear the state about which
     589             :  * parts of the buffer have been logged.  We also clear the flag indicating
     590             :  * that this is an inode buffer since the data in the buffer will no longer
     591             :  * be valid.
     592             :  *
     593             :  * We set the stale bit in the buffer as well since we're getting rid of it.
     594             :  */
     595             : void
     596    39892959 : xfs_trans_binval(
     597             :         xfs_trans_t             *tp,
     598             :         struct xfs_buf          *bp)
     599             : {
     600    39892959 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     601    39892959 :         int                     i;
     602             : 
     603    39892959 :         ASSERT(bp->b_transp == tp);
     604    39892959 :         ASSERT(bip != NULL);
     605    39892959 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     606             : 
     607    39892959 :         trace_xfs_trans_binval(bip);
     608             : 
     609    39884601 :         if (bip->bli_flags & XFS_BLI_STALE) {
     610             :                 /*
     611             :                  * If the buffer is already invalidated, then
     612             :                  * just return.
     613             :                  */
     614           0 :                 ASSERT(bp->b_flags & XBF_STALE);
     615           0 :                 ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
     616           0 :                 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_INODE_BUF));
     617           0 :                 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLFT_MASK));
     618           0 :                 ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
     619           0 :                 ASSERT(test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
     620           0 :                 ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
     621           0 :                 return;
     622             :         }
     623             : 
     624    39884601 :         xfs_buf_stale(bp);
     625             : 
     626    39954037 :         bip->bli_flags |= XFS_BLI_STALE;
     627    39954037 :         bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY);
     628    39954037 :         bip->__bli_format.blf_flags &= ~XFS_BLF_INODE_BUF;
     629    39954037 :         bip->__bli_format.blf_flags |= XFS_BLF_CANCEL;
     630    39954037 :         bip->__bli_format.blf_flags &= ~XFS_BLFT_MASK;
     631    79903947 :         for (i = 0; i < bip->bli_format_count; i++) {
     632    79915115 :                 memset(bip->bli_formats[i].blf_data_map, 0,
     633             :                        (bip->bli_formats[i].blf_map_size * sizeof(uint)));
     634             :         }
     635    39938742 :         set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
     636    39961136 :         tp->t_flags |= XFS_TRANS_DIRTY;
     637             : }
     638             : 
     639             : /*
     640             :  * This call is used to indicate that the buffer contains on-disk inodes which
     641             :  * must be handled specially during recovery.  They require special handling
     642             :  * because only the di_next_unlinked from the inodes in the buffer should be
     643             :  * recovered.  The rest of the data in the buffer is logged via the inodes
     644             :  * themselves.
     645             :  *
     646             :  * All we do is set the XFS_BLI_INODE_BUF flag in the items flags so it can be
     647             :  * transferred to the buffer's log format structure so that we'll know what to
     648             :  * do at recovery time.
     649             :  */
     650             : void
     651    58781488 : xfs_trans_inode_buf(
     652             :         xfs_trans_t             *tp,
     653             :         struct xfs_buf          *bp)
     654             : {
     655    58781488 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     656             : 
     657    58781488 :         ASSERT(bp->b_transp == tp);
     658    58781488 :         ASSERT(bip != NULL);
     659    58781488 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     660             : 
     661    58781488 :         bip->bli_flags |= XFS_BLI_INODE_BUF;
     662    58781488 :         bp->b_flags |= _XBF_INODES;
     663    58781488 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
     664    58508347 : }
     665             : 
     666             : /*
     667             :  * This call is used to indicate that the buffer is going to
     668             :  * be staled and was an inode buffer. This means it gets
     669             :  * special processing during unpin - where any inodes
     670             :  * associated with the buffer should be removed from ail.
     671             :  * There is also special processing during recovery,
     672             :  * any replay of the inodes in the buffer needs to be
     673             :  * prevented as the buffer may have been reused.
     674             :  */
     675             : void
     676      660338 : xfs_trans_stale_inode_buf(
     677             :         xfs_trans_t             *tp,
     678             :         struct xfs_buf          *bp)
     679             : {
     680      660338 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     681             : 
     682      660338 :         ASSERT(bp->b_transp == tp);
     683      660338 :         ASSERT(bip != NULL);
     684      660338 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     685             : 
     686      660338 :         bip->bli_flags |= XFS_BLI_STALE_INODE;
     687      660338 :         bp->b_flags |= _XBF_INODES;
     688      660338 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
     689      660329 : }
     690             : 
     691             : /*
     692             :  * Mark the buffer as being one which contains newly allocated
     693             :  * inodes.  We need to make sure that even if this buffer is
     694             :  * relogged as an 'inode buf' we still recover all of the inode
     695             :  * images in the face of a crash.  This works in coordination with
     696             :  * xfs_buf_item_committed() to ensure that the buffer remains in the
     697             :  * AIL at its original location even after it has been relogged.
     698             :  */
     699             : /* ARGSUSED */
     700             : void
     701     2199871 : xfs_trans_inode_alloc_buf(
     702             :         xfs_trans_t             *tp,
     703             :         struct xfs_buf          *bp)
     704             : {
     705     2199871 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     706             : 
     707     2199871 :         ASSERT(bp->b_transp == tp);
     708     2199871 :         ASSERT(bip != NULL);
     709     2199871 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     710             : 
     711     2199871 :         bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
     712     2199871 :         bp->b_flags |= _XBF_INODES;
     713     2199871 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
     714     2199825 : }
     715             : 
     716             : /*
     717             :  * Mark the buffer as ordered for this transaction. This means that the contents
     718             :  * of the buffer are not recorded in the transaction but it is tracked in the
     719             :  * AIL as though it was. This allows us to record logical changes in
     720             :  * transactions rather than the physical changes we make to the buffer without
     721             :  * changing writeback ordering constraints of metadata buffers.
     722             :  */
     723             : bool
     724     2613391 : xfs_trans_ordered_buf(
     725             :         struct xfs_trans        *tp,
     726             :         struct xfs_buf          *bp)
     727             : {
     728     2613391 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     729             : 
     730     2613391 :         ASSERT(bp->b_transp == tp);
     731     2613391 :         ASSERT(bip != NULL);
     732     2613391 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     733             : 
     734     2613391 :         if (xfs_buf_item_dirty_format(bip))
     735             :                 return false;
     736             : 
     737     2611848 :         bip->bli_flags |= XFS_BLI_ORDERED;
     738     2611848 :         trace_xfs_buf_item_ordered(bip);
     739             : 
     740             :         /*
     741             :          * We don't log a dirty range of an ordered buffer but it still needs
     742             :          * to be marked dirty and that it has been logged.
     743             :          */
     744     2611727 :         xfs_trans_dirty_buf(tp, bp);
     745     2611727 :         return true;
     746             : }
     747             : 
     748             : /*
     749             :  * Set the type of the buffer for log recovery so that it can correctly identify
     750             :  * and hence attach the correct buffer ops to the buffer after replay.
     751             :  */
     752             : void
     753 18563260329 : xfs_trans_buf_set_type(
     754             :         struct xfs_trans        *tp,
     755             :         struct xfs_buf          *bp,
     756             :         enum xfs_blft           type)
     757             : {
     758 18563260329 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     759             : 
     760 18563260329 :         if (!tp)
     761             :                 return;
     762             : 
     763 18182593761 :         ASSERT(bp->b_transp == tp);
     764 18182593761 :         ASSERT(bip != NULL);
     765 18182593761 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     766             : 
     767 18182593761 :         xfs_blft_to_flags(&bip->__bli_format, type);
     768             : }
     769             : 
     770             : void
     771       17340 : xfs_trans_buf_copy_type(
     772             :         struct xfs_buf          *dst_bp,
     773             :         struct xfs_buf          *src_bp)
     774             : {
     775       17340 :         struct xfs_buf_log_item *sbip = src_bp->b_log_item;
     776       17340 :         struct xfs_buf_log_item *dbip = dst_bp->b_log_item;
     777       17340 :         enum xfs_blft           type;
     778             : 
     779       17340 :         type = xfs_blft_from_flags(&sbip->__bli_format);
     780       17340 :         xfs_blft_to_flags(&dbip->__bli_format, type);
     781       17340 : }
     782             : 
     783             : /*
     784             :  * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of
     785             :  * dquots. However, unlike in inode buffer recovery, dquot buffers get
     786             :  * recovered in their entirety. (Hence, no XFS_BLI_DQUOT_ALLOC_BUF flag).
     787             :  * The only thing that makes dquot buffers different from regular
     788             :  * buffers is that we must not replay dquot bufs when recovering
     789             :  * if a _corresponding_ quotaoff has happened. We also have to distinguish
     790             :  * between usr dquot bufs and grp dquot bufs, because usr and grp quotas
     791             :  * can be turned off independently.
     792             :  */
     793             : /* ARGSUSED */
     794             : void
     795     6017273 : xfs_trans_dquot_buf(
     796             :         xfs_trans_t             *tp,
     797             :         struct xfs_buf          *bp,
     798             :         uint                    type)
     799             : {
     800     6017273 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     801             : 
     802     6017273 :         ASSERT(type == XFS_BLF_UDQUOT_BUF ||
     803             :                type == XFS_BLF_PDQUOT_BUF ||
     804             :                type == XFS_BLF_GDQUOT_BUF);
     805             : 
     806     6017273 :         bip->__bli_format.blf_flags |= type;
     807             : 
     808     6017273 :         switch (type) {
     809             :         case XFS_BLF_UDQUOT_BUF:
     810             :                 type = XFS_BLFT_UDQUOT_BUF;
     811             :                 break;
     812             :         case XFS_BLF_PDQUOT_BUF:
     813             :                 type = XFS_BLFT_PDQUOT_BUF;
     814             :                 break;
     815             :         case XFS_BLF_GDQUOT_BUF:
     816             :                 type = XFS_BLFT_GDQUOT_BUF;
     817             :                 break;
     818             :         default:
     819             :                 type = XFS_BLFT_UNKNOWN_BUF;
     820             :                 break;
     821             :         }
     822             : 
     823     6017273 :         bp->b_flags |= _XBF_DQUOTS;
     824     6017273 :         xfs_trans_buf_set_type(tp, bp, type);
     825     6017927 : }

Generated by: LCOV version 1.14