diff options
author | Joel Becker <joel.becker@oracle.com> | 2008-11-13 17:49:14 -0500 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:36:53 -0500 |
commit | 68f64d471be38631d7196b938d9809802dd467fa (patch) | |
tree | b94f14b3a8b093dc52f2b034e7666b14c536f0d6 /fs/ocfs2/suballoc.c | |
parent | 57e3e7971136003c96766346049aa73b82cab079 (diff) |
ocfs2: Wrap group descriptor reads in a dedicated function.
We have a clean call for validating group descriptors, but every place
that wants the always does a read_block()+validate() call pair. Create
a toplevel ocfs2_read_group_descriptor() that does the right
thing. This allows us to leverage the single call point later for
fancier handling. We also add validation of gd->bg_generation against
the superblock and gd->bg_blkno against the block we thought we read.
Signed-off-by: Joel Becker <joel.becker@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/suballoc.c')
-rw-r--r-- | fs/ocfs2/suballoc.c | 108 |
1 files changed, 65 insertions, 43 deletions
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index ddba97dc06a..797f509d725 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c | |||
@@ -145,13 +145,13 @@ static u32 ocfs2_bits_per_group(struct ocfs2_chain_list *cl) | |||
145 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); | 145 | return (u32)le16_to_cpu(cl->cl_cpg) * (u32)le16_to_cpu(cl->cl_bpc); |
146 | } | 146 | } |
147 | 147 | ||
148 | /* somewhat more expensive than our other checks, so use sparingly. */ | ||
149 | int ocfs2_validate_group_descriptor(struct super_block *sb, | 148 | int ocfs2_validate_group_descriptor(struct super_block *sb, |
150 | struct ocfs2_dinode *di, | 149 | struct ocfs2_dinode *di, |
151 | struct ocfs2_group_desc *gd, | 150 | struct buffer_head *bh, |
152 | int clean_error) | 151 | int clean_error) |
153 | { | 152 | { |
154 | unsigned int max_bits; | 153 | unsigned int max_bits; |
154 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | ||
155 | 155 | ||
156 | #define do_error(fmt, ...) \ | 156 | #define do_error(fmt, ...) \ |
157 | do{ \ | 157 | do{ \ |
@@ -162,16 +162,32 @@ int ocfs2_validate_group_descriptor(struct super_block *sb, | |||
162 | } while (0) | 162 | } while (0) |
163 | 163 | ||
164 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | 164 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { |
165 | do_error("Group Descriptor #%llu has bad signature %.*s", | 165 | do_error("Group descriptor #%llu has bad signature %.*s", |
166 | (unsigned long long)le64_to_cpu(gd->bg_blkno), 7, | 166 | (unsigned long long)bh->b_blocknr, 7, |
167 | gd->bg_signature); | 167 | gd->bg_signature); |
168 | return -EINVAL; | 168 | return -EINVAL; |
169 | } | 169 | } |
170 | 170 | ||
171 | if (le64_to_cpu(gd->bg_blkno) != bh->b_blocknr) { | ||
172 | do_error("Group descriptor #%llu has an invalid bg_blkno " | ||
173 | "of %llu", | ||
174 | (unsigned long long)bh->b_blocknr, | ||
175 | (unsigned long long)le64_to_cpu(gd->bg_blkno)); | ||
176 | return -EINVAL; | ||
177 | } | ||
178 | |||
179 | if (le32_to_cpu(gd->bg_generation) != OCFS2_SB(sb)->fs_generation) { | ||
180 | do_error("Group descriptor #%llu has an invalid " | ||
181 | "fs_generation of #%u", | ||
182 | (unsigned long long)bh->b_blocknr, | ||
183 | le32_to_cpu(gd->bg_generation)); | ||
184 | return -EINVAL; | ||
185 | } | ||
186 | |||
171 | if (di->i_blkno != gd->bg_parent_dinode) { | 187 | if (di->i_blkno != gd->bg_parent_dinode) { |
172 | do_error("Group descriptor # %llu has bad parent " | 188 | do_error("Group descriptor #%llu has bad parent " |
173 | "pointer (%llu, expected %llu)", | 189 | "pointer (%llu, expected %llu)", |
174 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 190 | (unsigned long long)bh->b_blocknr, |
175 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), | 191 | (unsigned long long)le64_to_cpu(gd->bg_parent_dinode), |
176 | (unsigned long long)le64_to_cpu(di->i_blkno)); | 192 | (unsigned long long)le64_to_cpu(di->i_blkno)); |
177 | return -EINVAL; | 193 | return -EINVAL; |
@@ -179,33 +195,33 @@ int ocfs2_validate_group_descriptor(struct super_block *sb, | |||
179 | 195 | ||
180 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); | 196 | max_bits = le16_to_cpu(di->id2.i_chain.cl_cpg) * le16_to_cpu(di->id2.i_chain.cl_bpc); |
181 | if (le16_to_cpu(gd->bg_bits) > max_bits) { | 197 | if (le16_to_cpu(gd->bg_bits) > max_bits) { |
182 | do_error("Group descriptor # %llu has bit count of %u", | 198 | do_error("Group descriptor #%llu has bit count of %u", |
183 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 199 | (unsigned long long)bh->b_blocknr, |
184 | le16_to_cpu(gd->bg_bits)); | 200 | le16_to_cpu(gd->bg_bits)); |
185 | return -EINVAL; | 201 | return -EINVAL; |
186 | } | 202 | } |
187 | 203 | ||
188 | if (le16_to_cpu(gd->bg_chain) >= | 204 | if (le16_to_cpu(gd->bg_chain) >= |
189 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { | 205 | le16_to_cpu(di->id2.i_chain.cl_next_free_rec)) { |
190 | do_error("Group descriptor # %llu has bad chain %u", | 206 | do_error("Group descriptor #%llu has bad chain %u", |
191 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 207 | (unsigned long long)bh->b_blocknr, |
192 | le16_to_cpu(gd->bg_chain)); | 208 | le16_to_cpu(gd->bg_chain)); |
193 | return -EINVAL; | 209 | return -EINVAL; |
194 | } | 210 | } |
195 | 211 | ||
196 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { | 212 | if (le16_to_cpu(gd->bg_free_bits_count) > le16_to_cpu(gd->bg_bits)) { |
197 | do_error("Group descriptor # %llu has bit count %u but " | 213 | do_error("Group descriptor #%llu has bit count %u but " |
198 | "claims that %u are free", | 214 | "claims that %u are free", |
199 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 215 | (unsigned long long)bh->b_blocknr, |
200 | le16_to_cpu(gd->bg_bits), | 216 | le16_to_cpu(gd->bg_bits), |
201 | le16_to_cpu(gd->bg_free_bits_count)); | 217 | le16_to_cpu(gd->bg_free_bits_count)); |
202 | return -EINVAL; | 218 | return -EINVAL; |
203 | } | 219 | } |
204 | 220 | ||
205 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { | 221 | if (le16_to_cpu(gd->bg_bits) > (8 * le16_to_cpu(gd->bg_size))) { |
206 | do_error("Group descriptor # %llu has bit count %u but " | 222 | do_error("Group descriptor #%llu has bit count %u but " |
207 | "max bitmap bits of %u", | 223 | "max bitmap bits of %u", |
208 | (unsigned long long)le64_to_cpu(gd->bg_blkno), | 224 | (unsigned long long)bh->b_blocknr, |
209 | le16_to_cpu(gd->bg_bits), | 225 | le16_to_cpu(gd->bg_bits), |
210 | 8 * le16_to_cpu(gd->bg_size)); | 226 | 8 * le16_to_cpu(gd->bg_size)); |
211 | return -EINVAL; | 227 | return -EINVAL; |
@@ -215,6 +231,30 @@ int ocfs2_validate_group_descriptor(struct super_block *sb, | |||
215 | return 0; | 231 | return 0; |
216 | } | 232 | } |
217 | 233 | ||
234 | int ocfs2_read_group_descriptor(struct inode *inode, struct ocfs2_dinode *di, | ||
235 | u64 gd_blkno, struct buffer_head **bh) | ||
236 | { | ||
237 | int rc; | ||
238 | struct buffer_head *tmp = *bh; | ||
239 | |||
240 | rc = ocfs2_read_block(inode, gd_blkno, &tmp); | ||
241 | if (rc) | ||
242 | goto out; | ||
243 | |||
244 | rc = ocfs2_validate_group_descriptor(inode->i_sb, di, tmp, 0); | ||
245 | if (rc) { | ||
246 | brelse(tmp); | ||
247 | goto out; | ||
248 | } | ||
249 | |||
250 | /* If ocfs2_read_block() got us a new bh, pass it up. */ | ||
251 | if (!*bh) | ||
252 | *bh = tmp; | ||
253 | |||
254 | out: | ||
255 | return rc; | ||
256 | } | ||
257 | |||
218 | static int ocfs2_block_group_fill(handle_t *handle, | 258 | static int ocfs2_block_group_fill(handle_t *handle, |
219 | struct inode *alloc_inode, | 259 | struct inode *alloc_inode, |
220 | struct buffer_head *bg_bh, | 260 | struct buffer_head *bg_bh, |
@@ -1177,21 +1217,17 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, | |||
1177 | u16 found; | 1217 | u16 found; |
1178 | struct buffer_head *group_bh = NULL; | 1218 | struct buffer_head *group_bh = NULL; |
1179 | struct ocfs2_group_desc *gd; | 1219 | struct ocfs2_group_desc *gd; |
1220 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)ac->ac_bh->b_data; | ||
1180 | struct inode *alloc_inode = ac->ac_inode; | 1221 | struct inode *alloc_inode = ac->ac_inode; |
1181 | 1222 | ||
1182 | ret = ocfs2_read_block(alloc_inode, gd_blkno, &group_bh); | 1223 | ret = ocfs2_read_group_descriptor(alloc_inode, di, gd_blkno, |
1224 | &group_bh); | ||
1183 | if (ret < 0) { | 1225 | if (ret < 0) { |
1184 | mlog_errno(ret); | 1226 | mlog_errno(ret); |
1185 | return ret; | 1227 | return ret; |
1186 | } | 1228 | } |
1187 | 1229 | ||
1188 | gd = (struct ocfs2_group_desc *) group_bh->b_data; | 1230 | gd = (struct ocfs2_group_desc *) group_bh->b_data; |
1189 | if (!OCFS2_IS_VALID_GROUP_DESC(gd)) { | ||
1190 | OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, gd); | ||
1191 | ret = -EIO; | ||
1192 | goto out; | ||
1193 | } | ||
1194 | |||
1195 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, | 1231 | ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits, |
1196 | ac->ac_max_block, bit_off, &found); | 1232 | ac->ac_max_block, bit_off, &found); |
1197 | if (ret < 0) { | 1233 | if (ret < 0) { |
@@ -1248,19 +1284,14 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1248 | bits_wanted, chain, | 1284 | bits_wanted, chain, |
1249 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); | 1285 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno); |
1250 | 1286 | ||
1251 | status = ocfs2_read_block(alloc_inode, | 1287 | status = ocfs2_read_group_descriptor(alloc_inode, fe, |
1252 | le64_to_cpu(cl->cl_recs[chain].c_blkno), | 1288 | le64_to_cpu(cl->cl_recs[chain].c_blkno), |
1253 | &group_bh); | 1289 | &group_bh); |
1254 | if (status < 0) { | 1290 | if (status < 0) { |
1255 | mlog_errno(status); | 1291 | mlog_errno(status); |
1256 | goto bail; | 1292 | goto bail; |
1257 | } | 1293 | } |
1258 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1294 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
1259 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); | ||
1260 | if (status) { | ||
1261 | mlog_errno(status); | ||
1262 | goto bail; | ||
1263 | } | ||
1264 | 1295 | ||
1265 | status = -ENOSPC; | 1296 | status = -ENOSPC; |
1266 | /* for now, the chain search is a bit simplistic. We just use | 1297 | /* for now, the chain search is a bit simplistic. We just use |
@@ -1278,18 +1309,13 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, | |||
1278 | next_group = le64_to_cpu(bg->bg_next_group); | 1309 | next_group = le64_to_cpu(bg->bg_next_group); |
1279 | prev_group_bh = group_bh; | 1310 | prev_group_bh = group_bh; |
1280 | group_bh = NULL; | 1311 | group_bh = NULL; |
1281 | status = ocfs2_read_block(alloc_inode, | 1312 | status = ocfs2_read_group_descriptor(alloc_inode, fe, |
1282 | next_group, &group_bh); | 1313 | next_group, &group_bh); |
1283 | if (status < 0) { | 1314 | if (status < 0) { |
1284 | mlog_errno(status); | 1315 | mlog_errno(status); |
1285 | goto bail; | 1316 | goto bail; |
1286 | } | 1317 | } |
1287 | bg = (struct ocfs2_group_desc *) group_bh->b_data; | 1318 | bg = (struct ocfs2_group_desc *) group_bh->b_data; |
1288 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, bg); | ||
1289 | if (status) { | ||
1290 | mlog_errno(status); | ||
1291 | goto bail; | ||
1292 | } | ||
1293 | } | 1319 | } |
1294 | if (status < 0) { | 1320 | if (status < 0) { |
1295 | if (status != -ENOSPC) | 1321 | if (status != -ENOSPC) |
@@ -1801,18 +1827,14 @@ int ocfs2_free_suballoc_bits(handle_t *handle, | |||
1801 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, | 1827 | (unsigned long long)OCFS2_I(alloc_inode)->ip_blkno, count, |
1802 | (unsigned long long)bg_blkno, start_bit); | 1828 | (unsigned long long)bg_blkno, start_bit); |
1803 | 1829 | ||
1804 | status = ocfs2_read_block(alloc_inode, bg_blkno, &group_bh); | 1830 | status = ocfs2_read_group_descriptor(alloc_inode, fe, bg_blkno, |
1831 | &group_bh); | ||
1805 | if (status < 0) { | 1832 | if (status < 0) { |
1806 | mlog_errno(status); | 1833 | mlog_errno(status); |
1807 | goto bail; | 1834 | goto bail; |
1808 | } | 1835 | } |
1809 | |||
1810 | group = (struct ocfs2_group_desc *) group_bh->b_data; | 1836 | group = (struct ocfs2_group_desc *) group_bh->b_data; |
1811 | status = ocfs2_check_group_descriptor(alloc_inode->i_sb, fe, group); | 1837 | |
1812 | if (status) { | ||
1813 | mlog_errno(status); | ||
1814 | goto bail; | ||
1815 | } | ||
1816 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); | 1838 | BUG_ON((count + start_bit) > le16_to_cpu(group->bg_bits)); |
1817 | 1839 | ||
1818 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, | 1840 | status = ocfs2_block_group_clear_bits(handle, alloc_inode, |