diff options
Diffstat (limited to 'fs/gfs2/dir.c')
-rw-r--r-- | fs/gfs2/dir.c | 56 |
1 files changed, 26 insertions, 30 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 739028688270..40e94ac0b93d 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
@@ -106,7 +106,7 @@ static int gfs2_dir_get_existing_buffer(struct gfs2_inode *ip, u64 block, | |||
106 | struct buffer_head *bh; | 106 | struct buffer_head *bh; |
107 | int error; | 107 | int error; |
108 | 108 | ||
109 | error = gfs2_meta_read(ip->i_gl, block, DIO_START | DIO_WAIT, &bh); | 109 | error = gfs2_meta_read(ip->i_gl, block, DIO_WAIT, &bh); |
110 | if (error) | 110 | if (error) |
111 | return error; | 111 | return error; |
112 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) { | 112 | if (gfs2_metatype_check(GFS2_SB(&ip->i_inode), bh, GFS2_METATYPE_JD)) { |
@@ -246,7 +246,7 @@ fail: | |||
246 | } | 246 | } |
247 | 247 | ||
248 | static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf, | 248 | static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf, |
249 | unsigned int offset, unsigned int size) | 249 | u64 offset, unsigned int size) |
250 | { | 250 | { |
251 | struct buffer_head *dibh; | 251 | struct buffer_head *dibh; |
252 | int error; | 252 | int error; |
@@ -271,8 +271,8 @@ static int gfs2_dir_read_stuffed(struct gfs2_inode *ip, char *buf, | |||
271 | * | 271 | * |
272 | * Returns: The amount of data actually copied or the error | 272 | * Returns: The amount of data actually copied or the error |
273 | */ | 273 | */ |
274 | static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, | 274 | static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, u64 offset, |
275 | u64 offset, unsigned int size) | 275 | unsigned int size, unsigned ra) |
276 | { | 276 | { |
277 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); | 277 | struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); |
278 | u64 lblock, dblock; | 278 | u64 lblock, dblock; |
@@ -291,8 +291,7 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, | |||
291 | return 0; | 291 | return 0; |
292 | 292 | ||
293 | if (gfs2_is_stuffed(ip)) | 293 | if (gfs2_is_stuffed(ip)) |
294 | return gfs2_dir_read_stuffed(ip, buf, (unsigned int)offset, | 294 | return gfs2_dir_read_stuffed(ip, buf, offset, size); |
295 | size); | ||
296 | 295 | ||
297 | if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip))) | 296 | if (gfs2_assert_warn(sdp, gfs2_is_jdata(ip))) |
298 | return -EINVAL; | 297 | return -EINVAL; |
@@ -313,34 +312,31 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, | |||
313 | new = 0; | 312 | new = 0; |
314 | error = gfs2_extent_map(&ip->i_inode, lblock, &new, | 313 | error = gfs2_extent_map(&ip->i_inode, lblock, &new, |
315 | &dblock, &extlen); | 314 | &dblock, &extlen); |
316 | if (error) | 315 | if (error || !dblock) |
317 | goto fail; | 316 | goto fail; |
317 | BUG_ON(extlen < 1); | ||
318 | if (!ra) | ||
319 | extlen = 1; | ||
320 | bh = gfs2_meta_ra(ip->i_gl, dblock, extlen); | ||
318 | } | 321 | } |
319 | 322 | if (!bh) { | |
320 | if (extlen > 1) | 323 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_WAIT, &bh); |
321 | gfs2_meta_ra(ip->i_gl, dblock, extlen); | ||
322 | |||
323 | if (dblock) { | ||
324 | if (new) | ||
325 | error = gfs2_dir_get_new_buffer(ip, dblock, &bh); | ||
326 | else | ||
327 | error = gfs2_dir_get_existing_buffer(ip, dblock, &bh); | ||
328 | if (error) | 324 | if (error) |
329 | goto fail; | 325 | goto fail; |
330 | dblock++; | 326 | } |
331 | extlen--; | 327 | error = gfs2_metatype_check(sdp, bh, GFS2_METATYPE_JD); |
332 | } else | 328 | if (error) { |
333 | bh = NULL; | 329 | brelse(bh); |
334 | 330 | goto fail; | |
331 | } | ||
332 | dblock++; | ||
333 | extlen--; | ||
335 | memcpy(buf, bh->b_data + o, amount); | 334 | memcpy(buf, bh->b_data + o, amount); |
336 | brelse(bh); | 335 | brelse(bh); |
337 | if (error) | 336 | bh = NULL; |
338 | goto fail; | ||
339 | |||
340 | buf += amount; | 337 | buf += amount; |
341 | copied += amount; | 338 | copied += amount; |
342 | lblock++; | 339 | lblock++; |
343 | |||
344 | o = sizeof(struct gfs2_meta_header); | 340 | o = sizeof(struct gfs2_meta_header); |
345 | } | 341 | } |
346 | 342 | ||
@@ -701,7 +697,7 @@ static int get_leaf(struct gfs2_inode *dip, u64 leaf_no, | |||
701 | { | 697 | { |
702 | int error; | 698 | int error; |
703 | 699 | ||
704 | error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_START | DIO_WAIT, bhp); | 700 | error = gfs2_meta_read(dip->i_gl, leaf_no, DIO_WAIT, bhp); |
705 | if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) { | 701 | if (!error && gfs2_metatype_check(GFS2_SB(&dip->i_inode), *bhp, GFS2_METATYPE_LF)) { |
706 | /* printk(KERN_INFO "block num=%llu\n", leaf_no); */ | 702 | /* printk(KERN_INFO "block num=%llu\n", leaf_no); */ |
707 | error = -EIO; | 703 | error = -EIO; |
@@ -727,7 +723,7 @@ static int get_leaf_nr(struct gfs2_inode *dip, u32 index, | |||
727 | 723 | ||
728 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, | 724 | error = gfs2_dir_read_data(dip, (char *)&leaf_no, |
729 | index * sizeof(u64), | 725 | index * sizeof(u64), |
730 | sizeof(u64)); | 726 | sizeof(u64), 0); |
731 | if (error != sizeof(u64)) | 727 | if (error != sizeof(u64)) |
732 | return (error < 0) ? error : -EIO; | 728 | return (error < 0) ? error : -EIO; |
733 | 729 | ||
@@ -1095,7 +1091,7 @@ static int dir_double_exhash(struct gfs2_inode *dip) | |||
1095 | for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { | 1091 | for (block = dip->i_di.di_size >> sdp->sd_hash_bsize_shift; block--;) { |
1096 | error = gfs2_dir_read_data(dip, (char *)buf, | 1092 | error = gfs2_dir_read_data(dip, (char *)buf, |
1097 | block * sdp->sd_hash_bsize, | 1093 | block * sdp->sd_hash_bsize, |
1098 | sdp->sd_hash_bsize); | 1094 | sdp->sd_hash_bsize, 1); |
1099 | if (error != sdp->sd_hash_bsize) { | 1095 | if (error != sdp->sd_hash_bsize) { |
1100 | if (error >= 0) | 1096 | if (error >= 0) |
1101 | error = -EIO; | 1097 | error = -EIO; |
@@ -1375,7 +1371,7 @@ static int dir_e_read(struct inode *inode, u64 *offset, void *opaque, | |||
1375 | if (ht_offset_cur != ht_offset) { | 1371 | if (ht_offset_cur != ht_offset) { |
1376 | error = gfs2_dir_read_data(dip, (char *)lp, | 1372 | error = gfs2_dir_read_data(dip, (char *)lp, |
1377 | ht_offset * sizeof(u64), | 1373 | ht_offset * sizeof(u64), |
1378 | sdp->sd_hash_bsize); | 1374 | sdp->sd_hash_bsize, 1); |
1379 | if (error != sdp->sd_hash_bsize) { | 1375 | if (error != sdp->sd_hash_bsize) { |
1380 | if (error >= 0) | 1376 | if (error >= 0) |
1381 | error = -EIO; | 1377 | error = -EIO; |
@@ -1745,7 +1741,7 @@ static int foreach_leaf(struct gfs2_inode *dip, leaf_call_t lc, void *data) | |||
1745 | if (ht_offset_cur != ht_offset) { | 1741 | if (ht_offset_cur != ht_offset) { |
1746 | error = gfs2_dir_read_data(dip, (char *)lp, | 1742 | error = gfs2_dir_read_data(dip, (char *)lp, |
1747 | ht_offset * sizeof(u64), | 1743 | ht_offset * sizeof(u64), |
1748 | sdp->sd_hash_bsize); | 1744 | sdp->sd_hash_bsize, 1); |
1749 | if (error != sdp->sd_hash_bsize) { | 1745 | if (error != sdp->sd_hash_bsize) { |
1750 | if (error >= 0) | 1746 | if (error >= 0) |
1751 | error = -EIO; | 1747 | error = -EIO; |