Commit e3088ae2 authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Darrick J. Wong
Browse files

xfs: move RT bitmap and summary information to the rtgroup



Move the pointers to the RT bitmap and summary inodes as well as the
summary cache to the rtgroups structure to prepare for having a
separate bitmap and summary inodes for each rtgroup.

Code using the inodes now needs to operate on a rtgroup.  Where easily
possible such code is converted to iterate over all rtgroups, else
rtgroup 0 (the only one that can currently exist) is hardcoded.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
parent c8edf1cb
Loading
Loading
Loading
Loading
+10 −3
Original line number Diff line number Diff line
@@ -5121,19 +5121,26 @@ xfs_bmap_free_rtblocks(
	struct xfs_trans	*tp,
	struct xfs_bmbt_irec	*del)
{
	struct xfs_rtgroup	*rtg;
	int			error;

	rtg = xfs_rtgroup_grab(tp->t_mountp, 0);
	if (!rtg)
		return -EIO;

	/*
	 * Ensure the bitmap and summary inodes are locked and joined to the
	 * transaction before modifying them.
	 */
	if (!(tp->t_flags & XFS_TRANS_RTBITMAP_LOCKED)) {
		tp->t_flags |= XFS_TRANS_RTBITMAP_LOCKED;
		xfs_rtbitmap_lock(tp->t_mountp);
		xfs_rtbitmap_trans_join(tp);
		xfs_rtgroup_lock(rtg, XFS_RTGLOCK_BITMAP);
		xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_BITMAP);
	}

	error = xfs_rtfree_blocks(tp, del->br_startblock, del->br_blockcount);
	error = xfs_rtfree_blocks(tp, rtg, del->br_startblock,
			del->br_blockcount);
	xfs_rtgroup_rele(rtg);
	return error;
}

