diff options
author | Ingo Molnar <mingo@elte.hu> | 2009-05-11 08:44:27 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-05-11 08:44:31 -0400 |
commit | 41fb454ebe6024f5c1e3b3cbc0abc0da762e7b51 (patch) | |
tree | 51c50bcb67a5039448ddfa1869d7948cab1217e9 /fs/ext2 | |
parent | 19c1a6f5764d787113fa323ffb18be7991208f82 (diff) | |
parent | 091bf7624d1c90cec9e578a18529f615213ff847 (diff) |
Merge commit 'v2.6.30-rc5' into core/iommu
Merge reason: core/iommu was on an .30-rc1 base,
update it to .30-rc5 to refresh.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/inode.c | 44 | ||||
-rw-r--r-- | fs/ext2/super.c | 4 |
2 files changed, 36 insertions, 12 deletions
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b43b95563663..acf678831103 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -590,9 +590,8 @@ static int ext2_get_blocks(struct inode *inode, | |||
590 | 590 | ||
591 | if (depth == 0) | 591 | if (depth == 0) |
592 | return (err); | 592 | return (err); |
593 | reread: | ||
594 | partial = ext2_get_branch(inode, depth, offsets, chain, &err); | ||
595 | 593 | ||
594 | partial = ext2_get_branch(inode, depth, offsets, chain, &err); | ||
596 | /* Simplest case - block found, no allocation needed */ | 595 | /* Simplest case - block found, no allocation needed */ |
597 | if (!partial) { | 596 | if (!partial) { |
598 | first_block = le32_to_cpu(chain[depth - 1].key); | 597 | first_block = le32_to_cpu(chain[depth - 1].key); |
@@ -602,15 +601,16 @@ reread: | |||
602 | while (count < maxblocks && count <= blocks_to_boundary) { | 601 | while (count < maxblocks && count <= blocks_to_boundary) { |
603 | ext2_fsblk_t blk; | 602 | ext2_fsblk_t blk; |
604 | 603 | ||
605 | if (!verify_chain(chain, partial)) { | 604 | if (!verify_chain(chain, chain + depth - 1)) { |
606 | /* | 605 | /* |
607 | * Indirect block might be removed by | 606 | * Indirect block might be removed by |
608 | * truncate while we were reading it. | 607 | * truncate while we were reading it. |
609 | * Handling of that case: forget what we've | 608 | * Handling of that case: forget what we've |
610 | * got now, go to reread. | 609 | * got now, go to reread. |
611 | */ | 610 | */ |
611 | err = -EAGAIN; | ||
612 | count = 0; | 612 | count = 0; |
613 | goto changed; | 613 | break; |
614 | } | 614 | } |
615 | blk = le32_to_cpu(*(chain[depth-1].p + count)); | 615 | blk = le32_to_cpu(*(chain[depth-1].p + count)); |
616 | if (blk == first_block + count) | 616 | if (blk == first_block + count) |
@@ -618,7 +618,8 @@ reread: | |||
618 | else | 618 | else |
619 | break; | 619 | break; |
620 | } | 620 | } |
621 | goto got_it; | 621 | if (err != -EAGAIN) |
622 | goto got_it; | ||
622 | } | 623 | } |
623 | 624 | ||
624 | /* Next simple case - plain lookup or failed read of indirect block */ | 625 | /* Next simple case - plain lookup or failed read of indirect block */ |
@@ -626,6 +627,33 @@ reread: | |||
626 | goto cleanup; | 627 | goto cleanup; |
627 | 628 | ||
628 | mutex_lock(&ei->truncate_mutex); | 629 | mutex_lock(&ei->truncate_mutex); |
630 | /* | ||
631 | * If the indirect block is missing while we are reading | ||
632 | * the chain(ext3_get_branch() returns -EAGAIN err), or | ||
633 | * if the chain has been changed after we grab the semaphore, | ||
634 | * (either because another process truncated this branch, or | ||
635 | * another get_block allocated this branch) re-grab the chain to see if | ||
636 | * the request block has been allocated or not. | ||
637 | * | ||
638 | * Since we already block the truncate/other get_block | ||
639 | * at this point, we will have the current copy of the chain when we | ||
640 | * splice the branch into the tree. | ||
641 | */ | ||
642 | if (err == -EAGAIN || !verify_chain(chain, partial)) { | ||
643 | while (partial > chain) { | ||
644 | brelse(partial->bh); | ||
645 | partial--; | ||
646 | } | ||
647 | partial = ext2_get_branch(inode, depth, offsets, chain, &err); | ||
648 | if (!partial) { | ||
649 | count++; | ||
650 | mutex_unlock(&ei->truncate_mutex); | ||
651 | if (err) | ||
652 | goto cleanup; | ||
653 | clear_buffer_new(bh_result); | ||
654 | goto got_it; | ||
655 | } | ||
656 | } | ||
629 | 657 | ||
630 | /* | 658 | /* |
631 | * Okay, we need to do block allocation. Lazily initialize the block | 659 | * Okay, we need to do block allocation. Lazily initialize the block |
@@ -683,12 +711,6 @@ cleanup: | |||
683 | partial--; | 711 | partial--; |
684 | } | 712 | } |
685 | return err; | 713 | return err; |
686 | changed: | ||
687 | while (partial > chain) { | ||
688 | brelse(partial->bh); | ||
689 | partial--; | ||
690 | } | ||
691 | goto reread; | ||
692 | } | 714 | } |
693 | 715 | ||
694 | int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) | 716 | int ext2_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) |
diff --git a/fs/ext2/super.c b/fs/ext2/super.c index f983225266dc..5c4afe652245 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -1395,8 +1395,10 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, | |||
1395 | blk++; | 1395 | blk++; |
1396 | } | 1396 | } |
1397 | out: | 1397 | out: |
1398 | if (len == towrite) | 1398 | if (len == towrite) { |
1399 | mutex_unlock(&inode->i_mutex); | ||
1399 | return err; | 1400 | return err; |
1401 | } | ||
1400 | if (inode->i_size < off+len-towrite) | 1402 | if (inode->i_size < off+len-towrite) |
1401 | i_size_write(inode, off+len-towrite); | 1403 | i_size_write(inode, off+len-towrite); |
1402 | inode->i_version++; | 1404 | inode->i_version++; |