@@ -434,16 +434,17 @@ xrep_adoption_check_dcache(
434
434
{
435
435
struct qstr qname = QSTR_INIT (adopt -> xname -> name ,
436
436
adopt -> xname -> len );
437
+ struct xfs_scrub * sc = adopt -> sc ;
437
438
struct dentry * d_orphanage , * d_child ;
438
439
int error = 0 ;
439
440
440
- d_orphanage = d_find_alias (VFS_I (adopt -> sc -> orphanage ));
441
+ d_orphanage = d_find_alias (VFS_I (sc -> orphanage ));
441
442
if (!d_orphanage )
442
443
return 0 ;
443
444
444
445
d_child = d_hash_and_lookup (d_orphanage , & qname );
445
446
if (d_child ) {
446
- trace_xrep_adoption_check_child (adopt -> sc -> mp , d_child );
447
+ trace_xrep_adoption_check_child (sc -> mp , d_child );
447
448
448
449
if (d_is_positive (d_child )) {
449
450
ASSERT (d_is_negative (d_child ));
@@ -454,49 +455,33 @@ xrep_adoption_check_dcache(
454
455
}
455
456
456
457
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 );
477
458
return error ;
478
459
}
479
460
480
461
/*
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.
484
467
*/
485
468
static void
486
469
xrep_adoption_zap_dcache (
487
470
struct xrep_adoption * adopt )
488
471
{
489
472
struct qstr qname = QSTR_INIT (adopt -> xname -> name ,
490
473
adopt -> xname -> len );
474
+ struct xfs_scrub * sc = adopt -> sc ;
491
475
struct dentry * d_orphanage , * d_child ;
492
476
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 ));
494
479
if (!d_orphanage )
495
480
return ;
496
481
497
482
d_child = d_hash_and_lookup (d_orphanage , & qname );
498
483
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 );
500
485
501
486
ASSERT (d_is_negative (d_child ));
502
487
d_invalidate (d_child );
@@ -505,6 +490,14 @@ xrep_adoption_zap_dcache(
505
490
}
506
491
507
492
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
+ }
508
501
}
509
502
510
503
/*
0 commit comments