diff options
| -rw-r--r-- | fs/btrfs/inode.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 04e9fffee8c..4822b313278 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -2664,10 +2664,10 @@ failed: | |||
| 2664 | * recovery code. It remove a link in a directory with a given name, and | 2664 | * recovery code. It remove a link in a directory with a given name, and |
| 2665 | * also drops the back refs in the inode to the directory | 2665 | * also drops the back refs in the inode to the directory |
| 2666 | */ | 2666 | */ |
| 2667 | int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | 2667 | static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans, |
| 2668 | struct btrfs_root *root, | 2668 | struct btrfs_root *root, |
| 2669 | struct inode *dir, struct inode *inode, | 2669 | struct inode *dir, struct inode *inode, |
| 2670 | const char *name, int name_len) | 2670 | const char *name, int name_len) |
| 2671 | { | 2671 | { |
| 2672 | struct btrfs_path *path; | 2672 | struct btrfs_path *path; |
| 2673 | int ret = 0; | 2673 | int ret = 0; |
| @@ -2739,12 +2739,25 @@ err: | |||
| 2739 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); | 2739 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); |
| 2740 | inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME; | 2740 | inode->i_ctime = dir->i_mtime = dir->i_ctime = CURRENT_TIME; |
| 2741 | btrfs_update_inode(trans, root, dir); | 2741 | btrfs_update_inode(trans, root, dir); |
| 2742 | btrfs_drop_nlink(inode); | ||
| 2743 | ret = btrfs_update_inode(trans, root, inode); | ||
| 2744 | out: | 2742 | out: |
| 2745 | return ret; | 2743 | return ret; |
| 2746 | } | 2744 | } |
| 2747 | 2745 | ||
| 2746 | int btrfs_unlink_inode(struct btrfs_trans_handle *trans, | ||
| 2747 | struct btrfs_root *root, | ||
| 2748 | struct inode *dir, struct inode *inode, | ||
| 2749 | const char *name, int name_len) | ||
| 2750 | { | ||
| 2751 | int ret; | ||
| 2752 | ret = __btrfs_unlink_inode(trans, root, dir, inode, name, name_len); | ||
| 2753 | if (!ret) { | ||
| 2754 | btrfs_drop_nlink(inode); | ||
| 2755 | ret = btrfs_update_inode(trans, root, inode); | ||
| 2756 | } | ||
| 2757 | return ret; | ||
| 2758 | } | ||
| 2759 | |||
| 2760 | |||
| 2748 | /* helper to check if there is any shared block in the path */ | 2761 | /* helper to check if there is any shared block in the path */ |
| 2749 | static int check_path_shared(struct btrfs_root *root, | 2762 | static int check_path_shared(struct btrfs_root *root, |
| 2750 | struct btrfs_path *path) | 2763 | struct btrfs_path *path) |
| @@ -6999,11 +7012,12 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
| 6999 | old_dentry->d_name.name, | 7012 | old_dentry->d_name.name, |
| 7000 | old_dentry->d_name.len); | 7013 | old_dentry->d_name.len); |
| 7001 | } else { | 7014 | } else { |
| 7002 | btrfs_inc_nlink(old_dentry->d_inode); | 7015 | ret = __btrfs_unlink_inode(trans, root, old_dir, |
| 7003 | ret = btrfs_unlink_inode(trans, root, old_dir, | 7016 | old_dentry->d_inode, |
| 7004 | old_dentry->d_inode, | 7017 | old_dentry->d_name.name, |
| 7005 | old_dentry->d_name.name, | 7018 | old_dentry->d_name.len); |
| 7006 | old_dentry->d_name.len); | 7019 | if (!ret) |
| 7020 | ret = btrfs_update_inode(trans, root, old_inode); | ||
| 7007 | } | 7021 | } |
| 7008 | BUG_ON(ret); | 7022 | BUG_ON(ret); |
| 7009 | 7023 | ||
