diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2009-04-06 22:01:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-04-07 11:31:17 -0400 |
commit | 47420c799830d4676e544dbec56b2a7f787528f5 (patch) | |
tree | dd61f6c96942b07f762129c893d9cbbbeff60735 /fs/nilfs2/inode.c | |
parent | a2e7d2df82cafb76f76809ddf6e2caa8afe4f75e (diff) |
nilfs2: avoid double error caused by nilfs_transaction_end
Pekka Enberg pointed out that double error handlings found after
nilfs_transaction_end() can be avoided by separating abort operation:
OK, I don't understand this. The only way nilfs_transaction_end() can
fail is if we have NILFS_TI_SYNC set and we fail to construct the
segment. But why do we want to construct a segment if we don't commit?
I guess what I'm asking is why don't we have a separate
nilfs_transaction_abort() function that can't fail for the erroneous
case to avoid this double error value tracking thing?
This does the separation and renames nilfs_transaction_end() to
nilfs_transaction_commit() for clarification.
Since, some calls of these functions were used just for exclusion control
against the segment constructor, they are replaced with semaphore
operations.
Acked-by: Pekka Enberg <penberg@cs.helsinki.fi>
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/nilfs2/inode.c')
-rw-r--r-- | fs/nilfs2/inode.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 289d1798decb..4bf1e2c5bac6 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
@@ -77,7 +77,6 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
77 | goto out; | 77 | goto out; |
78 | err = nilfs_bmap_insert(ii->i_bmap, (unsigned long)blkoff, | 78 | err = nilfs_bmap_insert(ii->i_bmap, (unsigned long)blkoff, |
79 | (unsigned long)bh_result); | 79 | (unsigned long)bh_result); |
80 | nilfs_transaction_end(inode->i_sb, !err); | ||
81 | if (unlikely(err != 0)) { | 80 | if (unlikely(err != 0)) { |
82 | if (err == -EEXIST) { | 81 | if (err == -EEXIST) { |
83 | /* | 82 | /* |
@@ -100,8 +99,10 @@ int nilfs_get_block(struct inode *inode, sector_t blkoff, | |||
100 | inode->i_ino); | 99 | inode->i_ino); |
101 | err = -EIO; | 100 | err = -EIO; |
102 | } | 101 | } |
102 | nilfs_transaction_abort(inode->i_sb); | ||
103 | goto out; | 103 | goto out; |
104 | } | 104 | } |
105 | nilfs_transaction_commit(inode->i_sb); /* never fails */ | ||
105 | /* Error handling should be detailed */ | 106 | /* Error handling should be detailed */ |
106 | set_buffer_new(bh_result); | 107 | set_buffer_new(bh_result); |
107 | map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed | 108 | map_bh(bh_result, inode->i_sb, 0); /* dbn must be changed |
@@ -203,7 +204,7 @@ static int nilfs_write_begin(struct file *file, struct address_space *mapping, | |||
203 | err = block_write_begin(file, mapping, pos, len, flags, pagep, | 204 | err = block_write_begin(file, mapping, pos, len, flags, pagep, |
204 | fsdata, nilfs_get_block); | 205 | fsdata, nilfs_get_block); |
205 | if (unlikely(err)) | 206 | if (unlikely(err)) |
206 | nilfs_transaction_end(inode->i_sb, 0); | 207 | nilfs_transaction_abort(inode->i_sb); |
207 | return err; | 208 | return err; |
208 | } | 209 | } |
209 | 210 | ||
@@ -221,7 +222,7 @@ static int nilfs_write_end(struct file *file, struct address_space *mapping, | |||
221 | copied = generic_write_end(file, mapping, pos, len, copied, page, | 222 | copied = generic_write_end(file, mapping, pos, len, copied, page, |
222 | fsdata); | 223 | fsdata); |
223 | nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty); | 224 | nilfs_set_file_dirty(NILFS_SB(inode->i_sb), inode, nr_dirty); |
224 | err = nilfs_transaction_end(inode->i_sb, 1); | 225 | err = nilfs_transaction_commit(inode->i_sb); |
225 | return err ? : copied; | 226 | return err ? : copied; |
226 | } | 227 | } |
227 | 228 | ||
@@ -641,7 +642,7 @@ void nilfs_truncate(struct inode *inode) | |||
641 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 642 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
642 | 643 | ||
643 | nilfs_set_file_dirty(NILFS_SB(sb), inode, 0); | 644 | nilfs_set_file_dirty(NILFS_SB(sb), inode, 0); |
644 | nilfs_transaction_end(sb, 1); | 645 | nilfs_transaction_commit(sb); |
645 | /* May construct a logical segment and may fail in sync mode. | 646 | /* May construct a logical segment and may fail in sync mode. |
646 | But truncate has no return value. */ | 647 | But truncate has no return value. */ |
647 | } | 648 | } |
@@ -669,7 +670,7 @@ void nilfs_delete_inode(struct inode *inode) | |||
669 | /* nilfs_free_inode() marks inode buffer dirty */ | 670 | /* nilfs_free_inode() marks inode buffer dirty */ |
670 | if (IS_SYNC(inode)) | 671 | if (IS_SYNC(inode)) |
671 | nilfs_set_transaction_flag(NILFS_TI_SYNC); | 672 | nilfs_set_transaction_flag(NILFS_TI_SYNC); |
672 | nilfs_transaction_end(sb, 1); | 673 | nilfs_transaction_commit(sb); |
673 | /* May construct a logical segment and may fail in sync mode. | 674 | /* May construct a logical segment and may fail in sync mode. |
674 | But delete_inode has no return value. */ | 675 | But delete_inode has no return value. */ |
675 | } | 676 | } |
@@ -679,7 +680,7 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
679 | struct nilfs_transaction_info ti; | 680 | struct nilfs_transaction_info ti; |
680 | struct inode *inode = dentry->d_inode; | 681 | struct inode *inode = dentry->d_inode; |
681 | struct super_block *sb = inode->i_sb; | 682 | struct super_block *sb = inode->i_sb; |
682 | int err, err2; | 683 | int err; |
683 | 684 | ||
684 | err = inode_change_ok(inode, iattr); | 685 | err = inode_change_ok(inode, iattr); |
685 | if (err) | 686 | if (err) |
@@ -691,8 +692,12 @@ int nilfs_setattr(struct dentry *dentry, struct iattr *iattr) | |||
691 | err = inode_setattr(inode, iattr); | 692 | err = inode_setattr(inode, iattr); |
692 | if (!err && (iattr->ia_valid & ATTR_MODE)) | 693 | if (!err && (iattr->ia_valid & ATTR_MODE)) |
693 | err = nilfs_acl_chmod(inode); | 694 | err = nilfs_acl_chmod(inode); |
694 | err2 = nilfs_transaction_end(sb, 1); | 695 | if (likely(!err)) |
695 | return err ? : err2; | 696 | err = nilfs_transaction_commit(sb); |
697 | else | ||
698 | nilfs_transaction_abort(sb); | ||
699 | |||
700 | return err; | ||
696 | } | 701 | } |
697 | 702 | ||
698 | int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, | 703 | int nilfs_load_inode_block(struct nilfs_sb_info *sbi, struct inode *inode, |
@@ -817,5 +822,5 @@ void nilfs_dirty_inode(struct inode *inode) | |||
817 | nilfs_transaction_begin(inode->i_sb, &ti, 0); | 822 | nilfs_transaction_begin(inode->i_sb, &ti, 0); |
818 | if (likely(inode->i_ino != NILFS_SKETCH_INO)) | 823 | if (likely(inode->i_ino != NILFS_SKETCH_INO)) |
819 | nilfs_mark_inode_dirty(inode); | 824 | nilfs_mark_inode_dirty(inode); |
820 | nilfs_transaction_end(inode->i_sb, 1); /* never fails */ | 825 | nilfs_transaction_commit(inode->i_sb); /* never fails */ |
821 | } | 826 | } |