xfs: split xfs_zone_record_blocks
xfs_zone_record_blocks not only records successfully written blocks that now back file data, but is also used for blocks speculatively written by garbage collection that were never linked to an inode and instantly become invalid. Split the latter functionality out to be easier to understand. This also make it clear that we don't need to attach the rmap inode to a transaction for the skipped blocks case as we never dirty any peristent data structure. Also make the argument order to xfs_zone_record_blocks a bit more natural. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Carlos Maiolino <cem@kernel.org>
This commit is contained in:
committed by
Carlos Maiolino
parent
5d94b19f06
commit
f76823e3b2
@@ -455,6 +455,7 @@ DEFINE_EVENT(xfs_zone_alloc_class, name, \
|
||||
xfs_extlen_t len), \
|
||||
TP_ARGS(oz, rgbno, len))
|
||||
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_record_blocks);
|
||||
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_skip_blocks);
|
||||
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_alloc_blocks);
|
||||
|
||||
TRACE_EVENT(xfs_zone_gc_select_victim,
|
||||
|
||||
+29
-13
@@ -166,10 +166,9 @@ xfs_open_zone_mark_full(
|
||||
static void
|
||||
xfs_zone_record_blocks(
|
||||
struct xfs_trans *tp,
|
||||
xfs_fsblock_t fsbno,
|
||||
xfs_filblks_t len,
|
||||
struct xfs_open_zone *oz,
|
||||
bool used)
|
||||
xfs_fsblock_t fsbno,
|
||||
xfs_filblks_t len)
|
||||
{
|
||||
struct xfs_mount *mp = tp->t_mountp;
|
||||
struct xfs_rtgroup *rtg = oz->oz_rtg;
|
||||
@@ -179,18 +178,37 @@ xfs_zone_record_blocks(
|
||||
|
||||
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
|
||||
xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP);
|
||||
if (used) {
|
||||
rmapip->i_used_blocks += len;
|
||||
ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
|
||||
} else {
|
||||
xfs_add_frextents(mp, len);
|
||||
}
|
||||
rmapip->i_used_blocks += len;
|
||||
ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
|
||||
oz->oz_written += len;
|
||||
if (oz->oz_written == rtg_blocks(rtg))
|
||||
xfs_open_zone_mark_full(oz);
|
||||
xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called for blocks that have been written to disk, but not actually linked to
|
||||
* an inode, which can happen when garbage collection races with user data
|
||||
* writes to a file.
|
||||
*/
|
||||
static void
|
||||
xfs_zone_skip_blocks(
|
||||
struct xfs_open_zone *oz,
|
||||
xfs_filblks_t len)
|
||||
{
|
||||
struct xfs_rtgroup *rtg = oz->oz_rtg;
|
||||
|
||||
trace_xfs_zone_skip_blocks(oz, 0, len);
|
||||
|
||||
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
|
||||
oz->oz_written += len;
|
||||
if (oz->oz_written == rtg_blocks(rtg))
|
||||
xfs_open_zone_mark_full(oz);
|
||||
xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
|
||||
|
||||
xfs_add_frextents(rtg_mount(rtg), len);
|
||||
}
|
||||
|
||||
static int
|
||||
xfs_zoned_map_extent(
|
||||
struct xfs_trans *tp,
|
||||
@@ -250,8 +268,7 @@ xfs_zoned_map_extent(
|
||||
}
|
||||
}
|
||||
|
||||
xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz,
|
||||
true);
|
||||
xfs_zone_record_blocks(tp, oz, new->br_startblock, new->br_blockcount);
|
||||
|
||||
/* Map the new blocks into the data fork. */
|
||||
xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, new);
|
||||
@@ -259,8 +276,7 @@ xfs_zoned_map_extent(
|
||||
|
||||
skip:
|
||||
trace_xfs_reflink_cow_remap_skip(ip, new);
|
||||
xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz,
|
||||
false);
|
||||
xfs_zone_skip_blocks(oz, new->br_blockcount);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user