@@ -33,52 +33,23 @@ xchk_setup_directory(
3333/* Scrub a directory entry. */
3434
3535/* Check that an inode's mode matches a given XFS_DIR3_FT_* type. */
36- STATIC int
36+ STATIC void
3737xchk_dir_check_ftype (
3838 struct xfs_scrub * sc ,
3939 xfs_fileoff_t offset ,
40- xfs_ino_t inum ,
40+ struct xfs_inode * ip ,
4141 int ftype )
4242{
4343 struct xfs_mount * mp = sc -> mp ;
44- struct xfs_inode * ip ;
45- int error = 0 ;
4644
4745 if (!xfs_has_ftype (mp )) {
4846 if (ftype != XFS_DIR3_FT_UNKNOWN && ftype != XFS_DIR3_FT_DIR )
4947 xchk_fblock_set_corrupt (sc , XFS_DATA_FORK , offset );
50- goto out ;
51- }
52-
53- /*
54- * Grab the inode pointed to by the dirent. We release the
55- * inode before we cancel the scrub transaction. Since we're
56- * don't know a priori that releasing the inode won't trigger
57- * eofblocks cleanup (which allocates what would be a nested
58- * transaction), we can't use DONTCACHE here because DONTCACHE
59- * inodes can trigger immediate inactive cleanup of the inode.
60- * Use UNTRUSTED here to check the allocation status of the inode in
61- * the inode btrees.
62- *
63- * If _iget returns -EINVAL or -ENOENT then the child inode number is
64- * garbage and the directory is corrupt. If the _iget returns
65- * -EFSCORRUPTED or -EFSBADCRC then the child is corrupt which is a
66- * cross referencing error. Any other error is an operational error.
67- */
68- error = xfs_iget (mp , sc -> tp , inum , XFS_IGET_UNTRUSTED , 0 , & ip );
69- if (error == - EINVAL || error == - ENOENT ) {
70- error = - EFSCORRUPTED ;
71- xchk_fblock_process_error (sc , XFS_DATA_FORK , 0 , & error );
72- goto out ;
48+ return ;
7349 }
74- if (!xchk_fblock_xref_process_error (sc , XFS_DATA_FORK , offset , & error ))
75- goto out ;
7650
7751 if (xfs_mode_to_ftype (VFS_I (ip )-> i_mode ) != ftype )
7852 xchk_fblock_set_corrupt (sc , XFS_DATA_FORK , offset );
79- xfs_irele (ip );
80- out :
81- return error ;
8253}
8354
8455/*
@@ -97,9 +68,9 @@ xchk_dir_actor(
9768 void * priv )
9869{
9970 struct xfs_mount * mp = dp -> i_mount ;
71+ struct xfs_inode * ip ;
10072 xfs_ino_t lookup_ino ;
10173 xfs_dablk_t offset ;
102- bool checked_ftype = false;
10374 int error = 0 ;
10475
10576 offset = xfs_dir2_db_to_da (mp -> m_dir_geo ,
@@ -122,19 +93,13 @@ xchk_dir_actor(
12293
12394 if (!strncmp ("." , name -> name , name -> len )) {
12495 /* If this is "." then check that the inum matches the dir. */
125- if (xfs_has_ftype (mp ) && name -> type != XFS_DIR3_FT_DIR )
126- xchk_fblock_set_corrupt (sc , XFS_DATA_FORK , offset );
127- checked_ftype = true;
12896 if (ino != dp -> i_ino )
12997 xchk_fblock_set_corrupt (sc , XFS_DATA_FORK , offset );
13098 } else if (!strncmp (".." , name -> name , name -> len )) {
13199 /*
132100 * If this is ".." in the root inode, check that the inum
133101 * matches this dir.
134102 */
135- if (xfs_has_ftype (mp ) && name -> type != XFS_DIR3_FT_DIR )
136- xchk_fblock_set_corrupt (sc , XFS_DATA_FORK , offset );
137- checked_ftype = true;
138103 if (dp -> i_ino == mp -> m_sb .sb_rootino && ino != dp -> i_ino )
139104 xchk_fblock_set_corrupt (sc , XFS_DATA_FORK , offset );
140105 }
@@ -151,14 +116,32 @@ xchk_dir_actor(
151116 return - ECANCELED ;
152117 }
153118
154- /* Verify the file type. This function absorbs error codes. */
155- if (!checked_ftype ) {
156- error = xchk_dir_check_ftype (sc , offset , lookup_ino ,
157- name -> type );
158- if (error )
159- goto out ;
119+ /*
120+ * Grab the inode pointed to by the dirent. We release the
121+ * inode before we cancel the scrub transaction. Since we're
122+ * don't know a priori that releasing the inode won't trigger
123+ * eofblocks cleanup (which allocates what would be a nested
124+ * transaction), we can't use DONTCACHE here because DONTCACHE
125+ * inodes can trigger immediate inactive cleanup of the inode.
126+ * Use UNTRUSTED here to check the allocation status of the inode in
127+ * the inode btrees.
128+ *
129+ * If _iget returns -EINVAL or -ENOENT then the child inode number is
130+ * garbage and the directory is corrupt. If the _iget returns
131+ * -EFSCORRUPTED or -EFSBADCRC then the child is corrupt which is a
132+ * cross referencing error. Any other error is an operational error.
133+ */
134+ error = xfs_iget (mp , sc -> tp , ino , XFS_IGET_UNTRUSTED , 0 , & ip );
135+ if (error == - EINVAL || error == - ENOENT ) {
136+ error = - EFSCORRUPTED ;
137+ xchk_fblock_process_error (sc , XFS_DATA_FORK , 0 , & error );
138+ goto out ;
160139 }
140+ if (!xchk_fblock_xref_process_error (sc , XFS_DATA_FORK , offset , & error ))
141+ goto out ;
161142
143+ xchk_dir_check_ftype (sc , offset , ip , name -> type );
144+ xfs_irele (ip );
162145out :
163146 if (sc -> sm -> sm_flags & XFS_SCRUB_OFLAG_CORRUPT )
164147 return - ECANCELED ;
0 commit comments