tree:
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git
reserve-rt-metadata-space
head: 1cc2dc6cc907783eca0a0665605e0a9e7e8d9bfd
commit: cb6f96a35342bcb1c9d3ed6012feaf2249f3922c [129/219] xfs: create deferred log items
for extent swapping
config: x86_64-randconfig-r006-20210209 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0
reproduce (this is a W=1 build):
#
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git/comm...
git remote add djwong-xfs
https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux.git
git fetch --no-tags djwong-xfs reserve-rt-metadata-space
git checkout cb6f96a35342bcb1c9d3ed6012feaf2249f3922c
# save the attached .config to linux build tree
make W=1 ARCH=x86_64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp(a)intel.com>
All warnings (new ones prefixed by >>):
fs/xfs/libxfs/xfs_swapext.c: In function 'xfs_swapext_finish_one':
> fs/xfs/libxfs/xfs_swapext.c:239:17: warning: variable
'qflag' set but not used [-Wunused-but-set-variable]
239 | unsigned
int qflag;
| ^~~~~
vim +/qflag +239 fs/xfs/libxfs/xfs_swapext.c
231
232 /* Finish one extent swap, possibly log more. */
233 int
234 xfs_swapext_finish_one(
235 struct xfs_trans *tp,
236 struct xfs_swapext_intent *sxi)
237 {
238 struct xfs_bmbt_irec irec1, irec2;
239 unsigned int qflag;
240 int whichfork;
241 int nimaps;
242 int bmap_flags;
243 int error;
244
245 whichfork = (sxi->sxi_flags & XFS_SWAP_EXTENT_ATTR_FORK) ?
246 XFS_ATTR_FORK : XFS_DATA_FORK;
247 bmap_flags = xfs_bmapi_aflag(whichfork);
248 qflag = XFS_IS_REALTIME_INODE(sxi->sxi_ip1) ? XFS_TRANS_DQ_RTBCOUNT :
249 XFS_TRANS_DQ_BCOUNT;
250
251 while (sxi->sxi_blockcount > 0) {
252 int64_t ip1_delta = 0, ip2_delta = 0;
253
254 /* Read extent from the first file */
255 nimaps = 1;
256 error = xfs_bmapi_read(sxi->sxi_ip1, sxi->sxi_startoff1,
257 sxi->sxi_blockcount, &irec1, &nimaps,
258 bmap_flags);
259 if (error)
260 return error;
261 if (nimaps != 1 ||
262 irec1.br_startblock == DELAYSTARTBLOCK ||
263 irec1.br_startoff != sxi->sxi_startoff1) {
264 /*
265 * We should never get no mapping or a delalloc extent
266 * or something that doesn't match what we asked for,
267 * since the caller flushed both inodes and we hold the
268 * ILOCKs for both inodes.
269 */
270 ASSERT(0);
271 return -EINVAL;
272 }
273
274 /*
275 * If the caller told us to ignore sparse areas of file1, jump
276 * ahead to the next region.
277 */
278 if ((sxi->sxi_flags & XFS_SWAP_EXTENT_SKIP_FILE1_HOLES) &&
279 irec1.br_startblock == HOLESTARTBLOCK) {
280 trace_xfs_swapext_extent1(sxi->sxi_ip1, &irec1);
281
282 sxi->sxi_startoff1 += irec1.br_blockcount;
283 sxi->sxi_startoff2 += irec1.br_blockcount;
284 sxi->sxi_blockcount -= irec1.br_blockcount;
285 continue;
286 }
287
288 /* Read extent from the second file */
289 nimaps = 1;
290 error = xfs_bmapi_read(sxi->sxi_ip2, sxi->sxi_startoff2,
291 irec1.br_blockcount, &irec2, &nimaps,
292 bmap_flags);
293 if (error)
294 return error;
295 if (nimaps != 1 ||
296 irec2.br_startblock == DELAYSTARTBLOCK ||
297 irec2.br_startoff != sxi->sxi_startoff2) {
298 /*
299 * We should never get no mapping or a delalloc extent
300 * or something that doesn't match what we asked for,
301 * since the caller flushed both inodes and we hold the
302 * ILOCKs for both inodes.
303 */
304 ASSERT(0);
305 return -EINVAL;
306 }
307
308 /*
309 * We can only swap as many blocks as the smaller of the two
310 * extent maps.
311 */
312 irec1.br_blockcount = min(irec1.br_blockcount,
313 irec2.br_blockcount);
314
315 trace_xfs_swapext_extent1(sxi->sxi_ip1, &irec1);
316 trace_xfs_swapext_extent2(sxi->sxi_ip2, &irec2);
317
318 /*
319 * Two extents mapped to the same physical block must not have
320 * different states; that's filesystem corruption. Move on to
321 * the next extent if they're both holes or both the same
322 * physical extent.
323 */
324 if (irec1.br_startblock == irec2.br_startblock) {
325 if (irec1.br_state != irec2.br_state)
326 return -EFSCORRUPTED;
327
328 sxi->sxi_startoff1 += irec1.br_blockcount;
329 sxi->sxi_startoff2 += irec1.br_blockcount;
330 sxi->sxi_blockcount -= irec1.br_blockcount;
331 continue;
332 }
333
334 /* Update quota accounting. */
335 if (xfs_bmap_is_real_extent(&irec1)) {
336 ip1_delta -= irec1.br_blockcount;
337 ip2_delta += irec1.br_blockcount;
338 }
339 if (xfs_bmap_is_real_extent(&irec2)) {
340 ip1_delta += irec2.br_blockcount;
341 ip2_delta -= irec2.br_blockcount;
342 }
343 xfs_trans_mod_dquot_byino(tp, sxi->sxi_ip1, qflag, ip1_delta);
344 xfs_trans_mod_dquot_byino(tp, sxi->sxi_ip2, qflag, ip2_delta);
345
346 /* Remove both mappings. */
347 xfs_bmap_unmap_extent(tp, sxi->sxi_ip1, whichfork, &irec1);
348 xfs_bmap_unmap_extent(tp, sxi->sxi_ip2, whichfork, &irec2);
349
350 /*
351 * Re-add both mappings. We swap the file offsets between the
352 * two maps and add the opposite map, which has the effect of
353 * filling the logical offsets we just unmapped, but with with
354 * the physical mapping information swapped.
355 */
356 swap(irec1.br_startoff, irec2.br_startoff);
357 xfs_bmap_map_extent(tp, sxi->sxi_ip1, whichfork, &irec2);
358 xfs_bmap_map_extent(tp, sxi->sxi_ip2, whichfork, &irec1);
359
360 /* Make sure we're not mapping extents past EOF. */
361 if (whichfork == XFS_DATA_FORK) {
362 xfs_swapext_update_size(tp, sxi->sxi_ip1, &irec2,
363 sxi->sxi_isize1);
364 xfs_swapext_update_size(tp, sxi->sxi_ip2, &irec1,
365 sxi->sxi_isize2);
366 }
367
368 /*
369 * Advance our cursor and exit. The caller (either defer ops
370 * or log recovery) will log the SXD item, and if *blockcount
371 * is nonzero, it will log a new SXI item for the remainder
372 * and call us back.
373 */
374 sxi->sxi_startoff1 += irec1.br_blockcount;
375 sxi->sxi_startoff2 += irec1.br_blockcount;
376 sxi->sxi_blockcount -= irec1.br_blockcount;
377 break;
378 }
379
380 /*
381 * If the caller asked us to exchange the file sizes and we're done
382 * moving extents, update the ondisk file sizes now.
383 */
384 if (sxi->sxi_blockcount == 0 &&
385 (sxi->sxi_flags & XFS_SWAP_EXTENT_SET_SIZES)) {
386 sxi->sxi_ip1->i_d.di_size = sxi->sxi_isize1;
387 sxi->sxi_ip2->i_d.di_size = sxi->sxi_isize2;
388
389 xfs_trans_log_inode(tp, sxi->sxi_ip1, XFS_ILOG_CORE);
390 xfs_trans_log_inode(tp, sxi->sxi_ip2, XFS_ILOG_CORE);
391 }
392
393 if (xfs_swapext_has_more_work(sxi))
394 trace_xfs_swapext_defer(tp->t_mountp, sxi);
395
396 return 0;
397 }
398
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org