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.9-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux

Pull xfs fixes from Chandan Babu:

- Allow stripe unit/width value passed via mount option to be written
over existing values in the super block

- Do not set current->journal_info to avoid its value from being miused
by another filesystem context

* tag 'xfs-6.9-fixes-1' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
xfs: don't use current->journal_info
xfs: allow sunit mount option to repair bad primary sb stripe values

+41 -32
+31 -9
fs/xfs/libxfs/xfs_sb.c
··· 530 530 } 531 531 532 532 if (!xfs_validate_stripe_geometry(mp, XFS_FSB_TO_B(mp, sbp->sb_unit), 533 - XFS_FSB_TO_B(mp, sbp->sb_width), 0, false)) 533 + XFS_FSB_TO_B(mp, sbp->sb_width), 0, 534 + xfs_buf_daddr(bp) == XFS_SB_DADDR, false)) 534 535 return -EFSCORRUPTED; 535 536 536 537 /* ··· 1324 1323 } 1325 1324 1326 1325 /* 1327 - * sunit, swidth, sectorsize(optional with 0) should be all in bytes, 1328 - * so users won't be confused by values in error messages. 1326 + * sunit, swidth, sectorsize(optional with 0) should be all in bytes, so users 1327 + * won't be confused by values in error messages. This function returns false 1328 + * if the stripe geometry is invalid and the caller is unable to repair the 1329 + * stripe configuration later in the mount process. 1329 1330 */ 1330 1331 bool 1331 1332 xfs_validate_stripe_geometry( ··· 1335 1332 __s64 sunit, 1336 1333 __s64 swidth, 1337 1334 int sectorsize, 1335 + bool may_repair, 1338 1336 bool silent) 1339 1337 { 1340 1338 if (swidth > INT_MAX) { 1341 1339 if (!silent) 1342 1340 xfs_notice(mp, 1343 1341 "stripe width (%lld) is too large", swidth); 1344 - return false; 1342 + goto check_override; 1345 1343 } 1346 1344 1347 1345 if (sunit > swidth) { 1348 1346 if (!silent) 1349 1347 xfs_notice(mp, 1350 1348 "stripe unit (%lld) is larger than the stripe width (%lld)", sunit, swidth); 1351 - return false; 1349 + goto check_override; 1352 1350 } 1353 1351 1354 1352 if (sectorsize && (int)sunit % sectorsize) { ··· 1357 1353 xfs_notice(mp, 1358 1354 "stripe unit (%lld) must be a multiple of the sector size (%d)", 1359 1355 sunit, sectorsize); 1360 - return false; 1356 + goto check_override; 1361 1357 } 1362 1358 1363 1359 if (sunit && !swidth) { 1364 1360 if (!silent) 1365 1361 xfs_notice(mp, 1366 1362 "invalid stripe unit (%lld) and stripe width of 0", sunit); 1367 - return false; 1363 + goto check_override; 1368 1364 } 1369 1365 1370 1366 if (!sunit && swidth) { 1371 1367 if (!silent) 1372 1368 xfs_notice(mp, 1373 1369 "invalid stripe width (%lld) and stripe unit of 0", swidth); 1374 - return false; 1370 + goto check_override; 1375 1371 } 1376 1372 1377 1373 if (sunit && (int)swidth % (int)sunit) { ··· 1379 1375 xfs_notice(mp, 1380 1376 "stripe width (%lld) must be a multiple of the stripe unit (%lld)", 1381 1377 swidth, sunit); 1382 - return false; 1378 + goto check_override; 1383 1379 } 1380 + return true; 1381 + 1382 + check_override: 1383 + if (!may_repair) 1384 + return false; 1385 + /* 1386 + * During mount, mp->m_dalign will not be set unless the sunit mount 1387 + * option was set. If it was set, ignore the bad stripe alignment values 1388 + * and allow the validation and overwrite later in the mount process to 1389 + * attempt to overwrite the bad stripe alignment values with the values 1390 + * supplied by mount options. 1391 + */ 1392 + if (!mp->m_dalign) 1393 + return false; 1394 + if (!silent) 1395 + xfs_notice(mp, 1396 + "Will try to correct with specified mount options sunit (%d) and swidth (%d)", 1397 + BBTOB(mp->m_dalign), BBTOB(mp->m_swidth)); 1384 1398 return true; 1385 1399 } 1386 1400
+3 -2
fs/xfs/libxfs/xfs_sb.h
··· 35 35 struct xfs_trans *tp, xfs_agnumber_t agno, 36 36 struct xfs_buf **bpp); 37 37 38 - extern bool xfs_validate_stripe_geometry(struct xfs_mount *mp, 39 - __s64 sunit, __s64 swidth, int sectorsize, bool silent); 38 + bool xfs_validate_stripe_geometry(struct xfs_mount *mp, 39 + __s64 sunit, __s64 swidth, int sectorsize, bool may_repair, 40 + bool silent); 40 41 41 42 uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents); 42 43
+1 -3
fs/xfs/scrub/common.c
··· 1044 1044 struct xfs_scrub *sc, 1045 1045 struct xfs_inode *ip) 1046 1046 { 1047 - if (current->journal_info != NULL) { 1048 - ASSERT(current->journal_info == sc->tp); 1049 - 1047 + if (sc->tp) { 1050 1048 /* 1051 1049 * If we are in a transaction, we /cannot/ drop the inode 1052 1050 * ourselves, because the VFS will trigger writeback, which
-7
fs/xfs/xfs_aops.c
··· 503 503 { 504 504 struct xfs_writepage_ctx wpc = { }; 505 505 506 - /* 507 - * Writing back data in a transaction context can result in recursive 508 - * transactions. This is bad, so issue a warning and get out of here. 509 - */ 510 - if (WARN_ON_ONCE(current->journal_info)) 511 - return 0; 512 - 513 506 xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED); 514 507 return iomap_writepages(mapping, wbc, &wpc.ctx, &xfs_writeback_ops); 515 508 }
+5 -3
fs/xfs/xfs_icache.c
··· 2039 2039 * - Memory shrinkers queued the inactivation worker and it hasn't finished. 2040 2040 * - The queue depth exceeds the maximum allowable percpu backlog. 2041 2041 * 2042 - * Note: If the current thread is running a transaction, we don't ever want to 2043 - * wait for other transactions because that could introduce a deadlock. 2042 + * Note: If we are in a NOFS context here (e.g. current thread is running a 2043 + * transaction) the we don't want to block here as inodegc progress may require 2044 + * filesystem resources we hold to make progress and that could result in a 2045 + * deadlock. Hence we skip out of here if we are in a scoped NOFS context. 2044 2046 */ 2045 2047 static inline bool 2046 2048 xfs_inodegc_want_flush_work( ··· 2050 2048 unsigned int items, 2051 2049 unsigned int shrinker_hits) 2052 2050 { 2053 - if (current->journal_info) 2051 + if (current->flags & PF_MEMALLOC_NOFS) 2054 2052 return false; 2055 2053 2056 2054 if (shrinker_hits > 0)
+1 -8
fs/xfs/xfs_trans.h
··· 268 268 xfs_trans_set_context( 269 269 struct xfs_trans *tp) 270 270 { 271 - ASSERT(current->journal_info == NULL); 272 271 tp->t_pflags = memalloc_nofs_save(); 273 - current->journal_info = tp; 274 272 } 275 273 276 274 static inline void 277 275 xfs_trans_clear_context( 278 276 struct xfs_trans *tp) 279 277 { 280 - if (current->journal_info == tp) { 281 - memalloc_nofs_restore(tp->t_pflags); 282 - current->journal_info = NULL; 283 - } 278 + memalloc_nofs_restore(tp->t_pflags); 284 279 } 285 280 286 281 static inline void ··· 283 288 struct xfs_trans *old_tp, 284 289 struct xfs_trans *new_tp) 285 290 { 286 - ASSERT(current->journal_info == old_tp); 287 291 new_tp->t_pflags = old_tp->t_pflags; 288 292 old_tp->t_pflags = 0; 289 - current->journal_info = new_tp; 290 293 } 291 294 292 295 #endif /* __XFS_TRANS_H__ */