@@ -2667,41 +2667,35 @@ xlog_recover_clear_agi_bucket(
26672667 return ;
26682668}
26692669
2670- STATIC xfs_agino_t
2671- xlog_recover_process_one_iunlink (
2672- struct xfs_perag * pag ,
2673- xfs_agino_t agino ,
2674- int bucket )
2670+ static int
2671+ xlog_recover_iunlink_bucket (
2672+ struct xfs_perag * pag ,
2673+ struct xfs_agi * agi ,
2674+ int bucket )
26752675{
2676- struct xfs_inode * ip ;
2677- xfs_ino_t ino ;
2678- int error ;
2676+ struct xfs_mount * mp = pag -> pag_mount ;
2677+ struct xfs_inode * ip ;
2678+ xfs_agino_t agino ;
26792679
2680- ino = XFS_AGINO_TO_INO (pag -> pag_mount , pag -> pag_agno , agino );
2681- error = xfs_iget (pag -> pag_mount , NULL , ino , 0 , 0 , & ip );
2682- if (error )
2683- goto fail ;
2680+ agino = be32_to_cpu (agi -> agi_unlinked [bucket ]);
2681+ while (agino != NULLAGINO ) {
2682+ int error ;
26842683
2685- xfs_iflags_clear (ip , XFS_IRECOVERY );
2686- ASSERT (VFS_I (ip )-> i_nlink == 0 );
2687- ASSERT (VFS_I (ip )-> i_mode != 0 );
2684+ error = xfs_iget (mp , NULL ,
2685+ XFS_AGINO_TO_INO (mp , pag -> pag_agno , agino ),
2686+ 0 , 0 , & ip );
2687+ if (error )
2688+ return error ;;
26882689
2689- agino = ip -> i_next_unlinked ;
2690- xfs_irele (ip );
2691- return agino ;
2690+ ASSERT (VFS_I (ip )-> i_nlink == 0 );
2691+ ASSERT (VFS_I (ip )-> i_mode != 0 );
2692+ xfs_iflags_clear (ip , XFS_IRECOVERY );
2693+ agino = ip -> i_next_unlinked ;
26922694
2693- fail :
2694- /*
2695- * We can't read in the inode this bucket points to, or this inode
2696- * is messed up. Just ditch this bucket of inodes. We will lose
2697- * some inodes and space, but at least we won't hang.
2698- *
2699- * Call xlog_recover_clear_agi_bucket() to perform a transaction to
2700- * clear the inode pointer in the bucket.
2701- */
2702- xfs_inodegc_flush (pag -> pag_mount );
2703- xlog_recover_clear_agi_bucket (pag , bucket );
2704- return NULLAGINO ;
2695+ xfs_irele (ip );
2696+ cond_resched ();
2697+ }
2698+ return 0 ;
27052699}
27062700
27072701/*
@@ -2727,59 +2721,70 @@ xlog_recover_process_one_iunlink(
27272721 * scheduled on this CPU to ensure other scheduled work can run without undue
27282722 * latency.
27292723 */
2730- STATIC void
2731- xlog_recover_process_iunlinks (
2732- struct xlog * log )
2724+ static void
2725+ xlog_recover_iunlink_ag (
2726+ struct xfs_perag * pag )
27332727{
2734- struct xfs_mount * mp = log -> l_mp ;
2735- struct xfs_perag * pag ;
2736- xfs_agnumber_t agno ;
27372728 struct xfs_agi * agi ;
27382729 struct xfs_buf * agibp ;
2739- xfs_agino_t agino ;
27402730 int bucket ;
27412731 int error ;
27422732
2743- for_each_perag (mp , agno , pag ) {
2744- error = xfs_read_agi (pag , NULL , & agibp );
2733+ error = xfs_read_agi (pag , NULL , & agibp );
2734+ if (error ) {
2735+ /*
2736+ * AGI is b0rked. Don't process it.
2737+ *
2738+ * We should probably mark the filesystem as corrupt after we've
2739+ * recovered all the ag's we can....
2740+ */
2741+ return ;
2742+ }
2743+
2744+ /*
2745+ * Unlock the buffer so that it can be acquired in the normal course of
2746+ * the transaction to truncate and free each inode. Because we are not
2747+ * racing with anyone else here for the AGI buffer, we don't even need
2748+ * to hold it locked to read the initial unlinked bucket entries out of
2749+ * the buffer. We keep buffer reference though, so that it stays pinned
2750+ * in memory while we need the buffer.
2751+ */
2752+ agi = agibp -> b_addr ;
2753+ xfs_buf_unlock (agibp );
2754+
2755+ for (bucket = 0 ; bucket < XFS_AGI_UNLINKED_BUCKETS ; bucket ++ ) {
2756+ error = xlog_recover_iunlink_bucket (pag , agi , bucket );
27452757 if (error ) {
27462758 /*
2747- * AGI is b0rked. Don't process it.
2748- *
2749- * We should probably mark the filesystem as corrupt
2750- * after we've recovered all the ag's we can... .
2759+ * Bucket is unrecoverable, so only a repair scan can
2760+ * free the remaining unlinked inodes. Just empty the
2761+ * bucket and remaining inodes on it unreferenced and
2762+ * unfreeable .
27512763 */
2752- continue ;
2753- }
2754- /*
2755- * Unlock the buffer so that it can be acquired in the normal
2756- * course of the transaction to truncate and free each inode.
2757- * Because we are not racing with anyone else here for the AGI
2758- * buffer, we don't even need to hold it locked to read the
2759- * initial unlinked bucket entries out of the buffer. We keep
2760- * buffer reference though, so that it stays pinned in memory
2761- * while we need the buffer.
2762- */
2763- agi = agibp -> b_addr ;
2764- xfs_buf_unlock (agibp );
2765-
2766- for (bucket = 0 ; bucket < XFS_AGI_UNLINKED_BUCKETS ; bucket ++ ) {
2767- agino = be32_to_cpu (agi -> agi_unlinked [bucket ]);
2768- while (agino != NULLAGINO ) {
2769- agino = xlog_recover_process_one_iunlink (pag ,
2770- agino , bucket );
2771- cond_resched ();
2772- }
2764+ xfs_inodegc_flush (pag -> pag_mount );
2765+ xlog_recover_clear_agi_bucket (pag , bucket );
27732766 }
2774- xfs_buf_rele (agibp );
27752767 }
27762768
2769+ xfs_buf_rele (agibp );
2770+ }
2771+
2772+ static void
2773+ xlog_recover_process_iunlinks (
2774+ struct xlog * log )
2775+ {
2776+ struct xfs_perag * pag ;
2777+ xfs_agnumber_t agno ;
2778+
2779+ for_each_perag (log -> l_mp , agno , pag )
2780+ xlog_recover_iunlink_ag (pag );
2781+
27772782 /*
27782783 * Flush the pending unlinked inodes to ensure that the inactivations
27792784 * are fully completed on disk and the incore inodes can be reclaimed
27802785 * before we signal that recovery is complete.
27812786 */
2782- xfs_inodegc_flush (mp );
2787+ xfs_inodegc_flush (log -> l_mp );
27832788}
27842789
27852790STATIC void
0 commit comments