Skip to content

Commit 5e1c7d0

Browse files
author
Darrick J. Wong
committed
xfs: invalidate dentries for a file before moving it to the orphanage
Invalidate the cached dentries that point to the file that we're moving to lost+found before we actually move it. Signed-off-by: Darrick J. Wong <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]>
1 parent 6d33523 commit 5e1c7d0

File tree

2 files changed

+20
-29
lines changed

2 files changed

+20
-29
lines changed

fs/xfs/scrub/orphanage.c

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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/trace.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3265,8 +3265,6 @@ DEFINE_EVENT(xrep_dentry_class, name, \
32653265
TP_PROTO(struct xfs_mount *mp, const struct dentry *dentry), \
32663266
TP_ARGS(mp, dentry))
32673267
DEFINE_REPAIR_DENTRY_EVENT(xrep_adoption_check_child);
3268-
DEFINE_REPAIR_DENTRY_EVENT(xrep_adoption_check_alias);
3269-
DEFINE_REPAIR_DENTRY_EVENT(xrep_adoption_check_dentry);
32703268
DEFINE_REPAIR_DENTRY_EVENT(xrep_adoption_invalidate_child);
32713269
DEFINE_REPAIR_DENTRY_EVENT(xrep_dirtree_delete_child);
32723270

0 commit comments

Comments
 (0)