Skip to content

Commit f76823e

Browse files
Christoph Hellwigcmaiolino
authored andcommitted
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 <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Carlos Maiolino <[email protected]>
1 parent 5d94b19 commit f76823e

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

fs/xfs/xfs_trace.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,7 @@ DEFINE_EVENT(xfs_zone_alloc_class, name, \
455455
xfs_extlen_t len), \
456456
TP_ARGS(oz, rgbno, len))
457457
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_record_blocks);
458+
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_skip_blocks);
458459
DEFINE_ZONE_ALLOC_EVENT(xfs_zone_alloc_blocks);
459460

460461
TRACE_EVENT(xfs_zone_gc_select_victim,

fs/xfs/xfs_zone_alloc.c

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -166,10 +166,9 @@ xfs_open_zone_mark_full(
166166
static void
167167
xfs_zone_record_blocks(
168168
struct xfs_trans *tp,
169-
xfs_fsblock_t fsbno,
170-
xfs_filblks_t len,
171169
struct xfs_open_zone *oz,
172-
bool used)
170+
xfs_fsblock_t fsbno,
171+
xfs_filblks_t len)
173172
{
174173
struct xfs_mount *mp = tp->t_mountp;
175174
struct xfs_rtgroup *rtg = oz->oz_rtg;
@@ -179,18 +178,37 @@ xfs_zone_record_blocks(
179178

180179
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
181180
xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP);
182-
if (used) {
183-
rmapip->i_used_blocks += len;
184-
ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
185-
} else {
186-
xfs_add_frextents(mp, len);
187-
}
181+
rmapip->i_used_blocks += len;
182+
ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg));
188183
oz->oz_written += len;
189184
if (oz->oz_written == rtg_blocks(rtg))
190185
xfs_open_zone_mark_full(oz);
191186
xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE);
192187
}
193188

189+
/*
190+
* Called for blocks that have been written to disk, but not actually linked to
191+
* an inode, which can happen when garbage collection races with user data
192+
* writes to a file.
193+
*/
194+
static void
195+
xfs_zone_skip_blocks(
196+
struct xfs_open_zone *oz,
197+
xfs_filblks_t len)
198+
{
199+
struct xfs_rtgroup *rtg = oz->oz_rtg;
200+
201+
trace_xfs_zone_skip_blocks(oz, 0, len);
202+
203+
xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP);
204+
oz->oz_written += len;
205+
if (oz->oz_written == rtg_blocks(rtg))
206+
xfs_open_zone_mark_full(oz);
207+
xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP);
208+
209+
xfs_add_frextents(rtg_mount(rtg), len);
210+
}
211+
194212
static int
195213
xfs_zoned_map_extent(
196214
struct xfs_trans *tp,
@@ -250,17 +268,15 @@ xfs_zoned_map_extent(
250268
}
251269
}
252270

253-
xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz,
254-
true);
271+
xfs_zone_record_blocks(tp, oz, new->br_startblock, new->br_blockcount);
255272

256273
/* Map the new blocks into the data fork. */
257274
xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, new);
258275
return 0;
259276

260277
skip:
261278
trace_xfs_reflink_cow_remap_skip(ip, new);
262-
xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz,
263-
false);
279+
xfs_zone_skip_blocks(oz, new->br_blockcount);
264280
return 0;
265281
}
266282

0 commit comments

Comments
 (0)