@@ -382,7 +382,7 @@ xrep_adoption_trans_alloc(
382382out_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 */
485468static void
486469xrep_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/*
0 commit comments