diff options
| author | Paul Mackerras <paulus@samba.org> | 2006-08-31 01:45:48 -0400 | 
|---|---|---|
| committer | Paul Mackerras <paulus@samba.org> | 2006-08-31 01:45:48 -0400 | 
| commit | aa43f77939c97bf9d3580c6a5e71a5a40290e451 (patch) | |
| tree | 095c0b8b3da4b6554a3f8ef4b39240a5d9216d4d /fs/ufs/truncate.c | |
| parent | 2818c5dec5e28d65d52afbb7695bbbafe6377ee5 (diff) | |
| parent | 4c15343167b5febe7bb0ba96aad5bef42ae94d3b (diff) | |
Merge branch 'merge'
Diffstat (limited to 'fs/ufs/truncate.c')
| -rw-r--r-- | fs/ufs/truncate.c | 77 | 
1 files changed, 25 insertions, 52 deletions
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index c9b55872079b..ea11d04c41a0 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c  | |||
| @@ -375,17 +375,15 @@ static int ufs_alloc_lastblock(struct inode *inode) | |||
| 375 | int err = 0; | 375 | int err = 0; | 
| 376 | struct address_space *mapping = inode->i_mapping; | 376 | struct address_space *mapping = inode->i_mapping; | 
| 377 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; | 377 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; | 
| 378 | struct ufs_inode_info *ufsi = UFS_I(inode); | ||
| 379 | unsigned lastfrag, i, end; | 378 | unsigned lastfrag, i, end; | 
| 380 | struct page *lastpage; | 379 | struct page *lastpage; | 
| 381 | struct buffer_head *bh; | 380 | struct buffer_head *bh; | 
| 382 | 381 | ||
| 383 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; | 382 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; | 
| 384 | 383 | ||
| 385 | if (!lastfrag) { | 384 | if (!lastfrag) | 
| 386 | ufsi->i_lastfrag = 0; | ||
| 387 | goto out; | 385 | goto out; | 
| 388 | } | 386 | |
| 389 | lastfrag--; | 387 | lastfrag--; | 
| 390 | 388 | ||
| 391 | lastpage = ufs_get_locked_page(mapping, lastfrag >> | 389 | lastpage = ufs_get_locked_page(mapping, lastfrag >> | 
| @@ -400,25 +398,25 @@ static int ufs_alloc_lastblock(struct inode *inode) | |||
| 400 | for (i = 0; i < end; ++i) | 398 | for (i = 0; i < end; ++i) | 
| 401 | bh = bh->b_this_page; | 399 | bh = bh->b_this_page; | 
| 402 | 400 | ||
| 403 | if (!buffer_mapped(bh)) { | 401 | |
| 404 | err = ufs_getfrag_block(inode, lastfrag, bh, 1); | 402 | err = ufs_getfrag_block(inode, lastfrag, bh, 1); | 
| 405 | 403 | ||
| 406 | if (unlikely(err)) | 404 | if (unlikely(err)) | 
| 407 | goto out_unlock; | 405 | goto out_unlock; | 
| 408 | 406 | ||
| 409 | if (buffer_new(bh)) { | 407 | if (buffer_new(bh)) { | 
| 410 | clear_buffer_new(bh); | 408 | clear_buffer_new(bh); | 
| 411 | unmap_underlying_metadata(bh->b_bdev, | 409 | unmap_underlying_metadata(bh->b_bdev, | 
| 412 | bh->b_blocknr); | 410 | bh->b_blocknr); | 
| 413 | /* | 411 | /* | 
| 414 | * we do not zeroize fragment, because of | 412 | * we do not zeroize fragment, because of | 
| 415 | * if it maped to hole, it already contains zeroes | 413 | * if it maped to hole, it already contains zeroes | 
| 416 | */ | 414 | */ | 
| 417 | set_buffer_uptodate(bh); | 415 | set_buffer_uptodate(bh); | 
| 418 | mark_buffer_dirty(bh); | 416 | mark_buffer_dirty(bh); | 
| 419 | set_page_dirty(lastpage); | 417 | set_page_dirty(lastpage); | 
| 420 | } | ||
| 421 | } | 418 | } | 
| 419 | |||
| 422 | out_unlock: | 420 | out_unlock: | 
| 423 | ufs_put_locked_page(lastpage); | 421 | ufs_put_locked_page(lastpage); | 
| 424 | out: | 422 | out: | 
| @@ -440,23 +438,11 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) | |||
| 440 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 438 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | 
| 441 | return -EPERM; | 439 | return -EPERM; | 
| 442 | 440 | ||
| 443 | if (inode->i_size > old_i_size) { | 441 | err = ufs_alloc_lastblock(inode); | 
| 444 | /* | ||
| 445 | * if we expand file we should care about | ||
| 446 | * allocation of block for last byte first of all | ||
| 447 | */ | ||
| 448 | err = ufs_alloc_lastblock(inode); | ||
| 449 | 442 | ||
| 450 | if (err) { | 443 | if (err) { | 
| 451 | i_size_write(inode, old_i_size); | 444 | i_size_write(inode, old_i_size); | 
| 452 | goto out; | 445 | goto out; | 
| 453 | } | ||
| 454 | /* | ||
| 455 | * go away, because of we expand file, and we do not | ||
| 456 | * need free blocks, and zeroizes page | ||
| 457 | */ | ||
| 458 | lock_kernel(); | ||
| 459 | goto almost_end; | ||
| 460 | } | 446 | } | 
| 461 | 447 | ||
| 462 | block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); | 448 | block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); | 
| @@ -477,21 +463,8 @@ int ufs_truncate(struct inode *inode, loff_t old_i_size) | |||
| 477 | yield(); | 463 | yield(); | 
| 478 | } | 464 | } | 
| 479 | 465 | ||
| 480 | if (inode->i_size < old_i_size) { | ||
| 481 | /* | ||
| 482 | * now we should have enough space | ||
| 483 | * to allocate block for last byte | ||
| 484 | */ | ||
| 485 | err = ufs_alloc_lastblock(inode); | ||
| 486 | if (err) | ||
| 487 | /* | ||
| 488 | * looks like all the same - we have no space, | ||
| 489 | * but we truncate file already | ||
| 490 | */ | ||
| 491 | inode->i_size = (ufsi->i_lastfrag - 1) * uspi->s_fsize; | ||
| 492 | } | ||
| 493 | almost_end: | ||
| 494 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 466 | inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; | 
| 467 | ufsi->i_lastfrag = DIRECT_FRAGMENT; | ||
| 495 | unlock_kernel(); | 468 | unlock_kernel(); | 
| 496 | mark_inode_dirty(inode); | 469 | mark_inode_dirty(inode); | 
| 497 | out: | 470 | out: | 
