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.

Merge tag 'xfs-6.3-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Darrick Wong:

- Fix a crash if mount time quotacheck fails when there are inodes
queued for garbage collection.

- Fix an off by one error when discarding folios after writeback
failure.

* tag 'xfs-6.3-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: fix off-by-one-block in xfs_discard_folio()
xfs: quotacheck failure can race with background inode inactivation

+40 -21
+14 -7
fs/xfs/xfs_aops.c
··· 449 449 } 450 450 451 451 /* 452 - * If the page has delalloc blocks on it, we need to punch them out before we 453 - * invalidate the page. If we don't, we leave a stale delalloc mapping on the 454 - * inode that can trip up a later direct I/O read operation on the same region. 452 + * If the folio has delalloc blocks on it, the caller is asking us to punch them 453 + * out. If we don't, we can leave a stale delalloc mapping covered by a clean 454 + * page that needs to be dirtied again before the delalloc mapping can be 455 + * converted. This stale delalloc mapping can trip up a later direct I/O read 456 + * operation on the same region. 455 457 * 456 - * We prevent this by truncating away the delalloc regions on the page. Because 458 + * We prevent this by truncating away the delalloc regions on the folio. Because 457 459 * they are delalloc, we can do this without needing a transaction. Indeed - if 458 460 * we get ENOSPC errors, we have to be able to do this truncation without a 459 - * transaction as there is no space left for block reservation (typically why we 460 - * see a ENOSPC in writeback). 461 + * transaction as there is no space left for block reservation (typically why 462 + * we see a ENOSPC in writeback). 461 463 */ 462 464 static void 463 465 xfs_discard_folio( ··· 477 475 "page discard on page "PTR_FMT", inode 0x%llx, pos %llu.", 478 476 folio, ip->i_ino, pos); 479 477 478 + /* 479 + * The end of the punch range is always the offset of the the first 480 + * byte of the next folio. Hence the end offset is only dependent on the 481 + * folio itself and not the start offset that is passed in. 482 + */ 480 483 error = xfs_bmap_punch_delalloc_range(ip, pos, 481 - round_up(pos, folio_size(folio))); 484 + folio_pos(folio) + folio_size(folio)); 482 485 483 486 if (error && !xfs_is_shutdown(mp)) 484 487 xfs_alert(mp, "page discard unable to remove delalloc mapping.");
+26 -14
fs/xfs/xfs_qm.c
··· 1321 1321 1322 1322 error = xfs_iwalk_threaded(mp, 0, 0, xfs_qm_dqusage_adjust, 0, true, 1323 1323 NULL); 1324 - if (error) { 1325 - /* 1326 - * The inode walk may have partially populated the dquot 1327 - * caches. We must purge them before disabling quota and 1328 - * tearing down the quotainfo, or else the dquots will leak. 1329 - */ 1330 - xfs_qm_dqpurge_all(mp); 1331 - goto error_return; 1332 - } 1324 + 1325 + /* 1326 + * On error, the inode walk may have partially populated the dquot 1327 + * caches. We must purge them before disabling quota and tearing down 1328 + * the quotainfo, or else the dquots will leak. 1329 + */ 1330 + if (error) 1331 + goto error_purge; 1333 1332 1334 1333 /* 1335 1334 * We've made all the changes that we need to make incore. Flush them ··· 1362 1363 * and turn quotaoff. The dquots won't be attached to any of the inodes 1363 1364 * at this point (because we intentionally didn't in dqget_noattach). 1364 1365 */ 1365 - if (error) { 1366 - xfs_qm_dqpurge_all(mp); 1367 - goto error_return; 1368 - } 1366 + if (error) 1367 + goto error_purge; 1369 1368 1370 1369 /* 1371 1370 * If one type of quotas is off, then it will lose its ··· 1373 1376 mp->m_qflags &= ~XFS_ALL_QUOTA_CHKD; 1374 1377 mp->m_qflags |= flags; 1375 1378 1376 - error_return: 1379 + error_return: 1377 1380 xfs_buf_delwri_cancel(&buffer_list); 1378 1381 1379 1382 if (error) { ··· 1392 1395 } else 1393 1396 xfs_notice(mp, "Quotacheck: Done."); 1394 1397 return error; 1398 + 1399 + error_purge: 1400 + /* 1401 + * On error, we may have inodes queued for inactivation. This may try 1402 + * to attach dquots to the inode before running cleanup operations on 1403 + * the inode and this can race with the xfs_qm_destroy_quotainfo() call 1404 + * below that frees mp->m_quotainfo. To avoid this race, flush all the 1405 + * pending inodegc operations before we purge the dquots from memory, 1406 + * ensuring that background inactivation is idle whilst we turn off 1407 + * quotas. 1408 + */ 1409 + xfs_inodegc_flush(mp); 1410 + xfs_qm_dqpurge_all(mp); 1411 + goto error_return; 1412 + 1395 1413 } 1396 1414 1397 1415 /*