diff options
| author | Steven Whitehouse <swhiteho@redhat.com> | 2006-05-05 16:59:11 -0400 |
|---|---|---|
| committer | Steven Whitehouse <swhiteho@redhat.com> | 2006-05-05 16:59:11 -0400 |
| commit | fd88de569b802c4a04aaa6ee74667775f4aed8c6 (patch) | |
| tree | 1766c45303798bf289059afc8f117cf8bc784086 | |
| parent | 5bb76af1e089ac186c15c6aa792340d22b63d4b4 (diff) | |
[GFS2] Readpages support
This adds readpages support (and also corrects a small bug in
the readpage error path at the same time). Hopefully this will
improve performance by allowing GFS to submit larger lumps of
I/O at a time.
In order to simplify the setting of BH_Boundary, it currently gets
set when we hit the end of a indirect pointer block. There is
always a boundary at this point with the current allocation code.
It doesn't get all the boundaries right though, so there is still
room for improvement in this.
See comments in fs/gfs2/ops_address.c for further information about
readpages with GFS2.
Signed-off-by: Steven Whitehouse
| -rw-r--r-- | fs/gfs2/bmap.c | 170 | ||||
| -rw-r--r-- | fs/gfs2/bmap.h | 5 | ||||
| -rw-r--r-- | fs/gfs2/dir.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/glock.c | 2 | ||||
| -rw-r--r-- | fs/gfs2/inode.c | 5 | ||||
| -rw-r--r-- | fs/gfs2/log.c | 4 | ||||
| -rw-r--r-- | fs/gfs2/ops_address.c | 145 | ||||
| -rw-r--r-- | fs/gfs2/ops_super.c | 3 | ||||
| -rw-r--r-- | fs/gfs2/ops_vm.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/quota.c | 5 | ||||
| -rw-r--r-- | fs/gfs2/recovery.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/rgrp.c | 15 | ||||
| -rw-r--r-- | fs/gfs2/unlinked.c | 5 |
13 files changed, 254 insertions, 129 deletions
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index cfe1a428c668..474b9a16f0f5 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
| @@ -314,13 +314,17 @@ static void find_metapath(struct gfs2_inode *ip, uint64_t block, | |||
| 314 | * metadata tree. | 314 | * metadata tree. |
| 315 | */ | 315 | */ |
| 316 | 316 | ||
| 317 | static inline uint64_t *metapointer(struct buffer_head *bh, | 317 | static inline u64 *metapointer(struct buffer_head *bh, int *boundary, |
| 318 | unsigned int height, struct metapath *mp) | 318 | unsigned int height, const struct metapath *mp) |
| 319 | { | 319 | { |
| 320 | unsigned int head_size = (height > 0) ? | 320 | unsigned int head_size = (height > 0) ? |
| 321 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); | 321 | sizeof(struct gfs2_meta_header) : sizeof(struct gfs2_dinode); |
| 322 | 322 | u64 *ptr; | |
| 323 | return ((uint64_t *)(bh->b_data + head_size)) + mp->mp_list[height]; | 323 | *boundary = 0; |
| 324 | ptr = ((u64 *)(bh->b_data + head_size)) + mp->mp_list[height]; | ||
| 325 | if (ptr + 1 == (u64*)(bh->b_data + bh->b_size)) | ||
| 326 | *boundary = 1; | ||
| 327 | return ptr; | ||
| 324 | } | 328 | } |
| 325 | 329 | ||
| 326 | /** | 330 | /** |
| @@ -339,24 +343,24 @@ static inline uint64_t *metapointer(struct buffer_head *bh, | |||
| 339 | * | 343 | * |
| 340 | */ | 344 | */ |
| 341 | 345 | ||
| 342 | static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | 346 | static int lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, |
| 343 | unsigned int height, struct metapath *mp, int create, | 347 | unsigned int height, struct metapath *mp, int create, |
| 344 | int *new, uint64_t *block) | 348 | int *new, uint64_t *block) |
| 345 | { | 349 | { |
| 346 | uint64_t *ptr = metapointer(bh, height, mp); | 350 | int boundary; |
| 351 | uint64_t *ptr = metapointer(bh, &boundary, height, mp); | ||
| 347 | 352 | ||
| 348 | if (*ptr) { | 353 | if (*ptr) { |
| 349 | *block = be64_to_cpu(*ptr); | 354 | *block = be64_to_cpu(*ptr); |
| 350 | return; | 355 | return boundary; |
| 351 | } | 356 | } |
| 352 | 357 | ||
| 353 | *block = 0; | 358 | *block = 0; |
| 354 | 359 | ||
| 355 | if (!create) | 360 | if (!create) |
| 356 | return; | 361 | return 0; |
| 357 | 362 | ||
| 358 | if (height == ip->i_di.di_height - 1 && | 363 | if (height == ip->i_di.di_height - 1 && !gfs2_is_dir(ip)) |
| 359 | !gfs2_is_dir(ip)) | ||
| 360 | *block = gfs2_alloc_data(ip); | 364 | *block = gfs2_alloc_data(ip); |
| 361 | else | 365 | else |
| 362 | *block = gfs2_alloc_meta(ip); | 366 | *block = gfs2_alloc_meta(ip); |
| @@ -367,15 +371,16 @@ static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
| 367 | ip->i_di.di_blocks++; | 371 | ip->i_di.di_blocks++; |
| 368 | 372 | ||
| 369 | *new = 1; | 373 | *new = 1; |
| 374 | return 0; | ||
| 370 | } | 375 | } |
| 371 | 376 | ||
| 372 | /** | 377 | /** |
| 373 | * gfs2_block_map - Map a block from an inode to a disk block | 378 | * gfs2_block_pointers - Map a block from an inode to a disk block |
| 374 | * @ip: The GFS2 inode | 379 | * @inode: The inode |
| 375 | * @lblock: The logical block number | 380 | * @lblock: The logical block number |
| 376 | * @new: Value/Result argument (1 = may create/did create new blocks) | 381 | * @new: Value/Result argument (1 = may create/did create new blocks) |
| 377 | * @dblock: the disk block number of the start of an extent | 382 | * @boundary: gets set if we've hit a block boundary |
| 378 | * @extlen: the size of the extent | 383 | * @mp: metapath to use |
| 379 | * | 384 | * |
| 380 | * Find the block number on the current device which corresponds to an | 385 | * Find the block number on the current device which corresponds to an |
| 381 | * inode's block. If the block had to be created, "new" will be set. | 386 | * inode's block. If the block had to be created, "new" will be set. |
| @@ -383,12 +388,14 @@ static void lookup_block(struct gfs2_inode *ip, struct buffer_head *bh, | |||
| 383 | * Returns: errno | 388 | * Returns: errno |
| 384 | */ | 389 | */ |
| 385 | 390 | ||
| 386 | int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, | 391 | static struct buffer_head *gfs2_block_pointers(struct inode *inode, u64 lblock, |
| 387 | uint64_t *dblock, uint32_t *extlen) | 392 | int *new, u64 *dblock, |
| 393 | int *boundary, | ||
| 394 | struct metapath *mp) | ||
| 388 | { | 395 | { |
| 396 | struct gfs2_inode *ip = inode->u.generic_ip; | ||
| 389 | struct gfs2_sbd *sdp = ip->i_sbd; | 397 | struct gfs2_sbd *sdp = ip->i_sbd; |
| 390 | struct buffer_head *bh; | 398 | struct buffer_head *bh; |
| 391 | struct metapath mp; | ||
| 392 | int create = *new; | 399 | int create = *new; |
| 393 | unsigned int bsize; | 400 | unsigned int bsize; |
| 394 | unsigned int height; | 401 | unsigned int height; |
| @@ -398,13 +405,6 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, | |||
| 398 | 405 | ||
| 399 | *new = 0; | 406 | *new = 0; |
| 400 | *dblock = 0; | 407 | *dblock = 0; |
| 401 | if (extlen) | ||
| 402 | *extlen = 0; | ||
| 403 | |||
| 404 | if (create) | ||
| 405 | down_write(&ip->i_rw_mutex); | ||
| 406 | else | ||
| 407 | down_read(&ip->i_rw_mutex); | ||
| 408 | 408 | ||
| 409 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) | 409 | if (gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip))) |
| 410 | goto out; | 410 | goto out; |
| @@ -421,7 +421,7 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, | |||
| 421 | goto out; | 421 | goto out; |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | find_metapath(ip, lblock, &mp); | 424 | find_metapath(ip, lblock, mp); |
| 425 | end_of_metadata = ip->i_di.di_height - 1; | 425 | end_of_metadata = ip->i_di.di_height - 1; |
| 426 | 426 | ||
| 427 | error = gfs2_meta_inode_buffer(ip, &bh); | 427 | error = gfs2_meta_inode_buffer(ip, &bh); |
| @@ -429,7 +429,7 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, | |||
| 429 | goto out; | 429 | goto out; |
| 430 | 430 | ||
| 431 | for (x = 0; x < end_of_metadata; x++) { | 431 | for (x = 0; x < end_of_metadata; x++) { |
| 432 | lookup_block(ip, bh, x, &mp, create, new, dblock); | 432 | lookup_block(ip, bh, x, mp, create, new, dblock); |
| 433 | brelse(bh); | 433 | brelse(bh); |
| 434 | if (!*dblock) | 434 | if (!*dblock) |
| 435 | goto out; | 435 | goto out; |
| @@ -439,49 +439,95 @@ int gfs2_block_map(struct gfs2_inode *ip, uint64_t lblock, int *new, | |||
| 439 | goto out; | 439 | goto out; |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | lookup_block(ip, bh, end_of_metadata, &mp, create, new, dblock); | 442 | *boundary = lookup_block(ip, bh, end_of_metadata, mp, create, new, dblock); |
| 443 | |||
| 444 | if (extlen && *dblock) { | ||
| 445 | *extlen = 1; | ||
| 446 | |||
| 447 | if (!*new) { | ||
| 448 | uint64_t tmp_dblock; | ||
| 449 | int tmp_new; | ||
| 450 | unsigned int nptrs; | ||
| 451 | |||
| 452 | nptrs = (end_of_metadata) ? sdp->sd_inptrs : | ||
| 453 | sdp->sd_diptrs; | ||
| 454 | |||
| 455 | while (++mp.mp_list[end_of_metadata] < nptrs) { | ||
| 456 | lookup_block(ip, bh, end_of_metadata, &mp, | ||
| 457 | 0, &tmp_new, &tmp_dblock); | ||
| 458 | |||
| 459 | if (*dblock + *extlen != tmp_dblock) | ||
| 460 | break; | ||
| 461 | |||
| 462 | (*extlen)++; | ||
| 463 | } | ||
| 464 | } | ||
| 465 | } | ||
| 466 | |||
| 467 | brelse(bh); | ||
| 468 | |||
| 469 | if (*new) { | 443 | if (*new) { |
| 470 | error = gfs2_meta_inode_buffer(ip, &bh); | 444 | struct buffer_head *dibh; |
| 445 | error = gfs2_meta_inode_buffer(ip, &dibh); | ||
| 471 | if (!error) { | 446 | if (!error) { |
| 472 | gfs2_trans_add_bh(ip->i_gl, bh, 1); | 447 | gfs2_trans_add_bh(ip->i_gl, dibh, 1); |
| 473 | gfs2_dinode_out(&ip->i_di, bh->b_data); | 448 | gfs2_dinode_out(&ip->i_di, dibh->b_data); |
| 474 | brelse(bh); | 449 | brelse(dibh); |
| 475 | } | 450 | } |
| 476 | } | 451 | } |
| 452 | return bh; | ||
| 453 | out: | ||
| 454 | return ERR_PTR(error); | ||
| 455 | } | ||
| 477 | 456 | ||
| 478 | out: | 457 | |
| 458 | static inline void bmap_lock(struct inode *inode, int create) | ||
| 459 | { | ||
| 460 | struct gfs2_inode *ip = inode->u.generic_ip; | ||
| 461 | if (create) | ||
| 462 | down_write(&ip->i_rw_mutex); | ||
| 463 | else | ||
| 464 | down_read(&ip->i_rw_mutex); | ||
| 465 | } | ||
| 466 | |||
| 467 | static inline void bmap_unlock(struct inode *inode, int create) | ||
| 468 | { | ||
| 469 | struct gfs2_inode *ip = inode->u.generic_ip; | ||
| 479 | if (create) | 470 | if (create) |
| 480 | up_write(&ip->i_rw_mutex); | 471 | up_write(&ip->i_rw_mutex); |
| 481 | else | 472 | else |
| 482 | up_read(&ip->i_rw_mutex); | 473 | up_read(&ip->i_rw_mutex); |
| 474 | } | ||
| 483 | 475 | ||
| 484 | return error; | 476 | int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary) |
| 477 | { | ||
| 478 | struct metapath mp; | ||
| 479 | struct buffer_head *bh; | ||
| 480 | int create = *new; | ||
| 481 | |||
| 482 | bmap_lock(inode, create); | ||
| 483 | bh = gfs2_block_pointers(inode, lblock, new, dblock, boundary, &mp); | ||
| 484 | bmap_unlock(inode, create); | ||
| 485 | if (!bh) | ||
| 486 | return 0; | ||
| 487 | if (IS_ERR(bh)) | ||
| 488 | return PTR_ERR(bh); | ||
| 489 | brelse(bh); | ||
| 490 | return 0; | ||
| 491 | } | ||
| 492 | |||
| 493 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen) | ||
| 494 | { | ||
| 495 | struct gfs2_inode *ip = inode->u.generic_ip; | ||
| 496 | struct gfs2_sbd *sdp = ip->i_sbd; | ||
| 497 | struct metapath mp; | ||
| 498 | struct buffer_head *bh; | ||
| 499 | int boundary; | ||
| 500 | int create = *new; | ||
| 501 | |||
| 502 | BUG_ON(!extlen); | ||
| 503 | BUG_ON(!dblock); | ||
| 504 | BUG_ON(!new); | ||
| 505 | |||
| 506 | bmap_lock(inode, create); | ||
| 507 | bh = gfs2_block_pointers(inode, lblock, new, dblock, &boundary, &mp); | ||
| 508 | *extlen = 1; | ||
| 509 | |||
| 510 | if (bh && !IS_ERR(bh) && *dblock && !*new) { | ||
| 511 | u64 tmp_dblock; | ||
| 512 | int tmp_new; | ||
| 513 | unsigned int nptrs; | ||
| 514 | unsigned end_of_metadata = ip->i_di.di_height - 1; | ||
| 515 | |||
| 516 | nptrs = (end_of_metadata) ? sdp->sd_inptrs : sdp->sd_diptrs; | ||
| 517 | while (++mp.mp_list[end_of_metadata] < nptrs) { | ||
| 518 | lookup_block(ip, bh, end_of_metadata, &mp, 0, &tmp_new, &tmp_dblock); | ||
| 519 | if (*dblock + *extlen != tmp_dblock) | ||
| 520 | break; | ||
| 521 | (*extlen)++; | ||
| 522 | } | ||
| 523 | } | ||
| 524 | bmap_unlock(inode, create); | ||
| 525 | if (!bh) | ||
| 526 | return 0; | ||
| 527 | if (IS_ERR(bh)) | ||
| 528 | return PTR_ERR(bh); | ||
| 529 | brelse(bh); | ||
| 530 | return 0; | ||
| 485 | } | 531 | } |
| 486 | 532 | ||
| 487 | /** | 533 | /** |
| @@ -1053,7 +1099,7 @@ int gfs2_write_alloc_required(struct gfs2_inode *ip, uint64_t offset, | |||
| 1053 | } | 1099 | } |
| 1054 | 1100 | ||
| 1055 | for (; lblock < lblock_stop; lblock += extlen) { | 1101 | for (; lblock < lblock_stop; lblock += extlen) { |
| 1056 | error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); | 1102 | error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen); |
| 1057 | if (error) | 1103 | if (error) |
| 1058 | return error; | 1104 | return error; |
| 1059 | 1105 | ||
diff --git a/fs/gfs2/bmap.h b/fs/gfs2/bmap.h index 23fb6589d5e3..bc46c1149120 100644 --- a/fs/gfs2/bmap.h +++ b/fs/gfs2/bmap.h | |||
| @@ -16,9 +16,8 @@ typedef int (*gfs2_unstuffer_t) (struct gfs2_inode * ip, | |||
| 16 | int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer, | 16 | int gfs2_unstuff_dinode(struct gfs2_inode *ip, gfs2_unstuffer_t unstuffer, |
| 17 | void *private); | 17 | void *private); |
| 18 | 18 | ||
| 19 | int gfs2_block_map(struct gfs2_inode *ip, | 19 | int gfs2_block_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, int *boundary); |
| 20 | uint64_t lblock, int *new, | 20 | int gfs2_extent_map(struct inode *inode, u64 lblock, int *new, u64 *dblock, unsigned *extlen); |
| 21 | uint64_t *dblock, uint32_t *extlen); | ||
| 22 | 21 | ||
| 23 | int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size); | 22 | int gfs2_truncatei(struct gfs2_inode *ip, uint64_t size); |
| 24 | int gfs2_truncatei_resume(struct gfs2_inode *ip); | 23 | int gfs2_truncatei_resume(struct gfs2_inode *ip); |
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index 0404783f39b3..7f8b27e40916 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c | |||
| @@ -197,8 +197,8 @@ static int gfs2_dir_write_data(struct gfs2_inode *ip, const char *buf, | |||
| 197 | 197 | ||
| 198 | if (!extlen) { | 198 | if (!extlen) { |
| 199 | new = 1; | 199 | new = 1; |
| 200 | error = gfs2_block_map(ip, lblock, &new, &dblock, | 200 | error = gfs2_extent_map(ip->i_vnode, lblock, &new, |
| 201 | &extlen); | 201 | &dblock, &extlen); |
| 202 | if (error) | 202 | if (error) |
| 203 | goto fail; | 203 | goto fail; |
| 204 | error = -EIO; | 204 | error = -EIO; |
| @@ -314,8 +314,8 @@ static int gfs2_dir_read_data(struct gfs2_inode *ip, char *buf, | |||
| 314 | 314 | ||
| 315 | if (!extlen) { | 315 | if (!extlen) { |
| 316 | new = 0; | 316 | new = 0; |
| 317 | error = gfs2_block_map(ip, lblock, &new, &dblock, | 317 | error = gfs2_extent_map(ip->i_vnode, lblock, &new, |
| 318 | &extlen); | 318 | &dblock, &extlen); |
| 319 | if (error) | 319 | if (error) |
| 320 | goto fail; | 320 | goto fail; |
| 321 | } | 321 | } |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 4fb8066dc745..9d4ae094fa2d 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
| @@ -2125,7 +2125,7 @@ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp, int wait) | |||
| 2125 | mutex_lock(&sdp->sd_invalidate_inodes_mutex); | 2125 | mutex_lock(&sdp->sd_invalidate_inodes_mutex); |
| 2126 | invalidate_inodes(sdp->sd_vfs); | 2126 | invalidate_inodes(sdp->sd_vfs); |
| 2127 | mutex_unlock(&sdp->sd_invalidate_inodes_mutex); | 2127 | mutex_unlock(&sdp->sd_invalidate_inodes_mutex); |
| 2128 | yield(); | 2128 | msleep(10); |
| 2129 | } | 2129 | } |
| 2130 | } | 2130 | } |
| 2131 | 2131 | ||
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 9084d6037a0c..0817f6ede188 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
| @@ -1606,9 +1606,8 @@ int gfs2_glock_nq_atime(struct gfs2_holder *gh) | |||
| 1606 | curtime = get_seconds(); | 1606 | curtime = get_seconds(); |
| 1607 | if (curtime - ip->i_di.di_atime >= quantum) { | 1607 | if (curtime - ip->i_di.di_atime >= quantum) { |
| 1608 | gfs2_glock_dq(gh); | 1608 | gfs2_glock_dq(gh); |
| 1609 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, | 1609 | gfs2_holder_reinit(LM_ST_EXCLUSIVE, gh->gh_flags & ~LM_FLAG_ANY, |
| 1610 | gh->gh_flags & ~LM_FLAG_ANY, | 1610 | gh); |
| 1611 | gh); | ||
| 1612 | error = gfs2_glock_nq(gh); | 1611 | error = gfs2_glock_nq(gh); |
| 1613 | if (error) | 1612 | if (error) |
| 1614 | return error; | 1613 | return error; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index 134fc57e21d3..02d31e35f0ca 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
| @@ -211,9 +211,9 @@ static uint64_t log_bmap(struct gfs2_sbd *sdp, unsigned int lbn) | |||
| 211 | int new = 0; | 211 | int new = 0; |
| 212 | uint64_t dbn; | 212 | uint64_t dbn; |
| 213 | int error; | 213 | int error; |
| 214 | int bdy; | ||
| 214 | 215 | ||
| 215 | error = gfs2_block_map(sdp->sd_jdesc->jd_inode->u.generic_ip, | 216 | error = gfs2_block_map(sdp->sd_jdesc->jd_inode, lbn, &new, &dbn, &bdy); |
| 216 | lbn, &new, &dbn, NULL); | ||
| 217 | gfs2_assert_withdraw(sdp, !error && dbn); | 217 | gfs2_assert_withdraw(sdp, !error && dbn); |
| 218 | 218 | ||
| 219 | return dbn; | 219 | return dbn; |
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index afcc12a00a3c..d89179b316fe 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/completion.h> | 13 | #include <linux/completion.h> |
| 14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
| 15 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
| 16 | #include <linux/pagevec.h> | ||
| 16 | #include <linux/mpage.h> | 17 | #include <linux/mpage.h> |
| 17 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
| 18 | #include <linux/gfs2_ondisk.h> | 19 | #include <linux/gfs2_ondisk.h> |
| @@ -47,12 +48,12 @@ | |||
| 47 | int gfs2_get_block(struct inode *inode, sector_t lblock, | 48 | int gfs2_get_block(struct inode *inode, sector_t lblock, |
| 48 | struct buffer_head *bh_result, int create) | 49 | struct buffer_head *bh_result, int create) |
| 49 | { | 50 | { |
| 50 | struct gfs2_inode *ip = inode->u.generic_ip; | ||
| 51 | int new = create; | 51 | int new = create; |
| 52 | uint64_t dblock; | 52 | uint64_t dblock; |
| 53 | int error; | 53 | int error; |
| 54 | int boundary; | ||
| 54 | 55 | ||
| 55 | error = gfs2_block_map(ip, lblock, &new, &dblock, NULL); | 56 | error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary); |
| 56 | if (error) | 57 | if (error) |
| 57 | return error; | 58 | return error; |
| 58 | 59 | ||
| @@ -62,6 +63,8 @@ int gfs2_get_block(struct inode *inode, sector_t lblock, | |||
| 62 | map_bh(bh_result, inode->i_sb, dblock); | 63 | map_bh(bh_result, inode->i_sb, dblock); |
| 63 | if (new) | 64 | if (new) |
| 64 | set_buffer_new(bh_result); | 65 | set_buffer_new(bh_result); |
| 66 | if (boundary) | ||
| 67 | set_buffer_boundary(bh_result); | ||
| 65 | 68 | ||
| 66 | return 0; | 69 | return 0; |
| 67 | } | 70 | } |
| @@ -83,8 +86,9 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock, | |||
| 83 | int new = 0; | 86 | int new = 0; |
| 84 | uint64_t dblock; | 87 | uint64_t dblock; |
| 85 | int error; | 88 | int error; |
| 89 | int boundary; | ||
| 86 | 90 | ||
| 87 | error = gfs2_block_map(ip, lblock, &new, &dblock, NULL); | 91 | error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary); |
| 88 | if (error) | 92 | if (error) |
| 89 | return error; | 93 | return error; |
| 90 | 94 | ||
| @@ -92,6 +96,8 @@ static int get_block_noalloc(struct inode *inode, sector_t lblock, | |||
| 92 | map_bh(bh_result, inode->i_sb, dblock); | 96 | map_bh(bh_result, inode->i_sb, dblock); |
| 93 | else if (gfs2_assert_withdraw(ip->i_sbd, !create)) | 97 | else if (gfs2_assert_withdraw(ip->i_sbd, !create)) |
| 94 | error = -EIO; | 98 | error = -EIO; |
| 99 | if (boundary) | ||
| 100 | set_buffer_boundary(bh_result); | ||
| 95 | 101 | ||
| 96 | return error; | 102 | return error; |
| 97 | } | 103 | } |
| @@ -151,6 +157,19 @@ out_ignore: | |||
| 151 | return 0; | 157 | return 0; |
| 152 | } | 158 | } |
| 153 | 159 | ||
| 160 | static int zero_readpage(struct page *page) | ||
| 161 | { | ||
| 162 | void *kaddr; | ||
| 163 | |||
| 164 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 165 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
| 166 | kunmap_atomic(page, KM_USER0); | ||
| 167 | |||
| 168 | SetPageUptodate(page); | ||
| 169 | |||
| 170 | return 0; | ||
| 171 | } | ||
| 172 | |||
| 154 | /** | 173 | /** |
| 155 | * stuffed_readpage - Fill in a Linux page with stuffed file data | 174 | * stuffed_readpage - Fill in a Linux page with stuffed file data |
| 156 | * @ip: the inode | 175 | * @ip: the inode |
| @@ -165,17 +184,18 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
| 165 | void *kaddr; | 184 | void *kaddr; |
| 166 | int error; | 185 | int error; |
| 167 | 186 | ||
| 187 | /* Only the first page of a stuffed file might contain data */ | ||
| 188 | if (unlikely(page->index)) | ||
| 189 | return zero_readpage(page); | ||
| 190 | |||
| 168 | error = gfs2_meta_inode_buffer(ip, &dibh); | 191 | error = gfs2_meta_inode_buffer(ip, &dibh); |
| 169 | if (error) | 192 | if (error) |
| 170 | return error; | 193 | return error; |
| 171 | 194 | ||
| 172 | kaddr = kmap_atomic(page, KM_USER0); | 195 | kaddr = kmap_atomic(page, KM_USER0); |
| 173 | memcpy((char *)kaddr, | 196 | memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode), |
| 174 | dibh->b_data + sizeof(struct gfs2_dinode), | ||
| 175 | ip->i_di.di_size); | 197 | ip->i_di.di_size); |
| 176 | memset((char *)kaddr + ip->i_di.di_size, | 198 | memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size); |
| 177 | 0, | ||
| 178 | PAGE_CACHE_SIZE - ip->i_di.di_size); | ||
| 179 | kunmap_atomic(page, KM_USER0); | 199 | kunmap_atomic(page, KM_USER0); |
| 180 | 200 | ||
| 181 | brelse(dibh); | 201 | brelse(dibh); |
| @@ -185,19 +205,6 @@ static int stuffed_readpage(struct gfs2_inode *ip, struct page *page) | |||
| 185 | return 0; | 205 | return 0; |
| 186 | } | 206 | } |
| 187 | 207 | ||
| 188 | static int zero_readpage(struct page *page) | ||
| 189 | { | ||
| 190 | void *kaddr; | ||
| 191 | |||
| 192 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 193 | memset(kaddr, 0, PAGE_CACHE_SIZE); | ||
| 194 | kunmap_atomic(page, KM_USER0); | ||
| 195 | |||
| 196 | SetPageUptodate(page); | ||
| 197 | unlock_page(page); | ||
| 198 | |||
| 199 | return 0; | ||
| 200 | } | ||
| 201 | 208 | ||
| 202 | /** | 209 | /** |
| 203 | * gfs2_readpage - readpage with locking | 210 | * gfs2_readpage - readpage with locking |
| @@ -215,19 +222,16 @@ static int gfs2_readpage(struct file *file, struct page *page) | |||
| 215 | struct gfs2_holder gh; | 222 | struct gfs2_holder gh; |
| 216 | int error; | 223 | int error; |
| 217 | 224 | ||
| 218 | if (file != &gfs2_internal_file_sentinal) { | 225 | if (likely(file != &gfs2_internal_file_sentinal)) { |
| 219 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); | 226 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh); |
| 220 | error = gfs2_glock_nq_m_atime(1, &gh); | 227 | error = gfs2_glock_nq_m_atime(1, &gh); |
| 221 | if (error) | 228 | if (unlikely(error)) |
| 222 | goto out_unlock; | 229 | goto out_unlock; |
| 223 | } | 230 | } |
| 224 | 231 | ||
| 225 | if (gfs2_is_stuffed(ip)) { | 232 | if (gfs2_is_stuffed(ip)) { |
| 226 | if (!page->index) { | 233 | error = stuffed_readpage(ip, page); |
| 227 | error = stuffed_readpage(ip, page); | 234 | unlock_page(page); |
| 228 | unlock_page(page); | ||
| 229 | } else | ||
| 230 | error = zero_readpage(page); | ||
| 231 | } else | 235 | } else |
| 232 | error = mpage_readpage(page, gfs2_get_block); | 236 | error = mpage_readpage(page, gfs2_get_block); |
| 233 | 237 | ||
| @@ -242,6 +246,90 @@ out: | |||
| 242 | return error; | 246 | return error; |
| 243 | out_unlock: | 247 | out_unlock: |
| 244 | unlock_page(page); | 248 | unlock_page(page); |
| 249 | if (file != &gfs2_internal_file_sentinal) | ||
| 250 | gfs2_holder_uninit(&gh); | ||
| 251 | goto out; | ||
| 252 | } | ||
| 253 | |||
| 254 | #define list_to_page(head) (list_entry((head)->prev, struct page, lru)) | ||
| 255 | |||
| 256 | /** | ||
| 257 | * gfs2_readpages - Read a bunch of pages at once | ||
| 258 | * | ||
| 259 | * Some notes: | ||
| 260 | * 1. This is only for readahead, so we can simply ignore any things | ||
| 261 | * which are slightly inconvenient (such as locking conflicts between | ||
| 262 | * the page lock and the glock) and return having done no I/O. Its | ||
| 263 | * obviously not something we'd want to do on too regular a basis. | ||
| 264 | * Any I/O we ignore at this time will be done via readpage later. | ||
| 265 | * 2. We have to handle stuffed files here too. | ||
| 266 | * 3. mpage_readpages() does most of the heavy lifting in the common case. | ||
| 267 | * 4. gfs2_get_block() is relied upon to set BH_Boundary in the right places. | ||
| 268 | * 5. We use LM_FLAG_TRY_1CB here, effectively we then have lock-ahead as | ||
| 269 | * well as read-ahead. | ||
| 270 | */ | ||
| 271 | static int gfs2_readpages(struct file *file, struct address_space *mapping, | ||
| 272 | struct list_head *pages, unsigned nr_pages) | ||
| 273 | { | ||
| 274 | struct inode *inode = mapping->host; | ||
| 275 | struct gfs2_inode *ip = inode->u.generic_ip; | ||
| 276 | struct gfs2_sbd *sdp = ip->i_sbd; | ||
| 277 | struct gfs2_holder gh; | ||
| 278 | unsigned page_idx; | ||
| 279 | int ret; | ||
| 280 | |||
| 281 | if (likely(file != &gfs2_internal_file_sentinal)) { | ||
| 282 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, | ||
| 283 | LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh); | ||
| 284 | ret = gfs2_glock_nq_m_atime(1, &gh); | ||
| 285 | if (ret == GLR_TRYFAILED) | ||
| 286 | goto out_noerror; | ||
| 287 | if (unlikely(ret)) | ||
| 288 | goto out_unlock; | ||
| 289 | } | ||
| 290 | |||
| 291 | if (gfs2_is_stuffed(ip)) { | ||
| 292 | struct pagevec lru_pvec; | ||
| 293 | pagevec_init(&lru_pvec, 0); | ||
| 294 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | ||
| 295 | struct page *page = list_to_page(pages); | ||
| 296 | list_del(&page->lru); | ||
| 297 | if (!add_to_page_cache(page, mapping, | ||
| 298 | page->index, GFP_KERNEL)) { | ||
| 299 | ret = stuffed_readpage(ip, page); | ||
| 300 | unlock_page(page); | ||
| 301 | if (!pagevec_add(&lru_pvec, page)) | ||
| 302 | __pagevec_lru_add(&lru_pvec); | ||
| 303 | } | ||
| 304 | page_cache_release(page); | ||
| 305 | } | ||
| 306 | pagevec_lru_add(&lru_pvec); | ||
| 307 | ret = 0; | ||
| 308 | } else { | ||
| 309 | /* What we really want to do .... */ | ||
| 310 | ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block); | ||
| 311 | } | ||
| 312 | |||
| 313 | if (likely(file != &gfs2_internal_file_sentinal)) { | ||
| 314 | gfs2_glock_dq_m(1, &gh); | ||
| 315 | gfs2_holder_uninit(&gh); | ||
| 316 | } | ||
| 317 | out: | ||
| 318 | if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags))) | ||
| 319 | ret = -EIO; | ||
| 320 | return ret; | ||
| 321 | out_noerror: | ||
| 322 | ret = 0; | ||
| 323 | out_unlock: | ||
| 324 | /* unlock all pages, we can't do any I/O right now */ | ||
| 325 | for (page_idx = 0; page_idx < nr_pages; page_idx++) { | ||
| 326 | struct page *page = list_to_page(pages); | ||
| 327 | list_del(&page->lru); | ||
| 328 | unlock_page(page); | ||
| 329 | page_cache_release(page); | ||
| 330 | } | ||
| 331 | if (likely(file != &gfs2_internal_file_sentinal)) | ||
| 332 | gfs2_holder_uninit(&gh); | ||
| 245 | goto out; | 333 | goto out; |
| 246 | } | 334 | } |
| 247 | 335 | ||
| @@ -572,6 +660,7 @@ static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb, | |||
| 572 | struct address_space_operations gfs2_file_aops = { | 660 | struct address_space_operations gfs2_file_aops = { |
| 573 | .writepage = gfs2_writepage, | 661 | .writepage = gfs2_writepage, |
| 574 | .readpage = gfs2_readpage, | 662 | .readpage = gfs2_readpage, |
| 663 | .readpages = gfs2_readpages, | ||
| 575 | .sync_page = block_sync_page, | 664 | .sync_page = block_sync_page, |
| 576 | .prepare_write = gfs2_prepare_write, | 665 | .prepare_write = gfs2_prepare_write, |
| 577 | .commit_write = gfs2_commit_write, | 666 | .commit_write = gfs2_commit_write, |
diff --git a/fs/gfs2/ops_super.c b/fs/gfs2/ops_super.c index 60bf2563c7b4..5910c7b5c846 100644 --- a/fs/gfs2/ops_super.c +++ b/fs/gfs2/ops_super.c | |||
| @@ -92,7 +92,6 @@ static void gfs2_put_super(struct super_block *sb) | |||
| 92 | if (error) | 92 | if (error) |
| 93 | gfs2_io_error(sdp); | 93 | gfs2_io_error(sdp); |
| 94 | } | 94 | } |
| 95 | |||
| 96 | /* At this point, we're through modifying the disk */ | 95 | /* At this point, we're through modifying the disk */ |
| 97 | 96 | ||
| 98 | /* Release stuff */ | 97 | /* Release stuff */ |
| @@ -125,12 +124,10 @@ static void gfs2_put_super(struct super_block *sb) | |||
| 125 | gfs2_jindex_free(sdp); | 124 | gfs2_jindex_free(sdp); |
| 126 | /* Take apart glock structures and buffer lists */ | 125 | /* Take apart glock structures and buffer lists */ |
| 127 | gfs2_gl_hash_clear(sdp, WAIT); | 126 | gfs2_gl_hash_clear(sdp, WAIT); |
| 128 | |||
| 129 | /* Unmount the locking protocol */ | 127 | /* Unmount the locking protocol */ |
| 130 | gfs2_lm_unmount(sdp); | 128 | gfs2_lm_unmount(sdp); |
| 131 | 129 | ||
| 132 | /* At this point, we're through participating in the lockspace */ | 130 | /* At this point, we're through participating in the lockspace */ |
| 133 | |||
| 134 | gfs2_sys_fs_del(sdp); | 131 | gfs2_sys_fs_del(sdp); |
| 135 | vfree(sdp); | 132 | vfree(sdp); |
| 136 | sb->s_fs_info = NULL; | 133 | sb->s_fs_info = NULL; |
diff --git a/fs/gfs2/ops_vm.c b/fs/gfs2/ops_vm.c index dbc57071e7bb..d67248cae9b9 100644 --- a/fs/gfs2/ops_vm.c +++ b/fs/gfs2/ops_vm.c | |||
| @@ -90,8 +90,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
| 90 | if (error) | 90 | if (error) |
| 91 | goto out_gunlock_q; | 91 | goto out_gunlock_q; |
| 92 | 92 | ||
| 93 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, | 93 | gfs2_write_calc_reserv(ip, PAGE_CACHE_SIZE, &data_blocks, &ind_blocks); |
| 94 | &data_blocks, &ind_blocks); | ||
| 95 | 94 | ||
| 96 | al->al_requested = data_blocks + ind_blocks; | 95 | al->al_requested = data_blocks + ind_blocks; |
| 97 | 96 | ||
| @@ -99,8 +98,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
| 99 | if (error) | 98 | if (error) |
| 100 | goto out_gunlock_q; | 99 | goto out_gunlock_q; |
| 101 | 100 | ||
| 102 | error = gfs2_trans_begin(sdp, | 101 | error = gfs2_trans_begin(sdp, al->al_rgd->rd_ri.ri_length + |
| 103 | al->al_rgd->rd_ri.ri_length + | ||
| 104 | ind_blocks + RES_DINODE + | 102 | ind_blocks + RES_DINODE + |
| 105 | RES_STATFS + RES_QUOTA, 0); | 103 | RES_STATFS + RES_QUOTA, 0); |
| 106 | if (error) | 104 | if (error) |
| @@ -117,7 +115,7 @@ static int alloc_page_backing(struct gfs2_inode *ip, struct page *page) | |||
| 117 | unsigned int extlen; | 115 | unsigned int extlen; |
| 118 | int new = 1; | 116 | int new = 1; |
| 119 | 117 | ||
| 120 | error = gfs2_block_map(ip, lblock, &new, &dblock, &extlen); | 118 | error = gfs2_extent_map(ip->i_vnode, lblock, &new, &dblock, &extlen); |
| 121 | if (error) | 119 | if (error) |
| 122 | goto out_trans; | 120 | goto out_trans; |
| 123 | 121 | ||
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index 942c4c8b9f56..d49ff43b3a86 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
| @@ -255,6 +255,7 @@ static int bh_get(struct gfs2_quota_data *qd) | |||
| 255 | int new = 0; | 255 | int new = 0; |
| 256 | struct buffer_head *bh; | 256 | struct buffer_head *bh; |
| 257 | int error; | 257 | int error; |
| 258 | int boundary; | ||
| 258 | 259 | ||
| 259 | mutex_lock(&sdp->sd_quota_mutex); | 260 | mutex_lock(&sdp->sd_quota_mutex); |
| 260 | 261 | ||
| @@ -266,7 +267,7 @@ static int bh_get(struct gfs2_quota_data *qd) | |||
| 266 | block = qd->qd_slot / sdp->sd_qc_per_block; | 267 | block = qd->qd_slot / sdp->sd_qc_per_block; |
| 267 | offset = qd->qd_slot % sdp->sd_qc_per_block;; | 268 | offset = qd->qd_slot % sdp->sd_qc_per_block;; |
| 268 | 269 | ||
| 269 | error = gfs2_block_map(ip, block, &new, &dblock, NULL); | 270 | error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary); |
| 270 | if (error) | 271 | if (error) |
| 271 | goto fail; | 272 | goto fail; |
| 272 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh); | 273 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh); |
| @@ -1162,7 +1163,7 @@ int gfs2_quota_init(struct gfs2_sbd *sdp) | |||
| 1162 | 1163 | ||
| 1163 | if (!extlen) { | 1164 | if (!extlen) { |
| 1164 | int new = 0; | 1165 | int new = 0; |
| 1165 | error = gfs2_block_map(ip, x, &new, &dblock, &extlen); | 1166 | error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen); |
| 1166 | if (error) | 1167 | if (error) |
| 1167 | goto fail; | 1168 | goto fail; |
| 1168 | } | 1169 | } |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index d916817fb6e3..87adebea3bc3 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
| @@ -40,8 +40,7 @@ int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, | |||
| 40 | uint32_t extlen; | 40 | uint32_t extlen; |
| 41 | int error; | 41 | int error; |
| 42 | 42 | ||
| 43 | error = gfs2_block_map(ip, blk, &new, &dblock, | 43 | error = gfs2_extent_map(ip->i_vnode, blk, &new, &dblock, &extlen); |
| 44 | &extlen); | ||
| 45 | if (error) | 44 | if (error) |
| 46 | return error; | 45 | return error; |
| 47 | if (!dblock) { | 46 | if (!dblock) { |
| @@ -378,10 +377,11 @@ static int clean_journal(struct gfs2_jdesc *jd, struct gfs2_log_header *head) | |||
| 378 | uint32_t hash; | 377 | uint32_t hash; |
| 379 | struct buffer_head *bh; | 378 | struct buffer_head *bh; |
| 380 | int error; | 379 | int error; |
| 381 | 380 | int boundary; | |
| 381 | |||
| 382 | lblock = head->lh_blkno; | 382 | lblock = head->lh_blkno; |
| 383 | gfs2_replay_incr_blk(sdp, &lblock); | 383 | gfs2_replay_incr_blk(sdp, &lblock); |
| 384 | error = gfs2_block_map(ip, lblock, &new, &dblock, NULL); | 384 | error = gfs2_block_map(ip->i_vnode, lblock, &new, &dblock, &boundary); |
| 385 | if (error) | 385 | if (error) |
| 386 | return error; | 386 | return error; |
| 387 | if (!dblock) { | 387 | if (!dblock) { |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index 4ae559694396..15c326ce13d1 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
| @@ -956,8 +956,7 @@ static uint32_t rgblk_search(struct gfs2_rgrpd *rgd, uint32_t goal, | |||
| 956 | search in the first part of our first-searched bit block. */ | 956 | search in the first part of our first-searched bit block. */ |
| 957 | for (x = 0; x <= length; x++) { | 957 | for (x = 0; x <= length; x++) { |
| 958 | if (bi->bi_clone) | 958 | if (bi->bi_clone) |
| 959 | blk = gfs2_bitfit(rgd, | 959 | blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, |
| 960 | bi->bi_clone + bi->bi_offset, | ||
| 961 | bi->bi_len, goal, old_state); | 960 | bi->bi_len, goal, old_state); |
| 962 | else | 961 | else |
| 963 | blk = gfs2_bitfit(rgd, | 962 | blk = gfs2_bitfit(rgd, |
| @@ -976,12 +975,10 @@ static uint32_t rgblk_search(struct gfs2_rgrpd *rgd, uint32_t goal, | |||
| 976 | blk = 0; | 975 | blk = 0; |
| 977 | 976 | ||
| 978 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); | 977 | gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1); |
| 979 | gfs2_setbit(rgd, | 978 | gfs2_setbit(rgd, bi->bi_bh->b_data + bi->bi_offset, |
| 980 | bi->bi_bh->b_data + bi->bi_offset, | ||
| 981 | bi->bi_len, blk, new_state); | 979 | bi->bi_len, blk, new_state); |
| 982 | if (bi->bi_clone) | 980 | if (bi->bi_clone) |
| 983 | gfs2_setbit(rgd, | 981 | gfs2_setbit(rgd, bi->bi_clone + bi->bi_offset, |
| 984 | bi->bi_clone + bi->bi_offset, | ||
| 985 | bi->bi_len, blk, new_state); | 982 | bi->bi_len, blk, new_state); |
| 986 | 983 | ||
| 987 | return bi->bi_start * GFS2_NBBY + blk; | 984 | return bi->bi_start * GFS2_NBBY + blk; |
| @@ -1064,8 +1061,7 @@ uint64_t gfs2_alloc_data(struct gfs2_inode *ip) | |||
| 1064 | else | 1061 | else |
| 1065 | goal = rgd->rd_last_alloc_data; | 1062 | goal = rgd->rd_last_alloc_data; |
| 1066 | 1063 | ||
| 1067 | blk = rgblk_search(rgd, goal, | 1064 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); |
| 1068 | GFS2_BLKST_FREE, GFS2_BLKST_USED); | ||
| 1069 | rgd->rd_last_alloc_data = blk; | 1065 | rgd->rd_last_alloc_data = blk; |
| 1070 | 1066 | ||
| 1071 | block = rgd->rd_ri.ri_data0 + blk; | 1067 | block = rgd->rd_ri.ri_data0 + blk; |
| @@ -1109,8 +1105,7 @@ uint64_t gfs2_alloc_meta(struct gfs2_inode *ip) | |||
| 1109 | else | 1105 | else |
| 1110 | goal = rgd->rd_last_alloc_meta; | 1106 | goal = rgd->rd_last_alloc_meta; |
| 1111 | 1107 | ||
| 1112 | blk = rgblk_search(rgd, goal, | 1108 | blk = rgblk_search(rgd, goal, GFS2_BLKST_FREE, GFS2_BLKST_USED); |
| 1113 | GFS2_BLKST_FREE, GFS2_BLKST_USED); | ||
| 1114 | rgd->rd_last_alloc_meta = blk; | 1109 | rgd->rd_last_alloc_meta = blk; |
| 1115 | 1110 | ||
| 1116 | block = rgd->rd_ri.ri_data0 + blk; | 1111 | block = rgd->rd_ri.ri_data0 + blk; |
diff --git a/fs/gfs2/unlinked.c b/fs/gfs2/unlinked.c index 24b91c23bc2d..0d2314a5252c 100644 --- a/fs/gfs2/unlinked.c +++ b/fs/gfs2/unlinked.c | |||
| @@ -35,11 +35,12 @@ static int munge_ondisk(struct gfs2_sbd *sdp, unsigned int slot, | |||
| 35 | int new = 0; | 35 | int new = 0; |
| 36 | struct buffer_head *bh; | 36 | struct buffer_head *bh; |
| 37 | int error; | 37 | int error; |
| 38 | int boundary; | ||
| 38 | 39 | ||
| 39 | block = slot / sdp->sd_ut_per_block; | 40 | block = slot / sdp->sd_ut_per_block; |
| 40 | offset = slot % sdp->sd_ut_per_block; | 41 | offset = slot % sdp->sd_ut_per_block; |
| 41 | 42 | ||
| 42 | error = gfs2_block_map(ip, block, &new, &dblock, NULL); | 43 | error = gfs2_block_map(ip->i_vnode, block, &new, &dblock, &boundary); |
| 43 | if (error) | 44 | if (error) |
| 44 | return error; | 45 | return error; |
| 45 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh); | 46 | error = gfs2_meta_read(ip->i_gl, dblock, DIO_START | DIO_WAIT, &bh); |
| @@ -354,7 +355,7 @@ int gfs2_unlinked_init(struct gfs2_sbd *sdp) | |||
| 354 | 355 | ||
| 355 | if (!extlen) { | 356 | if (!extlen) { |
| 356 | int new = 0; | 357 | int new = 0; |
| 357 | error = gfs2_block_map(ip, x, &new, &dblock, &extlen); | 358 | error = gfs2_extent_map(ip->i_vnode, x, &new, &dblock, &extlen); |
| 358 | if (error) | 359 | if (error) |
| 359 | goto fail; | 360 | goto fail; |
| 360 | } | 361 | } |
