Skip to content
This repository was archived by the owner on Nov 8, 2023. It is now read-only.

Commit 712e142

Browse files
committed
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
2 parents fe764a7 + f2e812c commit 712e142

File tree

6 files changed

+41
-32
lines changed

6 files changed

+41
-32
lines changed

fs/xfs/libxfs/xfs_sb.c

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -530,7 +530,8 @@ xfs_validate_sb_common(
530530
}
531531

532532
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))
534535
return -EFSCORRUPTED;
535536

536537
/*
@@ -1323,61 +1324,82 @@ xfs_sb_get_secondary(
13231324
}
13241325

13251326
/*
1326-
* sunit, swidth, sectorsize(optional with 0) should be all in bytes,
1327-
* so users won't be confused by values in error messages.
1327+
* sunit, swidth, sectorsize(optional with 0) should be all in bytes, so users
1328+
* won't be confused by values in error messages. This function returns false
1329+
* if the stripe geometry is invalid and the caller is unable to repair the
1330+
* stripe configuration later in the mount process.
13281331
*/
13291332
bool
13301333
xfs_validate_stripe_geometry(
13311334
struct xfs_mount *mp,
13321335
__s64 sunit,
13331336
__s64 swidth,
13341337
int sectorsize,
1338+
bool may_repair,
13351339
bool silent)
13361340
{
13371341
if (swidth > INT_MAX) {
13381342
if (!silent)
13391343
xfs_notice(mp,
13401344
"stripe width (%lld) is too large", swidth);
1341-
return false;
1345+
goto check_override;
13421346
}
13431347

13441348
if (sunit > swidth) {
13451349
if (!silent)
13461350
xfs_notice(mp,
13471351
"stripe unit (%lld) is larger than the stripe width (%lld)", sunit, swidth);
1348-
return false;
1352+
goto check_override;
13491353
}
13501354

13511355
if (sectorsize && (int)sunit % sectorsize) {
13521356
if (!silent)
13531357
xfs_notice(mp,
13541358
"stripe unit (%lld) must be a multiple of the sector size (%d)",
13551359
sunit, sectorsize);
1356-
return false;
1360+
goto check_override;
13571361
}
13581362

13591363
if (sunit && !swidth) {
13601364
if (!silent)
13611365
xfs_notice(mp,
13621366
"invalid stripe unit (%lld) and stripe width of 0", sunit);
1363-
return false;
1367+
goto check_override;
13641368
}
13651369

13661370
if (!sunit && swidth) {
13671371
if (!silent)
13681372
xfs_notice(mp,
13691373
"invalid stripe width (%lld) and stripe unit of 0", swidth);
1370-
return false;
1374+
goto check_override;
13711375
}
13721376

13731377
if (sunit && (int)swidth % (int)sunit) {
13741378
if (!silent)
13751379
xfs_notice(mp,
13761380
"stripe width (%lld) must be a multiple of the stripe unit (%lld)",
13771381
swidth, sunit);
1378-
return false;
1382+
goto check_override;
13791383
}
13801384
return true;
1385+
1386+
check_override:
1387+
if (!may_repair)
1388+
return false;
1389+
/*
1390+
* During mount, mp->m_dalign will not be set unless the sunit mount
1391+
* option was set. If it was set, ignore the bad stripe alignment values
1392+
* and allow the validation and overwrite later in the mount process to
1393+
* attempt to overwrite the bad stripe alignment values with the values
1394+
* supplied by mount options.
1395+
*/
1396+
if (!mp->m_dalign)
1397+
return false;
1398+
if (!silent)
1399+
xfs_notice(mp,
1400+
"Will try to correct with specified mount options sunit (%d) and swidth (%d)",
1401+
BBTOB(mp->m_dalign), BBTOB(mp->m_swidth));
1402+
return true;
13811403
}
13821404

13831405
/*

fs/xfs/libxfs/xfs_sb.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,9 @@ extern int xfs_sb_get_secondary(struct xfs_mount *mp,
3535
struct xfs_trans *tp, xfs_agnumber_t agno,
3636
struct xfs_buf **bpp);
3737

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);
4041

4142
uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents);
4243

fs/xfs/scrub/common.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,9 +1044,7 @@ xchk_irele(
10441044
struct xfs_scrub *sc,
10451045
struct xfs_inode *ip)
10461046
{
1047-
if (current->journal_info != NULL) {
1048-
ASSERT(current->journal_info == sc->tp);
1049-
1047+
if (sc->tp) {
10501048
/*
10511049
* If we are in a transaction, we /cannot/ drop the inode
10521050
* ourselves, because the VFS will trigger writeback, which

fs/xfs/xfs_aops.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -503,13 +503,6 @@ xfs_vm_writepages(
503503
{
504504
struct xfs_writepage_ctx wpc = { };
505505

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-
513506
xfs_iflags_clear(XFS_I(mapping->host), XFS_ITRUNCATED);
514507
return iomap_writepages(mapping, wbc, &wpc.ctx, &xfs_writeback_ops);
515508
}

fs/xfs/xfs_icache.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,16 +2039,18 @@ xfs_inodegc_want_queue_work(
20392039
* - Memory shrinkers queued the inactivation worker and it hasn't finished.
20402040
* - The queue depth exceeds the maximum allowable percpu backlog.
20412041
*
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.
20442046
*/
20452047
static inline bool
20462048
xfs_inodegc_want_flush_work(
20472049
struct xfs_inode *ip,
20482050
unsigned int items,
20492051
unsigned int shrinker_hits)
20502052
{
2051-
if (current->journal_info)
2053+
if (current->flags & PF_MEMALLOC_NOFS)
20522054
return false;
20532055

20542056
if (shrinker_hits > 0)

fs/xfs/xfs_trans.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -268,30 +268,23 @@ static inline void
268268
xfs_trans_set_context(
269269
struct xfs_trans *tp)
270270
{
271-
ASSERT(current->journal_info == NULL);
272271
tp->t_pflags = memalloc_nofs_save();
273-
current->journal_info = tp;
274272
}
275273

276274
static inline void
277275
xfs_trans_clear_context(
278276
struct xfs_trans *tp)
279277
{
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);
284279
}
285280

286281
static inline void
287282
xfs_trans_switch_context(
288283
struct xfs_trans *old_tp,
289284
struct xfs_trans *new_tp)
290285
{
291-
ASSERT(current->journal_info == old_tp);
292286
new_tp->t_pflags = old_tp->t_pflags;
293287
old_tp->t_pflags = 0;
294-
current->journal_info = new_tp;
295288
}
296289

297290
#endif /* __XFS_TRANS_H__ */

0 commit comments

Comments
 (0)