11da177e4SLinus Torvalds /* 27b718769SNathan Scott * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. 37b718769SNathan Scott * All Rights Reserved. 41da177e4SLinus Torvalds * 57b718769SNathan Scott * This program is free software; you can redistribute it and/or 67b718769SNathan Scott * modify it under the terms of the GNU General Public License as 71da177e4SLinus Torvalds * published by the Free Software Foundation. 81da177e4SLinus Torvalds * 97b718769SNathan Scott * This program is distributed in the hope that it would be useful, 107b718769SNathan Scott * but WITHOUT ANY WARRANTY; without even the implied warranty of 117b718769SNathan Scott * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 127b718769SNathan Scott * GNU General Public License for more details. 131da177e4SLinus Torvalds * 147b718769SNathan Scott * You should have received a copy of the GNU General Public License 157b718769SNathan Scott * along with this program; if not, write the Free Software Foundation, 167b718769SNathan Scott * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 171da177e4SLinus Torvalds */ 181da177e4SLinus Torvalds #include "xfs.h" 19a844f451SNathan Scott #include "xfs_fs.h" 201da177e4SLinus Torvalds #include "xfs_types.h" 21a844f451SNathan Scott #include "xfs_bit.h" 221da177e4SLinus Torvalds #include "xfs_log.h" 23a844f451SNathan Scott #include "xfs_inum.h" 241da177e4SLinus Torvalds #include "xfs_trans.h" 251da177e4SLinus Torvalds #include "xfs_sb.h" 261da177e4SLinus Torvalds #include "xfs_ag.h" 271da177e4SLinus Torvalds #include "xfs_mount.h" 28a844f451SNathan Scott #include "xfs_bmap_btree.h" 29a844f451SNathan Scott #include "xfs_alloc_btree.h" 30a844f451SNathan Scott #include "xfs_ialloc_btree.h" 31a844f451SNathan Scott #include "xfs_dinode.h" 32a844f451SNathan Scott #include "xfs_inode.h" 33a844f451SNathan Scott #include "xfs_buf_item.h" 341da177e4SLinus Torvalds #include "xfs_trans_priv.h" 351da177e4SLinus Torvalds #include "xfs_error.h" 361da177e4SLinus Torvalds #include "xfs_rw.h" 370b1b213fSChristoph Hellwig #include "xfs_trace.h" 381da177e4SLinus Torvalds 394a5224d7SChristoph Hellwig /* 404a5224d7SChristoph Hellwig * Check to see if a buffer matching the given parameters is already 414a5224d7SChristoph Hellwig * a part of the given transaction. 424a5224d7SChristoph Hellwig */ 434a5224d7SChristoph Hellwig STATIC struct xfs_buf * 444a5224d7SChristoph Hellwig xfs_trans_buf_item_match( 454a5224d7SChristoph Hellwig struct xfs_trans *tp, 464a5224d7SChristoph Hellwig struct xfs_buftarg *target, 474a5224d7SChristoph Hellwig xfs_daddr_t blkno, 484a5224d7SChristoph Hellwig int len) 494a5224d7SChristoph Hellwig { 50e98c414fSChristoph Hellwig struct xfs_log_item_desc *lidp; 51e98c414fSChristoph Hellwig struct xfs_buf_log_item *blip; 521da177e4SLinus Torvalds 534a5224d7SChristoph Hellwig len = BBTOB(len); 54e98c414fSChristoph Hellwig list_for_each_entry(lidp, &tp->t_items, lid_trans) { 55e98c414fSChristoph Hellwig blip = (struct xfs_buf_log_item *)lidp->lid_item; 56e98c414fSChristoph Hellwig if (blip->bli_item.li_type == XFS_LI_BUF && 57e98c414fSChristoph Hellwig XFS_BUF_TARGET(blip->bli_buf) == target && 584a5224d7SChristoph Hellwig XFS_BUF_ADDR(blip->bli_buf) == blkno && 594a5224d7SChristoph Hellwig XFS_BUF_COUNT(blip->bli_buf) == len) 604a5224d7SChristoph Hellwig return blip->bli_buf; 614a5224d7SChristoph Hellwig } 624a5224d7SChristoph Hellwig 634a5224d7SChristoph Hellwig return NULL; 644a5224d7SChristoph Hellwig } 651da177e4SLinus Torvalds 66d7e84f41SChristoph Hellwig /* 67d7e84f41SChristoph Hellwig * Add the locked buffer to the transaction. 68d7e84f41SChristoph Hellwig * 69d7e84f41SChristoph Hellwig * The buffer must be locked, and it cannot be associated with any 70d7e84f41SChristoph Hellwig * transaction. 71d7e84f41SChristoph Hellwig * 72d7e84f41SChristoph Hellwig * If the buffer does not yet have a buf log item associated with it, 73d7e84f41SChristoph Hellwig * then allocate one for it. Then add the buf item to the transaction. 74d7e84f41SChristoph Hellwig */ 75d7e84f41SChristoph Hellwig STATIC void 76d7e84f41SChristoph Hellwig _xfs_trans_bjoin( 77d7e84f41SChristoph Hellwig struct xfs_trans *tp, 78d7e84f41SChristoph Hellwig struct xfs_buf *bp, 79d7e84f41SChristoph Hellwig int reset_recur) 80d7e84f41SChristoph Hellwig { 81d7e84f41SChristoph Hellwig struct xfs_buf_log_item *bip; 82d7e84f41SChristoph Hellwig 83d7e84f41SChristoph Hellwig ASSERT(XFS_BUF_ISBUSY(bp)); 84bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == NULL); 85d7e84f41SChristoph Hellwig 86d7e84f41SChristoph Hellwig /* 87d7e84f41SChristoph Hellwig * The xfs_buf_log_item pointer is stored in b_fsprivate. If 88d7e84f41SChristoph Hellwig * it doesn't have one yet, then allocate one and initialize it. 89d7e84f41SChristoph Hellwig * The checks to see if one is there are in xfs_buf_item_init(). 90d7e84f41SChristoph Hellwig */ 91d7e84f41SChristoph Hellwig xfs_buf_item_init(bp, tp->t_mountp); 92adadbeefSChristoph Hellwig bip = bp->b_fspriv; 93d7e84f41SChristoph Hellwig ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 94c1155410SDave Chinner ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 95d7e84f41SChristoph Hellwig ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); 96d7e84f41SChristoph Hellwig if (reset_recur) 97d7e84f41SChristoph Hellwig bip->bli_recur = 0; 98d7e84f41SChristoph Hellwig 99d7e84f41SChristoph Hellwig /* 100d7e84f41SChristoph Hellwig * Take a reference for this transaction on the buf item. 101d7e84f41SChristoph Hellwig */ 102d7e84f41SChristoph Hellwig atomic_inc(&bip->bli_refcount); 103d7e84f41SChristoph Hellwig 104d7e84f41SChristoph Hellwig /* 105d7e84f41SChristoph Hellwig * Get a log_item_desc to point at the new item. 106d7e84f41SChristoph Hellwig */ 107e98c414fSChristoph Hellwig xfs_trans_add_item(tp, &bip->bli_item); 108d7e84f41SChristoph Hellwig 109d7e84f41SChristoph Hellwig /* 110d7e84f41SChristoph Hellwig * Initialize b_fsprivate2 so we can find it with incore_match() 111d7e84f41SChristoph Hellwig * in xfs_trans_get_buf() and friends above. 112d7e84f41SChristoph Hellwig */ 113bf9d9013SChristoph Hellwig bp->b_transp = tp; 114d7e84f41SChristoph Hellwig 115d7e84f41SChristoph Hellwig } 116d7e84f41SChristoph Hellwig 117d7e84f41SChristoph Hellwig void 118d7e84f41SChristoph Hellwig xfs_trans_bjoin( 119d7e84f41SChristoph Hellwig struct xfs_trans *tp, 120d7e84f41SChristoph Hellwig struct xfs_buf *bp) 121d7e84f41SChristoph Hellwig { 122d7e84f41SChristoph Hellwig _xfs_trans_bjoin(tp, bp, 0); 123d7e84f41SChristoph Hellwig trace_xfs_trans_bjoin(bp->b_fspriv); 124d7e84f41SChristoph Hellwig } 1251da177e4SLinus Torvalds 1261da177e4SLinus Torvalds /* 1271da177e4SLinus Torvalds * Get and lock the buffer for the caller if it is not already 1281da177e4SLinus Torvalds * locked within the given transaction. If it is already locked 1291da177e4SLinus Torvalds * within the transaction, just increment its lock recursion count 1301da177e4SLinus Torvalds * and return a pointer to it. 1311da177e4SLinus Torvalds * 1321da177e4SLinus Torvalds * If the transaction pointer is NULL, make this just a normal 1331da177e4SLinus Torvalds * get_buf() call. 1341da177e4SLinus Torvalds */ 1351da177e4SLinus Torvalds xfs_buf_t * 1361da177e4SLinus Torvalds xfs_trans_get_buf(xfs_trans_t *tp, 1371da177e4SLinus Torvalds xfs_buftarg_t *target_dev, 1381da177e4SLinus Torvalds xfs_daddr_t blkno, 1391da177e4SLinus Torvalds int len, 1401da177e4SLinus Torvalds uint flags) 1411da177e4SLinus Torvalds { 1421da177e4SLinus Torvalds xfs_buf_t *bp; 1431da177e4SLinus Torvalds xfs_buf_log_item_t *bip; 1441da177e4SLinus Torvalds 1451da177e4SLinus Torvalds if (flags == 0) 1460cadda1cSChristoph Hellwig flags = XBF_LOCK | XBF_MAPPED; 1471da177e4SLinus Torvalds 1481da177e4SLinus Torvalds /* 1491da177e4SLinus Torvalds * Default to a normal get_buf() call if the tp is NULL. 1501da177e4SLinus Torvalds */ 1516ad112bfSChristoph Hellwig if (tp == NULL) 1520cadda1cSChristoph Hellwig return xfs_buf_get(target_dev, blkno, len, 1530cadda1cSChristoph Hellwig flags | XBF_DONT_BLOCK); 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds /* 1561da177e4SLinus Torvalds * If we find the buffer in the cache with this transaction 1571da177e4SLinus Torvalds * pointer in its b_fsprivate2 field, then we know we already 1581da177e4SLinus Torvalds * have it locked. In this case we just increment the lock 1591da177e4SLinus Torvalds * recursion count and return the buffer to the caller. 1601da177e4SLinus Torvalds */ 1611da177e4SLinus Torvalds bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len); 1621da177e4SLinus Torvalds if (bp != NULL) { 1630c842ad4SChristoph Hellwig ASSERT(xfs_buf_islocked(bp)); 1640b1b213fSChristoph Hellwig if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) 1651da177e4SLinus Torvalds XFS_BUF_SUPER_STALE(bp); 1660b1b213fSChristoph Hellwig 1671da177e4SLinus Torvalds /* 1681da177e4SLinus Torvalds * If the buffer is stale then it was binval'ed 1691da177e4SLinus Torvalds * since last read. This doesn't matter since the 1701da177e4SLinus Torvalds * caller isn't allowed to use the data anyway. 1711da177e4SLinus Torvalds */ 1720b1b213fSChristoph Hellwig else if (XFS_BUF_ISSTALE(bp)) 1731da177e4SLinus Torvalds ASSERT(!XFS_BUF_ISDELAYWRITE(bp)); 1740b1b213fSChristoph Hellwig 175bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 176adadbeefSChristoph Hellwig bip = bp->b_fspriv; 1771da177e4SLinus Torvalds ASSERT(bip != NULL); 1781da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 1791da177e4SLinus Torvalds bip->bli_recur++; 1800b1b213fSChristoph Hellwig trace_xfs_trans_get_buf_recur(bip); 1811da177e4SLinus Torvalds return (bp); 1821da177e4SLinus Torvalds } 1831da177e4SLinus Torvalds 1841da177e4SLinus Torvalds /* 1850cadda1cSChristoph Hellwig * We always specify the XBF_DONT_BLOCK flag within a transaction 1860cadda1cSChristoph Hellwig * so that get_buf does not try to push out a delayed write buffer 1871da177e4SLinus Torvalds * which might cause another transaction to take place (if the 1881da177e4SLinus Torvalds * buffer was delayed alloc). Such recursive transactions can 1891da177e4SLinus Torvalds * easily deadlock with our current transaction as well as cause 1901da177e4SLinus Torvalds * us to run out of stack space. 1911da177e4SLinus Torvalds */ 1920cadda1cSChristoph Hellwig bp = xfs_buf_get(target_dev, blkno, len, flags | XBF_DONT_BLOCK); 1931da177e4SLinus Torvalds if (bp == NULL) { 1941da177e4SLinus Torvalds return NULL; 1951da177e4SLinus Torvalds } 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds ASSERT(!XFS_BUF_GETERROR(bp)); 1981da177e4SLinus Torvalds 199d7e84f41SChristoph Hellwig _xfs_trans_bjoin(tp, bp, 1); 200d7e84f41SChristoph Hellwig trace_xfs_trans_get_buf(bp->b_fspriv); 2011da177e4SLinus Torvalds return (bp); 2021da177e4SLinus Torvalds } 2031da177e4SLinus Torvalds 2041da177e4SLinus Torvalds /* 2051da177e4SLinus Torvalds * Get and lock the superblock buffer of this file system for the 2061da177e4SLinus Torvalds * given transaction. 2071da177e4SLinus Torvalds * 2081da177e4SLinus Torvalds * We don't need to use incore_match() here, because the superblock 2091da177e4SLinus Torvalds * buffer is a private buffer which we keep a pointer to in the 2101da177e4SLinus Torvalds * mount structure. 2111da177e4SLinus Torvalds */ 2121da177e4SLinus Torvalds xfs_buf_t * 2131da177e4SLinus Torvalds xfs_trans_getsb(xfs_trans_t *tp, 2141da177e4SLinus Torvalds struct xfs_mount *mp, 2151da177e4SLinus Torvalds int flags) 2161da177e4SLinus Torvalds { 2171da177e4SLinus Torvalds xfs_buf_t *bp; 2181da177e4SLinus Torvalds xfs_buf_log_item_t *bip; 2191da177e4SLinus Torvalds 2201da177e4SLinus Torvalds /* 2211da177e4SLinus Torvalds * Default to just trying to lock the superblock buffer 2221da177e4SLinus Torvalds * if tp is NULL. 2231da177e4SLinus Torvalds */ 2241da177e4SLinus Torvalds if (tp == NULL) { 2251da177e4SLinus Torvalds return (xfs_getsb(mp, flags)); 2261da177e4SLinus Torvalds } 2271da177e4SLinus Torvalds 2281da177e4SLinus Torvalds /* 2291da177e4SLinus Torvalds * If the superblock buffer already has this transaction 2301da177e4SLinus Torvalds * pointer in its b_fsprivate2 field, then we know we already 2311da177e4SLinus Torvalds * have it locked. In this case we just increment the lock 2321da177e4SLinus Torvalds * recursion count and return the buffer to the caller. 2331da177e4SLinus Torvalds */ 2341da177e4SLinus Torvalds bp = mp->m_sb_bp; 235bf9d9013SChristoph Hellwig if (bp->b_transp == tp) { 236adadbeefSChristoph Hellwig bip = bp->b_fspriv; 2371da177e4SLinus Torvalds ASSERT(bip != NULL); 2381da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 2391da177e4SLinus Torvalds bip->bli_recur++; 2400b1b213fSChristoph Hellwig trace_xfs_trans_getsb_recur(bip); 2411da177e4SLinus Torvalds return (bp); 2421da177e4SLinus Torvalds } 2431da177e4SLinus Torvalds 2441da177e4SLinus Torvalds bp = xfs_getsb(mp, flags); 245d7e84f41SChristoph Hellwig if (bp == NULL) 2461da177e4SLinus Torvalds return NULL; 2471da177e4SLinus Torvalds 248d7e84f41SChristoph Hellwig _xfs_trans_bjoin(tp, bp, 1); 249d7e84f41SChristoph Hellwig trace_xfs_trans_getsb(bp->b_fspriv); 2501da177e4SLinus Torvalds return (bp); 2511da177e4SLinus Torvalds } 2521da177e4SLinus Torvalds 2531da177e4SLinus Torvalds #ifdef DEBUG 2541da177e4SLinus Torvalds xfs_buftarg_t *xfs_error_target; 2551da177e4SLinus Torvalds int xfs_do_error; 2561da177e4SLinus Torvalds int xfs_req_num; 2571da177e4SLinus Torvalds int xfs_error_mod = 33; 2581da177e4SLinus Torvalds #endif 2591da177e4SLinus Torvalds 2601da177e4SLinus Torvalds /* 2611da177e4SLinus Torvalds * Get and lock the buffer for the caller if it is not already 2621da177e4SLinus Torvalds * locked within the given transaction. If it has not yet been 2631da177e4SLinus Torvalds * read in, read it from disk. If it is already locked 2641da177e4SLinus Torvalds * within the transaction and already read in, just increment its 2651da177e4SLinus Torvalds * lock recursion count and return a pointer to it. 2661da177e4SLinus Torvalds * 2671da177e4SLinus Torvalds * If the transaction pointer is NULL, make this just a normal 2681da177e4SLinus Torvalds * read_buf() call. 2691da177e4SLinus Torvalds */ 2701da177e4SLinus Torvalds int 2711da177e4SLinus Torvalds xfs_trans_read_buf( 2721da177e4SLinus Torvalds xfs_mount_t *mp, 2731da177e4SLinus Torvalds xfs_trans_t *tp, 2741da177e4SLinus Torvalds xfs_buftarg_t *target, 2751da177e4SLinus Torvalds xfs_daddr_t blkno, 2761da177e4SLinus Torvalds int len, 2771da177e4SLinus Torvalds uint flags, 2781da177e4SLinus Torvalds xfs_buf_t **bpp) 2791da177e4SLinus Torvalds { 2801da177e4SLinus Torvalds xfs_buf_t *bp; 2811da177e4SLinus Torvalds xfs_buf_log_item_t *bip; 2821da177e4SLinus Torvalds int error; 2831da177e4SLinus Torvalds 2841da177e4SLinus Torvalds if (flags == 0) 2850cadda1cSChristoph Hellwig flags = XBF_LOCK | XBF_MAPPED; 2861da177e4SLinus Torvalds 2871da177e4SLinus Torvalds /* 2881da177e4SLinus Torvalds * Default to a normal get_buf() call if the tp is NULL. 2891da177e4SLinus Torvalds */ 2901da177e4SLinus Torvalds if (tp == NULL) { 2910cadda1cSChristoph Hellwig bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK); 2921da177e4SLinus Torvalds if (!bp) 2930cadda1cSChristoph Hellwig return (flags & XBF_TRYLOCK) ? 294a3f74ffbSDavid Chinner EAGAIN : XFS_ERROR(ENOMEM); 2951da177e4SLinus Torvalds 296a0f7bfd3SJulia Lawall if (XFS_BUF_GETERROR(bp) != 0) { 2971da177e4SLinus Torvalds xfs_ioerror_alert("xfs_trans_read_buf", mp, 2981da177e4SLinus Torvalds bp, blkno); 2991da177e4SLinus Torvalds error = XFS_BUF_GETERROR(bp); 3001da177e4SLinus Torvalds xfs_buf_relse(bp); 3011da177e4SLinus Torvalds return error; 3021da177e4SLinus Torvalds } 3031da177e4SLinus Torvalds #ifdef DEBUG 304a0f7bfd3SJulia Lawall if (xfs_do_error) { 3051da177e4SLinus Torvalds if (xfs_error_target == target) { 3061da177e4SLinus Torvalds if (((xfs_req_num++) % xfs_error_mod) == 0) { 3071da177e4SLinus Torvalds xfs_buf_relse(bp); 3080b932cccSDave Chinner xfs_debug(mp, "Returning error!"); 3091da177e4SLinus Torvalds return XFS_ERROR(EIO); 3101da177e4SLinus Torvalds } 3111da177e4SLinus Torvalds } 3121da177e4SLinus Torvalds } 3131da177e4SLinus Torvalds #endif 3141da177e4SLinus Torvalds if (XFS_FORCED_SHUTDOWN(mp)) 3151da177e4SLinus Torvalds goto shutdown_abort; 3161da177e4SLinus Torvalds *bpp = bp; 3171da177e4SLinus Torvalds return 0; 3181da177e4SLinus Torvalds } 3191da177e4SLinus Torvalds 3201da177e4SLinus Torvalds /* 3211da177e4SLinus Torvalds * If we find the buffer in the cache with this transaction 3221da177e4SLinus Torvalds * pointer in its b_fsprivate2 field, then we know we already 3231da177e4SLinus Torvalds * have it locked. If it is already read in we just increment 3241da177e4SLinus Torvalds * the lock recursion count and return the buffer to the caller. 3251da177e4SLinus Torvalds * If the buffer is not yet read in, then we read it in, increment 3261da177e4SLinus Torvalds * the lock recursion count, and return it to the caller. 3271da177e4SLinus Torvalds */ 3281da177e4SLinus Torvalds bp = xfs_trans_buf_item_match(tp, target, blkno, len); 3291da177e4SLinus Torvalds if (bp != NULL) { 3300c842ad4SChristoph Hellwig ASSERT(xfs_buf_islocked(bp)); 331bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 332adadbeefSChristoph Hellwig ASSERT(bp->b_fspriv != NULL); 3331da177e4SLinus Torvalds ASSERT((XFS_BUF_ISERROR(bp)) == 0); 3341da177e4SLinus Torvalds if (!(XFS_BUF_ISDONE(bp))) { 3350b1b213fSChristoph Hellwig trace_xfs_trans_read_buf_io(bp, _RET_IP_); 3361da177e4SLinus Torvalds ASSERT(!XFS_BUF_ISASYNC(bp)); 3371da177e4SLinus Torvalds XFS_BUF_READ(bp); 3381da177e4SLinus Torvalds xfsbdstrat(tp->t_mountp, bp); 3391a1a3e97SChristoph Hellwig error = xfs_buf_iowait(bp); 340d64e31a2SDavid Chinner if (error) { 3411da177e4SLinus Torvalds xfs_ioerror_alert("xfs_trans_read_buf", mp, 3421da177e4SLinus Torvalds bp, blkno); 3431da177e4SLinus Torvalds xfs_buf_relse(bp); 3441da177e4SLinus Torvalds /* 345d64e31a2SDavid Chinner * We can gracefully recover from most read 346d64e31a2SDavid Chinner * errors. Ones we can't are those that happen 347d64e31a2SDavid Chinner * after the transaction's already dirty. 3481da177e4SLinus Torvalds */ 3491da177e4SLinus Torvalds if (tp->t_flags & XFS_TRANS_DIRTY) 3501da177e4SLinus Torvalds xfs_force_shutdown(tp->t_mountp, 3517d04a335SNathan Scott SHUTDOWN_META_IO_ERROR); 3521da177e4SLinus Torvalds return error; 3531da177e4SLinus Torvalds } 3541da177e4SLinus Torvalds } 3551da177e4SLinus Torvalds /* 3561da177e4SLinus Torvalds * We never locked this buf ourselves, so we shouldn't 3571da177e4SLinus Torvalds * brelse it either. Just get out. 3581da177e4SLinus Torvalds */ 3591da177e4SLinus Torvalds if (XFS_FORCED_SHUTDOWN(mp)) { 3600b1b213fSChristoph Hellwig trace_xfs_trans_read_buf_shut(bp, _RET_IP_); 3611da177e4SLinus Torvalds *bpp = NULL; 3621da177e4SLinus Torvalds return XFS_ERROR(EIO); 3631da177e4SLinus Torvalds } 3641da177e4SLinus Torvalds 3651da177e4SLinus Torvalds 366adadbeefSChristoph Hellwig bip = bp->b_fspriv; 3671da177e4SLinus Torvalds bip->bli_recur++; 3681da177e4SLinus Torvalds 3691da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 3700b1b213fSChristoph Hellwig trace_xfs_trans_read_buf_recur(bip); 3711da177e4SLinus Torvalds *bpp = bp; 3721da177e4SLinus Torvalds return 0; 3731da177e4SLinus Torvalds } 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds /* 3760cadda1cSChristoph Hellwig * We always specify the XBF_DONT_BLOCK flag within a transaction 3770cadda1cSChristoph Hellwig * so that get_buf does not try to push out a delayed write buffer 3781da177e4SLinus Torvalds * which might cause another transaction to take place (if the 3791da177e4SLinus Torvalds * buffer was delayed alloc). Such recursive transactions can 3801da177e4SLinus Torvalds * easily deadlock with our current transaction as well as cause 3811da177e4SLinus Torvalds * us to run out of stack space. 3821da177e4SLinus Torvalds */ 3830cadda1cSChristoph Hellwig bp = xfs_buf_read(target, blkno, len, flags | XBF_DONT_BLOCK); 3841da177e4SLinus Torvalds if (bp == NULL) { 3851da177e4SLinus Torvalds *bpp = NULL; 3867401aafdSDave Chinner return (flags & XBF_TRYLOCK) ? 3877401aafdSDave Chinner 0 : XFS_ERROR(ENOMEM); 3881da177e4SLinus Torvalds } 3891da177e4SLinus Torvalds if (XFS_BUF_GETERROR(bp) != 0) { 3901da177e4SLinus Torvalds XFS_BUF_SUPER_STALE(bp); 3911da177e4SLinus Torvalds error = XFS_BUF_GETERROR(bp); 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds xfs_ioerror_alert("xfs_trans_read_buf", mp, 3941da177e4SLinus Torvalds bp, blkno); 3951da177e4SLinus Torvalds if (tp->t_flags & XFS_TRANS_DIRTY) 3967d04a335SNathan Scott xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR); 3971da177e4SLinus Torvalds xfs_buf_relse(bp); 3981da177e4SLinus Torvalds return error; 3991da177e4SLinus Torvalds } 4001da177e4SLinus Torvalds #ifdef DEBUG 4011da177e4SLinus Torvalds if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) { 4021da177e4SLinus Torvalds if (xfs_error_target == target) { 4031da177e4SLinus Torvalds if (((xfs_req_num++) % xfs_error_mod) == 0) { 4041da177e4SLinus Torvalds xfs_force_shutdown(tp->t_mountp, 4057d04a335SNathan Scott SHUTDOWN_META_IO_ERROR); 4061da177e4SLinus Torvalds xfs_buf_relse(bp); 4070b932cccSDave Chinner xfs_debug(mp, "Returning trans error!"); 4081da177e4SLinus Torvalds return XFS_ERROR(EIO); 4091da177e4SLinus Torvalds } 4101da177e4SLinus Torvalds } 4111da177e4SLinus Torvalds } 4121da177e4SLinus Torvalds #endif 4131da177e4SLinus Torvalds if (XFS_FORCED_SHUTDOWN(mp)) 4141da177e4SLinus Torvalds goto shutdown_abort; 4151da177e4SLinus Torvalds 416d7e84f41SChristoph Hellwig _xfs_trans_bjoin(tp, bp, 1); 417d7e84f41SChristoph Hellwig trace_xfs_trans_read_buf(bp->b_fspriv); 4181da177e4SLinus Torvalds 4191da177e4SLinus Torvalds *bpp = bp; 4201da177e4SLinus Torvalds return 0; 4211da177e4SLinus Torvalds 4221da177e4SLinus Torvalds shutdown_abort: 4231da177e4SLinus Torvalds /* 4241da177e4SLinus Torvalds * the theory here is that buffer is good but we're 4251da177e4SLinus Torvalds * bailing out because the filesystem is being forcibly 4261da177e4SLinus Torvalds * shut down. So we should leave the b_flags alone since 4271da177e4SLinus Torvalds * the buffer's not staled and just get out. 4281da177e4SLinus Torvalds */ 4291da177e4SLinus Torvalds #if defined(DEBUG) 4301da177e4SLinus Torvalds if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp)) 4310b932cccSDave Chinner xfs_notice(mp, "about to pop assert, bp == 0x%p", bp); 4321da177e4SLinus Torvalds #endif 4330cadda1cSChristoph Hellwig ASSERT((XFS_BUF_BFLAGS(bp) & (XBF_STALE|XBF_DELWRI)) != 4340cadda1cSChristoph Hellwig (XBF_STALE|XBF_DELWRI)); 4351da177e4SLinus Torvalds 4360b1b213fSChristoph Hellwig trace_xfs_trans_read_buf_shut(bp, _RET_IP_); 4371da177e4SLinus Torvalds xfs_buf_relse(bp); 4381da177e4SLinus Torvalds *bpp = NULL; 4391da177e4SLinus Torvalds return XFS_ERROR(EIO); 4401da177e4SLinus Torvalds } 4411da177e4SLinus Torvalds 4421da177e4SLinus Torvalds 4431da177e4SLinus Torvalds /* 4441da177e4SLinus Torvalds * Release the buffer bp which was previously acquired with one of the 4451da177e4SLinus Torvalds * xfs_trans_... buffer allocation routines if the buffer has not 4461da177e4SLinus Torvalds * been modified within this transaction. If the buffer is modified 4471da177e4SLinus Torvalds * within this transaction, do decrement the recursion count but do 4481da177e4SLinus Torvalds * not release the buffer even if the count goes to 0. If the buffer is not 4491da177e4SLinus Torvalds * modified within the transaction, decrement the recursion count and 4501da177e4SLinus Torvalds * release the buffer if the recursion count goes to 0. 4511da177e4SLinus Torvalds * 4521da177e4SLinus Torvalds * If the buffer is to be released and it was not modified before 4531da177e4SLinus Torvalds * this transaction began, then free the buf_log_item associated with it. 4541da177e4SLinus Torvalds * 4551da177e4SLinus Torvalds * If the transaction pointer is NULL, make this just a normal 4561da177e4SLinus Torvalds * brelse() call. 4571da177e4SLinus Torvalds */ 4581da177e4SLinus Torvalds void 4591da177e4SLinus Torvalds xfs_trans_brelse(xfs_trans_t *tp, 4601da177e4SLinus Torvalds xfs_buf_t *bp) 4611da177e4SLinus Torvalds { 4621da177e4SLinus Torvalds xfs_buf_log_item_t *bip; 4631da177e4SLinus Torvalds 4641da177e4SLinus Torvalds /* 4651da177e4SLinus Torvalds * Default to a normal brelse() call if the tp is NULL. 4661da177e4SLinus Torvalds */ 4671da177e4SLinus Torvalds if (tp == NULL) { 468adadbeefSChristoph Hellwig struct xfs_log_item *lip = bp->b_fspriv; 469adadbeefSChristoph Hellwig 470bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == NULL); 471adadbeefSChristoph Hellwig 4721da177e4SLinus Torvalds /* 4731da177e4SLinus Torvalds * If there's a buf log item attached to the buffer, 4741da177e4SLinus Torvalds * then let the AIL know that the buffer is being 4751da177e4SLinus Torvalds * unlocked. 4761da177e4SLinus Torvalds */ 477adadbeefSChristoph Hellwig if (lip != NULL && lip->li_type == XFS_LI_BUF) { 478adadbeefSChristoph Hellwig bip = bp->b_fspriv; 479adadbeefSChristoph Hellwig xfs_trans_unlocked_item(bip->bli_item.li_ailp, lip); 4801da177e4SLinus Torvalds } 4811da177e4SLinus Torvalds xfs_buf_relse(bp); 4821da177e4SLinus Torvalds return; 4831da177e4SLinus Torvalds } 4841da177e4SLinus Torvalds 485bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 486adadbeefSChristoph Hellwig bip = bp->b_fspriv; 4871da177e4SLinus Torvalds ASSERT(bip->bli_item.li_type == XFS_LI_BUF); 4881da177e4SLinus Torvalds ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 489c1155410SDave Chinner ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 4901da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 4911da177e4SLinus Torvalds 4920b1b213fSChristoph Hellwig trace_xfs_trans_brelse(bip); 4930b1b213fSChristoph Hellwig 4941da177e4SLinus Torvalds /* 4951da177e4SLinus Torvalds * If the release is just for a recursive lock, 4961da177e4SLinus Torvalds * then decrement the count and return. 4971da177e4SLinus Torvalds */ 4981da177e4SLinus Torvalds if (bip->bli_recur > 0) { 4991da177e4SLinus Torvalds bip->bli_recur--; 5001da177e4SLinus Torvalds return; 5011da177e4SLinus Torvalds } 5021da177e4SLinus Torvalds 5031da177e4SLinus Torvalds /* 5041da177e4SLinus Torvalds * If the buffer is dirty within this transaction, we can't 5051da177e4SLinus Torvalds * release it until we commit. 5061da177e4SLinus Torvalds */ 507e98c414fSChristoph Hellwig if (bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY) 5081da177e4SLinus Torvalds return; 5091da177e4SLinus Torvalds 5101da177e4SLinus Torvalds /* 5111da177e4SLinus Torvalds * If the buffer has been invalidated, then we can't release 5121da177e4SLinus Torvalds * it until the transaction commits to disk unless it is re-dirtied 5131da177e4SLinus Torvalds * as part of this transaction. This prevents us from pulling 5141da177e4SLinus Torvalds * the item from the AIL before we should. 5151da177e4SLinus Torvalds */ 5160b1b213fSChristoph Hellwig if (bip->bli_flags & XFS_BLI_STALE) 5171da177e4SLinus Torvalds return; 5181da177e4SLinus Torvalds 5191da177e4SLinus Torvalds ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED)); 5201da177e4SLinus Torvalds 5211da177e4SLinus Torvalds /* 5221da177e4SLinus Torvalds * Free up the log item descriptor tracking the released item. 5231da177e4SLinus Torvalds */ 524e98c414fSChristoph Hellwig xfs_trans_del_item(&bip->bli_item); 5251da177e4SLinus Torvalds 5261da177e4SLinus Torvalds /* 5271da177e4SLinus Torvalds * Clear the hold flag in the buf log item if it is set. 5281da177e4SLinus Torvalds * We wouldn't want the next user of the buffer to 5291da177e4SLinus Torvalds * get confused. 5301da177e4SLinus Torvalds */ 5311da177e4SLinus Torvalds if (bip->bli_flags & XFS_BLI_HOLD) { 5321da177e4SLinus Torvalds bip->bli_flags &= ~XFS_BLI_HOLD; 5331da177e4SLinus Torvalds } 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds /* 5361da177e4SLinus Torvalds * Drop our reference to the buf log item. 5371da177e4SLinus Torvalds */ 5381da177e4SLinus Torvalds atomic_dec(&bip->bli_refcount); 5391da177e4SLinus Torvalds 5401da177e4SLinus Torvalds /* 5411da177e4SLinus Torvalds * If the buf item is not tracking data in the log, then 5421da177e4SLinus Torvalds * we must free it before releasing the buffer back to the 5431da177e4SLinus Torvalds * free pool. Before releasing the buffer to the free pool, 5441da177e4SLinus Torvalds * clear the transaction pointer in b_fsprivate2 to dissolve 5451da177e4SLinus Torvalds * its relation to this transaction. 5461da177e4SLinus Torvalds */ 5471da177e4SLinus Torvalds if (!xfs_buf_item_dirty(bip)) { 5481da177e4SLinus Torvalds /*** 5491da177e4SLinus Torvalds ASSERT(bp->b_pincount == 0); 5501da177e4SLinus Torvalds ***/ 5511da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) == 0); 5521da177e4SLinus Torvalds ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL)); 5531da177e4SLinus Torvalds ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF)); 5541da177e4SLinus Torvalds xfs_buf_item_relse(bp); 5551da177e4SLinus Torvalds bip = NULL; 5561da177e4SLinus Torvalds } 557bf9d9013SChristoph Hellwig bp->b_transp = NULL; 5581da177e4SLinus Torvalds 5591da177e4SLinus Torvalds /* 5601da177e4SLinus Torvalds * If we've still got a buf log item on the buffer, then 5611da177e4SLinus Torvalds * tell the AIL that the buffer is being unlocked. 5621da177e4SLinus Torvalds */ 5631da177e4SLinus Torvalds if (bip != NULL) { 564783a2f65SDavid Chinner xfs_trans_unlocked_item(bip->bli_item.li_ailp, 5651da177e4SLinus Torvalds (xfs_log_item_t*)bip); 5661da177e4SLinus Torvalds } 5671da177e4SLinus Torvalds 5681da177e4SLinus Torvalds xfs_buf_relse(bp); 5691da177e4SLinus Torvalds return; 5701da177e4SLinus Torvalds } 5711da177e4SLinus Torvalds 5721da177e4SLinus Torvalds /* 5731da177e4SLinus Torvalds * Mark the buffer as not needing to be unlocked when the buf item's 5741da177e4SLinus Torvalds * IOP_UNLOCK() routine is called. The buffer must already be locked 5751da177e4SLinus Torvalds * and associated with the given transaction. 5761da177e4SLinus Torvalds */ 5771da177e4SLinus Torvalds /* ARGSUSED */ 5781da177e4SLinus Torvalds void 5791da177e4SLinus Torvalds xfs_trans_bhold(xfs_trans_t *tp, 5801da177e4SLinus Torvalds xfs_buf_t *bp) 5811da177e4SLinus Torvalds { 582adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 5831da177e4SLinus Torvalds 5841da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 585bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 586adadbeefSChristoph Hellwig ASSERT(bip != NULL); 5871da177e4SLinus Torvalds ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 588c1155410SDave Chinner ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 5891da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 590adadbeefSChristoph Hellwig 5911da177e4SLinus Torvalds bip->bli_flags |= XFS_BLI_HOLD; 5920b1b213fSChristoph Hellwig trace_xfs_trans_bhold(bip); 5931da177e4SLinus Torvalds } 5941da177e4SLinus Torvalds 5951da177e4SLinus Torvalds /* 596efa092f3STim Shimmin * Cancel the previous buffer hold request made on this buffer 597efa092f3STim Shimmin * for this transaction. 598efa092f3STim Shimmin */ 599efa092f3STim Shimmin void 600efa092f3STim Shimmin xfs_trans_bhold_release(xfs_trans_t *tp, 601efa092f3STim Shimmin xfs_buf_t *bp) 602efa092f3STim Shimmin { 603adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 604efa092f3STim Shimmin 605efa092f3STim Shimmin ASSERT(XFS_BUF_ISBUSY(bp)); 606bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 607adadbeefSChristoph Hellwig ASSERT(bip != NULL); 608efa092f3STim Shimmin ASSERT(!(bip->bli_flags & XFS_BLI_STALE)); 609c1155410SDave Chinner ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_CANCEL)); 610efa092f3STim Shimmin ASSERT(atomic_read(&bip->bli_refcount) > 0); 611efa092f3STim Shimmin ASSERT(bip->bli_flags & XFS_BLI_HOLD); 6120b1b213fSChristoph Hellwig 613adadbeefSChristoph Hellwig bip->bli_flags &= ~XFS_BLI_HOLD; 6140b1b213fSChristoph Hellwig trace_xfs_trans_bhold_release(bip); 615efa092f3STim Shimmin } 616efa092f3STim Shimmin 617efa092f3STim Shimmin /* 6181da177e4SLinus Torvalds * This is called to mark bytes first through last inclusive of the given 6191da177e4SLinus Torvalds * buffer as needing to be logged when the transaction is committed. 6201da177e4SLinus Torvalds * The buffer must already be associated with the given transaction. 6211da177e4SLinus Torvalds * 6221da177e4SLinus Torvalds * First and last are numbers relative to the beginning of this buffer, 6231da177e4SLinus Torvalds * so the first byte in the buffer is numbered 0 regardless of the 6241da177e4SLinus Torvalds * value of b_blkno. 6251da177e4SLinus Torvalds */ 6261da177e4SLinus Torvalds void 6271da177e4SLinus Torvalds xfs_trans_log_buf(xfs_trans_t *tp, 6281da177e4SLinus Torvalds xfs_buf_t *bp, 6291da177e4SLinus Torvalds uint first, 6301da177e4SLinus Torvalds uint last) 6311da177e4SLinus Torvalds { 632adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 6331da177e4SLinus Torvalds 6341da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 635bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 636adadbeefSChristoph Hellwig ASSERT(bip != NULL); 6371da177e4SLinus Torvalds ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp))); 638*cb669ca5SChristoph Hellwig ASSERT(bp->b_iodone == NULL || 639*cb669ca5SChristoph Hellwig bp->b_iodone == xfs_buf_iodone_callbacks); 6401da177e4SLinus Torvalds 6411da177e4SLinus Torvalds /* 6421da177e4SLinus Torvalds * Mark the buffer as needing to be written out eventually, 6431da177e4SLinus Torvalds * and set its iodone function to remove the buffer's buf log 6441da177e4SLinus Torvalds * item from the AIL and free it when the buffer is flushed 6451da177e4SLinus Torvalds * to disk. See xfs_buf_attach_iodone() for more details 6461da177e4SLinus Torvalds * on li_cb and xfs_buf_iodone_callbacks(). 6471da177e4SLinus Torvalds * If we end up aborting this transaction, we trap this buffer 6481da177e4SLinus Torvalds * inside the b_bdstrat callback so that this won't get written to 6491da177e4SLinus Torvalds * disk. 6501da177e4SLinus Torvalds */ 6511da177e4SLinus Torvalds XFS_BUF_DELAYWRITE(bp); 6521da177e4SLinus Torvalds XFS_BUF_DONE(bp); 6531da177e4SLinus Torvalds 6541da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 655*cb669ca5SChristoph Hellwig bp->b_iodone = xfs_buf_iodone_callbacks; 656ca30b2a7SChristoph Hellwig bip->bli_item.li_cb = xfs_buf_iodone; 6571da177e4SLinus Torvalds 6580b1b213fSChristoph Hellwig trace_xfs_trans_log_buf(bip); 6590b1b213fSChristoph Hellwig 6601da177e4SLinus Torvalds /* 6611da177e4SLinus Torvalds * If we invalidated the buffer within this transaction, then 6621da177e4SLinus Torvalds * cancel the invalidation now that we're dirtying the buffer 6631da177e4SLinus Torvalds * again. There are no races with the code in xfs_buf_item_unpin(), 6641da177e4SLinus Torvalds * because we have a reference to the buffer this entire time. 6651da177e4SLinus Torvalds */ 6661da177e4SLinus Torvalds if (bip->bli_flags & XFS_BLI_STALE) { 6671da177e4SLinus Torvalds bip->bli_flags &= ~XFS_BLI_STALE; 6681da177e4SLinus Torvalds ASSERT(XFS_BUF_ISSTALE(bp)); 6691da177e4SLinus Torvalds XFS_BUF_UNSTALE(bp); 670c1155410SDave Chinner bip->bli_format.blf_flags &= ~XFS_BLF_CANCEL; 6711da177e4SLinus Torvalds } 6721da177e4SLinus Torvalds 6731da177e4SLinus Torvalds tp->t_flags |= XFS_TRANS_DIRTY; 674e98c414fSChristoph Hellwig bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; 6751da177e4SLinus Torvalds bip->bli_flags |= XFS_BLI_LOGGED; 6761da177e4SLinus Torvalds xfs_buf_item_log(bip, first, last); 6771da177e4SLinus Torvalds } 6781da177e4SLinus Torvalds 6791da177e4SLinus Torvalds 6801da177e4SLinus Torvalds /* 6811da177e4SLinus Torvalds * This called to invalidate a buffer that is being used within 6821da177e4SLinus Torvalds * a transaction. Typically this is because the blocks in the 6831da177e4SLinus Torvalds * buffer are being freed, so we need to prevent it from being 6841da177e4SLinus Torvalds * written out when we're done. Allowing it to be written again 6851da177e4SLinus Torvalds * might overwrite data in the free blocks if they are reallocated 6861da177e4SLinus Torvalds * to a file. 6871da177e4SLinus Torvalds * 6881da177e4SLinus Torvalds * We prevent the buffer from being written out by clearing the 6891da177e4SLinus Torvalds * B_DELWRI flag. We can't always 6901da177e4SLinus Torvalds * get rid of the buf log item at this point, though, because 6911da177e4SLinus Torvalds * the buffer may still be pinned by another transaction. If that 6921da177e4SLinus Torvalds * is the case, then we'll wait until the buffer is committed to 6931da177e4SLinus Torvalds * disk for the last time (we can tell by the ref count) and 6941da177e4SLinus Torvalds * free it in xfs_buf_item_unpin(). Until it is cleaned up we 6951da177e4SLinus Torvalds * will keep the buffer locked so that the buffer and buf log item 6961da177e4SLinus Torvalds * are not reused. 6971da177e4SLinus Torvalds */ 6981da177e4SLinus Torvalds void 6991da177e4SLinus Torvalds xfs_trans_binval( 7001da177e4SLinus Torvalds xfs_trans_t *tp, 7011da177e4SLinus Torvalds xfs_buf_t *bp) 7021da177e4SLinus Torvalds { 703adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 7041da177e4SLinus Torvalds 7051da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 706bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 707adadbeefSChristoph Hellwig ASSERT(bip != NULL); 7081da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 7091da177e4SLinus Torvalds 7100b1b213fSChristoph Hellwig trace_xfs_trans_binval(bip); 7110b1b213fSChristoph Hellwig 7121da177e4SLinus Torvalds if (bip->bli_flags & XFS_BLI_STALE) { 7131da177e4SLinus Torvalds /* 7141da177e4SLinus Torvalds * If the buffer is already invalidated, then 7151da177e4SLinus Torvalds * just return. 7161da177e4SLinus Torvalds */ 7171da177e4SLinus Torvalds ASSERT(!(XFS_BUF_ISDELAYWRITE(bp))); 7181da177e4SLinus Torvalds ASSERT(XFS_BUF_ISSTALE(bp)); 7191da177e4SLinus Torvalds ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY))); 720c1155410SDave Chinner ASSERT(!(bip->bli_format.blf_flags & XFS_BLF_INODE_BUF)); 721c1155410SDave Chinner ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL); 722e98c414fSChristoph Hellwig ASSERT(bip->bli_item.li_desc->lid_flags & XFS_LID_DIRTY); 7231da177e4SLinus Torvalds ASSERT(tp->t_flags & XFS_TRANS_DIRTY); 7241da177e4SLinus Torvalds return; 7251da177e4SLinus Torvalds } 7261da177e4SLinus Torvalds 7271da177e4SLinus Torvalds /* 7281da177e4SLinus Torvalds * Clear the dirty bit in the buffer and set the STALE flag 7291da177e4SLinus Torvalds * in the buf log item. The STALE flag will be used in 7301da177e4SLinus Torvalds * xfs_buf_item_unpin() to determine if it should clean up 7311da177e4SLinus Torvalds * when the last reference to the buf item is given up. 732c1155410SDave Chinner * We set the XFS_BLF_CANCEL flag in the buf log format structure 7331da177e4SLinus Torvalds * and log the buf item. This will be used at recovery time 7341da177e4SLinus Torvalds * to determine that copies of the buffer in the log before 7351da177e4SLinus Torvalds * this should not be replayed. 7361da177e4SLinus Torvalds * We mark the item descriptor and the transaction dirty so 7371da177e4SLinus Torvalds * that we'll hold the buffer until after the commit. 7381da177e4SLinus Torvalds * 7391da177e4SLinus Torvalds * Since we're invalidating the buffer, we also clear the state 7401da177e4SLinus Torvalds * about which parts of the buffer have been logged. We also 7411da177e4SLinus Torvalds * clear the flag indicating that this is an inode buffer since 7421da177e4SLinus Torvalds * the data in the buffer will no longer be valid. 7431da177e4SLinus Torvalds * 7441da177e4SLinus Torvalds * We set the stale bit in the buffer as well since we're getting 7451da177e4SLinus Torvalds * rid of it. 7461da177e4SLinus Torvalds */ 7471da177e4SLinus Torvalds XFS_BUF_UNDELAYWRITE(bp); 7481da177e4SLinus Torvalds XFS_BUF_STALE(bp); 7491da177e4SLinus Torvalds bip->bli_flags |= XFS_BLI_STALE; 750ccf7c23fSDave Chinner bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY); 751c1155410SDave Chinner bip->bli_format.blf_flags &= ~XFS_BLF_INODE_BUF; 752c1155410SDave Chinner bip->bli_format.blf_flags |= XFS_BLF_CANCEL; 7531da177e4SLinus Torvalds memset((char *)(bip->bli_format.blf_data_map), 0, 7541da177e4SLinus Torvalds (bip->bli_format.blf_map_size * sizeof(uint))); 755e98c414fSChristoph Hellwig bip->bli_item.li_desc->lid_flags |= XFS_LID_DIRTY; 7561da177e4SLinus Torvalds tp->t_flags |= XFS_TRANS_DIRTY; 7571da177e4SLinus Torvalds } 7581da177e4SLinus Torvalds 7591da177e4SLinus Torvalds /* 760ccf7c23fSDave Chinner * This call is used to indicate that the buffer contains on-disk inodes which 761ccf7c23fSDave Chinner * must be handled specially during recovery. They require special handling 762ccf7c23fSDave Chinner * because only the di_next_unlinked from the inodes in the buffer should be 763ccf7c23fSDave Chinner * recovered. The rest of the data in the buffer is logged via the inodes 764ccf7c23fSDave Chinner * themselves. 7651da177e4SLinus Torvalds * 766ccf7c23fSDave Chinner * All we do is set the XFS_BLI_INODE_BUF flag in the items flags so it can be 767ccf7c23fSDave Chinner * transferred to the buffer's log format structure so that we'll know what to 768ccf7c23fSDave Chinner * do at recovery time. 7691da177e4SLinus Torvalds */ 7701da177e4SLinus Torvalds void 7711da177e4SLinus Torvalds xfs_trans_inode_buf( 7721da177e4SLinus Torvalds xfs_trans_t *tp, 7731da177e4SLinus Torvalds xfs_buf_t *bp) 7741da177e4SLinus Torvalds { 775adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 7761da177e4SLinus Torvalds 7771da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 778bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 779adadbeefSChristoph Hellwig ASSERT(bip != NULL); 7801da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 7811da177e4SLinus Torvalds 782ccf7c23fSDave Chinner bip->bli_flags |= XFS_BLI_INODE_BUF; 7831da177e4SLinus Torvalds } 7841da177e4SLinus Torvalds 7851da177e4SLinus Torvalds /* 7861da177e4SLinus Torvalds * This call is used to indicate that the buffer is going to 7871da177e4SLinus Torvalds * be staled and was an inode buffer. This means it gets 7881da177e4SLinus Torvalds * special processing during unpin - where any inodes 7891da177e4SLinus Torvalds * associated with the buffer should be removed from ail. 7901da177e4SLinus Torvalds * There is also special processing during recovery, 7911da177e4SLinus Torvalds * any replay of the inodes in the buffer needs to be 7921da177e4SLinus Torvalds * prevented as the buffer may have been reused. 7931da177e4SLinus Torvalds */ 7941da177e4SLinus Torvalds void 7951da177e4SLinus Torvalds xfs_trans_stale_inode_buf( 7961da177e4SLinus Torvalds xfs_trans_t *tp, 7971da177e4SLinus Torvalds xfs_buf_t *bp) 7981da177e4SLinus Torvalds { 799adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 8001da177e4SLinus Torvalds 8011da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 802bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 803adadbeefSChristoph Hellwig ASSERT(bip != NULL); 8041da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 8051da177e4SLinus Torvalds 8061da177e4SLinus Torvalds bip->bli_flags |= XFS_BLI_STALE_INODE; 807ca30b2a7SChristoph Hellwig bip->bli_item.li_cb = xfs_buf_iodone; 8081da177e4SLinus Torvalds } 8091da177e4SLinus Torvalds 8101da177e4SLinus Torvalds /* 8111da177e4SLinus Torvalds * Mark the buffer as being one which contains newly allocated 8121da177e4SLinus Torvalds * inodes. We need to make sure that even if this buffer is 8131da177e4SLinus Torvalds * relogged as an 'inode buf' we still recover all of the inode 8141da177e4SLinus Torvalds * images in the face of a crash. This works in coordination with 8151da177e4SLinus Torvalds * xfs_buf_item_committed() to ensure that the buffer remains in the 8161da177e4SLinus Torvalds * AIL at its original location even after it has been relogged. 8171da177e4SLinus Torvalds */ 8181da177e4SLinus Torvalds /* ARGSUSED */ 8191da177e4SLinus Torvalds void 8201da177e4SLinus Torvalds xfs_trans_inode_alloc_buf( 8211da177e4SLinus Torvalds xfs_trans_t *tp, 8221da177e4SLinus Torvalds xfs_buf_t *bp) 8231da177e4SLinus Torvalds { 824adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 8251da177e4SLinus Torvalds 8261da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 827bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 828adadbeefSChristoph Hellwig ASSERT(bip != NULL); 8291da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 8301da177e4SLinus Torvalds 8311da177e4SLinus Torvalds bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF; 8321da177e4SLinus Torvalds } 8331da177e4SLinus Torvalds 8341da177e4SLinus Torvalds 8351da177e4SLinus Torvalds /* 8361da177e4SLinus Torvalds * Similar to xfs_trans_inode_buf(), this marks the buffer as a cluster of 8371da177e4SLinus Torvalds * dquots. However, unlike in inode buffer recovery, dquot buffers get 8381da177e4SLinus Torvalds * recovered in their entirety. (Hence, no XFS_BLI_DQUOT_ALLOC_BUF flag). 8391da177e4SLinus Torvalds * The only thing that makes dquot buffers different from regular 8401da177e4SLinus Torvalds * buffers is that we must not replay dquot bufs when recovering 8411da177e4SLinus Torvalds * if a _corresponding_ quotaoff has happened. We also have to distinguish 8421da177e4SLinus Torvalds * between usr dquot bufs and grp dquot bufs, because usr and grp quotas 8431da177e4SLinus Torvalds * can be turned off independently. 8441da177e4SLinus Torvalds */ 8451da177e4SLinus Torvalds /* ARGSUSED */ 8461da177e4SLinus Torvalds void 8471da177e4SLinus Torvalds xfs_trans_dquot_buf( 8481da177e4SLinus Torvalds xfs_trans_t *tp, 8491da177e4SLinus Torvalds xfs_buf_t *bp, 8501da177e4SLinus Torvalds uint type) 8511da177e4SLinus Torvalds { 852adadbeefSChristoph Hellwig xfs_buf_log_item_t *bip = bp->b_fspriv; 8531da177e4SLinus Torvalds 8541da177e4SLinus Torvalds ASSERT(XFS_BUF_ISBUSY(bp)); 855bf9d9013SChristoph Hellwig ASSERT(bp->b_transp == tp); 856adadbeefSChristoph Hellwig ASSERT(bip != NULL); 857c1155410SDave Chinner ASSERT(type == XFS_BLF_UDQUOT_BUF || 858c1155410SDave Chinner type == XFS_BLF_PDQUOT_BUF || 859c1155410SDave Chinner type == XFS_BLF_GDQUOT_BUF); 8601da177e4SLinus Torvalds ASSERT(atomic_read(&bip->bli_refcount) > 0); 8611da177e4SLinus Torvalds 8621da177e4SLinus Torvalds bip->bli_format.blf_flags |= type; 8631da177e4SLinus Torvalds } 864