Skip to content

Commit 4b0bf86

Browse files
author
Chandan Babu R
committed
Merge tag 'repair-fixes-6.10_2024-04-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.10-mergeC
xfs: minor fixes to online repair Here are some miscellaneous bug fixes for the online repair code. Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: Chandan Babu R <[email protected]> * tag 'repair-fixes-6.10_2024-04-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: invalidate dentries for a file before moving it to the orphanage xfs: exchange-range for repairs is no longer dynamic xfs: fix iunlock calls in xrep_adoption_trans_alloc xfs: drop the scrub file's iolock when transaction allocation fails
2 parents b878dbb + 5e1c7d0 commit 4b0bf86

File tree

12 files changed

+49
-76
lines changed

12 files changed

+49
-76
lines changed

fs/xfs/scrub/attr_repair.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,9 @@ xrep_xattr(
16301630
/* The rmapbt is required to reap the old attr fork. */
16311631
if (!xfs_has_rmapbt(sc->mp))
16321632
return -EOPNOTSUPP;
1633+
/* We require atomic file exchange range to rebuild anything. */
1634+
if (!xfs_has_exchange_range(sc->mp))
1635+
return -EOPNOTSUPP;
16331636

16341637
error = xrep_xattr_setup_scan(sc, &rx);
16351638
if (error)

fs/xfs/scrub/dir_repair.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,6 +1993,9 @@ xrep_directory(
19931993
/* The rmapbt is required to reap the old data fork. */
19941994
if (!xfs_has_rmapbt(sc->mp))
19951995
return -EOPNOTSUPP;
1996+
/* We require atomic file exchange range to rebuild anything. */
1997+
if (!xfs_has_exchange_range(sc->mp))
1998+
return -EOPNOTSUPP;
19961999

19972000
error = xrep_dir_setup_scan(rd);
19982001
if (error)

fs/xfs/scrub/nlinks_repair.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,10 @@ xrep_nlinks_repair_inode(
138138

139139
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_link, 0, 0, 0,
140140
&sc->tp);
141-
if (error)
141+
if (error) {
142+
xchk_iunlock(sc, XFS_IOLOCK_EXCL);
142143
return error;
144+
}
143145

144146
xchk_ilock(sc, XFS_ILOCK_EXCL);
145147
xfs_trans_ijoin(sc->tp, ip, 0);

fs/xfs/scrub/orphanage.c

Lines changed: 21 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ xrep_adoption_trans_alloc(
382382
out_cancel:
383383
xchk_trans_cancel(sc);
384384
xrep_orphanage_iunlock(sc, XFS_ILOCK_EXCL);
385-
xrep_orphanage_iunlock(sc, XFS_IOLOCK_EXCL);
385+
xchk_iunlock(sc, XFS_ILOCK_EXCL);
386386
return error;
387387
}
388388

@@ -434,16 +434,17 @@ xrep_adoption_check_dcache(
434434
{
435435
struct qstr qname = QSTR_INIT(adopt->xname->name,
436436
adopt->xname->len);
437+
struct xfs_scrub *sc = adopt->sc;
437438
struct dentry *d_orphanage, *d_child;
438439
int error = 0;
439440

440-
d_orphanage = d_find_alias(VFS_I(adopt->sc->orphanage));
441+
d_orphanage = d_find_alias(VFS_I(sc->orphanage));
441442
if (!d_orphanage)
442443
return 0;
443444

444445
d_child = d_hash_and_lookup(d_orphanage, &qname);
445446
if (d_child) {
446-
trace_xrep_adoption_check_child(adopt->sc->mp, d_child);
447+
trace_xrep_adoption_check_child(sc->mp, d_child);
447448

448449
if (d_is_positive(d_child)) {
449450
ASSERT(d_is_negative(d_child));
@@ -454,49 +455,33 @@ xrep_adoption_check_dcache(
454455
}
455456

456457
dput(d_orphanage);
457-
if (error)
458-
return error;
459-
460-
/*
461-
* Do we need to update d_parent of the dentry for the file being
462-
* repaired? There shouldn't be a hashed dentry with a parent since
463-
* the file had nonzero nlink but wasn't connected to any parent dir.
464-
*/
465-
d_child = d_find_alias(VFS_I(adopt->sc->ip));
466-
if (!d_child)
467-
return 0;
468-
469-
trace_xrep_adoption_check_alias(adopt->sc->mp, d_child);
470-
471-
if (d_child->d_parent && !d_unhashed(d_child)) {
472-
ASSERT(d_child->d_parent == NULL || d_unhashed(d_child));
473-
error = -EFSCORRUPTED;
474-
}
475-
476-
dput(d_child);
477458
return error;
478459
}
479460

480461
/*
481-
* Remove all negative dentries from the dcache. There should not be any
482-
* positive entries, since we've maintained our lock on the orphanage
483-
* directory.
462+
* Invalidate all dentries for the name that was added to the orphanage
463+
* directory, and all dentries pointing to the child inode that was moved.
464+
*
465+
* There should not be any positive entries for the name, since we've
466+
* maintained our lock on the orphanage directory.
484467
*/
485468
static void
486469
xrep_adoption_zap_dcache(
487470
struct xrep_adoption *adopt)
488471
{
489472
struct qstr qname = QSTR_INIT(adopt->xname->name,
490473
adopt->xname->len);
474+
struct xfs_scrub *sc = adopt->sc;
491475
struct dentry *d_orphanage, *d_child;
492476

493-
d_orphanage = d_find_alias(VFS_I(adopt->sc->orphanage));
477+
/* Invalidate all dentries for the adoption name */
478+
d_orphanage = d_find_alias(VFS_I(sc->orphanage));
494479
if (!d_orphanage)
495480
return;
496481

497482
d_child = d_hash_and_lookup(d_orphanage, &qname);
498483
while (d_child != NULL) {
499-
trace_xrep_adoption_invalidate_child(adopt->sc->mp, d_child);
484+
trace_xrep_adoption_invalidate_child(sc->mp, d_child);
500485

501486
ASSERT(d_is_negative(d_child));
502487
d_invalidate(d_child);
@@ -505,6 +490,14 @@ xrep_adoption_zap_dcache(
505490
}
506491

507492
dput(d_orphanage);
493+
494+
/* Invalidate all the dentries pointing down to this file. */
495+
while ((d_child = d_find_alias(VFS_I(sc->ip))) != NULL) {
496+
trace_xrep_adoption_invalidate_child(sc->mp, d_child);
497+
498+
d_invalidate(d_child);
499+
dput(d_child);
500+
}
508501
}
509502

510503
/*

fs/xfs/scrub/parent_repair.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,10 +1571,14 @@ xrep_parent(
15711571
/*
15721572
* When the parent pointers feature is enabled, repairs are committed
15731573
* by atomically committing a new xattr structure and reaping the old
1574-
* attr fork. Reaping requires rmap to be enabled.
1574+
* attr fork. Reaping requires rmap and exchange-range to be enabled.
15751575
*/
1576-
if (xfs_has_parent(sc->mp) && !xfs_has_rmapbt(sc->mp))
1577-
return -EOPNOTSUPP;
1576+
if (xfs_has_parent(sc->mp)) {
1577+
if (!xfs_has_rmapbt(sc->mp))
1578+
return -EOPNOTSUPP;
1579+
if (!xfs_has_exchange_range(sc->mp))
1580+
return -EOPNOTSUPP;
1581+
}
15781582

15791583
error = xrep_parent_setup_scan(rp);
15801584
if (error)

fs/xfs/scrub/rtsummary_repair.c

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,7 @@ xrep_setup_rtsummary(
6262
return -EOPNOTSUPP;
6363

6464
rts->resblks += blocks;
65-
66-
/*
67-
* Grab support for atomic file content exchanges before we allocate
68-
* any transactions or grab ILOCKs.
69-
*/
70-
return xrep_tempexch_enable(sc);
65+
return 0;
7166
}
7267

7368
static int
@@ -111,6 +106,9 @@ xrep_rtsummary(
111106
/* We require the rmapbt to rebuild anything. */
112107
if (!xfs_has_rmapbt(mp))
113108
return -EOPNOTSUPP;
109+
/* We require atomic file exchange range to rebuild anything. */
110+
if (!xfs_has_exchange_range(mp))
111+
return -EOPNOTSUPP;
114112

115113
/* Walk away if we disagree on the size of the rt bitmap. */
116114
if (rts->rbmblocks != mp->m_sb.sb_rbmblocks)

fs/xfs/scrub/scrub.c

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,14 @@ xchk_probe(
154154

155155
/* Scrub setup and teardown */
156156

157-
#define FSGATES_MASK (XCHK_FSGATES_ALL | XREP_FSGATES_ALL)
158157
static inline void
159158
xchk_fsgates_disable(
160159
struct xfs_scrub *sc)
161160
{
162-
if (!(sc->flags & FSGATES_MASK))
161+
if (!(sc->flags & XCHK_FSGATES_ALL))
163162
return;
164163

165-
trace_xchk_fsgates_disable(sc, sc->flags & FSGATES_MASK);
164+
trace_xchk_fsgates_disable(sc, sc->flags & XCHK_FSGATES_ALL);
166165

167166
if (sc->flags & XCHK_FSGATES_DRAIN)
168167
xfs_drain_wait_disable();
@@ -176,9 +175,8 @@ xchk_fsgates_disable(
176175
if (sc->flags & XCHK_FSGATES_RMAP)
177176
xfs_rmap_hook_disable();
178177

179-
sc->flags &= ~FSGATES_MASK;
178+
sc->flags &= ~XCHK_FSGATES_ALL;
180179
}
181-
#undef FSGATES_MASK
182180

183181
/* Free the resources associated with a scrub subtype. */
184182
void

fs/xfs/scrub/scrub.h

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,6 @@ struct xfs_scrub {
188188
#define XCHK_FSGATES_QUOTA (1U << 4) /* quota live update enabled */
189189
#define XCHK_FSGATES_DIRENTS (1U << 5) /* directory live update enabled */
190190
#define XCHK_FSGATES_RMAP (1U << 6) /* rmapbt live update enabled */
191-
#define XREP_FSGATES_EXCHANGE_RANGE (1U << 29) /* uses file content exchange */
192191
#define XREP_RESET_PERAG_RESV (1U << 30) /* must reset AG space reservation */
193192
#define XREP_ALREADY_FIXED (1U << 31) /* checking our repair work */
194193

@@ -203,12 +202,6 @@ struct xfs_scrub {
203202
XCHK_FSGATES_DIRENTS | \
204203
XCHK_FSGATES_RMAP)
205204

206-
/*
207-
* The sole XREP_FSGATES* flag reflects a log intent item that is protected
208-
* by a log-incompat feature flag. No code patching in use here.
209-
*/
210-
#define XREP_FSGATES_ALL (XREP_FSGATES_EXCHANGE_RANGE)
211-
212205
struct xfs_scrub_subord {
213206
struct xfs_scrub sc;
214207
struct xfs_scrub *parent_sc;

fs/xfs/scrub/symlink_repair.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,9 @@ xrep_symlink(
490490
/* The rmapbt is required to reap the old data fork. */
491491
if (!xfs_has_rmapbt(sc->mp))
492492
return -EOPNOTSUPP;
493+
/* We require atomic file exchange range to rebuild anything. */
494+
if (!xfs_has_exchange_range(sc->mp))
495+
return -EOPNOTSUPP;
493496

494497
ASSERT(sc->ilock_flags & XFS_ILOCK_EXCL);
495498

fs/xfs/scrub/tempexch.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ struct xrep_tempexch {
1111
struct xfs_exchmaps_req req;
1212
};
1313

14-
int xrep_tempexch_enable(struct xfs_scrub *sc);
1514
int xrep_tempexch_trans_reserve(struct xfs_scrub *sc, int whichfork,
1615
struct xrep_tempexch *ti);
1716
int xrep_tempexch_trans_alloc(struct xfs_scrub *sc, int whichfork,

0 commit comments

Comments
 (0)