diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 40 |
1 files changed, 25 insertions, 15 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 0ccc7438ad34..b2d004ad66a0 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1786,7 +1786,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1786 | &ordered_extent->list); | 1786 | &ordered_extent->list); |
1787 | 1787 | ||
1788 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); | 1788 | ret = btrfs_ordered_update_i_size(inode, 0, ordered_extent); |
1789 | if (!ret) { | 1789 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { |
1790 | ret = btrfs_update_inode(trans, root, inode); | 1790 | ret = btrfs_update_inode(trans, root, inode); |
1791 | BUG_ON(ret); | 1791 | BUG_ON(ret); |
1792 | } | 1792 | } |
@@ -3510,15 +3510,19 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
3510 | err = btrfs_drop_extents(trans, inode, cur_offset, | 3510 | err = btrfs_drop_extents(trans, inode, cur_offset, |
3511 | cur_offset + hole_size, | 3511 | cur_offset + hole_size, |
3512 | &hint_byte, 1); | 3512 | &hint_byte, 1); |
3513 | if (err) | 3513 | if (err) { |
3514 | btrfs_end_transaction(trans, root); | ||
3514 | break; | 3515 | break; |
3516 | } | ||
3515 | 3517 | ||
3516 | err = btrfs_insert_file_extent(trans, root, | 3518 | err = btrfs_insert_file_extent(trans, root, |
3517 | btrfs_ino(inode), cur_offset, 0, | 3519 | btrfs_ino(inode), cur_offset, 0, |
3518 | 0, hole_size, 0, hole_size, | 3520 | 0, hole_size, 0, hole_size, |
3519 | 0, 0, 0); | 3521 | 0, 0, 0); |
3520 | if (err) | 3522 | if (err) { |
3523 | btrfs_end_transaction(trans, root); | ||
3521 | break; | 3524 | break; |
3525 | } | ||
3522 | 3526 | ||
3523 | btrfs_drop_extent_cache(inode, hole_start, | 3527 | btrfs_drop_extent_cache(inode, hole_start, |
3524 | last_byte - 1, 0); | 3528 | last_byte - 1, 0); |
@@ -3952,7 +3956,6 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
3952 | struct btrfs_root *root, int *new) | 3956 | struct btrfs_root *root, int *new) |
3953 | { | 3957 | { |
3954 | struct inode *inode; | 3958 | struct inode *inode; |
3955 | int bad_inode = 0; | ||
3956 | 3959 | ||
3957 | inode = btrfs_iget_locked(s, location->objectid, root); | 3960 | inode = btrfs_iget_locked(s, location->objectid, root); |
3958 | if (!inode) | 3961 | if (!inode) |
@@ -3968,15 +3971,12 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
3968 | if (new) | 3971 | if (new) |
3969 | *new = 1; | 3972 | *new = 1; |
3970 | } else { | 3973 | } else { |
3971 | bad_inode = 1; | 3974 | unlock_new_inode(inode); |
3975 | iput(inode); | ||
3976 | inode = ERR_PTR(-ESTALE); | ||
3972 | } | 3977 | } |
3973 | } | 3978 | } |
3974 | 3979 | ||
3975 | if (bad_inode) { | ||
3976 | iput(inode); | ||
3977 | inode = ERR_PTR(-ESTALE); | ||
3978 | } | ||
3979 | |||
3980 | return inode; | 3980 | return inode; |
3981 | } | 3981 | } |
3982 | 3982 | ||
@@ -4018,7 +4018,8 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
4018 | memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key)); | 4018 | memcpy(&location, dentry->d_fsdata, sizeof(struct btrfs_key)); |
4019 | kfree(dentry->d_fsdata); | 4019 | kfree(dentry->d_fsdata); |
4020 | dentry->d_fsdata = NULL; | 4020 | dentry->d_fsdata = NULL; |
4021 | d_clear_need_lookup(dentry); | 4021 | /* This thing is hashed, drop it for now */ |
4022 | d_drop(dentry); | ||
4022 | } else { | 4023 | } else { |
4023 | ret = btrfs_inode_by_name(dir, dentry, &location); | 4024 | ret = btrfs_inode_by_name(dir, dentry, &location); |
4024 | } | 4025 | } |
@@ -4085,7 +4086,15 @@ static void btrfs_dentry_release(struct dentry *dentry) | |||
4085 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | 4086 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, |
4086 | struct nameidata *nd) | 4087 | struct nameidata *nd) |
4087 | { | 4088 | { |
4088 | return d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); | 4089 | struct dentry *ret; |
4090 | |||
4091 | ret = d_splice_alias(btrfs_lookup_dentry(dir, dentry), dentry); | ||
4092 | if (unlikely(d_need_lookup(dentry))) { | ||
4093 | spin_lock(&dentry->d_lock); | ||
4094 | dentry->d_flags &= ~DCACHE_NEED_LOOKUP; | ||
4095 | spin_unlock(&dentry->d_lock); | ||
4096 | } | ||
4097 | return ret; | ||
4089 | } | 4098 | } |
4090 | 4099 | ||
4091 | unsigned char btrfs_filetype_table[] = { | 4100 | unsigned char btrfs_filetype_table[] = { |
@@ -4125,7 +4134,8 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4125 | 4134 | ||
4126 | /* special case for "." */ | 4135 | /* special case for "." */ |
4127 | if (filp->f_pos == 0) { | 4136 | if (filp->f_pos == 0) { |
4128 | over = filldir(dirent, ".", 1, 1, btrfs_ino(inode), DT_DIR); | 4137 | over = filldir(dirent, ".", 1, |
4138 | filp->f_pos, btrfs_ino(inode), DT_DIR); | ||
4129 | if (over) | 4139 | if (over) |
4130 | return 0; | 4140 | return 0; |
4131 | filp->f_pos = 1; | 4141 | filp->f_pos = 1; |
@@ -4134,7 +4144,7 @@ static int btrfs_real_readdir(struct file *filp, void *dirent, | |||
4134 | if (filp->f_pos == 1) { | 4144 | if (filp->f_pos == 1) { |
4135 | u64 pino = parent_ino(filp->f_path.dentry); | 4145 | u64 pino = parent_ino(filp->f_path.dentry); |
4136 | over = filldir(dirent, "..", 2, | 4146 | over = filldir(dirent, "..", 2, |
4137 | 2, pino, DT_DIR); | 4147 | filp->f_pos, pino, DT_DIR); |
4138 | if (over) | 4148 | if (over) |
4139 | return 0; | 4149 | return 0; |
4140 | filp->f_pos = 2; | 4150 | filp->f_pos = 2; |
@@ -5823,7 +5833,7 @@ again: | |||
5823 | 5833 | ||
5824 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); | 5834 | add_pending_csums(trans, inode, ordered->file_offset, &ordered->list); |
5825 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); | 5835 | ret = btrfs_ordered_update_i_size(inode, 0, ordered); |
5826 | if (!ret) | 5836 | if (!ret || !test_bit(BTRFS_ORDERED_PREALLOC, &ordered->flags)) |
5827 | btrfs_update_inode(trans, root, inode); | 5837 | btrfs_update_inode(trans, root, inode); |
5828 | ret = 0; | 5838 | ret = 0; |
5829 | out_unlock: | 5839 | out_unlock: |