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 | ||
