diff options
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 368 |
1 files changed, 262 insertions, 106 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9e81f3184f24..6036b36789cc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2373,6 +2373,69 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2373 | return ret; | 2373 | return ret; |
2374 | } | 2374 | } |
2375 | 2375 | ||
2376 | int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, | ||
2377 | struct btrfs_root *root, | ||
2378 | struct inode *dir, u64 objectid, | ||
2379 | const char *name, int name_len) | ||
2380 | { | ||
2381 | struct btrfs_path *path; | ||
2382 | struct extent_buffer *leaf; | ||
2383 | struct btrfs_dir_item *di; | ||
2384 | struct btrfs_key key; | ||
2385 | u64 index; | ||
2386 | int ret; | ||
2387 | |||
2388 | path = btrfs_alloc_path(); | ||
2389 | if (!path) | ||
2390 | return -ENOMEM; | ||
2391 | |||
2392 | di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, | ||
2393 | name, name_len, -1); | ||
2394 | BUG_ON(!di || IS_ERR(di)); | ||
2395 | |||
2396 | leaf = path->nodes[0]; | ||
2397 | btrfs_dir_item_key_to_cpu(leaf, di, &key); | ||
2398 | WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); | ||
2399 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | ||
2400 | BUG_ON(ret); | ||
2401 | btrfs_release_path(root, path); | ||
2402 | |||
2403 | ret = btrfs_del_root_ref(trans, root->fs_info->tree_root, | ||
2404 | objectid, root->root_key.objectid, | ||
2405 | dir->i_ino, &index, name, name_len); | ||
2406 | if (ret < 0) { | ||
2407 | BUG_ON(ret != -ENOENT); | ||
2408 | di = btrfs_search_dir_index_item(root, path, dir->i_ino, | ||
2409 | name, name_len); | ||
2410 | BUG_ON(!di || IS_ERR(di)); | ||
2411 | |||
2412 | leaf = path->nodes[0]; | ||
2413 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
2414 | btrfs_release_path(root, path); | ||
2415 | index = key.offset; | ||
2416 | } | ||
2417 | |||
2418 | di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, | ||
2419 | index, name, name_len, -1); | ||
2420 | BUG_ON(!di || IS_ERR(di)); | ||
2421 | |||
2422 | leaf = path->nodes[0]; | ||
2423 | btrfs_dir_item_key_to_cpu(leaf, di, &key); | ||
2424 | WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); | ||
2425 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | ||
2426 | BUG_ON(ret); | ||
2427 | btrfs_release_path(root, path); | ||
2428 | |||
2429 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); | ||
2430 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | ||
2431 | ret = btrfs_update_inode(trans, root, dir); | ||
2432 | BUG_ON(ret); | ||
2433 | dir->i_sb->s_dirt = 1; | ||
2434 | |||
2435 | btrfs_free_path(path); | ||
2436 | return 0; | ||
2437 | } | ||
2438 | |||
2376 | static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | 2439 | static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) |
2377 | { | 2440 | { |
2378 | struct inode *inode = dentry->d_inode; | 2441 | struct inode *inode = dentry->d_inode; |
@@ -2382,29 +2445,31 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2382 | struct btrfs_trans_handle *trans; | 2445 | struct btrfs_trans_handle *trans; |
2383 | unsigned long nr = 0; | 2446 | unsigned long nr = 0; |
2384 | 2447 | ||
2385 | /* | ||
2386 | * the FIRST_FREE_OBJECTID check makes sure we don't try to rmdir | ||
2387 | * the root of a subvolume or snapshot | ||
2388 | */ | ||
2389 | if (inode->i_size > BTRFS_EMPTY_DIR_SIZE || | 2448 | if (inode->i_size > BTRFS_EMPTY_DIR_SIZE || |
2390 | inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | 2449 | inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
2391 | return -ENOTEMPTY; | 2450 | return -ENOTEMPTY; |
2392 | } | ||
2393 | 2451 | ||
2394 | trans = btrfs_start_transaction(root, 1); | 2452 | trans = btrfs_start_transaction(root, 1); |
2395 | btrfs_set_trans_block_group(trans, dir); | 2453 | btrfs_set_trans_block_group(trans, dir); |
2396 | 2454 | ||
2455 | if (unlikely(inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { | ||
2456 | err = btrfs_unlink_subvol(trans, root, dir, | ||
2457 | BTRFS_I(inode)->location.objectid, | ||
2458 | dentry->d_name.name, | ||
2459 | dentry->d_name.len); | ||
2460 | goto out; | ||
2461 | } | ||
2462 | |||
2397 | err = btrfs_orphan_add(trans, inode); | 2463 | err = btrfs_orphan_add(trans, inode); |
2398 | if (err) | 2464 | if (err) |
2399 | goto fail_trans; | 2465 | goto out; |
2400 | 2466 | ||
2401 | /* now the directory is empty */ | 2467 | /* now the directory is empty */ |
2402 | err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, | 2468 | err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, |
2403 | dentry->d_name.name, dentry->d_name.len); | 2469 | dentry->d_name.name, dentry->d_name.len); |
2404 | if (!err) | 2470 | if (!err) |
2405 | btrfs_i_size_write(inode, 0); | 2471 | btrfs_i_size_write(inode, 0); |
2406 | 2472 | out: | |
2407 | fail_trans: | ||
2408 | nr = trans->blocks_used; | 2473 | nr = trans->blocks_used; |
2409 | ret = btrfs_end_transaction_throttle(trans, root); | 2474 | ret = btrfs_end_transaction_throttle(trans, root); |
2410 | btrfs_btree_balance_dirty(root, nr); | 2475 | btrfs_btree_balance_dirty(root, nr); |
@@ -3091,29 +3156,67 @@ out_err: | |||
3091 | * is kind of like crossing a mount point. | 3156 | * is kind of like crossing a mount point. |
3092 | */ | 3157 | */ |
3093 | static int fixup_tree_root_location(struct btrfs_root *root, | 3158 | static int fixup_tree_root_location(struct btrfs_root *root, |
3094 | struct btrfs_key *location, | 3159 | struct inode *dir, |
3095 | struct btrfs_root **sub_root, | 3160 | struct dentry *dentry, |
3096 | struct dentry *dentry) | 3161 | struct btrfs_key *location, |
3162 | struct btrfs_root **sub_root) | ||
3097 | { | 3163 | { |
3098 | struct btrfs_root_item *ri; | 3164 | struct btrfs_path *path; |
3165 | struct btrfs_root *new_root; | ||
3166 | struct btrfs_root_ref *ref; | ||
3167 | struct extent_buffer *leaf; | ||
3168 | int ret; | ||
3169 | int err = 0; | ||
3099 | 3170 | ||
3100 | if (btrfs_key_type(location) != BTRFS_ROOT_ITEM_KEY) | 3171 | path = btrfs_alloc_path(); |
3101 | return 0; | 3172 | if (!path) { |
3102 | if (location->objectid == BTRFS_ROOT_TREE_OBJECTID) | 3173 | err = -ENOMEM; |
3103 | return 0; | 3174 | goto out; |
3175 | } | ||
3104 | 3176 | ||
3105 | *sub_root = btrfs_read_fs_root(root->fs_info, location, | 3177 | err = -ENOENT; |
3106 | dentry->d_name.name, | 3178 | ret = btrfs_find_root_ref(root->fs_info->tree_root, path, |
3107 | dentry->d_name.len); | 3179 | BTRFS_I(dir)->root->root_key.objectid, |
3108 | if (IS_ERR(*sub_root)) | 3180 | location->objectid); |
3109 | return PTR_ERR(*sub_root); | 3181 | if (ret) { |
3182 | if (ret < 0) | ||
3183 | err = ret; | ||
3184 | goto out; | ||
3185 | } | ||
3110 | 3186 | ||
3111 | ri = &(*sub_root)->root_item; | 3187 | leaf = path->nodes[0]; |
3112 | location->objectid = btrfs_root_dirid(ri); | 3188 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); |
3113 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | 3189 | if (btrfs_root_ref_dirid(leaf, ref) != dir->i_ino || |
3114 | location->offset = 0; | 3190 | btrfs_root_ref_name_len(leaf, ref) != dentry->d_name.len) |
3191 | goto out; | ||
3115 | 3192 | ||
3116 | return 0; | 3193 | ret = memcmp_extent_buffer(leaf, dentry->d_name.name, |
3194 | (unsigned long)(ref + 1), | ||
3195 | dentry->d_name.len); | ||
3196 | if (ret) | ||
3197 | goto out; | ||
3198 | |||
3199 | btrfs_release_path(root->fs_info->tree_root, path); | ||
3200 | |||
3201 | new_root = btrfs_read_fs_root_no_name(root->fs_info, location); | ||
3202 | if (IS_ERR(new_root)) { | ||
3203 | err = PTR_ERR(new_root); | ||
3204 | goto out; | ||
3205 | } | ||
3206 | |||
3207 | if (btrfs_root_refs(&new_root->root_item) == 0) { | ||
3208 | err = -ENOENT; | ||
3209 | goto out; | ||
3210 | } | ||
3211 | |||
3212 | *sub_root = new_root; | ||
3213 | location->objectid = btrfs_root_dirid(&new_root->root_item); | ||
3214 | location->type = BTRFS_INODE_ITEM_KEY; | ||
3215 | location->offset = 0; | ||
3216 | err = 0; | ||
3217 | out: | ||
3218 | btrfs_free_path(path); | ||
3219 | return err; | ||
3117 | } | 3220 | } |
3118 | 3221 | ||
3119 | static void inode_tree_add(struct inode *inode) | 3222 | static void inode_tree_add(struct inode *inode) |
@@ -3246,11 +3349,34 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
3246 | return inode; | 3349 | return inode; |
3247 | } | 3350 | } |
3248 | 3351 | ||
3352 | static struct inode *new_simple_dir(struct super_block *s, | ||
3353 | struct btrfs_key *key, | ||
3354 | struct btrfs_root *root) | ||
3355 | { | ||
3356 | struct inode *inode = new_inode(s); | ||
3357 | |||
3358 | if (!inode) | ||
3359 | return ERR_PTR(-ENOMEM); | ||
3360 | |||
3361 | init_btrfs_i(inode); | ||
3362 | |||
3363 | BTRFS_I(inode)->root = root; | ||
3364 | memcpy(&BTRFS_I(inode)->location, key, sizeof(*key)); | ||
3365 | BTRFS_I(inode)->dummy_inode = 1; | ||
3366 | |||
3367 | inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; | ||
3368 | inode->i_op = &simple_dir_inode_operations; | ||
3369 | inode->i_fop = &simple_dir_operations; | ||
3370 | inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; | ||
3371 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | ||
3372 | |||
3373 | return inode; | ||
3374 | } | ||
3375 | |||
3249 | struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | 3376 | struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) |
3250 | { | 3377 | { |
3251 | struct inode *inode; | 3378 | struct inode *inode; |
3252 | struct btrfs_inode *bi = BTRFS_I(dir); | 3379 | struct btrfs_root *root = BTRFS_I(dir)->root; |
3253 | struct btrfs_root *root = bi->root; | ||
3254 | struct btrfs_root *sub_root = root; | 3380 | struct btrfs_root *sub_root = root; |
3255 | struct btrfs_key location; | 3381 | struct btrfs_key location; |
3256 | int ret; | 3382 | int ret; |
@@ -3263,17 +3389,25 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
3263 | if (ret < 0) | 3389 | if (ret < 0) |
3264 | return ERR_PTR(ret); | 3390 | return ERR_PTR(ret); |
3265 | 3391 | ||
3266 | inode = NULL; | 3392 | if (location.objectid == 0) |
3267 | if (location.objectid) { | 3393 | return NULL; |
3268 | ret = fixup_tree_root_location(root, &location, &sub_root, | 3394 | |
3269 | dentry); | 3395 | if (location.type == BTRFS_INODE_ITEM_KEY) { |
3270 | if (ret < 0) | 3396 | inode = btrfs_iget(dir->i_sb, &location, root); |
3271 | return ERR_PTR(ret); | 3397 | return inode; |
3272 | if (ret > 0) | 3398 | } |
3273 | return ERR_PTR(-ENOENT); | 3399 | |
3400 | BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); | ||
3401 | |||
3402 | ret = fixup_tree_root_location(root, dir, dentry, | ||
3403 | &location, &sub_root); | ||
3404 | if (ret < 0) { | ||
3405 | if (ret != -ENOENT) | ||
3406 | inode = ERR_PTR(ret); | ||
3407 | else | ||
3408 | inode = new_simple_dir(dir->i_sb, &location, sub_root); | ||
3409 | } else { | ||
3274 | inode = btrfs_iget(dir->i_sb, &location, sub_root); | 3410 | inode = btrfs_iget(dir->i_sb, &location, sub_root); |
3275 | if (IS_ERR(inode)) | ||
3276 | return ERR_CAST(inode); | ||
3277 | } | 3411 | } |
3278 | return inode; | 3412 | return inode; |
3279 | } | 3413 | } |
@@ -3283,9 +3417,6 @@ static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | |||
3283 | { | 3417 | { |
3284 | struct inode *inode; | 3418 | struct inode *inode; |
3285 | 3419 | ||
3286 | if (dentry->d_name.len > BTRFS_NAME_LEN) | ||
3287 | return ERR_PTR(-ENAMETOOLONG); | ||
3288 | |||
3289 | inode = btrfs_lookup_dentry(dir, dentry); | 3420 | inode = btrfs_lookup_dentry(dir, dentry); |
3290 | if (IS_ERR(inode)) | 3421 | if (IS_ERR(inode)) |
3291 | return ERR_CAST(inode); | 3422 | return ERR_CAST(inode); |
@@ -3691,26 +3822,35 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
3691 | struct inode *parent_inode, struct inode *inode, | 3822 | struct inode *parent_inode, struct inode *inode, |
3692 | const char *name, int name_len, int add_backref, u64 index) | 3823 | const char *name, int name_len, int add_backref, u64 index) |
3693 | { | 3824 | { |
3694 | int ret; | 3825 | int ret = 0; |
3695 | struct btrfs_key key; | 3826 | struct btrfs_key key; |
3696 | struct btrfs_root *root = BTRFS_I(parent_inode)->root; | 3827 | struct btrfs_root *root = BTRFS_I(parent_inode)->root; |
3697 | 3828 | ||
3698 | key.objectid = inode->i_ino; | 3829 | if (unlikely(inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { |
3699 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 3830 | memcpy(&key, &BTRFS_I(inode)->root->root_key, sizeof(key)); |
3700 | key.offset = 0; | 3831 | } else { |
3832 | key.objectid = inode->i_ino; | ||
3833 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | ||
3834 | key.offset = 0; | ||
3835 | } | ||
3836 | |||
3837 | if (unlikely(inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { | ||
3838 | ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, | ||
3839 | key.objectid, root->root_key.objectid, | ||
3840 | parent_inode->i_ino, | ||
3841 | index, name, name_len); | ||
3842 | } else if (add_backref) { | ||
3843 | ret = btrfs_insert_inode_ref(trans, root, | ||
3844 | name, name_len, inode->i_ino, | ||
3845 | parent_inode->i_ino, index); | ||
3846 | } | ||
3701 | 3847 | ||
3702 | ret = btrfs_insert_dir_item(trans, root, name, name_len, | ||
3703 | parent_inode->i_ino, | ||
3704 | &key, btrfs_inode_type(inode), | ||
3705 | index); | ||
3706 | if (ret == 0) { | 3848 | if (ret == 0) { |
3707 | if (add_backref) { | 3849 | ret = btrfs_insert_dir_item(trans, root, name, name_len, |
3708 | ret = btrfs_insert_inode_ref(trans, root, | 3850 | parent_inode->i_ino, &key, |
3709 | name, name_len, | 3851 | btrfs_inode_type(inode), index); |
3710 | inode->i_ino, | 3852 | BUG_ON(ret); |
3711 | parent_inode->i_ino, | 3853 | |
3712 | index); | ||
3713 | } | ||
3714 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 3854 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
3715 | name_len * 2); | 3855 | name_len * 2); |
3716 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; | 3856 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; |
@@ -4800,31 +4940,29 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4800 | { | 4940 | { |
4801 | struct btrfs_trans_handle *trans; | 4941 | struct btrfs_trans_handle *trans; |
4802 | struct btrfs_root *root = BTRFS_I(old_dir)->root; | 4942 | struct btrfs_root *root = BTRFS_I(old_dir)->root; |
4943 | struct btrfs_root *dest = BTRFS_I(new_dir)->root; | ||
4803 | struct inode *new_inode = new_dentry->d_inode; | 4944 | struct inode *new_inode = new_dentry->d_inode; |
4804 | struct inode *old_inode = old_dentry->d_inode; | 4945 | struct inode *old_inode = old_dentry->d_inode; |
4805 | struct timespec ctime = CURRENT_TIME; | 4946 | struct timespec ctime = CURRENT_TIME; |
4806 | u64 index = 0; | 4947 | u64 index = 0; |
4948 | u64 root_objectid; | ||
4807 | int ret; | 4949 | int ret; |
4808 | 4950 | ||
4809 | /* we're not allowed to rename between subvolumes */ | 4951 | /* we only allow rename subvolume link between subvolumes */ |
4810 | if (BTRFS_I(old_inode)->root->root_key.objectid != | 4952 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest) |
4811 | BTRFS_I(new_dir)->root->root_key.objectid) | ||
4812 | return -EXDEV; | 4953 | return -EXDEV; |
4813 | 4954 | ||
4814 | if (S_ISDIR(old_inode->i_mode) && new_inode && | 4955 | if (old_inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID || |
4815 | new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) { | 4956 | (new_inode && new_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) |
4816 | return -ENOTEMPTY; | 4957 | return -ENOTEMPTY; |
4817 | } | ||
4818 | 4958 | ||
4819 | /* to rename a snapshot or subvolume, we need to juggle the | 4959 | if (S_ISDIR(old_inode->i_mode) && new_inode && |
4820 | * backrefs. This isn't coded yet | 4960 | new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) |
4821 | */ | 4961 | return -ENOTEMPTY; |
4822 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
4823 | return -EXDEV; | ||
4824 | 4962 | ||
4825 | ret = btrfs_check_metadata_free_space(root); | 4963 | ret = btrfs_check_metadata_free_space(root); |
4826 | if (ret) | 4964 | if (ret) |
4827 | goto out_unlock; | 4965 | return ret; |
4828 | 4966 | ||
4829 | /* | 4967 | /* |
4830 | * we're using rename to replace one file with another. | 4968 | * we're using rename to replace one file with another. |
@@ -4837,6 +4975,9 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4837 | 4975 | ||
4838 | trans = btrfs_start_transaction(root, 1); | 4976 | trans = btrfs_start_transaction(root, 1); |
4839 | 4977 | ||
4978 | if (dest != root) | ||
4979 | btrfs_record_root_in_trans(trans, dest); | ||
4980 | |||
4840 | /* | 4981 | /* |
4841 | * make sure the inode gets flushed if it is replacing | 4982 | * make sure the inode gets flushed if it is replacing |
4842 | * something. | 4983 | * something. |
@@ -4846,18 +4987,22 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4846 | btrfs_add_ordered_operation(trans, root, old_inode); | 4987 | btrfs_add_ordered_operation(trans, root, old_inode); |
4847 | } | 4988 | } |
4848 | 4989 | ||
4849 | /* | 4990 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { |
4850 | * this is an ugly little race, but the rename is required to make | 4991 | /* force full log commit if subvolume involved. */ |
4851 | * sure that if we crash, the inode is either at the old name | 4992 | root->fs_info->last_trans_log_full_commit = trans->transid; |
4852 | * or the new one. pinning the log transaction lets us make sure | 4993 | } else { |
4853 | * we don't allow a log commit to come in after we unlink the | 4994 | /* |
4854 | * name but before we add the new name back in. | 4995 | * this is an ugly little race, but the rename is required |
4855 | */ | 4996 | * to make sure that if we crash, the inode is either at the |
4856 | btrfs_pin_log_trans(root); | 4997 | * old name or the new one. pinning the log transaction lets |
4998 | * us make sure we don't allow a log commit to come in after | ||
4999 | * we unlink the name but before we add the new name back in. | ||
5000 | */ | ||
5001 | btrfs_pin_log_trans(root); | ||
5002 | } | ||
4857 | 5003 | ||
4858 | btrfs_set_trans_block_group(trans, new_dir); | 5004 | btrfs_set_trans_block_group(trans, new_dir); |
4859 | 5005 | ||
4860 | btrfs_inc_nlink(old_dentry->d_inode); | ||
4861 | old_dir->i_ctime = old_dir->i_mtime = ctime; | 5006 | old_dir->i_ctime = old_dir->i_mtime = ctime; |
4862 | new_dir->i_ctime = new_dir->i_mtime = ctime; | 5007 | new_dir->i_ctime = new_dir->i_mtime = ctime; |
4863 | old_inode->i_ctime = ctime; | 5008 | old_inode->i_ctime = ctime; |
@@ -4865,47 +5010,58 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4865 | if (old_dentry->d_parent != new_dentry->d_parent) | 5010 | if (old_dentry->d_parent != new_dentry->d_parent) |
4866 | btrfs_record_unlink_dir(trans, old_dir, old_inode, 1); | 5011 | btrfs_record_unlink_dir(trans, old_dir, old_inode, 1); |
4867 | 5012 | ||
4868 | ret = btrfs_unlink_inode(trans, root, old_dir, old_dentry->d_inode, | 5013 | if (unlikely(old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { |
4869 | old_dentry->d_name.name, | 5014 | root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; |
4870 | old_dentry->d_name.len); | 5015 | ret = btrfs_unlink_subvol(trans, root, old_dir, root_objectid, |
4871 | if (ret) | 5016 | old_dentry->d_name.name, |
4872 | goto out_fail; | 5017 | old_dentry->d_name.len); |
5018 | } else { | ||
5019 | btrfs_inc_nlink(old_dentry->d_inode); | ||
5020 | ret = btrfs_unlink_inode(trans, root, old_dir, | ||
5021 | old_dentry->d_inode, | ||
5022 | old_dentry->d_name.name, | ||
5023 | old_dentry->d_name.len); | ||
5024 | } | ||
5025 | BUG_ON(ret); | ||
4873 | 5026 | ||
4874 | if (new_inode) { | 5027 | if (new_inode) { |
4875 | new_inode->i_ctime = CURRENT_TIME; | 5028 | new_inode->i_ctime = CURRENT_TIME; |
4876 | ret = btrfs_unlink_inode(trans, root, new_dir, | 5029 | if (unlikely(new_inode->i_ino == |
4877 | new_dentry->d_inode, | 5030 | BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { |
4878 | new_dentry->d_name.name, | 5031 | root_objectid = BTRFS_I(new_inode)->location.objectid; |
4879 | new_dentry->d_name.len); | 5032 | ret = btrfs_unlink_subvol(trans, dest, new_dir, |
4880 | if (ret) | 5033 | root_objectid, |
4881 | goto out_fail; | 5034 | new_dentry->d_name.name, |
5035 | new_dentry->d_name.len); | ||
5036 | BUG_ON(new_inode->i_nlink == 0); | ||
5037 | } else { | ||
5038 | ret = btrfs_unlink_inode(trans, dest, new_dir, | ||
5039 | new_dentry->d_inode, | ||
5040 | new_dentry->d_name.name, | ||
5041 | new_dentry->d_name.len); | ||
5042 | } | ||
5043 | BUG_ON(ret); | ||
4882 | if (new_inode->i_nlink == 0) { | 5044 | if (new_inode->i_nlink == 0) { |
4883 | ret = btrfs_orphan_add(trans, new_dentry->d_inode); | 5045 | ret = btrfs_orphan_add(trans, new_dentry->d_inode); |
4884 | if (ret) | 5046 | BUG_ON(ret); |
4885 | goto out_fail; | ||
4886 | } | 5047 | } |
4887 | |||
4888 | } | 5048 | } |
4889 | ret = btrfs_set_inode_index(new_dir, &index); | 5049 | ret = btrfs_set_inode_index(new_dir, &index); |
4890 | if (ret) | 5050 | BUG_ON(ret); |
4891 | goto out_fail; | ||
4892 | 5051 | ||
4893 | ret = btrfs_add_link(trans, new_dentry->d_parent->d_inode, | 5052 | ret = btrfs_add_link(trans, new_dir, old_inode, |
4894 | old_inode, new_dentry->d_name.name, | 5053 | new_dentry->d_name.name, |
4895 | new_dentry->d_name.len, 1, index); | 5054 | new_dentry->d_name.len, 1, index); |
4896 | if (ret) | 5055 | BUG_ON(ret); |
4897 | goto out_fail; | ||
4898 | 5056 | ||
4899 | btrfs_log_new_name(trans, old_inode, old_dir, | 5057 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { |
4900 | new_dentry->d_parent); | 5058 | btrfs_log_new_name(trans, old_inode, old_dir, |
4901 | out_fail: | 5059 | new_dentry->d_parent); |
5060 | btrfs_end_log_trans(root); | ||
5061 | } | ||
4902 | 5062 | ||
4903 | /* this btrfs_end_log_trans just allows the current | ||
4904 | * log-sub transaction to complete | ||
4905 | */ | ||
4906 | btrfs_end_log_trans(root); | ||
4907 | btrfs_end_transaction_throttle(trans, root); | 5063 | btrfs_end_transaction_throttle(trans, root); |
4908 | out_unlock: | 5064 | |
4909 | return ret; | 5065 | return ret; |
4910 | } | 5066 | } |
4911 | 5067 | ||