2020#include "xfs_bmap_btree.h"
2121#include "xfs_trans_space.h"
2222#include "xfs_attr.h"
23+ #include "xfs_rtgroup.h"
2324#include "scrub/scrub.h"
2425#include "scrub/common.h"
2526#include "scrub/trace.h"
@@ -79,6 +80,91 @@ xchk_metapath_cleanup(
7980 kfree (mpath -> path );
8081}
8182
83+ /* Set up a metadir path scan. @path must be dynamically allocated. */
84+ static inline int
85+ xchk_setup_metapath_scan (
86+ struct xfs_scrub * sc ,
87+ struct xfs_inode * dp ,
88+ const char * path ,
89+ struct xfs_inode * ip )
90+ {
91+ struct xchk_metapath * mpath ;
92+ int error ;
93+
94+ if (!path )
95+ return - ENOMEM ;
96+
97+ error = xchk_install_live_inode (sc , ip );
98+ if (error ) {
99+ kfree (path );
100+ return error ;
101+ }
102+
103+ mpath = kzalloc (sizeof (struct xchk_metapath ), XCHK_GFP_FLAGS );
104+ if (!mpath ) {
105+ kfree (path );
106+ return - ENOMEM ;
107+ }
108+
109+ mpath -> sc = sc ;
110+ sc -> buf = mpath ;
111+ sc -> buf_cleanup = xchk_metapath_cleanup ;
112+
113+ mpath -> dp = dp ;
114+ mpath -> path = path ; /* path is now owned by mpath */
115+
116+ mpath -> xname .name = mpath -> path ;
117+ mpath -> xname .len = strlen (mpath -> path );
118+ mpath -> xname .type = xfs_mode_to_ftype (VFS_I (ip )-> i_mode );
119+
120+ return 0 ;
121+ }
122+
123+ #ifdef CONFIG_XFS_RT
124+ /* Scan the /rtgroups directory itself. */
125+ static int
126+ xchk_setup_metapath_rtdir (
127+ struct xfs_scrub * sc )
128+ {
129+ if (!sc -> mp -> m_rtdirip )
130+ return - ENOENT ;
131+
132+ return xchk_setup_metapath_scan (sc , sc -> mp -> m_metadirip ,
133+ kasprintf (GFP_KERNEL , "rtgroups" ), sc -> mp -> m_rtdirip );
134+ }
135+
136+ /* Scan a rtgroup inode under the /rtgroups directory. */
137+ static int
138+ xchk_setup_metapath_rtginode (
139+ struct xfs_scrub * sc ,
140+ enum xfs_rtg_inodes type )
141+ {
142+ struct xfs_rtgroup * rtg ;
143+ struct xfs_inode * ip ;
144+ int error ;
145+
146+ rtg = xfs_rtgroup_get (sc -> mp , sc -> sm -> sm_agno );
147+ if (!rtg )
148+ return - ENOENT ;
149+
150+ ip = rtg -> rtg_inodes [type ];
151+ if (!ip ) {
152+ error = - ENOENT ;
153+ goto out_put_rtg ;
154+ }
155+
156+ error = xchk_setup_metapath_scan (sc , sc -> mp -> m_rtdirip ,
157+ xfs_rtginode_path (rtg_rgno (rtg ), type ), ip );
158+
159+ out_put_rtg :
160+ xfs_rtgroup_put (rtg );
161+ return error ;
162+ }
163+ #else
164+ # define xchk_setup_metapath_rtdir (...) (-ENOENT)
165+ # define xchk_setup_metapath_rtginode (...) (-ENOENT)
166+ #endif /* CONFIG_XFS_RT */
167+
82168int
83169xchk_setup_metapath (
84170 struct xfs_scrub * sc )
@@ -94,6 +180,12 @@ xchk_setup_metapath(
94180 if (sc -> sm -> sm_agno )
95181 return - EINVAL ;
96182 return 0 ;
183+ case XFS_SCRUB_METAPATH_RTDIR :
184+ return xchk_setup_metapath_rtdir (sc );
185+ case XFS_SCRUB_METAPATH_RTBITMAP :
186+ return xchk_setup_metapath_rtginode (sc , XFS_RTGI_BITMAP );
187+ case XFS_SCRUB_METAPATH_RTSUMMARY :
188+ return xchk_setup_metapath_rtginode (sc , XFS_RTGI_SUMMARY );
97189 default :
98190 return - ENOENT ;
99191 }
0 commit comments