20
20
#include "xfs_bmap_btree.h"
21
21
#include "xfs_trans_space.h"
22
22
#include "xfs_attr.h"
23
+ #include "xfs_rtgroup.h"
23
24
#include "scrub/scrub.h"
24
25
#include "scrub/common.h"
25
26
#include "scrub/trace.h"
@@ -79,6 +80,91 @@ xchk_metapath_cleanup(
79
80
kfree (mpath -> path );
80
81
}
81
82
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
+
82
168
int
83
169
xchk_setup_metapath (
84
170
struct xfs_scrub * sc )
@@ -94,6 +180,12 @@ xchk_setup_metapath(
94
180
if (sc -> sm -> sm_agno )
95
181
return - EINVAL ;
96
182
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 );
97
189
default :
98
190
return - ENOENT ;
99
191
}
0 commit comments