Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Christoph Hellwig and committed by
Carlos Maiolino
f76823e3 5d94b19f

+30 -13
+1
fs/xfs/xfs_trace.h
··· 455 455 xfs_extlen_t len), \ 456 456 TP_ARGS(oz, rgbno, len)) 457 457 DEFINE_ZONE_ALLOC_EVENT(xfs_zone_record_blocks); 458 + DEFINE_ZONE_ALLOC_EVENT(xfs_zone_skip_blocks); 458 459 DEFINE_ZONE_ALLOC_EVENT(xfs_zone_alloc_blocks); 459 460 460 461 TRACE_EVENT(xfs_zone_gc_select_victim,
+29 -13
fs/xfs/xfs_zone_alloc.c
··· 166 166 static void 167 167 xfs_zone_record_blocks( 168 168 struct xfs_trans *tp, 169 - xfs_fsblock_t fsbno, 170 - xfs_filblks_t len, 171 169 struct xfs_open_zone *oz, 172 - bool used) 170 + xfs_fsblock_t fsbno, 171 + xfs_filblks_t len) 173 172 { 174 173 struct xfs_mount *mp = tp->t_mountp; 175 174 struct xfs_rtgroup *rtg = oz->oz_rtg; ··· 178 179 179 180 xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP); 180 181 xfs_rtgroup_trans_join(tp, rtg, XFS_RTGLOCK_RMAP); 181 - if (used) { 182 - rmapip->i_used_blocks += len; 183 - ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg)); 184 - } else { 185 - xfs_add_frextents(mp, len); 186 - } 182 + rmapip->i_used_blocks += len; 183 + ASSERT(rmapip->i_used_blocks <= rtg_blocks(rtg)); 187 184 oz->oz_written += len; 188 185 if (oz->oz_written == rtg_blocks(rtg)) 189 186 xfs_open_zone_mark_full(oz); 190 187 xfs_trans_log_inode(tp, rmapip, XFS_ILOG_CORE); 188 + } 189 + 190 + /* 191 + * Called for blocks that have been written to disk, but not actually linked to 192 + * an inode, which can happen when garbage collection races with user data 193 + * writes to a file. 194 + */ 195 + static void 196 + xfs_zone_skip_blocks( 197 + struct xfs_open_zone *oz, 198 + xfs_filblks_t len) 199 + { 200 + struct xfs_rtgroup *rtg = oz->oz_rtg; 201 + 202 + trace_xfs_zone_skip_blocks(oz, 0, len); 203 + 204 + xfs_rtgroup_lock(rtg, XFS_RTGLOCK_RMAP); 205 + oz->oz_written += len; 206 + if (oz->oz_written == rtg_blocks(rtg)) 207 + xfs_open_zone_mark_full(oz); 208 + xfs_rtgroup_unlock(rtg, XFS_RTGLOCK_RMAP); 209 + 210 + xfs_add_frextents(rtg_mount(rtg), len); 191 211 } 192 212 193 213 static int ··· 268 250 } 269 251 } 270 252 271 - xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz, 272 - true); 253 + xfs_zone_record_blocks(tp, oz, new->br_startblock, new->br_blockcount); 273 254 274 255 /* Map the new blocks into the data fork. */ 275 256 xfs_bmap_map_extent(tp, ip, XFS_DATA_FORK, new); ··· 276 259 277 260 skip: 278 261 trace_xfs_reflink_cow_remap_skip(ip, new); 279 - xfs_zone_record_blocks(tp, new->br_startblock, new->br_blockcount, oz, 280 - false); 262 + xfs_zone_skip_blocks(oz, new->br_blockcount); 281 263 return 0; 282 264 } 283 265