+47 −93
Original line number Diff line number Diff line
@@ -90,12 +90,12 @@ xfs_rtbuf_get(
	if (issum) {
		cbpp = &args->sumbp;
		coffp = &args->sumoff;
		ip = mp->m_rsumip;
		ip = args->rtg->rtg_inodes[XFS_RTGI_SUMMARY];
		type = XFS_BLFT_RTSUMMARY_BUF;
	} else {
		cbpp = &args->rbmbp;
		coffp = &args->rbmoff;
		ip = mp->m_rbmip;
		ip = args->rtg->rtg_inodes[XFS_RTGI_BITMAP];
		type = XFS_BLFT_RTBITMAP_BUF;
	}

@@ -503,6 +503,7 @@ xfs_rtmodify_summary(
{
	struct xfs_mount	*mp = args->mp;
	xfs_rtsumoff_t		so = xfs_rtsumoffs(mp, log, bbno);
	uint8_t			*rsum_cache = args->rtg->rtg_rsum_cache;
	unsigned int		infoword;
	xfs_suminfo_t		val;
	int			error;
@@ -514,11 +515,11 @@ xfs_rtmodify_summary(
	infoword = xfs_rtsumoffs_to_infoword(mp, so);
	val = xfs_suminfo_add(args, infoword, delta);

	if (mp->m_rsum_cache) {
		if (val == 0 && log + 1 == mp->m_rsum_cache[bbno])
			mp->m_rsum_cache[bbno] = log;
		if (val != 0 && log >= mp->m_rsum_cache[bbno])
			mp->m_rsum_cache[bbno] = log + 1;
	if (rsum_cache) {
		if (val == 0 && log + 1 == rsum_cache[bbno])
			rsum_cache[bbno] = log;
		if (val != 0 && log >= rsum_cache[bbno])
			rsum_cache[bbno] = log + 1;
	}

	xfs_trans_log_rtsummary(args, infoword);
@@ -737,7 +738,7 @@ xfs_rtfree_range(
	/*
	 * Find the next allocated block (end of allocated extent).
	 */
	error = xfs_rtfind_forw(args, end, mp->m_sb.sb_rextents - 1,
	error = xfs_rtfind_forw(args, end, args->rtg->rtg_extents - 1,
			&postblock);
	if (error)
		return error;
@@ -961,19 +962,22 @@ xfs_rtcheck_alloc_range(
int
xfs_rtfree_extent(
	struct xfs_trans	*tp,	/* transaction pointer */
	struct xfs_rtgroup	*rtg,
	xfs_rtxnum_t		start,	/* starting rtext number to free */
	xfs_rtxlen_t		len)	/* length of extent freed */
{
	struct xfs_mount	*mp = tp->t_mountp;
	struct xfs_inode	*rbmip = rtg->rtg_inodes[XFS_RTGI_BITMAP];
	struct xfs_rtalloc_args	args = {
		.mp		= mp,
		.tp		= tp,
		.rtg		= rtg,
	};
	int			error;
	struct timespec64	atime;

	ASSERT(mp->m_rbmip->i_itemp != NULL);
	xfs_assert_ilocked(mp->m_rbmip, XFS_ILOCK_EXCL);
	ASSERT(rbmip->i_itemp != NULL);
	xfs_assert_ilocked(rbmip, XFS_ILOCK_EXCL);

	error = xfs_rtcheck_alloc_range(&args, start, len);
	if (error)
@@ -996,13 +1000,13 @@ xfs_rtfree_extent(
	 */
	if (tp->t_frextents_delta + mp->m_sb.sb_frextents ==
	    mp->m_sb.sb_rextents) {
		if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
			mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
		if (!(rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
			rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;

		atime = inode_get_atime(VFS_I(mp->m_rbmip));
		atime = inode_get_atime(VFS_I(rbmip));
		atime.tv_sec = 0;
		inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime);
		xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
		inode_set_atime_to_ts(VFS_I(rbmip), atime);
		xfs_trans_log_inode(tp, rbmip, XFS_ILOG_CORE);
	}
	error = 0;
out:
@@ -1018,6 +1022,7 @@ xfs_rtfree_extent(
int
xfs_rtfree_blocks(
	struct xfs_trans	*tp,
	struct xfs_rtgroup	*rtg,
	xfs_fsblock_t		rtbno,
	xfs_filblks_t		rtlen)
{
@@ -1038,21 +1043,23 @@ xfs_rtfree_blocks(
		return -EIO;
	}

	return xfs_rtfree_extent(tp, xfs_rtb_to_rtx(mp, rtbno),
			xfs_rtb_to_rtx(mp, rtlen));
	return xfs_rtfree_extent(tp, rtg, xfs_rtb_to_rtx(mp, rtbno),
			xfs_extlen_to_rtxlen(mp, rtlen));
}

/* Find all the free records within a given range. */
int
xfs_rtalloc_query_range(
	struct xfs_mount		*mp,
	struct xfs_rtgroup		*rtg,
	struct xfs_trans		*tp,
	xfs_rtxnum_t			start,
	xfs_rtxnum_t			end,
	xfs_rtalloc_query_range_fn	fn,
	void				*priv)
{
	struct xfs_mount		*mp = rtg_mount(rtg);
	struct xfs_rtalloc_args		args = {
		.rtg			= rtg,
		.mp			= mp,
		.tp			= tp,
	};
@@ -1060,10 +1067,10 @@ xfs_rtalloc_query_range(

	if (start > end)
		return -EINVAL;
	if (start == end || start >= mp->m_sb.sb_rextents)
	if (start == end || start >= rtg->rtg_extents)
		return 0;

	end = min(end, mp->m_sb.sb_rextents - 1);
	end = min(end, rtg->rtg_extents - 1);

	/* Iterate the bitmap, looking for discrepancies. */
	while (start <= end) {
@@ -1086,7 +1093,7 @@ xfs_rtalloc_query_range(
			rec.ar_startext = start;
			rec.ar_extcount = rtend - start + 1;

			error = fn(mp, tp, &rec, priv);
			error = fn(rtg, tp, &rec, priv);
			if (error)
				break;
		}
@@ -1101,26 +1108,27 @@ xfs_rtalloc_query_range(
/* Find all the free records. */
int
xfs_rtalloc_query_all(
	struct xfs_mount		*mp,
	struct xfs_rtgroup		*rtg,
	struct xfs_trans		*tp,
	xfs_rtalloc_query_range_fn	fn,
	void				*priv)
{
	return xfs_rtalloc_query_range(mp, tp, 0, mp->m_sb.sb_rextents - 1, fn,
	return xfs_rtalloc_query_range(rtg, tp, 0, rtg->rtg_extents - 1, fn,
			priv);
}

/* Is the given extent all free? */
int
xfs_rtalloc_extent_is_free(
	struct xfs_mount		*mp,
	struct xfs_rtgroup		*rtg,
	struct xfs_trans		*tp,
	xfs_rtxnum_t			start,
	xfs_rtxlen_t			len,
	bool				*is_free)
{
	struct xfs_rtalloc_args		args = {
		.mp			= mp,
		.mp			= rtg_mount(rtg),
		.rtg			= rtg,
		.tp			= tp,
	};
	xfs_rtxnum_t			end;
@@ -1161,65 +1169,6 @@ xfs_rtsummary_blockcount(
	return XFS_B_TO_FSB(mp, rsumwords << XFS_WORDLOG);
}

/* Lock both realtime free space metadata inodes for a freespace update. */
void
xfs_rtbitmap_lock(
	struct xfs_mount	*mp)
{
	xfs_ilock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
	xfs_ilock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
}

/*
 * Join both realtime free space metadata inodes to the transaction.  The
 * ILOCKs will be released on transaction commit.
 */
void
xfs_rtbitmap_trans_join(
	struct xfs_trans	*tp)
{
	xfs_trans_ijoin(tp, tp->t_mountp->m_rbmip, XFS_ILOCK_EXCL);
	xfs_trans_ijoin(tp, tp->t_mountp->m_rsumip, XFS_ILOCK_EXCL);
}

/* Unlock both realtime free space metadata inodes after a freespace update. */
void
xfs_rtbitmap_unlock(
	struct xfs_mount	*mp)
{
	xfs_iunlock(mp->m_rsumip, XFS_ILOCK_EXCL | XFS_ILOCK_RTSUM);
	xfs_iunlock(mp->m_rbmip, XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP);
}

/*
 * Lock the realtime free space metadata inodes for a freespace scan.  Callers
 * must walk metadata blocks in order of increasing file offset.
 */
void
xfs_rtbitmap_lock_shared(
	struct xfs_mount	*mp,
	unsigned int		rbmlock_flags)
{
	if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
		xfs_ilock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);

	if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
		xfs_ilock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);
}

/* Unlock the realtime free space metadata inodes after a freespace scan. */
void
xfs_rtbitmap_unlock_shared(
	struct xfs_mount	*mp,
	unsigned int		rbmlock_flags)
{
	if (rbmlock_flags & XFS_RBMLOCK_SUMMARY)
		xfs_iunlock(mp->m_rsumip, XFS_ILOCK_SHARED | XFS_ILOCK_RTSUM);

	if (rbmlock_flags & XFS_RBMLOCK_BITMAP)
		xfs_iunlock(mp->m_rbmip, XFS_ILOCK_SHARED | XFS_ILOCK_RTBITMAP);
}

static int
xfs_rtfile_alloc_blocks(
	struct xfs_inode	*ip,
@@ -1260,21 +1209,25 @@ xfs_rtfile_alloc_blocks(
/* Get a buffer for the block. */
static int
xfs_rtfile_initialize_block(
	struct xfs_inode	*ip,
	struct xfs_rtgroup	*rtg,
	enum xfs_rtg_inodes	type,
	xfs_fsblock_t		fsbno,
	void			*data)
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_mount	*mp = rtg_mount(rtg);
	struct xfs_inode	*ip = rtg->rtg_inodes[type];
	struct xfs_trans	*tp;
	struct xfs_buf		*bp;
	const size_t		copylen = mp->m_blockwsize << XFS_WORDLOG;
	enum xfs_blft		buf_type;
	int			error;

	if (ip == mp->m_rsumip)
	if (type == XFS_RTGI_BITMAP)
		buf_type = XFS_BLFT_RTBITMAP_BUF;
	else if (type == XFS_RTGI_SUMMARY)
		buf_type = XFS_BLFT_RTSUMMARY_BUF;
	else
		buf_type = XFS_BLFT_RTBITMAP_BUF;
		return -EINVAL;

	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_growrtzero, 0, 0, 0, &tp);
	if (error)
@@ -1306,12 +1259,13 @@ xfs_rtfile_initialize_block(
 */
int
xfs_rtfile_initialize_blocks(
	struct xfs_inode	*ip,		/* inode (bitmap/summary) */
	struct xfs_rtgroup	*rtg,
	enum xfs_rtg_inodes	type,
	xfs_fileoff_t		offset_fsb,	/* offset to start from */
	xfs_fileoff_t		end_fsb,	/* offset to allocate to */
	void			*data)		/* data to fill the blocks */
{
	struct xfs_mount	*mp = ip->i_mount;
	struct xfs_mount	*mp = rtg_mount(rtg);
	const size_t		copylen = mp->m_blockwsize << XFS_WORDLOG;

	while (offset_fsb < end_fsb) {
@@ -1319,8 +1273,8 @@ xfs_rtfile_initialize_blocks(
		xfs_filblks_t		i;
		int			error;

		error = xfs_rtfile_alloc_blocks(ip, offset_fsb,
				end_fsb - offset_fsb, &map);
		error = xfs_rtfile_alloc_blocks(rtg->rtg_inodes[type],
				offset_fsb, end_fsb - offset_fsb, &map);
		if (error)
			return error;

@@ -1330,7 +1284,7 @@ xfs_rtfile_initialize_blocks(
		 * Do this one block per transaction, to keep it simple.
		 */
		for (i = 0; i < map.br_blockcount; i++) {
			error = xfs_rtfile_initialize_block(ip,
			error = xfs_rtfile_initialize_block(rtg, type,
					map.br_startblock + i, data);
			if (error)
				return error;
+23 −41
Original line number Diff line number Diff line
@@ -6,7 +6,10 @@
#ifndef __XFS_RTBITMAP_H__
#define	__XFS_RTBITMAP_H__

#include "xfs_rtgroup.h"

struct xfs_rtalloc_args {
	struct xfs_rtgroup	*rtg;
	struct xfs_mount	*mp;
	struct xfs_trans	*tp;

@@ -268,7 +271,7 @@ struct xfs_rtalloc_rec {
};

typedef int (*xfs_rtalloc_query_range_fn)(
	struct xfs_mount		*mp,
	struct xfs_rtgroup		*rtg,
	struct xfs_trans		*tp,
	const struct xfs_rtalloc_rec	*rec,
	void				*priv);
@@ -291,53 +294,37 @@ int xfs_rtmodify_summary(struct xfs_rtalloc_args *args, int log,
		xfs_fileoff_t bbno, int delta);
int xfs_rtfree_range(struct xfs_rtalloc_args *args, xfs_rtxnum_t start,
		xfs_rtxlen_t len);
int xfs_rtalloc_query_range(struct xfs_mount *mp, struct xfs_trans *tp,
int xfs_rtalloc_query_range(struct xfs_rtgroup *rtg, struct xfs_trans *tp,
		xfs_rtxnum_t start, xfs_rtxnum_t end,
		xfs_rtalloc_query_range_fn fn, void *priv);
int xfs_rtalloc_query_all(struct xfs_mount *mp, struct xfs_trans *tp,
			  xfs_rtalloc_query_range_fn fn,
			  void *priv);
int xfs_rtalloc_extent_is_free(struct xfs_mount *mp, struct xfs_trans *tp,
			       xfs_rtxnum_t start, xfs_rtxlen_t len,
			       bool *is_free);
/*
 * Free an extent in the realtime subvolume.  Length is expressed in
 * realtime extents, as is the block number.
 */
int					/* error */
xfs_rtfree_extent(
	struct xfs_trans	*tp,	/* transaction pointer */
	xfs_rtxnum_t		start,	/* starting rtext number to free */
	xfs_rtxlen_t		len);	/* length of extent freed */

int xfs_rtalloc_query_all(struct xfs_rtgroup *rtg, struct xfs_trans *tp,
		xfs_rtalloc_query_range_fn fn, void *priv);
int xfs_rtalloc_extent_is_free(struct xfs_rtgroup *rtg, struct xfs_trans *tp,
		xfs_rtxnum_t start, xfs_rtxlen_t len, bool *is_free);
int xfs_rtfree_extent(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
		xfs_rtxnum_t start, xfs_rtxlen_t len);
/* Same as above, but in units of rt blocks. */
int xfs_rtfree_blocks(struct xfs_trans *tp, xfs_fsblock_t rtbno,
		xfs_filblks_t rtlen);
int xfs_rtfree_blocks(struct xfs_trans *tp, struct xfs_rtgroup *rtg,
		xfs_fsblock_t rtbno, xfs_filblks_t rtlen);

xfs_filblks_t xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t
		rtextents);
xfs_filblks_t xfs_rtsummary_blockcount(struct xfs_mount *mp,
		unsigned int rsumlevels, xfs_extlen_t rbmblocks);

int xfs_rtfile_initialize_blocks(struct xfs_inode *ip,
		xfs_fileoff_t offset_fsb, xfs_fileoff_t end_fsb, void *data);

void xfs_rtbitmap_lock(struct xfs_mount *mp);
void xfs_rtbitmap_unlock(struct xfs_mount *mp);
void xfs_rtbitmap_trans_join(struct xfs_trans *tp);

/* Lock the rt bitmap inode in shared mode */
#define XFS_RBMLOCK_BITMAP	(1U << 0)
/* Lock the rt summary inode in shared mode */
#define XFS_RBMLOCK_SUMMARY	(1U << 1)
int xfs_rtfile_initialize_blocks(struct xfs_rtgroup *rtg,
		enum xfs_rtg_inodes type, xfs_fileoff_t offset_fsb,
		xfs_fileoff_t end_fsb, void *data);

void xfs_rtbitmap_lock_shared(struct xfs_mount *mp,
		unsigned int rbmlock_flags);
void xfs_rtbitmap_unlock_shared(struct xfs_mount *mp,
		unsigned int rbmlock_flags);
#else /* CONFIG_XFS_RT */
# define xfs_rtfree_extent(t,b,l)			(-ENOSYS)
# define xfs_rtfree_blocks(t,rb,rl)			(-ENOSYS)

static inline int xfs_rtfree_blocks(struct xfs_trans *tp,
		struct xfs_rtgroup *rtg, xfs_fsblock_t rtbno,
		xfs_filblks_t rtlen)
{
	return -ENOSYS;
}
# define xfs_rtalloc_query_range(m,t,l,h,f,p)		(-ENOSYS)
# define xfs_rtalloc_query_all(m,t,f,p)			(-ENOSYS)
# define xfs_rtbitmap_read_buf(a,b)			(-ENOSYS)
@@ -351,11 +338,6 @@ xfs_rtbitmap_blockcount(struct xfs_mount *mp, xfs_rtbxlen_t rtextents)
	return 0;
}
# define xfs_rtsummary_blockcount(mp, l, b)		(0)
# define xfs_rtbitmap_lock(mp)			do { } while (0)
# define xfs_rtbitmap_trans_join(tp)		do { } while (0)
# define xfs_rtbitmap_unlock(mp)		do { } while (0)
# define xfs_rtbitmap_lock_shared(mp, lf)	do { } while (0)
# define xfs_rtbitmap_unlock_shared(mp, lf)	do { } while (0)
#endif /* CONFIG_XFS_RT */

#endif /* __XFS_RTBITMAP_H__ */
+60 −20
Original line number Diff line number Diff line
@@ -162,10 +162,16 @@ xfs_rtgroup_lock(
	ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) ||
	       !(rtglock_flags & XFS_RTGLOCK_BITMAP));

	if (rtglock_flags & XFS_RTGLOCK_BITMAP)
		xfs_rtbitmap_lock(rtg_mount(rtg));
	else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)
		xfs_rtbitmap_lock_shared(rtg_mount(rtg), XFS_RBMLOCK_BITMAP);
	if (rtglock_flags & XFS_RTGLOCK_BITMAP) {
		/*
		 * Lock both realtime free space metadata inodes for a freespace
		 * update.
		 */
		xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL);
		xfs_ilock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL);
	} else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) {
		xfs_ilock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED);
	}
}

/* Unlock metadata inodes associated with this rt group. */
@@ -178,10 +184,12 @@ xfs_rtgroup_unlock(
	ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) ||
	       !(rtglock_flags & XFS_RTGLOCK_BITMAP));

	if (rtglock_flags & XFS_RTGLOCK_BITMAP)
		xfs_rtbitmap_unlock(rtg_mount(rtg));
	else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED)
		xfs_rtbitmap_unlock_shared(rtg_mount(rtg), XFS_RBMLOCK_BITMAP);
	if (rtglock_flags & XFS_RTGLOCK_BITMAP) {
		xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_SUMMARY], XFS_ILOCK_EXCL);
		xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_EXCL);
	} else if (rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED) {
		xfs_iunlock(rtg->rtg_inodes[XFS_RTGI_BITMAP], XFS_ILOCK_SHARED);
	}
}

/*
@@ -197,8 +205,12 @@ xfs_rtgroup_trans_join(
	ASSERT(!(rtglock_flags & ~XFS_RTGLOCK_ALL_FLAGS));
	ASSERT(!(rtglock_flags & XFS_RTGLOCK_BITMAP_SHARED));

	if (rtglock_flags & XFS_RTGLOCK_BITMAP)
		xfs_rtbitmap_trans_join(tp);
	if (rtglock_flags & XFS_RTGLOCK_BITMAP) {
		xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_BITMAP],
				XFS_ILOCK_EXCL);
		xfs_trans_ijoin(tp, rtg->rtg_inodes[XFS_RTGI_SUMMARY],
				XFS_ILOCK_EXCL);
	}
}

#ifdef CONFIG_PROVE_LOCKING
@@ -263,6 +275,14 @@ struct xfs_rtginode_ops {
};

static const struct xfs_rtginode_ops xfs_rtginode_ops[XFS_RTGI_MAX] = {
	[XFS_RTGI_BITMAP] = {
		.name		= "bitmap",
		.metafile_type	= XFS_METAFILE_RTBITMAP,
	},
	[XFS_RTGI_SUMMARY] = {
		.name		= "summary",
		.metafile_type	= XFS_METAFILE_RTSUMMARY,
	},
};

/* Return the shortname of this rtgroup inode. */
@@ -302,7 +322,6 @@ xfs_rtginode_load(
	struct xfs_trans	*tp)
{
	struct xfs_mount	*mp = tp->t_mountp;
	const char		*path;
	struct xfs_inode	*ip;
	const struct xfs_rtginode_ops *ops = &xfs_rtginode_ops[type];
	int			error;
@@ -310,15 +329,36 @@ xfs_rtginode_load(
	if (!xfs_rtginode_enabled(rtg, type))
		return 0;

	if (!xfs_has_rtgroups(mp)) {
		xfs_ino_t	ino;

		switch (type) {
		case XFS_RTGI_BITMAP:
			ino = mp->m_sb.sb_rbmino;
			break;
		case XFS_RTGI_SUMMARY:
			ino = mp->m_sb.sb_rsumino;
			break;
		default:
			/* None of the other types exist on !rtgroups */
			return 0;
		}

		error = xfs_trans_metafile_iget(tp, ino, ops->metafile_type,
				&ip);
	} else {
		const char	*path;

		if (!mp->m_rtdirip)
			return -EFSCORRUPTED;

		path = xfs_rtginode_path(rtg_rgno(rtg), type);
		if (!path)
			return -ENOMEM;
	error = xfs_metadir_load(tp, mp->m_rtdirip, path, ops->metafile_type,
			&ip);
		error = xfs_metadir_load(tp, mp->m_rtdirip, path,
				ops->metafile_type, &ip);
		kfree(path);
	}

	if (error)
		return error;
+13 −1
Original line number Diff line number Diff line
@@ -12,6 +12,9 @@ struct xfs_mount;
struct xfs_trans;

enum xfs_rtg_inodes {
	XFS_RTGI_BITMAP,	/* allocation bitmap */
	XFS_RTGI_SUMMARY,	/* allocation summary */

	XFS_RTGI_MAX,
};

@@ -26,10 +29,19 @@ struct xfs_rtgroup {
	struct xfs_group	rtg_group;

	/* per-rtgroup metadata inodes */
	struct xfs_inode	*rtg_inodes[1 /* hack */];
	struct xfs_inode	*rtg_inodes[XFS_RTGI_MAX];

	/* Number of blocks in this group */
	xfs_rtxnum_t		rtg_extents;

	/*
	 * Cache of rt summary level per bitmap block with the invariant that
	 * rtg_rsum_cache[bbno] > the maximum i for which rsum[i][bbno] != 0,
	 * or 0 if rsum[i][bbno] == 0 for all i.
	 *
	 * Reads and writes are serialized by the rsumip inode lock.
	 */
	uint8_t			*rtg_rsum_cache;
};

static inline struct xfs_rtgroup *to_rtg(struct xfs_group *xg)
Loading