Esempio n. 1
0
/*
 * 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);
}
Esempio n. 2
0
File: xfs_sb.c Progetto: Abioy/kasan
/*
 * 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));
}
Esempio n. 3
0
/*
 * 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
}
Esempio n. 4
0
/*
 * 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;
}