···794794795795Roadmap:796796797797-2.6.35 Inclusion in mainline as an experimental mount option798798- => approximately 2-3 months to merge window799799- => needs to be in xfs-dev tree in 4-6 weeks800800- => code is nearing readiness for review801801-8027972.6.37 Remove experimental tag from mount option803798 => should be roughly 6 months after initial merge804799 => enough time to:
+15
fs/xfs/linux-2.6/xfs_aops.c
···13331333 trace_xfs_writepage(inode, page, 0);1334133413351335 /*13361336+ * Refuse to write the page out if we are called from reclaim context.13371337+ *13381338+ * This is primarily to avoid stack overflows when called from deep13391339+ * used stacks in random callers for direct reclaim, but disabling13401340+ * reclaim for kswap is a nice side-effect as kswapd causes rather13411341+ * suboptimal I/O patters, too.13421342+ *13431343+ * This should really be done by the core VM, but until that happens13441344+ * filesystems like XFS, btrfs and ext4 have to take care of this13451345+ * by themselves.13461346+ */13471347+ if (current->flags & PF_MEMALLOC)13481348+ goto out_fail;13491349+13501350+ /*13361351 * We need a transaction if:13371352 * 1. There are delalloc buffers on the page13381353 * 2. The page is uptodate and we have unmapped buffers
+13-3
fs/xfs/linux-2.6/xfs_iops.c
···585585 bf.l_len = len;586586587587 xfs_ilock(ip, XFS_IOLOCK_EXCL);588588+589589+ /* check the new inode size is valid before allocating */590590+ if (!(mode & FALLOC_FL_KEEP_SIZE) &&591591+ offset + len > i_size_read(inode)) {592592+ new_size = offset + len;593593+ error = inode_newsize_ok(inode, new_size);594594+ if (error)595595+ goto out_unlock;596596+ }597597+588598 error = -xfs_change_file_space(ip, XFS_IOC_RESVSP, &bf,589599 0, XFS_ATTR_NOLOCK);590590- if (!error && !(mode & FALLOC_FL_KEEP_SIZE) &&591591- offset + len > i_size_read(inode))592592- new_size = offset + len;600600+ if (error)601601+ goto out_unlock;593602594603 /* Change file size if needed */595604 if (new_size) {···609600 error = -xfs_setattr(ip, &iattr, XFS_ATTR_NOLOCK);610601 }611602603603+out_unlock:612604 xfs_iunlock(ip, XFS_IOLOCK_EXCL);613605out_error:614606 return error;
···227227228228 atomic_t pagf_fstrms; /* # of filestreams active in this AG */229229230230- int pag_ici_init; /* incore inode cache initialised */231230 rwlock_t pag_ici_lock; /* incore inode lock */232231 struct radix_tree_root pag_ici_root; /* incore inode cache root */233232 int pag_ici_reclaimable; /* reclaimable inodes */
+10-19
fs/xfs/xfs_iget.c
···382382383383 /* get the perag structure and ensure that it's inode capable */384384 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino));385385- if (!pag->pagi_inodeok)386386- return EINVAL;387387- ASSERT(pag->pag_ici_init);388385 agino = XFS_INO_TO_AGINO(mp, ino);389386390387again:···741744}742745743746#ifdef DEBUG744744-/*745745- * Debug-only routine, without additional rw_semaphore APIs, we can746746- * now only answer requests regarding whether we hold the lock for write747747- * (reader state is outside our visibility, we only track writer state).748748- *749749- * Note: this means !xfs_isilocked would give false positives, so don't do that.750750- */751747int752748xfs_isilocked(753749 xfs_inode_t *ip,754750 uint lock_flags)755751{756756- if ((lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) ==757757- XFS_ILOCK_EXCL) {758758- if (!ip->i_lock.mr_writer)759759- return 0;752752+ if (lock_flags & (XFS_ILOCK_EXCL|XFS_ILOCK_SHARED)) {753753+ if (!(lock_flags & XFS_ILOCK_SHARED))754754+ return !!ip->i_lock.mr_writer;755755+ return rwsem_is_locked(&ip->i_lock.mr_lock);760756 }761757762762- if ((lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) ==763763- XFS_IOLOCK_EXCL) {764764- if (!ip->i_iolock.mr_writer)765765- return 0;758758+ if (lock_flags & (XFS_IOLOCK_EXCL|XFS_IOLOCK_SHARED)) {759759+ if (!(lock_flags & XFS_IOLOCK_SHARED))760760+ return !!ip->i_iolock.mr_writer;761761+ return rwsem_is_locked(&ip->i_iolock.mr_lock);766762 }767763768768- return 1;764764+ ASSERT(0);765765+ return 0;769766}770767#endif
+66-86
fs/xfs/xfs_inode.c
···19401940 int blks_per_cluster;19411941 int nbufs;19421942 int ninodes;19431943- int i, j, found, pre_flushed;19431943+ int i, j;19441944 xfs_daddr_t blkno;19451945 xfs_buf_t *bp;19461946- xfs_inode_t *ip, **ip_found;19461946+ xfs_inode_t *ip;19471947 xfs_inode_log_item_t *iip;19481948 xfs_log_item_t *lip;19491949 struct xfs_perag *pag;···19601960 nbufs = XFS_IALLOC_BLOCKS(mp) / blks_per_cluster;19611961 }1962196219631963- ip_found = kmem_alloc(ninodes * sizeof(xfs_inode_t *), KM_NOFS);19641964-19651963 for (j = 0; j < nbufs; j++, inum += ninodes) {19641964+ int found = 0;19651965+19661966 blkno = XFS_AGB_TO_DADDR(mp, XFS_INO_TO_AGNO(mp, inum),19671967 XFS_INO_TO_AGBNO(mp, inum));1968196819691969-19701969 /*19711971- * Look for each inode in memory and attempt to lock it,19721972- * we can be racing with flush and tail pushing here.19731973- * any inode we get the locks on, add to an array of19741974- * inode items to process later.19751975- *19761976- * The get the buffer lock, we could beat a flush19771977- * or tail pushing thread to the lock here, in which19781978- * case they will go looking for the inode buffer19791979- * and fail, we need some other form of interlock19801980- * here.19701970+ * We obtain and lock the backing buffer first in the process19711971+ * here, as we have to ensure that any dirty inode that we19721972+ * can't get the flush lock on is attached to the buffer.19731973+ * If we scan the in-memory inodes first, then buffer IO can19741974+ * complete before we get a lock on it, and hence we may fail19751975+ * to mark all the active inodes on the buffer stale.19811976 */19821982- found = 0;19831983- for (i = 0; i < ninodes; i++) {19841984- read_lock(&pag->pag_ici_lock);19851985- ip = radix_tree_lookup(&pag->pag_ici_root,19861986- XFS_INO_TO_AGINO(mp, (inum + i)));19871987-19881988- /* Inode not in memory or we found it already,19891989- * nothing to do19901990- */19911991- if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {19921992- read_unlock(&pag->pag_ici_lock);19931993- continue;19941994- }19951995-19961996- if (xfs_inode_clean(ip)) {19971997- read_unlock(&pag->pag_ici_lock);19981998- continue;19991999- }20002000-20012001- /* If we can get the locks then add it to the20022002- * list, otherwise by the time we get the bp lock20032003- * below it will already be attached to the20042004- * inode buffer.20052005- */20062006-20072007- /* This inode will already be locked - by us, lets20082008- * keep it that way.20092009- */20102010-20112011- if (ip == free_ip) {20122012- if (xfs_iflock_nowait(ip)) {20132013- xfs_iflags_set(ip, XFS_ISTALE);20142014- if (xfs_inode_clean(ip)) {20152015- xfs_ifunlock(ip);20162016- } else {20172017- ip_found[found++] = ip;20182018- }20192019- }20202020- read_unlock(&pag->pag_ici_lock);20212021- continue;20222022- }20232023-20242024- if (xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {20252025- if (xfs_iflock_nowait(ip)) {20262026- xfs_iflags_set(ip, XFS_ISTALE);20272027-20282028- if (xfs_inode_clean(ip)) {20292029- xfs_ifunlock(ip);20302030- xfs_iunlock(ip, XFS_ILOCK_EXCL);20312031- } else {20322032- ip_found[found++] = ip;20332033- }20342034- } else {20352035- xfs_iunlock(ip, XFS_ILOCK_EXCL);20362036- }20372037- }20382038- read_unlock(&pag->pag_ici_lock);20392039- }20402040-20412041- bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, 19771977+ bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,20421978 mp->m_bsize * blks_per_cluster,20431979 XBF_LOCK);2044198020452045- pre_flushed = 0;19811981+ /*19821982+ * Walk the inodes already attached to the buffer and mark them19831983+ * stale. These will all have the flush locks held, so an19841984+ * in-memory inode walk can't lock them.19851985+ */20461986 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);20471987 while (lip) {20481988 if (lip->li_type == XFS_LI_INODE) {···19932053 &iip->ili_flush_lsn,19942054 &iip->ili_item.li_lsn);19952055 xfs_iflags_set(iip->ili_inode, XFS_ISTALE);19961996- pre_flushed++;20562056+ found++;19972057 }19982058 lip = lip->li_bio_list;19992059 }2000206020012001- for (i = 0; i < found; i++) {20022002- ip = ip_found[i];20032003- iip = ip->i_itemp;20612061+ /*20622062+ * For each inode in memory attempt to add it to the inode20632063+ * buffer and set it up for being staled on buffer IO20642064+ * completion. This is safe as we've locked out tail pushing20652065+ * and flushing by locking the buffer.20662066+ *20672067+ * We have already marked every inode that was part of a20682068+ * transaction stale above, which means there is no point in20692069+ * even trying to lock them.20702070+ */20712071+ for (i = 0; i < ninodes; i++) {20722072+ read_lock(&pag->pag_ici_lock);20732073+ ip = radix_tree_lookup(&pag->pag_ici_root,20742074+ XFS_INO_TO_AGINO(mp, (inum + i)));2004207520762076+ /* Inode not in memory or stale, nothing to do */20772077+ if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) {20782078+ read_unlock(&pag->pag_ici_lock);20792079+ continue;20802080+ }20812081+20822082+ /* don't try to lock/unlock the current inode */20832083+ if (ip != free_ip &&20842084+ !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) {20852085+ read_unlock(&pag->pag_ici_lock);20862086+ continue;20872087+ }20882088+ read_unlock(&pag->pag_ici_lock);20892089+20902090+ if (!xfs_iflock_nowait(ip)) {20912091+ if (ip != free_ip)20922092+ xfs_iunlock(ip, XFS_ILOCK_EXCL);20932093+ continue;20942094+ }20952095+20962096+ xfs_iflags_set(ip, XFS_ISTALE);20972097+ if (xfs_inode_clean(ip)) {20982098+ ASSERT(ip != free_ip);20992099+ xfs_ifunlock(ip);21002100+ xfs_iunlock(ip, XFS_ILOCK_EXCL);21012101+ continue;21022102+ }21032103+21042104+ iip = ip->i_itemp;20052105 if (!iip) {21062106+ /* inode with unlogged changes only */21072107+ ASSERT(ip != free_ip);20062108 ip->i_update_core = 0;20072109 xfs_ifunlock(ip);20082110 xfs_iunlock(ip, XFS_ILOCK_EXCL);20092111 continue;20102112 }21132113+ found++;2011211420122115 iip->ili_last_fields = iip->ili_format.ilf_fields;20132116 iip->ili_format.ilf_fields = 0;···20612078 xfs_buf_attach_iodone(bp,20622079 (void(*)(xfs_buf_t*,xfs_log_item_t*))20632080 xfs_istale_done, (xfs_log_item_t *)iip);20642064- if (ip != free_ip) {20812081+20822082+ if (ip != free_ip)20652083 xfs_iunlock(ip, XFS_ILOCK_EXCL);20662066- }20672084 }2068208520692069- if (found || pre_flushed)20862086+ if (found)20702087 xfs_trans_stale_inode_buf(tp, bp);20712088 xfs_trans_binval(tp, bp);20722089 }2073209020742074- kmem_free(ip_found);20752091 xfs_perag_put(pag);20762092}20772093···26312649 int i;2632265026332651 pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));26342634- ASSERT(pag->pagi_inodeok);26352635- ASSERT(pag->pag_ici_init);2636265226372653 inodes_per_cluster = XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog;26382654 ilist_size = inodes_per_cluster * sizeof(xfs_inode_t *);
···268268269269#if XFS_BIG_BLKNOS /* Limited by ULONG_MAX of page cache index */270270 if (nblocks >> (PAGE_CACHE_SHIFT - sbp->sb_blocklog) > ULONG_MAX)271271- return E2BIG;271271+ return EFBIG;272272#else /* Limited by UINT_MAX of sectors */273273 if (nblocks << (sbp->sb_blocklog - BBSHIFT) > UINT_MAX)274274- return E2BIG;274274+ return EFBIG;275275#endif276276 return 0;277277}···393393 xfs_sb_validate_fsb_count(sbp, sbp->sb_rblocks)) {394394 xfs_fs_mount_cmn_err(flags,395395 "file system too large to be mounted on this system.");396396- return XFS_ERROR(E2BIG);396396+ return XFS_ERROR(EFBIG);397397 }398398399399 if (unlikely(sbp->sb_inprogress)) {···413413 return 0;414414}415415416416-STATIC void417417-xfs_initialize_perag_icache(418418- xfs_perag_t *pag)419419-{420420- if (!pag->pag_ici_init) {421421- rwlock_init(&pag->pag_ici_lock);422422- INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);423423- pag->pag_ici_init = 1;424424- }425425-}426426-427416int428417xfs_initialize_perag(429418 xfs_mount_t *mp,···425436 xfs_agino_t agino;426437 xfs_ino_t ino;427438 xfs_sb_t *sbp = &mp->m_sb;428428- xfs_ino_t max_inum = XFS_MAXINUMBER_32;429439 int error = -ENOMEM;430430-431431- /* Check to see if the filesystem can overflow 32 bit inodes */432432- agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);433433- ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);434440435441 /*436442 * Walk the current per-ag tree so we don't try to initialise AGs···440456 }441457 if (!first_initialised)442458 first_initialised = index;459459+443460 pag = kmem_zalloc(sizeof(*pag), KM_MAYFAIL);444461 if (!pag)445462 goto out_unwind;463463+ pag->pag_agno = index;464464+ pag->pag_mount = mp;465465+ rwlock_init(&pag->pag_ici_lock);466466+ INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);467467+446468 if (radix_tree_preload(GFP_NOFS))447469 goto out_unwind;470470+448471 spin_lock(&mp->m_perag_lock);449472 if (radix_tree_insert(&mp->m_perag_tree, index, pag)) {450473 BUG();···460469 error = -EEXIST;461470 goto out_unwind;462471 }463463- pag->pag_agno = index;464464- pag->pag_mount = mp;465472 spin_unlock(&mp->m_perag_lock);466473 radix_tree_preload_end();467474 }468475469469- /* Clear the mount flag if no inode can overflow 32 bits470470- * on this filesystem, or if specifically requested..476476+ /*477477+ * If we mount with the inode64 option, or no inode overflows478478+ * the legacy 32-bit address space clear the inode32 option.471479 */472472- if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > max_inum) {473473- mp->m_flags |= XFS_MOUNT_32BITINODES;474474- } else {475475- mp->m_flags &= ~XFS_MOUNT_32BITINODES;476476- }480480+ agino = XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);481481+ ino = XFS_AGINO_TO_INO(mp, agcount - 1, agino);477482478478- /* If we can overflow then setup the ag headers accordingly */483483+ if ((mp->m_flags & XFS_MOUNT_SMALL_INUMS) && ino > XFS_MAXINUMBER_32)484484+ mp->m_flags |= XFS_MOUNT_32BITINODES;485485+ else486486+ mp->m_flags &= ~XFS_MOUNT_32BITINODES;487487+479488 if (mp->m_flags & XFS_MOUNT_32BITINODES) {480480- /* Calculate how much should be reserved for inodes to481481- * meet the max inode percentage.489489+ /*490490+ * Calculate how much should be reserved for inodes to meet491491+ * the max inode percentage.482492 */483493 if (mp->m_maxicount) {484494 __uint64_t icount;···492500 } else {493501 max_metadata = agcount;494502 }503503+495504 for (index = 0; index < agcount; index++) {496505 ino = XFS_AGINO_TO_INO(mp, index, agino);497497- if (ino > max_inum) {506506+ if (ino > XFS_MAXINUMBER_32) {498507 index++;499508 break;500509 }501510502502- /* This ag is preferred for inodes */503511 pag = xfs_perag_get(mp, index);504512 pag->pagi_inodeok = 1;505513 if (index < max_metadata)506514 pag->pagf_metadata = 1;507507- xfs_initialize_perag_icache(pag);508515 xfs_perag_put(pag);509516 }510517 } else {511511- /* Setup default behavior for smaller filesystems */512518 for (index = 0; index < agcount; index++) {513519 pag = xfs_perag_get(mp, index);514520 pag->pagi_inodeok = 1;515515- xfs_initialize_perag_icache(pag);516521 xfs_perag_put(pag);517522 }518523 }524524+519525 if (maxagi)520526 *maxagi = index;521527 return 0;···9991009 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);10001010 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_dblocks) {10011011 cmn_err(CE_WARN, "XFS: size check 1 failed");10021002- return XFS_ERROR(E2BIG);10121012+ return XFS_ERROR(EFBIG);10031013 }10041014 error = xfs_read_buf(mp, mp->m_ddev_targp,10051015 d - XFS_FSS_TO_BB(mp, 1),···10091019 } else {10101020 cmn_err(CE_WARN, "XFS: size check 2 failed");10111021 if (error == ENOSPC)10121012- error = XFS_ERROR(E2BIG);10221022+ error = XFS_ERROR(EFBIG);10131023 return error;10141024 }10151025···10171027 d = (xfs_daddr_t)XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);10181028 if (XFS_BB_TO_FSB(mp, d) != mp->m_sb.sb_logblocks) {10191029 cmn_err(CE_WARN, "XFS: size check 3 failed");10201020- return XFS_ERROR(E2BIG);10301030+ return XFS_ERROR(EFBIG);10211031 }10221032 error = xfs_read_buf(mp, mp->m_logdev_targp,10231033 d - XFS_FSB_TO_BB(mp, 1),···10271037 } else {10281038 cmn_err(CE_WARN, "XFS: size check 3 failed");10291039 if (error == ENOSPC)10301030- error = XFS_ERROR(E2BIG);10401040+ error = XFS_ERROR(EFBIG);10311041 return error;10321042 }10331043 }···12441254 * Allocate and initialize the per-ag data.12451255 */12461256 spin_lock_init(&mp->m_perag_lock);12471247- INIT_RADIX_TREE(&mp->m_perag_tree, GFP_NOFS);12571257+ INIT_RADIX_TREE(&mp->m_perag_tree, GFP_ATOMIC);12481258 error = xfs_initialize_perag(mp, sbp->sb_agcount, &mp->m_maxagi);12491259 if (error) {12501260 cmn_err(CE_WARN, "XFS: Failed per-ag init: %d", error);
+2-2
fs/xfs/xfs_rtalloc.c
···22472247 cmn_err(CE_WARN, "XFS: realtime mount -- %llu != %llu",22482248 (unsigned long long) XFS_BB_TO_FSB(mp, d),22492249 (unsigned long long) mp->m_sb.sb_rblocks);22502250- return XFS_ERROR(E2BIG);22502250+ return XFS_ERROR(EFBIG);22512251 }22522252 error = xfs_read_buf(mp, mp->m_rtdev_targp,22532253 d - XFS_FSB_TO_BB(mp, 1),···22562256 cmn_err(CE_WARN,22572257 "XFS: realtime mount -- xfs_read_buf failed, returned %d", error);22582258 if (error == ENOSPC)22592259- return XFS_ERROR(E2BIG);22592259+ return XFS_ERROR(EFBIG);22602260 return error;22612261 }22622262 xfs_buf_relse(bp);
+10-1
fs/xfs/xfs_rtalloc.h
···147147# define xfs_rtfree_extent(t,b,l) (ENOSYS)148148# define xfs_rtpick_extent(m,t,l,rb) (ENOSYS)149149# define xfs_growfs_rt(mp,in) (ENOSYS)150150-# define xfs_rtmount_init(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))150150+static inline int /* error */151151+xfs_rtmount_init(152152+ xfs_mount_t *mp) /* file system mount structure */153153+{154154+ if (mp->m_sb.sb_rblocks == 0)155155+ return 0;156156+157157+ cmn_err(CE_WARN, "XFS: Not built with CONFIG_XFS_RT");158158+ return ENOSYS;159159+}151160# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))152161# define xfs_rtunmount_inodes(m)153162#endif /* CONFIG_XFS_RT */
+400-46
fs/xfs/xfs_trans.c
···48484949kmem_zone_t *xfs_trans_zone;50505151+5152/*5252- * Reservation functions here avoid a huge stack in xfs_trans_init5353- * due to register overflow from temporaries in the calculations.5353+ * Various log reservation values.5454+ *5555+ * These are based on the size of the file system block because that is what5656+ * most transactions manipulate. Each adds in an additional 128 bytes per5757+ * item logged to try to account for the overhead of the transaction mechanism.5858+ *5959+ * Note: Most of the reservations underestimate the number of allocation6060+ * groups into which they could free extents in the xfs_bmap_finish() call.6161+ * This is because the number in the worst case is quite high and quite6262+ * unusual. In order to fix this we need to change xfs_bmap_finish() to free6363+ * extents in only a single AG at a time. This will require changes to the6464+ * EFI code as well, however, so that the EFI for the extents not freed is6565+ * logged again in each transaction. See SGI PV #261917.6666+ *6767+ * Reservation functions here avoid a huge stack in xfs_trans_init due to6868+ * register overflow from temporaries in the calculations.6969+ */7070+7171+7272+/*7373+ * In a write transaction we can allocate a maximum of 27474+ * extents. This gives:7575+ * the inode getting the new extents: inode size7676+ * the inode's bmap btree: max depth * block size7777+ * the agfs of the ags from which the extents are allocated: 2 * sector7878+ * the superblock free block counter: sector size7979+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size8080+ * And the bmap_finish transaction can free bmap blocks in a join:8181+ * the agfs of the ags containing the blocks: 2 * sector size8282+ * the agfls of the ags containing the blocks: 2 * sector size8383+ * the super block free block counter: sector size8484+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size5485 */5586STATIC uint5656-xfs_calc_write_reservation(xfs_mount_t *mp)8787+xfs_calc_write_reservation(8888+ struct xfs_mount *mp)5789{5858- return XFS_CALC_WRITE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);9090+ return XFS_DQUOT_LOGRES(mp) +9191+ MAX((mp->m_sb.sb_inodesize +9292+ XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) +9393+ 2 * mp->m_sb.sb_sectsize +9494+ mp->m_sb.sb_sectsize +9595+ XFS_ALLOCFREE_LOG_RES(mp, 2) +9696+ 128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) +9797+ XFS_ALLOCFREE_LOG_COUNT(mp, 2))),9898+ (2 * mp->m_sb.sb_sectsize +9999+ 2 * mp->m_sb.sb_sectsize +100100+ mp->m_sb.sb_sectsize +101101+ XFS_ALLOCFREE_LOG_RES(mp, 2) +102102+ 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));59103}60104105105+/*106106+ * In truncating a file we free up to two extents at once. We can modify:107107+ * the inode being truncated: inode size108108+ * the inode's bmap btree: (max depth + 1) * block size109109+ * And the bmap_finish transaction can free the blocks and bmap blocks:110110+ * the agf for each of the ags: 4 * sector size111111+ * the agfl for each of the ags: 4 * sector size112112+ * the super block to reflect the freed blocks: sector size113113+ * worst case split in allocation btrees per extent assuming 4 extents:114114+ * 4 exts * 2 trees * (2 * max depth - 1) * block size115115+ * the inode btree: max depth * blocksize116116+ * the allocation btrees: 2 trees * (max depth - 1) * block size117117+ */61118STATIC uint6262-xfs_calc_itruncate_reservation(xfs_mount_t *mp)119119+xfs_calc_itruncate_reservation(120120+ struct xfs_mount *mp)63121{6464- return XFS_CALC_ITRUNCATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);122122+ return XFS_DQUOT_LOGRES(mp) +123123+ MAX((mp->m_sb.sb_inodesize +124124+ XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) +125125+ 128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))),126126+ (4 * mp->m_sb.sb_sectsize +127127+ 4 * mp->m_sb.sb_sectsize +128128+ mp->m_sb.sb_sectsize +129129+ XFS_ALLOCFREE_LOG_RES(mp, 4) +130130+ 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4)) +131131+ 128 * 5 +132132+ XFS_ALLOCFREE_LOG_RES(mp, 1) +133133+ 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +134134+ XFS_ALLOCFREE_LOG_COUNT(mp, 1))));65135}66136137137+/*138138+ * In renaming a files we can modify:139139+ * the four inodes involved: 4 * inode size140140+ * the two directory btrees: 2 * (max depth + v2) * dir block size141141+ * the two directory bmap btrees: 2 * max depth * block size142142+ * And the bmap_finish transaction can free dir and bmap blocks (two sets143143+ * of bmap blocks) giving:144144+ * the agf for the ags in which the blocks live: 3 * sector size145145+ * the agfl for the ags in which the blocks live: 3 * sector size146146+ * the superblock for the free block count: sector size147147+ * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size148148+ */67149STATIC uint6868-xfs_calc_rename_reservation(xfs_mount_t *mp)150150+xfs_calc_rename_reservation(151151+ struct xfs_mount *mp)69152{7070- return XFS_CALC_RENAME_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);153153+ return XFS_DQUOT_LOGRES(mp) +154154+ MAX((4 * mp->m_sb.sb_inodesize +155155+ 2 * XFS_DIROP_LOG_RES(mp) +156156+ 128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp))),157157+ (3 * mp->m_sb.sb_sectsize +158158+ 3 * mp->m_sb.sb_sectsize +159159+ mp->m_sb.sb_sectsize +160160+ XFS_ALLOCFREE_LOG_RES(mp, 3) +161161+ 128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))));71162}72163164164+/*165165+ * For creating a link to an inode:166166+ * the parent directory inode: inode size167167+ * the linked inode: inode size168168+ * the directory btree could split: (max depth + v2) * dir block size169169+ * the directory bmap btree could join or split: (max depth + v2) * blocksize170170+ * And the bmap_finish transaction can free some bmap blocks giving:171171+ * the agf for the ag in which the blocks live: sector size172172+ * the agfl for the ag in which the blocks live: sector size173173+ * the superblock for the free block count: sector size174174+ * the allocation btrees: 2 trees * (2 * max depth - 1) * block size175175+ */73176STATIC uint7474-xfs_calc_link_reservation(xfs_mount_t *mp)177177+xfs_calc_link_reservation(178178+ struct xfs_mount *mp)75179{7676- return XFS_CALC_LINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);180180+ return XFS_DQUOT_LOGRES(mp) +181181+ MAX((mp->m_sb.sb_inodesize +182182+ mp->m_sb.sb_inodesize +183183+ XFS_DIROP_LOG_RES(mp) +184184+ 128 * (2 + XFS_DIROP_LOG_COUNT(mp))),185185+ (mp->m_sb.sb_sectsize +186186+ mp->m_sb.sb_sectsize +187187+ mp->m_sb.sb_sectsize +188188+ XFS_ALLOCFREE_LOG_RES(mp, 1) +189189+ 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))));77190}78191192192+/*193193+ * For removing a directory entry we can modify:194194+ * the parent directory inode: inode size195195+ * the removed inode: inode size196196+ * the directory btree could join: (max depth + v2) * dir block size197197+ * the directory bmap btree could join or split: (max depth + v2) * blocksize198198+ * And the bmap_finish transaction can free the dir and bmap blocks giving:199199+ * the agf for the ag in which the blocks live: 2 * sector size200200+ * the agfl for the ag in which the blocks live: 2 * sector size201201+ * the superblock for the free block count: sector size202202+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size203203+ */79204STATIC uint8080-xfs_calc_remove_reservation(xfs_mount_t *mp)205205+xfs_calc_remove_reservation(206206+ struct xfs_mount *mp)81207{8282- return XFS_CALC_REMOVE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);208208+ return XFS_DQUOT_LOGRES(mp) +209209+ MAX((mp->m_sb.sb_inodesize +210210+ mp->m_sb.sb_inodesize +211211+ XFS_DIROP_LOG_RES(mp) +212212+ 128 * (2 + XFS_DIROP_LOG_COUNT(mp))),213213+ (2 * mp->m_sb.sb_sectsize +214214+ 2 * mp->m_sb.sb_sectsize +215215+ mp->m_sb.sb_sectsize +216216+ XFS_ALLOCFREE_LOG_RES(mp, 2) +217217+ 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));83218}84219220220+/*221221+ * For symlink we can modify:222222+ * the parent directory inode: inode size223223+ * the new inode: inode size224224+ * the inode btree entry: 1 block225225+ * the directory btree: (max depth + v2) * dir block size226226+ * the directory inode's bmap btree: (max depth + v2) * block size227227+ * the blocks for the symlink: 1 kB228228+ * Or in the first xact we allocate some inodes giving:229229+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize230230+ * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize231231+ * the inode btree: max depth * blocksize232232+ * the allocation btrees: 2 trees * (2 * max depth - 1) * block size233233+ */85234STATIC uint8686-xfs_calc_symlink_reservation(xfs_mount_t *mp)235235+xfs_calc_symlink_reservation(236236+ struct xfs_mount *mp)87237{8888- return XFS_CALC_SYMLINK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);238238+ return XFS_DQUOT_LOGRES(mp) +239239+ MAX((mp->m_sb.sb_inodesize +240240+ mp->m_sb.sb_inodesize +241241+ XFS_FSB_TO_B(mp, 1) +242242+ XFS_DIROP_LOG_RES(mp) +243243+ 1024 +244244+ 128 * (4 + XFS_DIROP_LOG_COUNT(mp))),245245+ (2 * mp->m_sb.sb_sectsize +246246+ XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) +247247+ XFS_FSB_TO_B(mp, mp->m_in_maxlevels) +248248+ XFS_ALLOCFREE_LOG_RES(mp, 1) +249249+ 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +250250+ XFS_ALLOCFREE_LOG_COUNT(mp, 1))));89251}90252253253+/*254254+ * For create we can modify:255255+ * the parent directory inode: inode size256256+ * the new inode: inode size257257+ * the inode btree entry: block size258258+ * the superblock for the nlink flag: sector size259259+ * the directory btree: (max depth + v2) * dir block size260260+ * the directory inode's bmap btree: (max depth + v2) * block size261261+ * Or in the first xact we allocate some inodes giving:262262+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize263263+ * the superblock for the nlink flag: sector size264264+ * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize265265+ * the inode btree: max depth * blocksize266266+ * the allocation btrees: 2 trees * (max depth - 1) * block size267267+ */91268STATIC uint9292-xfs_calc_create_reservation(xfs_mount_t *mp)269269+xfs_calc_create_reservation(270270+ struct xfs_mount *mp)93271{9494- return XFS_CALC_CREATE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);272272+ return XFS_DQUOT_LOGRES(mp) +273273+ MAX((mp->m_sb.sb_inodesize +274274+ mp->m_sb.sb_inodesize +275275+ mp->m_sb.sb_sectsize +276276+ XFS_FSB_TO_B(mp, 1) +277277+ XFS_DIROP_LOG_RES(mp) +278278+ 128 * (3 + XFS_DIROP_LOG_COUNT(mp))),279279+ (3 * mp->m_sb.sb_sectsize +280280+ XFS_FSB_TO_B(mp, XFS_IALLOC_BLOCKS(mp)) +281281+ XFS_FSB_TO_B(mp, mp->m_in_maxlevels) +282282+ XFS_ALLOCFREE_LOG_RES(mp, 1) +283283+ 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +284284+ XFS_ALLOCFREE_LOG_COUNT(mp, 1))));95285}96286287287+/*288288+ * Making a new directory is the same as creating a new file.289289+ */97290STATIC uint9898-xfs_calc_mkdir_reservation(xfs_mount_t *mp)291291+xfs_calc_mkdir_reservation(292292+ struct xfs_mount *mp)99293{100100- return XFS_CALC_MKDIR_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);294294+ return xfs_calc_create_reservation(mp);101295}102296297297+/*298298+ * In freeing an inode we can modify:299299+ * the inode being freed: inode size300300+ * the super block free inode counter: sector size301301+ * the agi hash list and counters: sector size302302+ * the inode btree entry: block size303303+ * the on disk inode before ours in the agi hash list: inode cluster size304304+ * the inode btree: max depth * blocksize305305+ * the allocation btrees: 2 trees * (max depth - 1) * block size306306+ */103307STATIC uint104104-xfs_calc_ifree_reservation(xfs_mount_t *mp)308308+xfs_calc_ifree_reservation(309309+ struct xfs_mount *mp)105310{106106- return XFS_CALC_IFREE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);311311+ return XFS_DQUOT_LOGRES(mp) +312312+ mp->m_sb.sb_inodesize +313313+ mp->m_sb.sb_sectsize +314314+ mp->m_sb.sb_sectsize +315315+ XFS_FSB_TO_B(mp, 1) +316316+ MAX((__uint16_t)XFS_FSB_TO_B(mp, 1),317317+ XFS_INODE_CLUSTER_SIZE(mp)) +318318+ 128 * 5 +319319+ XFS_ALLOCFREE_LOG_RES(mp, 1) +320320+ 128 * (2 + XFS_IALLOC_BLOCKS(mp) + mp->m_in_maxlevels +321321+ XFS_ALLOCFREE_LOG_COUNT(mp, 1));107322}108323324324+/*325325+ * When only changing the inode we log the inode and possibly the superblock326326+ * We also add a bit of slop for the transaction stuff.327327+ */109328STATIC uint110110-xfs_calc_ichange_reservation(xfs_mount_t *mp)329329+xfs_calc_ichange_reservation(330330+ struct xfs_mount *mp)111331{112112- return XFS_CALC_ICHANGE_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);332332+ return XFS_DQUOT_LOGRES(mp) +333333+ mp->m_sb.sb_inodesize +334334+ mp->m_sb.sb_sectsize +335335+ 512;336336+113337}114338339339+/*340340+ * Growing the data section of the filesystem.341341+ * superblock342342+ * agi and agf343343+ * allocation btrees344344+ */115345STATIC uint116116-xfs_calc_growdata_reservation(xfs_mount_t *mp)346346+xfs_calc_growdata_reservation(347347+ struct xfs_mount *mp)117348{118118- return XFS_CALC_GROWDATA_LOG_RES(mp);349349+ return mp->m_sb.sb_sectsize * 3 +350350+ XFS_ALLOCFREE_LOG_RES(mp, 1) +351351+ 128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1));119352}120353354354+/*355355+ * Growing the rt section of the filesystem.356356+ * In the first set of transactions (ALLOC) we allocate space to the357357+ * bitmap or summary files.358358+ * superblock: sector size359359+ * agf of the ag from which the extent is allocated: sector size360360+ * bmap btree for bitmap/summary inode: max depth * blocksize361361+ * bitmap/summary inode: inode size362362+ * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize363363+ */121364STATIC uint122122-xfs_calc_growrtalloc_reservation(xfs_mount_t *mp)365365+xfs_calc_growrtalloc_reservation(366366+ struct xfs_mount *mp)123367{124124- return XFS_CALC_GROWRTALLOC_LOG_RES(mp);368368+ return 2 * mp->m_sb.sb_sectsize +369369+ XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) +370370+ mp->m_sb.sb_inodesize +371371+ XFS_ALLOCFREE_LOG_RES(mp, 1) +372372+ 128 * (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) +373373+ XFS_ALLOCFREE_LOG_COUNT(mp, 1));125374}126375376376+/*377377+ * Growing the rt section of the filesystem.378378+ * In the second set of transactions (ZERO) we zero the new metadata blocks.379379+ * one bitmap/summary block: blocksize380380+ */127381STATIC uint128128-xfs_calc_growrtzero_reservation(xfs_mount_t *mp)382382+xfs_calc_growrtzero_reservation(383383+ struct xfs_mount *mp)129384{130130- return XFS_CALC_GROWRTZERO_LOG_RES(mp);385385+ return mp->m_sb.sb_blocksize + 128;131386}132387388388+/*389389+ * Growing the rt section of the filesystem.390390+ * In the third set of transactions (FREE) we update metadata without391391+ * allocating any new blocks.392392+ * superblock: sector size393393+ * bitmap inode: inode size394394+ * summary inode: inode size395395+ * one bitmap block: blocksize396396+ * summary blocks: new summary size397397+ */133398STATIC uint134134-xfs_calc_growrtfree_reservation(xfs_mount_t *mp)399399+xfs_calc_growrtfree_reservation(400400+ struct xfs_mount *mp)135401{136136- return XFS_CALC_GROWRTFREE_LOG_RES(mp);402402+ return mp->m_sb.sb_sectsize +403403+ 2 * mp->m_sb.sb_inodesize +404404+ mp->m_sb.sb_blocksize +405405+ mp->m_rsumsize +406406+ 128 * 5;137407}138408409409+/*410410+ * Logging the inode modification timestamp on a synchronous write.411411+ * inode412412+ */139413STATIC uint140140-xfs_calc_swrite_reservation(xfs_mount_t *mp)414414+xfs_calc_swrite_reservation(415415+ struct xfs_mount *mp)141416{142142- return XFS_CALC_SWRITE_LOG_RES(mp);417417+ return mp->m_sb.sb_inodesize + 128;143418}144419420420+/*421421+ * Logging the inode mode bits when writing a setuid/setgid file422422+ * inode423423+ */145424STATIC uint146425xfs_calc_writeid_reservation(xfs_mount_t *mp)147426{148148- return XFS_CALC_WRITEID_LOG_RES(mp);427427+ return mp->m_sb.sb_inodesize + 128;149428}150429430430+/*431431+ * Converting the inode from non-attributed to attributed.432432+ * the inode being converted: inode size433433+ * agf block and superblock (for block allocation)434434+ * the new block (directory sized)435435+ * bmap blocks for the new directory block436436+ * allocation btrees437437+ */151438STATIC uint152152-xfs_calc_addafork_reservation(xfs_mount_t *mp)439439+xfs_calc_addafork_reservation(440440+ struct xfs_mount *mp)153441{154154- return XFS_CALC_ADDAFORK_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);442442+ return XFS_DQUOT_LOGRES(mp) +443443+ mp->m_sb.sb_inodesize +444444+ mp->m_sb.sb_sectsize * 2 +445445+ mp->m_dirblksize +446446+ XFS_FSB_TO_B(mp, XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) +447447+ XFS_ALLOCFREE_LOG_RES(mp, 1) +448448+ 128 * (4 + XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1 +449449+ XFS_ALLOCFREE_LOG_COUNT(mp, 1));155450}156451452452+/*453453+ * Removing the attribute fork of a file454454+ * the inode being truncated: inode size455455+ * the inode's bmap btree: max depth * block size456456+ * And the bmap_finish transaction can free the blocks and bmap blocks:457457+ * the agf for each of the ags: 4 * sector size458458+ * the agfl for each of the ags: 4 * sector size459459+ * the super block to reflect the freed blocks: sector size460460+ * worst case split in allocation btrees per extent assuming 4 extents:461461+ * 4 exts * 2 trees * (2 * max depth - 1) * block size462462+ */157463STATIC uint158158-xfs_calc_attrinval_reservation(xfs_mount_t *mp)464464+xfs_calc_attrinval_reservation(465465+ struct xfs_mount *mp)159466{160160- return XFS_CALC_ATTRINVAL_LOG_RES(mp);467467+ return MAX((mp->m_sb.sb_inodesize +468468+ XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +469469+ 128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))),470470+ (4 * mp->m_sb.sb_sectsize +471471+ 4 * mp->m_sb.sb_sectsize +472472+ mp->m_sb.sb_sectsize +473473+ XFS_ALLOCFREE_LOG_RES(mp, 4) +474474+ 128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))));161475}162476477477+/*478478+ * Setting an attribute.479479+ * the inode getting the attribute480480+ * the superblock for allocations481481+ * the agfs extents are allocated from482482+ * the attribute btree * max depth483483+ * the inode allocation btree484484+ * Since attribute transaction space is dependent on the size of the attribute,485485+ * the calculation is done partially at mount time and partially at runtime.486486+ */163487STATIC uint164164-xfs_calc_attrset_reservation(xfs_mount_t *mp)488488+xfs_calc_attrset_reservation(489489+ struct xfs_mount *mp)165490{166166- return XFS_CALC_ATTRSET_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);491491+ return XFS_DQUOT_LOGRES(mp) +492492+ mp->m_sb.sb_inodesize +493493+ mp->m_sb.sb_sectsize +494494+ XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) +495495+ 128 * (2 + XFS_DA_NODE_MAXDEPTH);167496}168497498498+/*499499+ * Removing an attribute.500500+ * the inode: inode size501501+ * the attribute btree could join: max depth * block size502502+ * the inode bmap btree could join or split: max depth * block size503503+ * And the bmap_finish transaction can free the attr blocks freed giving:504504+ * the agf for the ag in which the blocks live: 2 * sector size505505+ * the agfl for the ag in which the blocks live: 2 * sector size506506+ * the superblock for the free block count: sector size507507+ * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size508508+ */169509STATIC uint170170-xfs_calc_attrrm_reservation(xfs_mount_t *mp)510510+xfs_calc_attrrm_reservation(511511+ struct xfs_mount *mp)171512{172172- return XFS_CALC_ATTRRM_LOG_RES(mp) + XFS_DQUOT_LOGRES(mp);513513+ return XFS_DQUOT_LOGRES(mp) +514514+ MAX((mp->m_sb.sb_inodesize +515515+ XFS_FSB_TO_B(mp, XFS_DA_NODE_MAXDEPTH) +516516+ XFS_FSB_TO_B(mp, XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) +517517+ 128 * (1 + XFS_DA_NODE_MAXDEPTH +518518+ XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK))),519519+ (2 * mp->m_sb.sb_sectsize +520520+ 2 * mp->m_sb.sb_sectsize +521521+ mp->m_sb.sb_sectsize +522522+ XFS_ALLOCFREE_LOG_RES(mp, 2) +523523+ 128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))));173524}174525526526+/*527527+ * Clearing a bad agino number in an agi hash bucket.528528+ */175529STATIC uint176176-xfs_calc_clear_agi_bucket_reservation(xfs_mount_t *mp)530530+xfs_calc_clear_agi_bucket_reservation(531531+ struct xfs_mount *mp)177532{178178- return XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp);533533+ return mp->m_sb.sb_sectsize + 128;179534}180535181536/*···539184 */540185void541186xfs_trans_init(542542- xfs_mount_t *mp)187187+ struct xfs_mount *mp)543188{544544- xfs_trans_reservations_t *resp;189189+ struct xfs_trans_reservations *resp = &mp->m_reservations;545190546546- resp = &(mp->m_reservations);547191 resp->tr_write = xfs_calc_write_reservation(mp);548192 resp->tr_itruncate = xfs_calc_itruncate_reservation(mp);549193 resp->tr_rename = xfs_calc_rename_reservation(mp);
-411
fs/xfs/xfs_trans.h
···300300301301302302/*303303- * Various log reservation values.304304- * These are based on the size of the file system block305305- * because that is what most transactions manipulate.306306- * Each adds in an additional 128 bytes per item logged to307307- * try to account for the overhead of the transaction mechanism.308308- *309309- * Note:310310- * Most of the reservations underestimate the number of allocation311311- * groups into which they could free extents in the xfs_bmap_finish()312312- * call. This is because the number in the worst case is quite high313313- * and quite unusual. In order to fix this we need to change314314- * xfs_bmap_finish() to free extents in only a single AG at a time.315315- * This will require changes to the EFI code as well, however, so that316316- * the EFI for the extents not freed is logged again in each transaction.317317- * See bug 261917.318318- */319319-320320-/*321303 * Per-extent log reservation for the allocation btree changes322304 * involved in freeing or allocating an extent.323305 * 2 trees * (2 blocks/level * max depth - 1) * block size···323341 (XFS_DAENTER_BLOCKS(mp, XFS_DATA_FORK) + \324342 XFS_DAENTER_BMAPS(mp, XFS_DATA_FORK) + 1)325343326326-/*327327- * In a write transaction we can allocate a maximum of 2328328- * extents. This gives:329329- * the inode getting the new extents: inode size330330- * the inode's bmap btree: max depth * block size331331- * the agfs of the ags from which the extents are allocated: 2 * sector332332- * the superblock free block counter: sector size333333- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size334334- * And the bmap_finish transaction can free bmap blocks in a join:335335- * the agfs of the ags containing the blocks: 2 * sector size336336- * the agfls of the ags containing the blocks: 2 * sector size337337- * the super block free block counter: sector size338338- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size339339- */340340-#define XFS_CALC_WRITE_LOG_RES(mp) \341341- (MAX( \342342- ((mp)->m_sb.sb_inodesize + \343343- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \344344- (2 * (mp)->m_sb.sb_sectsize) + \345345- (mp)->m_sb.sb_sectsize + \346346- XFS_ALLOCFREE_LOG_RES(mp, 2) + \347347- (128 * (4 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + XFS_ALLOCFREE_LOG_COUNT(mp, 2)))),\348348- ((2 * (mp)->m_sb.sb_sectsize) + \349349- (2 * (mp)->m_sb.sb_sectsize) + \350350- (mp)->m_sb.sb_sectsize + \351351- XFS_ALLOCFREE_LOG_RES(mp, 2) + \352352- (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))353344354345#define XFS_WRITE_LOG_RES(mp) ((mp)->m_reservations.tr_write)355355-356356-/*357357- * In truncating a file we free up to two extents at once. We can modify:358358- * the inode being truncated: inode size359359- * the inode's bmap btree: (max depth + 1) * block size360360- * And the bmap_finish transaction can free the blocks and bmap blocks:361361- * the agf for each of the ags: 4 * sector size362362- * the agfl for each of the ags: 4 * sector size363363- * the super block to reflect the freed blocks: sector size364364- * worst case split in allocation btrees per extent assuming 4 extents:365365- * 4 exts * 2 trees * (2 * max depth - 1) * block size366366- * the inode btree: max depth * blocksize367367- * the allocation btrees: 2 trees * (max depth - 1) * block size368368- */369369-#define XFS_CALC_ITRUNCATE_LOG_RES(mp) \370370- (MAX( \371371- ((mp)->m_sb.sb_inodesize + \372372- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + 1) + \373373- (128 * (2 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \374374- ((4 * (mp)->m_sb.sb_sectsize) + \375375- (4 * (mp)->m_sb.sb_sectsize) + \376376- (mp)->m_sb.sb_sectsize + \377377- XFS_ALLOCFREE_LOG_RES(mp, 4) + \378378- (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))) + \379379- (128 * 5) + \380380- XFS_ALLOCFREE_LOG_RES(mp, 1) + \381381- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \382382- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))383383-384346#define XFS_ITRUNCATE_LOG_RES(mp) ((mp)->m_reservations.tr_itruncate)385385-386386-/*387387- * In renaming a files we can modify:388388- * the four inodes involved: 4 * inode size389389- * the two directory btrees: 2 * (max depth + v2) * dir block size390390- * the two directory bmap btrees: 2 * max depth * block size391391- * And the bmap_finish transaction can free dir and bmap blocks (two sets392392- * of bmap blocks) giving:393393- * the agf for the ags in which the blocks live: 3 * sector size394394- * the agfl for the ags in which the blocks live: 3 * sector size395395- * the superblock for the free block count: sector size396396- * the allocation btrees: 3 exts * 2 trees * (2 * max depth - 1) * block size397397- */398398-#define XFS_CALC_RENAME_LOG_RES(mp) \399399- (MAX( \400400- ((4 * (mp)->m_sb.sb_inodesize) + \401401- (2 * XFS_DIROP_LOG_RES(mp)) + \402402- (128 * (4 + 2 * XFS_DIROP_LOG_COUNT(mp)))), \403403- ((3 * (mp)->m_sb.sb_sectsize) + \404404- (3 * (mp)->m_sb.sb_sectsize) + \405405- (mp)->m_sb.sb_sectsize + \406406- XFS_ALLOCFREE_LOG_RES(mp, 3) + \407407- (128 * (7 + XFS_ALLOCFREE_LOG_COUNT(mp, 3))))))408408-409347#define XFS_RENAME_LOG_RES(mp) ((mp)->m_reservations.tr_rename)410410-411411-/*412412- * For creating a link to an inode:413413- * the parent directory inode: inode size414414- * the linked inode: inode size415415- * the directory btree could split: (max depth + v2) * dir block size416416- * the directory bmap btree could join or split: (max depth + v2) * blocksize417417- * And the bmap_finish transaction can free some bmap blocks giving:418418- * the agf for the ag in which the blocks live: sector size419419- * the agfl for the ag in which the blocks live: sector size420420- * the superblock for the free block count: sector size421421- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size422422- */423423-#define XFS_CALC_LINK_LOG_RES(mp) \424424- (MAX( \425425- ((mp)->m_sb.sb_inodesize + \426426- (mp)->m_sb.sb_inodesize + \427427- XFS_DIROP_LOG_RES(mp) + \428428- (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \429429- ((mp)->m_sb.sb_sectsize + \430430- (mp)->m_sb.sb_sectsize + \431431- (mp)->m_sb.sb_sectsize + \432432- XFS_ALLOCFREE_LOG_RES(mp, 1) + \433433- (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))434434-435348#define XFS_LINK_LOG_RES(mp) ((mp)->m_reservations.tr_link)436436-437437-/*438438- * For removing a directory entry we can modify:439439- * the parent directory inode: inode size440440- * the removed inode: inode size441441- * the directory btree could join: (max depth + v2) * dir block size442442- * the directory bmap btree could join or split: (max depth + v2) * blocksize443443- * And the bmap_finish transaction can free the dir and bmap blocks giving:444444- * the agf for the ag in which the blocks live: 2 * sector size445445- * the agfl for the ag in which the blocks live: 2 * sector size446446- * the superblock for the free block count: sector size447447- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size448448- */449449-#define XFS_CALC_REMOVE_LOG_RES(mp) \450450- (MAX( \451451- ((mp)->m_sb.sb_inodesize + \452452- (mp)->m_sb.sb_inodesize + \453453- XFS_DIROP_LOG_RES(mp) + \454454- (128 * (2 + XFS_DIROP_LOG_COUNT(mp)))), \455455- ((2 * (mp)->m_sb.sb_sectsize) + \456456- (2 * (mp)->m_sb.sb_sectsize) + \457457- (mp)->m_sb.sb_sectsize + \458458- XFS_ALLOCFREE_LOG_RES(mp, 2) + \459459- (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))460460-461349#define XFS_REMOVE_LOG_RES(mp) ((mp)->m_reservations.tr_remove)462462-463463-/*464464- * For symlink we can modify:465465- * the parent directory inode: inode size466466- * the new inode: inode size467467- * the inode btree entry: 1 block468468- * the directory btree: (max depth + v2) * dir block size469469- * the directory inode's bmap btree: (max depth + v2) * block size470470- * the blocks for the symlink: 1 kB471471- * Or in the first xact we allocate some inodes giving:472472- * the agi and agf of the ag getting the new inodes: 2 * sectorsize473473- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize474474- * the inode btree: max depth * blocksize475475- * the allocation btrees: 2 trees * (2 * max depth - 1) * block size476476- */477477-#define XFS_CALC_SYMLINK_LOG_RES(mp) \478478- (MAX( \479479- ((mp)->m_sb.sb_inodesize + \480480- (mp)->m_sb.sb_inodesize + \481481- XFS_FSB_TO_B(mp, 1) + \482482- XFS_DIROP_LOG_RES(mp) + \483483- 1024 + \484484- (128 * (4 + XFS_DIROP_LOG_COUNT(mp)))), \485485- (2 * (mp)->m_sb.sb_sectsize + \486486- XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \487487- XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \488488- XFS_ALLOCFREE_LOG_RES(mp, 1) + \489489- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \490490- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))491491-492350#define XFS_SYMLINK_LOG_RES(mp) ((mp)->m_reservations.tr_symlink)493493-494494-/*495495- * For create we can modify:496496- * the parent directory inode: inode size497497- * the new inode: inode size498498- * the inode btree entry: block size499499- * the superblock for the nlink flag: sector size500500- * the directory btree: (max depth + v2) * dir block size501501- * the directory inode's bmap btree: (max depth + v2) * block size502502- * Or in the first xact we allocate some inodes giving:503503- * the agi and agf of the ag getting the new inodes: 2 * sectorsize504504- * the superblock for the nlink flag: sector size505505- * the inode blocks allocated: XFS_IALLOC_BLOCKS * blocksize506506- * the inode btree: max depth * blocksize507507- * the allocation btrees: 2 trees * (max depth - 1) * block size508508- */509509-#define XFS_CALC_CREATE_LOG_RES(mp) \510510- (MAX( \511511- ((mp)->m_sb.sb_inodesize + \512512- (mp)->m_sb.sb_inodesize + \513513- (mp)->m_sb.sb_sectsize + \514514- XFS_FSB_TO_B(mp, 1) + \515515- XFS_DIROP_LOG_RES(mp) + \516516- (128 * (3 + XFS_DIROP_LOG_COUNT(mp)))), \517517- (3 * (mp)->m_sb.sb_sectsize + \518518- XFS_FSB_TO_B((mp), XFS_IALLOC_BLOCKS((mp))) + \519519- XFS_FSB_TO_B((mp), (mp)->m_in_maxlevels) + \520520- XFS_ALLOCFREE_LOG_RES(mp, 1) + \521521- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \522522- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))))523523-524351#define XFS_CREATE_LOG_RES(mp) ((mp)->m_reservations.tr_create)525525-526526-/*527527- * Making a new directory is the same as creating a new file.528528- */529529-#define XFS_CALC_MKDIR_LOG_RES(mp) XFS_CALC_CREATE_LOG_RES(mp)530530-531352#define XFS_MKDIR_LOG_RES(mp) ((mp)->m_reservations.tr_mkdir)532532-533533-/*534534- * In freeing an inode we can modify:535535- * the inode being freed: inode size536536- * the super block free inode counter: sector size537537- * the agi hash list and counters: sector size538538- * the inode btree entry: block size539539- * the on disk inode before ours in the agi hash list: inode cluster size540540- * the inode btree: max depth * blocksize541541- * the allocation btrees: 2 trees * (max depth - 1) * block size542542- */543543-#define XFS_CALC_IFREE_LOG_RES(mp) \544544- ((mp)->m_sb.sb_inodesize + \545545- (mp)->m_sb.sb_sectsize + \546546- (mp)->m_sb.sb_sectsize + \547547- XFS_FSB_TO_B((mp), 1) + \548548- MAX((__uint16_t)XFS_FSB_TO_B((mp), 1), XFS_INODE_CLUSTER_SIZE(mp)) + \549549- (128 * 5) + \550550- XFS_ALLOCFREE_LOG_RES(mp, 1) + \551551- (128 * (2 + XFS_IALLOC_BLOCKS(mp) + (mp)->m_in_maxlevels + \552552- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))553553-554554-555353#define XFS_IFREE_LOG_RES(mp) ((mp)->m_reservations.tr_ifree)556556-557557-/*558558- * When only changing the inode we log the inode and possibly the superblock559559- * We also add a bit of slop for the transaction stuff.560560- */561561-#define XFS_CALC_ICHANGE_LOG_RES(mp) ((mp)->m_sb.sb_inodesize + \562562- (mp)->m_sb.sb_sectsize + 512)563563-564354#define XFS_ICHANGE_LOG_RES(mp) ((mp)->m_reservations.tr_ichange)565565-566566-/*567567- * Growing the data section of the filesystem.568568- * superblock569569- * agi and agf570570- * allocation btrees571571- */572572-#define XFS_CALC_GROWDATA_LOG_RES(mp) \573573- ((mp)->m_sb.sb_sectsize * 3 + \574574- XFS_ALLOCFREE_LOG_RES(mp, 1) + \575575- (128 * (3 + XFS_ALLOCFREE_LOG_COUNT(mp, 1))))576576-577355#define XFS_GROWDATA_LOG_RES(mp) ((mp)->m_reservations.tr_growdata)578578-579579-/*580580- * Growing the rt section of the filesystem.581581- * In the first set of transactions (ALLOC) we allocate space to the582582- * bitmap or summary files.583583- * superblock: sector size584584- * agf of the ag from which the extent is allocated: sector size585585- * bmap btree for bitmap/summary inode: max depth * blocksize586586- * bitmap/summary inode: inode size587587- * allocation btrees for 1 block alloc: 2 * (2 * maxdepth - 1) * blocksize588588- */589589-#define XFS_CALC_GROWRTALLOC_LOG_RES(mp) \590590- (2 * (mp)->m_sb.sb_sectsize + \591591- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)) + \592592- (mp)->m_sb.sb_inodesize + \593593- XFS_ALLOCFREE_LOG_RES(mp, 1) + \594594- (128 * \595595- (3 + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK) + \596596- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))597597-598356#define XFS_GROWRTALLOC_LOG_RES(mp) ((mp)->m_reservations.tr_growrtalloc)599599-600600-/*601601- * Growing the rt section of the filesystem.602602- * In the second set of transactions (ZERO) we zero the new metadata blocks.603603- * one bitmap/summary block: blocksize604604- */605605-#define XFS_CALC_GROWRTZERO_LOG_RES(mp) \606606- ((mp)->m_sb.sb_blocksize + 128)607607-608357#define XFS_GROWRTZERO_LOG_RES(mp) ((mp)->m_reservations.tr_growrtzero)609609-610610-/*611611- * Growing the rt section of the filesystem.612612- * In the third set of transactions (FREE) we update metadata without613613- * allocating any new blocks.614614- * superblock: sector size615615- * bitmap inode: inode size616616- * summary inode: inode size617617- * one bitmap block: blocksize618618- * summary blocks: new summary size619619- */620620-#define XFS_CALC_GROWRTFREE_LOG_RES(mp) \621621- ((mp)->m_sb.sb_sectsize + \622622- 2 * (mp)->m_sb.sb_inodesize + \623623- (mp)->m_sb.sb_blocksize + \624624- (mp)->m_rsumsize + \625625- (128 * 5))626626-627358#define XFS_GROWRTFREE_LOG_RES(mp) ((mp)->m_reservations.tr_growrtfree)628628-629629-/*630630- * Logging the inode modification timestamp on a synchronous write.631631- * inode632632- */633633-#define XFS_CALC_SWRITE_LOG_RES(mp) \634634- ((mp)->m_sb.sb_inodesize + 128)635635-636359#define XFS_SWRITE_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)637637-638360/*639361 * Logging the inode timestamps on an fsync -- same as SWRITE640362 * as long as SWRITE logs the entire inode core641363 */642364#define XFS_FSYNC_TS_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)643643-644644-/*645645- * Logging the inode mode bits when writing a setuid/setgid file646646- * inode647647- */648648-#define XFS_CALC_WRITEID_LOG_RES(mp) \649649- ((mp)->m_sb.sb_inodesize + 128)650650-651365#define XFS_WRITEID_LOG_RES(mp) ((mp)->m_reservations.tr_swrite)652652-653653-/*654654- * Converting the inode from non-attributed to attributed.655655- * the inode being converted: inode size656656- * agf block and superblock (for block allocation)657657- * the new block (directory sized)658658- * bmap blocks for the new directory block659659- * allocation btrees660660- */661661-#define XFS_CALC_ADDAFORK_LOG_RES(mp) \662662- ((mp)->m_sb.sb_inodesize + \663663- (mp)->m_sb.sb_sectsize * 2 + \664664- (mp)->m_dirblksize + \665665- XFS_FSB_TO_B(mp, (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1)) + \666666- XFS_ALLOCFREE_LOG_RES(mp, 1) + \667667- (128 * (4 + (XFS_DAENTER_BMAP1B(mp, XFS_DATA_FORK) + 1) + \668668- XFS_ALLOCFREE_LOG_COUNT(mp, 1))))669669-670366#define XFS_ADDAFORK_LOG_RES(mp) ((mp)->m_reservations.tr_addafork)671671-672672-/*673673- * Removing the attribute fork of a file674674- * the inode being truncated: inode size675675- * the inode's bmap btree: max depth * block size676676- * And the bmap_finish transaction can free the blocks and bmap blocks:677677- * the agf for each of the ags: 4 * sector size678678- * the agfl for each of the ags: 4 * sector size679679- * the super block to reflect the freed blocks: sector size680680- * worst case split in allocation btrees per extent assuming 4 extents:681681- * 4 exts * 2 trees * (2 * max depth - 1) * block size682682- */683683-#define XFS_CALC_ATTRINVAL_LOG_RES(mp) \684684- (MAX( \685685- ((mp)->m_sb.sb_inodesize + \686686- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \687687- (128 * (1 + XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))), \688688- ((4 * (mp)->m_sb.sb_sectsize) + \689689- (4 * (mp)->m_sb.sb_sectsize) + \690690- (mp)->m_sb.sb_sectsize + \691691- XFS_ALLOCFREE_LOG_RES(mp, 4) + \692692- (128 * (9 + XFS_ALLOCFREE_LOG_COUNT(mp, 4))))))693693-694367#define XFS_ATTRINVAL_LOG_RES(mp) ((mp)->m_reservations.tr_attrinval)695695-696696-/*697697- * Setting an attribute.698698- * the inode getting the attribute699699- * the superblock for allocations700700- * the agfs extents are allocated from701701- * the attribute btree * max depth702702- * the inode allocation btree703703- * Since attribute transaction space is dependent on the size of the attribute,704704- * the calculation is done partially at mount time and partially at runtime.705705- */706706-#define XFS_CALC_ATTRSET_LOG_RES(mp) \707707- ((mp)->m_sb.sb_inodesize + \708708- (mp)->m_sb.sb_sectsize + \709709- XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \710710- (128 * (2 + XFS_DA_NODE_MAXDEPTH)))711711-712368#define XFS_ATTRSET_LOG_RES(mp, ext) \713369 ((mp)->m_reservations.tr_attrset + \714370 (ext * (mp)->m_sb.sb_sectsize) + \715371 (ext * XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK))) + \716372 (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))))717717-718718-/*719719- * Removing an attribute.720720- * the inode: inode size721721- * the attribute btree could join: max depth * block size722722- * the inode bmap btree could join or split: max depth * block size723723- * And the bmap_finish transaction can free the attr blocks freed giving:724724- * the agf for the ag in which the blocks live: 2 * sector size725725- * the agfl for the ag in which the blocks live: 2 * sector size726726- * the superblock for the free block count: sector size727727- * the allocation btrees: 2 exts * 2 trees * (2 * max depth - 1) * block size728728- */729729-#define XFS_CALC_ATTRRM_LOG_RES(mp) \730730- (MAX( \731731- ((mp)->m_sb.sb_inodesize + \732732- XFS_FSB_TO_B((mp), XFS_DA_NODE_MAXDEPTH) + \733733- XFS_FSB_TO_B((mp), XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)) + \734734- (128 * (1 + XFS_DA_NODE_MAXDEPTH + XFS_BM_MAXLEVELS(mp, XFS_DATA_FORK)))), \735735- ((2 * (mp)->m_sb.sb_sectsize) + \736736- (2 * (mp)->m_sb.sb_sectsize) + \737737- (mp)->m_sb.sb_sectsize + \738738- XFS_ALLOCFREE_LOG_RES(mp, 2) + \739739- (128 * (5 + XFS_ALLOCFREE_LOG_COUNT(mp, 2))))))740740-741373#define XFS_ATTRRM_LOG_RES(mp) ((mp)->m_reservations.tr_attrrm)742742-743743-/*744744- * Clearing a bad agino number in an agi hash bucket.745745- */746746-#define XFS_CALC_CLEAR_AGI_BUCKET_LOG_RES(mp) \747747- ((mp)->m_sb.sb_sectsize + 128)748748-749374#define XFS_CLEAR_AGI_BUCKET_LOG_RES(mp) ((mp)->m_reservations.tr_clearagi)750375751376