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-rc3-achx @ Mon Jul 31 20:08:12 PDT 2023 Lines: 273 294 92.9 %
Date: 2023-07-31 20:08:12 Functions: 20 21 95.2 %

          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 23718981736 : 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 23718981736 :         struct xfs_log_item     *lip;
      30 23718981736 :         struct xfs_buf_log_item *blip;
      31 23718981736 :         int                     len = 0;
      32 23718981736 :         int                     i;
      33             : 
      34 47433812326 :         for (i = 0; i < nmaps; i++)
      35 23714830590 :                 len += map[i].bm_len;
      36             : 
      37 >10546*10^7 :         list_for_each_entry(lip, &tp->t_items, li_trans) {
      38 82908920563 :                 blip = (struct xfs_buf_log_item *)lip;
      39 82908920563 :                 if (blip->bli_item.li_type == XFS_LI_BUF &&
      40 64234799499 :                     blip->bli_buf->b_target == target &&
      41 57248697680 :                     xfs_buf_daddr(blip->bli_buf) == map[0].bm_bn &&
      42  1163866033 :                     blip->bli_buf->b_length == len) {
      43  1163853271 :                         ASSERT(blip->bli_buf->b_map_count == nmaps);
      44  1163853271 :                         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 22643148213 : _xfs_trans_bjoin(
      62             :         struct xfs_trans        *tp,
      63             :         struct xfs_buf          *bp,
      64             :         int                     reset_recur)
      65             : {
      66 22643148213 :         struct xfs_buf_log_item *bip;
      67             : 
      68 22643148213 :         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 22643148213 :         xfs_buf_item_init(bp, tp->t_mountp);
      76 22651417400 :         bip = bp->b_log_item;
      77 22651417400 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
      78 22651417400 :         ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
      79 22651417400 :         ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
      80 22651417400 :         if (reset_recur)
      81 22642464019 :                 bip->bli_recur = 0;
      82             : 
      83             :         /*
      84             :          * Take a reference for this transaction on the buf item.
      85             :          */
      86 22651417400 :         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 22664517052 :         xfs_trans_add_item(tp, &bip->bli_item);
      93 22646498172 :         bp->b_transp = tp;
      94             : 
      95 22646498172 : }
      96             : 
      97             : void
      98     7157883 : xfs_trans_bjoin(
      99             :         struct xfs_trans        *tp,
     100             :         struct xfs_buf          *bp)
     101             : {
     102     7157883 :         _xfs_trans_bjoin(tp, bp, 0);
     103     7160934 :         trace_xfs_trans_bjoin(bp->b_log_item);
     104     7159870 : }
     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    66070612 : 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    66070612 :         struct xfs_buf          *bp;
     125    66070612 :         struct xfs_buf_log_item *bip;
     126    66070612 :         int                     error;
     127             : 
     128    66070612 :         *bpp = NULL;
     129    66070612 :         if (!tp)
     130     1048472 :                 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    65022140 :         bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
     139    65058065 :         if (bp != NULL) {
     140      308235 :                 ASSERT(xfs_buf_islocked(bp));
     141      616470 :                 if (xfs_is_shutdown(tp->t_mountp)) {
     142           0 :                         xfs_buf_stale(bp);
     143           0 :                         bp->b_flags |= XBF_DONE;
     144             :                 }
     145             : 
     146      308235 :                 ASSERT(bp->b_transp == tp);
     147      308235 :                 bip = bp->b_log_item;
     148      308235 :                 ASSERT(bip != NULL);
     149      308235 :                 ASSERT(atomic_read(&bip->bli_refcount) > 0);
     150      308235 :                 bip->bli_recur++;
     151      308235 :                 trace_xfs_trans_get_buf_recur(bip);
     152      308220 :                 *bpp = bp;
     153      308220 :                 return 0;
     154             :         }
     155             : 
     156    64749830 :         error = xfs_buf_get_map(target, map, nmaps, flags, &bp);
     157    64729275 :         if (error)
     158             :                 return error;
     159             : 
     160    64729275 :         ASSERT(!bp->b_error);
     161             : 
     162    64729275 :         _xfs_trans_bjoin(tp, bp, 1);
     163    64814592 :         trace_xfs_trans_get_buf(bp->b_log_item);
     164    64800015 :         *bpp = bp;
     165    64800015 :         return 0;
     166             : }
     167             : 
     168             : /*
     169             :  * Get and lock the superblock buffer for the given transaction.
     170             :  */
     171             : struct xfs_buf *
     172    86584206 : xfs_trans_getsb(
     173             :         struct xfs_trans        *tp)
     174             : {
     175    86584206 :         struct xfs_buf          *bp = tp->t_mountp->m_sb_bp;
     176             : 
     177             :         /*
     178             :          * Just increment the lock recursion count if the buffer is already
     179             :          * attached to this transaction.
     180             :          */
     181    86584206 :         if (bp->b_transp == tp) {
     182        1049 :                 struct xfs_buf_log_item *bip = bp->b_log_item;
     183             : 
     184        1049 :                 ASSERT(bip != NULL);
     185        1049 :                 ASSERT(atomic_read(&bip->bli_refcount) > 0);
     186        1049 :                 bip->bli_recur++;
     187             : 
     188        1049 :                 trace_xfs_trans_getsb_recur(bip);
     189             :         } else {
     190    86583157 :                 xfs_buf_lock(bp);
     191    86583157 :                 xfs_buf_hold(bp);
     192    86583157 :                 _xfs_trans_bjoin(tp, bp, 1);
     193             : 
     194    86583157 :                 trace_xfs_trans_getsb(bp->b_log_item);
     195             :         }
     196             : 
     197    86584206 :         return bp;
     198             : }
     199             : 
     200             : /*
     201             :  * Get and lock the buffer for the caller if it is not already
     202             :  * locked within the given transaction.  If it has not yet been
     203             :  * read in, read it from disk. If it is already locked
     204             :  * within the transaction and already read in, just increment its
     205             :  * lock recursion count and return a pointer to it.
     206             :  *
     207             :  * If the transaction pointer is NULL, make this just a normal
     208             :  * read_buf() call.
     209             :  */
     210             : int
     211 25105738347 : xfs_trans_read_buf_map(
     212             :         struct xfs_mount        *mp,
     213             :         struct xfs_trans        *tp,
     214             :         struct xfs_buftarg      *target,
     215             :         struct xfs_buf_map      *map,
     216             :         int                     nmaps,
     217             :         xfs_buf_flags_t         flags,
     218             :         struct xfs_buf          **bpp,
     219             :         const struct xfs_buf_ops *ops)
     220             : {
     221 25105738347 :         struct xfs_buf          *bp = NULL;
     222 25105738347 :         struct xfs_buf_log_item *bip;
     223 25105738347 :         int                     error;
     224             : 
     225 25105738347 :         *bpp = NULL;
     226             :         /*
     227             :          * If we find the buffer in the cache with this transaction
     228             :          * pointer in its b_fsprivate2 field, then we know we already
     229             :          * have it locked.  If it is already read in we just increment
     230             :          * the lock recursion count and return the buffer to the caller.
     231             :          * If the buffer is not yet read in, then we read it in, increment
     232             :          * the lock recursion count, and return it to the caller.
     233             :          */
     234 25105738347 :         if (tp)
     235 23658689534 :                 bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
     236 25105214165 :         if (bp) {
     237  1163120208 :                 ASSERT(xfs_buf_islocked(bp));
     238  1163120208 :                 ASSERT(bp->b_transp == tp);
     239  1163120208 :                 ASSERT(bp->b_log_item != NULL);
     240  1163120208 :                 ASSERT(!bp->b_error);
     241  1163120208 :                 ASSERT(bp->b_flags & XBF_DONE);
     242             : 
     243             :                 /*
     244             :                  * We never locked this buf ourselves, so we shouldn't
     245             :                  * brelse it either. Just get out.
     246             :                  */
     247  2326240416 :                 if (xfs_is_shutdown(mp)) {
     248         207 :                         trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
     249         207 :                         return -EIO;
     250             :                 }
     251             : 
     252             :                 /*
     253             :                  * Check if the caller is trying to read a buffer that is
     254             :                  * already attached to the transaction yet has no buffer ops
     255             :                  * assigned.  Ops are usually attached when the buffer is
     256             :                  * attached to the transaction, or by the read caller if
     257             :                  * special circumstances.  That didn't happen, which is not
     258             :                  * how this is supposed to go.
     259             :                  *
     260             :                  * If the buffer passes verification we'll let this go, but if
     261             :                  * not we have to shut down.  Let the transaction cleanup code
     262             :                  * release this buffer when it kills the tranaction.
     263             :                  */
     264  1163120001 :                 ASSERT(bp->b_ops != NULL);
     265  1163120001 :                 error = xfs_buf_reverify(bp, ops);
     266  1162698901 :                 if (error) {
     267           0 :                         xfs_buf_ioerror_alert(bp, __return_address);
     268             : 
     269           0 :                         if (tp->t_flags & XFS_TRANS_DIRTY)
     270           0 :                                 xfs_force_shutdown(tp->t_mountp,
     271             :                                                 SHUTDOWN_META_IO_ERROR);
     272             : 
     273             :                         /* bad CRC means corrupted metadata */
     274           0 :                         if (error == -EFSBADCRC)
     275           0 :                                 error = -EFSCORRUPTED;
     276           0 :                         return error;
     277             :                 }
     278             : 
     279  1162698901 :                 bip = bp->b_log_item;
     280  1162698901 :                 bip->bli_recur++;
     281             : 
     282  1162698901 :                 ASSERT(atomic_read(&bip->bli_refcount) > 0);
     283  1162698901 :                 trace_xfs_trans_read_buf_recur(bip);
     284  1162465439 :                 ASSERT(bp->b_ops != NULL || ops == NULL);
     285  1162465439 :                 *bpp = bp;
     286  1162465439 :                 return 0;
     287             :         }
     288             : 
     289 23942093957 :         error = xfs_buf_read_map(target, map, nmaps, flags, &bp, ops,
     290             :                         __return_address);
     291 23942081094 :         switch (error) {
     292             :         case 0:
     293 23935852558 :                 break;
     294       36097 :         default:
     295       36097 :                 if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
     296        2210 :                         xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
     297             :                 fallthrough;
     298             :         case -ENOMEM:
     299             :         case -EAGAIN:
     300             :                 return error;
     301             :         }
     302             : 
     303 47871705116 :         if (xfs_is_shutdown(mp)) {
     304     1663160 :                 xfs_buf_relse(bp);
     305     1663161 :                 trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
     306     1663161 :                 return -EIO;
     307             :         }
     308             : 
     309 23934189398 :         if (tp) {
     310 22487845444 :                 _xfs_trans_bjoin(tp, bp, 1);
     311 22487493814 :                 trace_xfs_trans_read_buf(bp->b_log_item);
     312             :         }
     313 23930400454 :         ASSERT(bp->b_ops != NULL || ops == NULL);
     314 23930400454 :         *bpp = bp;
     315 23930400454 :         return 0;
     316             : 
     317             : }
     318             : 
     319             : /* Has this buffer been dirtied by anyone? */
     320             : bool
     321           0 : xfs_trans_buf_is_dirty(
     322             :         struct xfs_buf          *bp)
     323             : {
     324           0 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     325             : 
     326           0 :         if (!bip)
     327             :                 return false;
     328           0 :         ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
     329           0 :         return test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
     330             : }
     331             : 
     332             : /*
     333             :  * Release a buffer previously joined to the transaction. If the buffer is
     334             :  * modified within this transaction, decrement the recursion count but do not
     335             :  * release the buffer even if the count goes to 0. If the buffer is not modified
     336             :  * within the transaction, decrement the recursion count and release the buffer
     337             :  * if the recursion count goes to 0.
     338             :  *
     339             :  * If the buffer is to be released and it was not already dirty before this
     340             :  * transaction began, then also free the buf_log_item associated with it.
     341             :  *
     342             :  * If the transaction pointer is NULL, this is a normal xfs_buf_relse() call.
     343             :  */
     344             : void
     345 22787000099 : xfs_trans_brelse(
     346             :         struct xfs_trans        *tp,
     347             :         struct xfs_buf          *bp)
     348             : {
     349 22787000099 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     350             : 
     351 22787000099 :         ASSERT(bp->b_transp == tp);
     352             : 
     353 22787000099 :         if (!tp) {
     354  1405338675 :                 xfs_buf_relse(bp);
     355  1405206522 :                 return;
     356             :         }
     357             : 
     358 21381661424 :         trace_xfs_trans_brelse(bip);
     359 21382147732 :         ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
     360 21382147732 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     361             : 
     362             :         /*
     363             :          * If the release is for a recursive lookup, then decrement the count
     364             :          * and return.
     365             :          */
     366 21382147732 :         if (bip->bli_recur > 0) {
     367   983248592 :                 bip->bli_recur--;
     368   983248592 :                 return;
     369             :         }
     370             : 
     371             :         /*
     372             :          * If the buffer is invalidated or dirty in this transaction, we can't
     373             :          * release it until we commit.
     374             :          */
     375 40797798280 :         if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags))
     376             :                 return;
     377 18119004874 :         if (bip->bli_flags & XFS_BLI_STALE)
     378             :                 return;
     379             : 
     380             :         /*
     381             :          * Unlink the log item from the transaction and clear the hold flag, if
     382             :          * set. We wouldn't want the next user of the buffer to get confused.
     383             :          */
     384 18119004874 :         ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
     385 18119004874 :         xfs_trans_del_item(&bip->bli_item);
     386 18126447221 :         bip->bli_flags &= ~XFS_BLI_HOLD;
     387             : 
     388             :         /* drop the reference to the bli */
     389 18126447221 :         xfs_buf_item_put(bip);
     390             : 
     391 18127740803 :         bp->b_transp = NULL;
     392 18127740803 :         xfs_buf_relse(bp);
     393             : }
     394             : 
     395             : /*
     396             :  * Forcibly detach a buffer previously joined to the transaction.  The caller
     397             :  * will retain its locked reference to the buffer after this function returns.
     398             :  * The buffer must be completely clean and must not be held to the transaction.
     399             :  */
     400             : void
     401   451239425 : xfs_trans_bdetach(
     402             :         struct xfs_trans        *tp,
     403             :         struct xfs_buf          *bp)
     404             : {
     405   451239425 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     406             : 
     407   451239425 :         ASSERT(tp != NULL);
     408   451239425 :         ASSERT(bp->b_transp == tp);
     409   451239425 :         ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
     410   451239425 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     411             : 
     412   451239425 :         trace_xfs_trans_bdetach(bip);
     413             : 
     414             :         /*
     415             :          * Erase all recursion count, since we're removing this buffer from the
     416             :          * transaction.
     417             :          */
     418   451238207 :         bip->bli_recur = 0;
     419             : 
     420             :         /*
     421             :          * The buffer must be completely clean.  Specifically, it had better
     422             :          * not be dirty, stale, logged, ordered, or held to the transaction.
     423             :          */
     424   451238207 :         ASSERT(!test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
     425   451238207 :         ASSERT(!(bip->bli_flags & XFS_BLI_DIRTY));
     426   451238207 :         ASSERT(!(bip->bli_flags & XFS_BLI_HOLD));
     427   451238207 :         ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
     428   451238207 :         ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
     429   451238207 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
     430             : 
     431             :         /* Unlink the log item from the transaction and drop the log item. */
     432   451238207 :         xfs_trans_del_item(&bip->bli_item);
     433   451243491 :         xfs_buf_item_put(bip);
     434   451245399 :         bp->b_transp = NULL;
     435   451245399 : }
     436             : 
     437             : /*
     438             :  * Mark the buffer as not needing to be unlocked when the buf item's
     439             :  * iop_committing() routine is called.  The buffer must already be locked
     440             :  * and associated with the given transaction.
     441             :  */
     442             : /* ARGSUSED */
     443             : void
     444     9760441 : xfs_trans_bhold(
     445             :         xfs_trans_t             *tp,
     446             :         struct xfs_buf          *bp)
     447             : {
     448     9760441 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     449             : 
     450     9760441 :         ASSERT(bp->b_transp == tp);
     451     9760441 :         ASSERT(bip != NULL);
     452     9760441 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
     453     9760441 :         ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
     454     9760441 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     455             : 
     456     9760441 :         bip->bli_flags |= XFS_BLI_HOLD;
     457     9760441 :         trace_xfs_trans_bhold(bip);
     458     9759718 : }
     459             : 
     460             : /*
     461             :  * Cancel the previous buffer hold request made on this buffer
     462             :  * for this transaction.
     463             :  */
     464             : void
     465      755057 : xfs_trans_bhold_release(
     466             :         xfs_trans_t             *tp,
     467             :         struct xfs_buf          *bp)
     468             : {
     469      755057 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     470             : 
     471      755057 :         ASSERT(bp->b_transp == tp);
     472      755057 :         ASSERT(bip != NULL);
     473      755057 :         ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
     474      755057 :         ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
     475      755057 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     476      755057 :         ASSERT(bip->bli_flags & XFS_BLI_HOLD);
     477             : 
     478      755057 :         bip->bli_flags &= ~XFS_BLI_HOLD;
     479      755057 :         trace_xfs_trans_bhold_release(bip);
     480      754920 : }
     481             : 
     482             : /*
     483             :  * Mark a buffer dirty in the transaction.
     484             :  */
     485             : void
     486  7393986459 : xfs_trans_dirty_buf(
     487             :         struct xfs_trans        *tp,
     488             :         struct xfs_buf          *bp)
     489             : {
     490  7393986459 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     491             : 
     492  7393986459 :         ASSERT(bp->b_transp == tp);
     493  7393986459 :         ASSERT(bip != NULL);
     494             : 
     495             :         /*
     496             :          * Mark the buffer as needing to be written out eventually,
     497             :          * and set its iodone function to remove the buffer's buf log
     498             :          * item from the AIL and free it when the buffer is flushed
     499             :          * to disk.
     500             :          */
     501  7393986459 :         bp->b_flags |= XBF_DONE;
     502             : 
     503  7393986459 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     504             : 
     505             :         /*
     506             :          * If we invalidated the buffer within this transaction, then
     507             :          * cancel the invalidation now that we're dirtying the buffer
     508             :          * again.  There are no races with the code in xfs_buf_item_unpin(),
     509             :          * because we have a reference to the buffer this entire time.
     510             :          */
     511  7393986459 :         if (bip->bli_flags & XFS_BLI_STALE) {
     512           1 :                 bip->bli_flags &= ~XFS_BLI_STALE;
     513           1 :                 ASSERT(bp->b_flags & XBF_STALE);
     514           1 :                 bp->b_flags &= ~XBF_STALE;
     515           1 :                 bip->__bli_format.blf_flags &= ~XFS_BLF_CANCEL;
     516             :         }
     517  7393986459 :         bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED;
     518             : 
     519  7393986459 :         tp->t_flags |= XFS_TRANS_DIRTY;
     520  7393986459 :         set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
     521  7401257431 : }
     522             : 
     523             : /*
     524             :  * This is called to mark bytes first through last inclusive of the given
     525             :  * buffer as needing to be logged when the transaction is committed.
     526             :  * The buffer must already be associated with the given transaction.
     527             :  *
     528             :  * First and last are numbers relative to the beginning of this buffer,
     529             :  * so the first byte in the buffer is numbered 0 regardless of the
     530             :  * value of b_blkno.
     531             :  */
     532             : void
     533  7387525325 : xfs_trans_log_buf(
     534             :         struct xfs_trans        *tp,
     535             :         struct xfs_buf          *bp,
     536             :         uint                    first,
     537             :         uint                    last)
     538             : {
     539  7387525325 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     540             : 
     541  7387525325 :         ASSERT(first <= last && last < BBTOB(bp->b_length));
     542  7387525325 :         ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
     543             : 
     544  7387525325 :         xfs_trans_dirty_buf(tp, bp);
     545             : 
     546  7394260287 :         trace_xfs_trans_log_buf(bip);
     547  7393450022 :         xfs_buf_item_log(bip, first, last);
     548  7391122467 : }
     549             : 
     550             : 
     551             : /*
     552             :  * Invalidate a buffer that is being used within a transaction.
     553             :  *
     554             :  * Typically this is because the blocks in the buffer are being freed, so we
     555             :  * need to prevent it from being written out when we're done.  Allowing it
     556             :  * to be written again might overwrite data in the free blocks if they are
     557             :  * reallocated to a file.
     558             :  *
     559             :  * We prevent the buffer from being written out by marking it stale.  We can't
     560             :  * get rid of the buf log item at this point because the buffer may still be
     561             :  * pinned by another transaction.  If that is the case, then we'll wait until
     562             :  * the buffer is committed to disk for the last time (we can tell by the ref
     563             :  * count) and free it in xfs_buf_item_unpin().  Until that happens we will
     564             :  * keep the buffer locked so that the buffer and buf log item are not reused.
     565             :  *
     566             :  * We also set the XFS_BLF_CANCEL flag in the buf log format structure and log
     567             :  * the buf item.  This will be used at recovery time to determine that copies
     568             :  * of the buffer in the log before this should not be replayed.
     569             :  *
     570             :  * We mark the item descriptor and the transaction dirty so that we'll hold
     571             :  * the buffer until after the commit.
     572             :  *
     573             :  * Since we're invalidating the buffer, we also clear the state about which
     574             :  * parts of the buffer have been logged.  We also clear the flag indicating
     575             :  * that this is an inode buffer since the data in the buffer will no longer
     576             :  * be valid.
     577             :  *
     578             :  * We set the stale bit in the buffer as well since we're getting rid of it.
     579             :  */
     580             : void
     581    31524358 : xfs_trans_binval(
     582             :         xfs_trans_t             *tp,
     583             :         struct xfs_buf          *bp)
     584             : {
     585    31524358 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     586    31524358 :         int                     i;
     587             : 
     588    31524358 :         ASSERT(bp->b_transp == tp);
     589    31524358 :         ASSERT(bip != NULL);
     590    31524358 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     591             : 
     592    31524358 :         trace_xfs_trans_binval(bip);
     593             : 
     594    31517592 :         if (bip->bli_flags & XFS_BLI_STALE) {
     595             :                 /*
     596             :                  * If the buffer is already invalidated, then
     597             :                  * just return.
     598             :                  */
     599           0 :                 ASSERT(bp->b_flags & XBF_STALE);
     600           0 :                 ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
     601           0 :                 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_INODE_BUF));
     602           0 :                 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLFT_MASK));
     603           0 :                 ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
     604           0 :                 ASSERT(test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
     605           0 :                 ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
     606           0 :                 return;
     607             :         }
     608             : 
     609    31517592 :         xfs_buf_stale(bp);
     610             : 
     611    31564532 :         bip->bli_flags |= XFS_BLI_STALE;
     612    31564532 :         bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY);
     613    31564532 :         bip->__bli_format.blf_flags &= ~XFS_BLF_INODE_BUF;
     614    31564532 :         bip->__bli_format.blf_flags |= XFS_BLF_CANCEL;
     615    31564532 :         bip->__bli_format.blf_flags &= ~XFS_BLFT_MASK;
     616    63126503 :         for (i = 0; i < bip->bli_format_count; i++) {
     617    63133475 :                 memset(bip->bli_formats[i].blf_data_map, 0,
     618             :                        (bip->bli_formats[i].blf_map_size * sizeof(uint)));
     619             :         }
     620    31554999 :         set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
     621    31567407 :         tp->t_flags |= XFS_TRANS_DIRTY;
     622             : }
     623             : 
     624             : /*
     625             :  * This call is used to indicate that the buffer contains on-disk inodes which
     626             :  * must be handled specially during recovery.  They require special handling
     627             :  * because only the di_next_unlinked from the inodes in the buffer should be
     628             :  * recovered.  The rest of the data in the buffer is logged via the inodes
     629             :  * themselves.
     630             :  *
     631             :  * All we do is set the XFS_BLI_INODE_BUF flag in the items flags so it can be
     632             :  * transferred to the buffer's log format structure so that we'll know what to
     633             :  * do at recovery time.
     634             :  */
     635             : void
     636    72946875 : xfs_trans_inode_buf(
     637             :         xfs_trans_t             *tp,
     638             :         struct xfs_buf          *bp)
     639             : {
     640    72946875 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     641             : 
     642    72946875 :         ASSERT(bp->b_transp == tp);
     643    72946875 :         ASSERT(bip != NULL);
     644    72946875 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     645             : 
     646    72946875 :         bip->bli_flags |= XFS_BLI_INODE_BUF;
     647    72946875 :         bp->b_flags |= _XBF_INODES;
     648    72946875 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
     649    72707814 : }
     650             : 
     651             : /*
     652             :  * This call is used to indicate that the buffer is going to
     653             :  * be staled and was an inode buffer. This means it gets
     654             :  * special processing during unpin - where any inodes
     655             :  * associated with the buffer should be removed from ail.
     656             :  * There is also special processing during recovery,
     657             :  * any replay of the inodes in the buffer needs to be
     658             :  * prevented as the buffer may have been reused.
     659             :  */
     660             : void
     661      713129 : xfs_trans_stale_inode_buf(
     662             :         xfs_trans_t             *tp,
     663             :         struct xfs_buf          *bp)
     664             : {
     665      713129 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     666             : 
     667      713129 :         ASSERT(bp->b_transp == tp);
     668      713129 :         ASSERT(bip != NULL);
     669      713129 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     670             : 
     671      713129 :         bip->bli_flags |= XFS_BLI_STALE_INODE;
     672      713129 :         bp->b_flags |= _XBF_INODES;
     673      713129 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
     674      713125 : }
     675             : 
     676             : /*
     677             :  * Mark the buffer as being one which contains newly allocated
     678             :  * inodes.  We need to make sure that even if this buffer is
     679             :  * relogged as an 'inode buf' we still recover all of the inode
     680             :  * images in the face of a crash.  This works in coordination with
     681             :  * xfs_buf_item_committed() to ensure that the buffer remains in the
     682             :  * AIL at its original location even after it has been relogged.
     683             :  */
     684             : /* ARGSUSED */
     685             : void
     686     2047250 : xfs_trans_inode_alloc_buf(
     687             :         xfs_trans_t             *tp,
     688             :         struct xfs_buf          *bp)
     689             : {
     690     2047250 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     691             : 
     692     2047250 :         ASSERT(bp->b_transp == tp);
     693     2047250 :         ASSERT(bip != NULL);
     694     2047250 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     695             : 
     696     2047250 :         bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
     697     2047250 :         bp->b_flags |= _XBF_INODES;
     698     2047250 :         xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
     699     2047097 : }
     700             : 
     701             : /*
     702             :  * Mark the buffer as ordered for this transaction. This means that the contents
     703             :  * of the buffer are not recorded in the transaction but it is tracked in the
     704             :  * AIL as though it was. This allows us to record logical changes in
     705             :  * transactions rather than the physical changes we make to the buffer without
     706             :  * changing writeback ordering constraints of metadata buffers.
     707             :  */
     708             : bool
     709     2166604 : xfs_trans_ordered_buf(
     710             :         struct xfs_trans        *tp,
     711             :         struct xfs_buf          *bp)
     712             : {
     713     2166604 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     714             : 
     715     2166604 :         ASSERT(bp->b_transp == tp);
     716     2166604 :         ASSERT(bip != NULL);
     717     2166604 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     718             : 
     719     2166604 :         if (xfs_buf_item_dirty_format(bip))
     720             :                 return false;
     721             : 
     722     2159286 :         bip->bli_flags |= XFS_BLI_ORDERED;
     723     2159286 :         trace_xfs_buf_item_ordered(bip);
     724             : 
     725             :         /*
     726             :          * We don't log a dirty range of an ordered buffer but it still needs
     727             :          * to be marked dirty and that it has been logged.
     728             :          */
     729     2159097 :         xfs_trans_dirty_buf(tp, bp);
     730     2159097 :         return true;
     731             : }
     732             : 
     733             : /*
     734             :  * Set the type of the buffer for log recovery so that it can correctly identify
     735             :  * and hence attach the correct buffer ops to the buffer after replay.
     736             :  */
     737             : void
     738 13179263766 : xfs_trans_buf_set_type(
     739             :         struct xfs_trans        *tp,
     740             :         struct xfs_buf          *bp,
     741             :         enum xfs_blft           type)
     742             : {
     743 13179263766 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     744             : 
     745 13179263766 :         if (!tp)
     746             :                 return;
     747             : 
     748 12930399526 :         ASSERT(bp->b_transp == tp);
     749 12930399526 :         ASSERT(bip != NULL);
     750 12930399526 :         ASSERT(atomic_read(&bip->bli_refcount) > 0);
     751             : 
     752 12930399526 :         xfs_blft_to_flags(&bip->__bli_format, type);
     753             : }
     754             : 
     755             : void
     756       17077 : xfs_trans_buf_copy_type(
     757             :         struct xfs_buf          *dst_bp,
     758             :         struct xfs_buf          *src_bp)
     759             : {
     760       17077 :         struct xfs_buf_log_item *sbip = src_bp->b_log_item;
     761       17077 :         struct xfs_buf_log_item *dbip = dst_bp->b_log_item;
     762       17077 :         enum xfs_blft           type;
     763             : 
     764       17077 :         type = xfs_blft_from_flags(&sbip->__bli_format);
     765       17077 :         xfs_blft_to_flags(&dbip->__bli_format, type);
     766       17079 : }
     767             : 
     768             : /*
     769             :  * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of
     770             :  * dquots. However, unlike in inode buffer recovery, dquot buffers get
     771             :  * recovered in their entirety. (Hence, no XFS_BLI_DQUOT_ALLOC_BUF flag).
     772             :  * The only thing that makes dquot buffers different from regular
     773             :  * buffers is that we must not replay dquot bufs when recovering
     774             :  * if a _corresponding_ quotaoff has happened. We also have to distinguish
     775             :  * between usr dquot bufs and grp dquot bufs, because usr and grp quotas
     776             :  * can be turned off independently.
     777             :  */
     778             : /* ARGSUSED */
     779             : void
     780     2926454 : xfs_trans_dquot_buf(
     781             :         xfs_trans_t             *tp,
     782             :         struct xfs_buf          *bp,
     783             :         uint                    type)
     784             : {
     785     2926454 :         struct xfs_buf_log_item *bip = bp->b_log_item;
     786             : 
     787     2926454 :         ASSERT(type == XFS_BLF_UDQUOT_BUF ||
     788             :                type == XFS_BLF_PDQUOT_BUF ||
     789             :                type == XFS_BLF_GDQUOT_BUF);
     790             : 
     791     2926454 :         bip->__bli_format.blf_flags |= type;
     792             : 
     793     2926454 :         switch (type) {
     794             :         case XFS_BLF_UDQUOT_BUF:
     795             :                 type = XFS_BLFT_UDQUOT_BUF;
     796             :                 break;
     797             :         case XFS_BLF_PDQUOT_BUF:
     798             :                 type = XFS_BLFT_PDQUOT_BUF;
     799             :                 break;
     800             :         case XFS_BLF_GDQUOT_BUF:
     801             :                 type = XFS_BLFT_GDQUOT_BUF;
     802             :                 break;
     803             :         default:
     804             :                 type = XFS_BLFT_UNKNOWN_BUF;
     805             :                 break;
     806             :         }
     807             : 
     808     2926454 :         bp->b_flags |= _XBF_DQUOTS;
     809     2926454 :         xfs_trans_buf_set_type(tp, bp, type);
     810     2926745 : }

Generated by: LCOV version 1.14