/* * xfs_mod_sb() can be used to copy arbitrary changes to the * in-core superblock into the superblock buffer to be logged. * It does not provide the higher level of locking that is * needed to protect the in-core superblock from concurrent * access. */ void xfs_mod_sb(xfs_trans_t *tp, __int64_t fields) { xfs_buf_t *bp; int first; int last; xfs_mount_t *mp; xfs_sb_field_t f; ASSERT(fields); if (!fields) return; mp = tp->t_mountp; bp = xfs_trans_getsb(tp, mp, 0); first = sizeof(xfs_sb_t); last = 0; /* translate/copy */ xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb, fields); /* find modified range */ f = (xfs_sb_field_t)xfs_highbit64((__uint64_t)fields); ASSERT((1LL << f) & XFS_SB_MOD_BITS); last = xfs_sb_info[f + 1].offset - 1; f = (xfs_sb_field_t)xfs_lowbit64((__uint64_t)fields); ASSERT((1LL << f) & XFS_SB_MOD_BITS); first = xfs_sb_info[f].offset; xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); xfs_trans_log_buf(tp, bp, first, last); }
/* * xfs_log_sb() can be used to copy arbitrary changes to the in-core superblock * into the superblock buffer to be logged. It does not provide the higher * level of locking that is needed to protect the in-core superblock from * concurrent access. */ void xfs_log_sb( struct xfs_trans *tp) { struct xfs_mount *mp = tp->t_mountp; struct xfs_buf *bp = xfs_trans_getsb(tp, mp, 0); xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb); xfs_trans_buf_set_type(tp, bp, XFS_BLFT_SB_BUF); xfs_trans_log_buf(tp, bp, 0, sizeof(struct xfs_dsb)); }
/* * xfs_trans_apply_sb_deltas() is called from the commit code * to bring the superblock buffer into the current transaction * and modify it as requested by earlier calls to xfs_trans_mod_sb(). * * For now we just look at each field allowed to change and change * it if necessary. */ STATIC void xfs_trans_apply_sb_deltas( xfs_trans_t *tp) { xfs_sb_t *sbp; xfs_buf_t *bp; int whole = 0; bp = xfs_trans_getsb(tp, tp->t_mountp, 0); sbp = XFS_BUF_TO_SBP(bp); /* * Check that superblock mods match the mods made to AGF counters. */ ASSERT((tp->t_fdblocks_delta + tp->t_res_fdblocks_delta) == (tp->t_ag_freeblks_delta + tp->t_ag_flist_delta + tp->t_ag_btree_delta)); if (tp->t_icount_delta != 0) { INT_MOD(sbp->sb_icount, ARCH_CONVERT, tp->t_icount_delta); } if (tp->t_ifree_delta != 0) { INT_MOD(sbp->sb_ifree, ARCH_CONVERT, tp->t_ifree_delta); } if (tp->t_fdblocks_delta != 0) { INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_fdblocks_delta); } if (tp->t_res_fdblocks_delta != 0) { INT_MOD(sbp->sb_fdblocks, ARCH_CONVERT, tp->t_res_fdblocks_delta); } if (tp->t_frextents_delta != 0) { INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_frextents_delta); } if (tp->t_res_frextents_delta != 0) { INT_MOD(sbp->sb_frextents, ARCH_CONVERT, tp->t_res_frextents_delta); } if (tp->t_dblocks_delta != 0) { INT_MOD(sbp->sb_dblocks, ARCH_CONVERT, tp->t_dblocks_delta); whole = 1; } if (tp->t_agcount_delta != 0) { INT_MOD(sbp->sb_agcount, ARCH_CONVERT, tp->t_agcount_delta); whole = 1; } if (tp->t_imaxpct_delta != 0) { INT_MOD(sbp->sb_imax_pct, ARCH_CONVERT, tp->t_imaxpct_delta); whole = 1; } if (tp->t_rextsize_delta != 0) { INT_MOD(sbp->sb_rextsize, ARCH_CONVERT, tp->t_rextsize_delta); whole = 1; } if (tp->t_rbmblocks_delta != 0) { INT_MOD(sbp->sb_rbmblocks, ARCH_CONVERT, tp->t_rbmblocks_delta); whole = 1; } if (tp->t_rblocks_delta != 0) { INT_MOD(sbp->sb_rblocks, ARCH_CONVERT, tp->t_rblocks_delta); whole = 1; } if (tp->t_rextents_delta != 0) { INT_MOD(sbp->sb_rextents, ARCH_CONVERT, tp->t_rextents_delta); whole = 1; } if (tp->t_rextslog_delta != 0) { INT_MOD(sbp->sb_rextslog, ARCH_CONVERT, tp->t_rextslog_delta); whole = 1; } if (whole) /* * Log the whole thing, the fields are noncontiguous. */ xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_sb_t) - 1); else /* * Since all the modifiable fields are contiguous, we * can get away with this. */ xfs_trans_log_buf(tp, bp, offsetof(xfs_sb_t, sb_icount), offsetof(xfs_sb_t, sb_frextents) + sizeof(sbp->sb_frextents) - 1); #ifdef XXXKAN XFS_MTOVFS(tp->t_mountp)->vfs_super->s_dirt = 1; #endif }
/* * xfs_trans_apply_sb_deltas() is called from the commit code * to bring the superblock buffer into the current transaction * and modify it as requested by earlier calls to xfs_trans_mod_sb(). * * For now we just look at each field allowed to change and change * it if necessary. */ STATIC void xfs_trans_apply_sb_deltas( xfs_trans_t *tp) { xfs_dsb_t *sbp; xfs_buf_t *bp; int whole = 0; bp = xfs_trans_getsb(tp, tp->t_mountp, 0); sbp = XFS_BUF_TO_SBP(bp); /* * Check that superblock mods match the mods made to AGF counters. */ ASSERT((tp->t_fdblocks_delta + tp->t_res_fdblocks_delta) == (tp->t_ag_freeblks_delta + tp->t_ag_flist_delta + tp->t_ag_btree_delta)); /* * Only update the superblock counters if we are logging them */ if (!xfs_sb_version_haslazysbcount(&(tp->t_mountp->m_sb))) { if (tp->t_icount_delta) be64_add_cpu(&sbp->sb_icount, tp->t_icount_delta); if (tp->t_ifree_delta) be64_add_cpu(&sbp->sb_ifree, tp->t_ifree_delta); if (tp->t_fdblocks_delta) be64_add_cpu(&sbp->sb_fdblocks, tp->t_fdblocks_delta); if (tp->t_res_fdblocks_delta) be64_add_cpu(&sbp->sb_fdblocks, tp->t_res_fdblocks_delta); } if (tp->t_frextents_delta) be64_add_cpu(&sbp->sb_frextents, tp->t_frextents_delta); if (tp->t_res_frextents_delta) be64_add_cpu(&sbp->sb_frextents, tp->t_res_frextents_delta); if (tp->t_dblocks_delta) { be64_add_cpu(&sbp->sb_dblocks, tp->t_dblocks_delta); whole = 1; } if (tp->t_agcount_delta) { be32_add_cpu(&sbp->sb_agcount, tp->t_agcount_delta); whole = 1; } if (tp->t_imaxpct_delta) { sbp->sb_imax_pct += tp->t_imaxpct_delta; whole = 1; } if (tp->t_rextsize_delta) { be32_add_cpu(&sbp->sb_rextsize, tp->t_rextsize_delta); whole = 1; } if (tp->t_rbmblocks_delta) { be32_add_cpu(&sbp->sb_rbmblocks, tp->t_rbmblocks_delta); whole = 1; } if (tp->t_rblocks_delta) { be64_add_cpu(&sbp->sb_rblocks, tp->t_rblocks_delta); whole = 1; } if (tp->t_rextents_delta) { be64_add_cpu(&sbp->sb_rextents, tp->t_rextents_delta); whole = 1; } if (tp->t_rextslog_delta) { sbp->sb_rextslog += tp->t_rextslog_delta; whole = 1; } if (whole) /* * Log the whole thing, the fields are noncontiguous. */ xfs_trans_log_buf(tp, bp, 0, sizeof(xfs_dsb_t) - 1); else /* * Since all the modifiable fields are contiguous, we * can get away with this. */ xfs_trans_log_buf(tp, bp, offsetof(xfs_dsb_t, sb_icount), offsetof(xfs_dsb_t, sb_frextents) + sizeof(sbp->sb_frextents) - 1); tp->t_mountp->m_super->s_dirt = 1; }