diff options
author | Chris Mason <clm@fb.com> | 2016-08-05 15:25:05 -0400 |
---|---|---|
committer | Chris Mason <clm@fb.com> | 2016-08-05 15:25:05 -0400 |
commit | 10838816547a28696ca10e038b3b32f2efec5a42 (patch) | |
tree | c8abb5cb6139473ea58859f2093a37d8328ee7bb | |
parent | 42049bf60db4c01e0432fc861463dcd3208c0d93 (diff) | |
parent | e6571499336e10f93a77c51a35fd1a96828eea71 (diff) |
Merge branch 'integration-4.8' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.8
-rw-r--r-- | fs/btrfs/delayed-ref.c | 27 | ||||
-rw-r--r-- | fs/btrfs/delayed-ref.h | 3 | ||||
-rw-r--r-- | fs/btrfs/file.c | 8 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 46 | ||||
-rw-r--r-- | fs/btrfs/send.c | 173 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 85 |
6 files changed, 283 insertions, 59 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index b6d210e7a993..d9ddcfc18c91 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -862,33 +862,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
862 | return 0; | 862 | return 0; |
863 | } | 863 | } |
864 | 864 | ||
865 | int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info, | ||
866 | struct btrfs_trans_handle *trans, | ||
867 | u64 ref_root, u64 bytenr, u64 num_bytes) | ||
868 | { | ||
869 | struct btrfs_delayed_ref_root *delayed_refs; | ||
870 | struct btrfs_delayed_ref_head *ref_head; | ||
871 | int ret = 0; | ||
872 | |||
873 | if (!fs_info->quota_enabled || !is_fstree(ref_root)) | ||
874 | return 0; | ||
875 | |||
876 | delayed_refs = &trans->transaction->delayed_refs; | ||
877 | |||
878 | spin_lock(&delayed_refs->lock); | ||
879 | ref_head = find_ref_head(&delayed_refs->href_root, bytenr, 0); | ||
880 | if (!ref_head) { | ||
881 | ret = -ENOENT; | ||
882 | goto out; | ||
883 | } | ||
884 | WARN_ON(ref_head->qgroup_reserved || ref_head->qgroup_ref_root); | ||
885 | ref_head->qgroup_ref_root = ref_root; | ||
886 | ref_head->qgroup_reserved = num_bytes; | ||
887 | out: | ||
888 | spin_unlock(&delayed_refs->lock); | ||
889 | return ret; | ||
890 | } | ||
891 | |||
892 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | 865 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, |
893 | struct btrfs_trans_handle *trans, | 866 | struct btrfs_trans_handle *trans, |
894 | u64 bytenr, u64 num_bytes, | 867 | u64 bytenr, u64 num_bytes, |
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index 5fca9534a271..43f3629760e9 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h | |||
@@ -250,9 +250,6 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | |||
250 | u64 parent, u64 ref_root, | 250 | u64 parent, u64 ref_root, |
251 | u64 owner, u64 offset, u64 reserved, int action, | 251 | u64 owner, u64 offset, u64 reserved, int action, |
252 | struct btrfs_delayed_extent_op *extent_op); | 252 | struct btrfs_delayed_extent_op *extent_op); |
253 | int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info, | ||
254 | struct btrfs_trans_handle *trans, | ||
255 | u64 ref_root, u64 bytenr, u64 num_bytes); | ||
256 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | 253 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, |
257 | struct btrfs_trans_handle *trans, | 254 | struct btrfs_trans_handle *trans, |
258 | u64 bytenr, u64 num_bytes, | 255 | u64 bytenr, u64 num_bytes, |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 9404121fd5f7..5842423f8f47 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2033,6 +2033,14 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) | |||
2033 | */ | 2033 | */ |
2034 | clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC, | 2034 | clear_bit(BTRFS_INODE_NEEDS_FULL_SYNC, |
2035 | &BTRFS_I(inode)->runtime_flags); | 2035 | &BTRFS_I(inode)->runtime_flags); |
2036 | /* | ||
2037 | * An ordered extent might have started before and completed | ||
2038 | * already with io errors, in which case the inode was not | ||
2039 | * updated and we end up here. So check the inode's mapping | ||
2040 | * flags for any errors that might have happened while doing | ||
2041 | * writeback of file data. | ||
2042 | */ | ||
2043 | ret = btrfs_inode_check_errors(inode); | ||
2036 | inode_unlock(inode); | 2044 | inode_unlock(inode); |
2037 | goto out; | 2045 | goto out; |
2038 | } | 2046 | } |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 72cfd15b1fa8..29636624a427 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3436,10 +3436,10 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
3436 | found_key.offset = 0; | 3436 | found_key.offset = 0; |
3437 | inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); | 3437 | inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); |
3438 | ret = PTR_ERR_OR_ZERO(inode); | 3438 | ret = PTR_ERR_OR_ZERO(inode); |
3439 | if (ret && ret != -ESTALE) | 3439 | if (ret && ret != -ENOENT) |
3440 | goto out; | 3440 | goto out; |
3441 | 3441 | ||
3442 | if (ret == -ESTALE && root == root->fs_info->tree_root) { | 3442 | if (ret == -ENOENT && root == root->fs_info->tree_root) { |
3443 | struct btrfs_root *dead_root; | 3443 | struct btrfs_root *dead_root; |
3444 | struct btrfs_fs_info *fs_info = root->fs_info; | 3444 | struct btrfs_fs_info *fs_info = root->fs_info; |
3445 | int is_dead_root = 0; | 3445 | int is_dead_root = 0; |
@@ -3475,7 +3475,7 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
3475 | * Inode is already gone but the orphan item is still there, | 3475 | * Inode is already gone but the orphan item is still there, |
3476 | * kill the orphan item. | 3476 | * kill the orphan item. |
3477 | */ | 3477 | */ |
3478 | if (ret == -ESTALE) { | 3478 | if (ret == -ENOENT) { |
3479 | trans = btrfs_start_transaction(root, 1); | 3479 | trans = btrfs_start_transaction(root, 1); |
3480 | if (IS_ERR(trans)) { | 3480 | if (IS_ERR(trans)) { |
3481 | ret = PTR_ERR(trans); | 3481 | ret = PTR_ERR(trans); |
@@ -3634,7 +3634,7 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf, | |||
3634 | /* | 3634 | /* |
3635 | * read an inode from the btree into the in-memory inode | 3635 | * read an inode from the btree into the in-memory inode |
3636 | */ | 3636 | */ |
3637 | static void btrfs_read_locked_inode(struct inode *inode) | 3637 | static int btrfs_read_locked_inode(struct inode *inode) |
3638 | { | 3638 | { |
3639 | struct btrfs_path *path; | 3639 | struct btrfs_path *path; |
3640 | struct extent_buffer *leaf; | 3640 | struct extent_buffer *leaf; |
@@ -3653,14 +3653,19 @@ static void btrfs_read_locked_inode(struct inode *inode) | |||
3653 | filled = true; | 3653 | filled = true; |
3654 | 3654 | ||
3655 | path = btrfs_alloc_path(); | 3655 | path = btrfs_alloc_path(); |
3656 | if (!path) | 3656 | if (!path) { |
3657 | ret = -ENOMEM; | ||
3657 | goto make_bad; | 3658 | goto make_bad; |
3659 | } | ||
3658 | 3660 | ||
3659 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); | 3661 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); |
3660 | 3662 | ||
3661 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); | 3663 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); |
3662 | if (ret) | 3664 | if (ret) { |
3665 | if (ret > 0) | ||
3666 | ret = -ENOENT; | ||
3663 | goto make_bad; | 3667 | goto make_bad; |
3668 | } | ||
3664 | 3669 | ||
3665 | leaf = path->nodes[0]; | 3670 | leaf = path->nodes[0]; |
3666 | 3671 | ||
@@ -3813,11 +3818,12 @@ cache_acl: | |||
3813 | } | 3818 | } |
3814 | 3819 | ||
3815 | btrfs_update_iflags(inode); | 3820 | btrfs_update_iflags(inode); |
3816 | return; | 3821 | return 0; |
3817 | 3822 | ||
3818 | make_bad: | 3823 | make_bad: |
3819 | btrfs_free_path(path); | 3824 | btrfs_free_path(path); |
3820 | make_bad_inode(inode); | 3825 | make_bad_inode(inode); |
3826 | return ret; | ||
3821 | } | 3827 | } |
3822 | 3828 | ||
3823 | /* | 3829 | /* |
@@ -4205,6 +4211,7 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
4205 | int err = 0; | 4211 | int err = 0; |
4206 | struct btrfs_root *root = BTRFS_I(dir)->root; | 4212 | struct btrfs_root *root = BTRFS_I(dir)->root; |
4207 | struct btrfs_trans_handle *trans; | 4213 | struct btrfs_trans_handle *trans; |
4214 | u64 last_unlink_trans; | ||
4208 | 4215 | ||
4209 | if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) | 4216 | if (inode->i_size > BTRFS_EMPTY_DIR_SIZE) |
4210 | return -ENOTEMPTY; | 4217 | return -ENOTEMPTY; |
@@ -4227,11 +4234,27 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
4227 | if (err) | 4234 | if (err) |
4228 | goto out; | 4235 | goto out; |
4229 | 4236 | ||
4237 | last_unlink_trans = BTRFS_I(inode)->last_unlink_trans; | ||
4238 | |||
4230 | /* now the directory is empty */ | 4239 | /* now the directory is empty */ |
4231 | err = btrfs_unlink_inode(trans, root, dir, d_inode(dentry), | 4240 | err = btrfs_unlink_inode(trans, root, dir, d_inode(dentry), |
4232 | dentry->d_name.name, dentry->d_name.len); | 4241 | dentry->d_name.name, dentry->d_name.len); |
4233 | if (!err) | 4242 | if (!err) { |
4234 | btrfs_i_size_write(inode, 0); | 4243 | btrfs_i_size_write(inode, 0); |
4244 | /* | ||
4245 | * Propagate the last_unlink_trans value of the deleted dir to | ||
4246 | * its parent directory. This is to prevent an unrecoverable | ||
4247 | * log tree in the case we do something like this: | ||
4248 | * 1) create dir foo | ||
4249 | * 2) create snapshot under dir foo | ||
4250 | * 3) delete the snapshot | ||
4251 | * 4) rmdir foo | ||
4252 | * 5) mkdir foo | ||
4253 | * 6) fsync foo or some file inside foo | ||
4254 | */ | ||
4255 | if (last_unlink_trans >= trans->transid) | ||
4256 | BTRFS_I(dir)->last_unlink_trans = last_unlink_trans; | ||
4257 | } | ||
4235 | out: | 4258 | out: |
4236 | btrfs_end_transaction(trans, root); | 4259 | btrfs_end_transaction(trans, root); |
4237 | btrfs_btree_balance_dirty(root); | 4260 | btrfs_btree_balance_dirty(root); |
@@ -5607,7 +5630,9 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
5607 | return ERR_PTR(-ENOMEM); | 5630 | return ERR_PTR(-ENOMEM); |
5608 | 5631 | ||
5609 | if (inode->i_state & I_NEW) { | 5632 | if (inode->i_state & I_NEW) { |
5610 | btrfs_read_locked_inode(inode); | 5633 | int ret; |
5634 | |||
5635 | ret = btrfs_read_locked_inode(inode); | ||
5611 | if (!is_bad_inode(inode)) { | 5636 | if (!is_bad_inode(inode)) { |
5612 | inode_tree_add(inode); | 5637 | inode_tree_add(inode); |
5613 | unlock_new_inode(inode); | 5638 | unlock_new_inode(inode); |
@@ -5616,7 +5641,8 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
5616 | } else { | 5641 | } else { |
5617 | unlock_new_inode(inode); | 5642 | unlock_new_inode(inode); |
5618 | iput(inode); | 5643 | iput(inode); |
5619 | inode = ERR_PTR(-ESTALE); | 5644 | ASSERT(ret < 0); |
5645 | inode = ERR_PTR(ret < 0 ? ret : -ESTALE); | ||
5620 | } | 5646 | } |
5621 | } | 5647 | } |
5622 | 5648 | ||
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index b71dd298385c..efe129fe2678 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -231,7 +231,6 @@ struct pending_dir_move { | |||
231 | u64 parent_ino; | 231 | u64 parent_ino; |
232 | u64 ino; | 232 | u64 ino; |
233 | u64 gen; | 233 | u64 gen; |
234 | bool is_orphan; | ||
235 | struct list_head update_refs; | 234 | struct list_head update_refs; |
236 | }; | 235 | }; |
237 | 236 | ||
@@ -274,6 +273,39 @@ struct name_cache_entry { | |||
274 | char name[]; | 273 | char name[]; |
275 | }; | 274 | }; |
276 | 275 | ||
276 | static void inconsistent_snapshot_error(struct send_ctx *sctx, | ||
277 | enum btrfs_compare_tree_result result, | ||
278 | const char *what) | ||
279 | { | ||
280 | const char *result_string; | ||
281 | |||
282 | switch (result) { | ||
283 | case BTRFS_COMPARE_TREE_NEW: | ||
284 | result_string = "new"; | ||
285 | break; | ||
286 | case BTRFS_COMPARE_TREE_DELETED: | ||
287 | result_string = "deleted"; | ||
288 | break; | ||
289 | case BTRFS_COMPARE_TREE_CHANGED: | ||
290 | result_string = "updated"; | ||
291 | break; | ||
292 | case BTRFS_COMPARE_TREE_SAME: | ||
293 | ASSERT(0); | ||
294 | result_string = "unchanged"; | ||
295 | break; | ||
296 | default: | ||
297 | ASSERT(0); | ||
298 | result_string = "unexpected"; | ||
299 | } | ||
300 | |||
301 | btrfs_err(sctx->send_root->fs_info, | ||
302 | "Send: inconsistent snapshot, found %s %s for inode %llu without updated inode item, send root is %llu, parent root is %llu", | ||
303 | result_string, what, sctx->cmp_key->objectid, | ||
304 | sctx->send_root->root_key.objectid, | ||
305 | (sctx->parent_root ? | ||
306 | sctx->parent_root->root_key.objectid : 0)); | ||
307 | } | ||
308 | |||
277 | static int is_waiting_for_move(struct send_ctx *sctx, u64 ino); | 309 | static int is_waiting_for_move(struct send_ctx *sctx, u64 ino); |
278 | 310 | ||
279 | static struct waiting_dir_move * | 311 | static struct waiting_dir_move * |
@@ -1861,7 +1893,8 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, | |||
1861 | * was already unlinked/moved, so we can safely assume that we will not | 1893 | * was already unlinked/moved, so we can safely assume that we will not |
1862 | * overwrite anything at this point in time. | 1894 | * overwrite anything at this point in time. |
1863 | */ | 1895 | */ |
1864 | if (other_inode > sctx->send_progress) { | 1896 | if (other_inode > sctx->send_progress || |
1897 | is_waiting_for_move(sctx, other_inode)) { | ||
1865 | ret = get_inode_info(sctx->parent_root, other_inode, NULL, | 1898 | ret = get_inode_info(sctx->parent_root, other_inode, NULL, |
1866 | who_gen, NULL, NULL, NULL, NULL); | 1899 | who_gen, NULL, NULL, NULL, NULL); |
1867 | if (ret < 0) | 1900 | if (ret < 0) |
@@ -2502,6 +2535,8 @@ verbose_printk("btrfs: send_utimes %llu\n", ino); | |||
2502 | key.type = BTRFS_INODE_ITEM_KEY; | 2535 | key.type = BTRFS_INODE_ITEM_KEY; |
2503 | key.offset = 0; | 2536 | key.offset = 0; |
2504 | ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); | 2537 | ret = btrfs_search_slot(NULL, sctx->send_root, &key, path, 0, 0); |
2538 | if (ret > 0) | ||
2539 | ret = -ENOENT; | ||
2505 | if (ret < 0) | 2540 | if (ret < 0) |
2506 | goto out; | 2541 | goto out; |
2507 | 2542 | ||
@@ -2947,6 +2982,10 @@ static int can_rmdir(struct send_ctx *sctx, u64 dir, u64 dir_gen, | |||
2947 | } | 2982 | } |
2948 | 2983 | ||
2949 | if (loc.objectid > send_progress) { | 2984 | if (loc.objectid > send_progress) { |
2985 | struct orphan_dir_info *odi; | ||
2986 | |||
2987 | odi = get_orphan_dir_info(sctx, dir); | ||
2988 | free_orphan_dir_info(sctx, odi); | ||
2950 | ret = 0; | 2989 | ret = 0; |
2951 | goto out; | 2990 | goto out; |
2952 | } | 2991 | } |
@@ -3047,7 +3086,6 @@ static int add_pending_dir_move(struct send_ctx *sctx, | |||
3047 | pm->parent_ino = parent_ino; | 3086 | pm->parent_ino = parent_ino; |
3048 | pm->ino = ino; | 3087 | pm->ino = ino; |
3049 | pm->gen = ino_gen; | 3088 | pm->gen = ino_gen; |
3050 | pm->is_orphan = is_orphan; | ||
3051 | INIT_LIST_HEAD(&pm->list); | 3089 | INIT_LIST_HEAD(&pm->list); |
3052 | INIT_LIST_HEAD(&pm->update_refs); | 3090 | INIT_LIST_HEAD(&pm->update_refs); |
3053 | RB_CLEAR_NODE(&pm->node); | 3091 | RB_CLEAR_NODE(&pm->node); |
@@ -3113,6 +3151,48 @@ static struct pending_dir_move *get_pending_dir_moves(struct send_ctx *sctx, | |||
3113 | return NULL; | 3151 | return NULL; |
3114 | } | 3152 | } |
3115 | 3153 | ||
3154 | static int path_loop(struct send_ctx *sctx, struct fs_path *name, | ||
3155 | u64 ino, u64 gen, u64 *ancestor_ino) | ||
3156 | { | ||
3157 | int ret = 0; | ||
3158 | u64 parent_inode = 0; | ||
3159 | u64 parent_gen = 0; | ||
3160 | u64 start_ino = ino; | ||
3161 | |||
3162 | *ancestor_ino = 0; | ||
3163 | while (ino != BTRFS_FIRST_FREE_OBJECTID) { | ||
3164 | fs_path_reset(name); | ||
3165 | |||
3166 | if (is_waiting_for_rm(sctx, ino)) | ||
3167 | break; | ||
3168 | if (is_waiting_for_move(sctx, ino)) { | ||
3169 | if (*ancestor_ino == 0) | ||
3170 | *ancestor_ino = ino; | ||
3171 | ret = get_first_ref(sctx->parent_root, ino, | ||
3172 | &parent_inode, &parent_gen, name); | ||
3173 | } else { | ||
3174 | ret = __get_cur_name_and_parent(sctx, ino, gen, | ||
3175 | &parent_inode, | ||
3176 | &parent_gen, name); | ||
3177 | if (ret > 0) { | ||
3178 | ret = 0; | ||
3179 | break; | ||
3180 | } | ||
3181 | } | ||
3182 | if (ret < 0) | ||
3183 | break; | ||
3184 | if (parent_inode == start_ino) { | ||
3185 | ret = 1; | ||
3186 | if (*ancestor_ino == 0) | ||
3187 | *ancestor_ino = ino; | ||
3188 | break; | ||
3189 | } | ||
3190 | ino = parent_inode; | ||
3191 | gen = parent_gen; | ||
3192 | } | ||
3193 | return ret; | ||
3194 | } | ||
3195 | |||
3116 | static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | 3196 | static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) |
3117 | { | 3197 | { |
3118 | struct fs_path *from_path = NULL; | 3198 | struct fs_path *from_path = NULL; |
@@ -3123,6 +3203,8 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | |||
3123 | u64 parent_ino, parent_gen; | 3203 | u64 parent_ino, parent_gen; |
3124 | struct waiting_dir_move *dm = NULL; | 3204 | struct waiting_dir_move *dm = NULL; |
3125 | u64 rmdir_ino = 0; | 3205 | u64 rmdir_ino = 0; |
3206 | u64 ancestor; | ||
3207 | bool is_orphan; | ||
3126 | int ret; | 3208 | int ret; |
3127 | 3209 | ||
3128 | name = fs_path_alloc(); | 3210 | name = fs_path_alloc(); |
@@ -3135,9 +3217,10 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | |||
3135 | dm = get_waiting_dir_move(sctx, pm->ino); | 3217 | dm = get_waiting_dir_move(sctx, pm->ino); |
3136 | ASSERT(dm); | 3218 | ASSERT(dm); |
3137 | rmdir_ino = dm->rmdir_ino; | 3219 | rmdir_ino = dm->rmdir_ino; |
3220 | is_orphan = dm->orphanized; | ||
3138 | free_waiting_dir_move(sctx, dm); | 3221 | free_waiting_dir_move(sctx, dm); |
3139 | 3222 | ||
3140 | if (pm->is_orphan) { | 3223 | if (is_orphan) { |
3141 | ret = gen_unique_name(sctx, pm->ino, | 3224 | ret = gen_unique_name(sctx, pm->ino, |
3142 | pm->gen, from_path); | 3225 | pm->gen, from_path); |
3143 | } else { | 3226 | } else { |
@@ -3155,6 +3238,24 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | |||
3155 | goto out; | 3238 | goto out; |
3156 | 3239 | ||
3157 | sctx->send_progress = sctx->cur_ino + 1; | 3240 | sctx->send_progress = sctx->cur_ino + 1; |
3241 | ret = path_loop(sctx, name, pm->ino, pm->gen, &ancestor); | ||
3242 | if (ret < 0) | ||
3243 | goto out; | ||
3244 | if (ret) { | ||
3245 | LIST_HEAD(deleted_refs); | ||
3246 | ASSERT(ancestor > BTRFS_FIRST_FREE_OBJECTID); | ||
3247 | ret = add_pending_dir_move(sctx, pm->ino, pm->gen, ancestor, | ||
3248 | &pm->update_refs, &deleted_refs, | ||
3249 | is_orphan); | ||
3250 | if (ret < 0) | ||
3251 | goto out; | ||
3252 | if (rmdir_ino) { | ||
3253 | dm = get_waiting_dir_move(sctx, pm->ino); | ||
3254 | ASSERT(dm); | ||
3255 | dm->rmdir_ino = rmdir_ino; | ||
3256 | } | ||
3257 | goto out; | ||
3258 | } | ||
3158 | fs_path_reset(name); | 3259 | fs_path_reset(name); |
3159 | to_path = name; | 3260 | to_path = name; |
3160 | name = NULL; | 3261 | name = NULL; |
@@ -3174,7 +3275,7 @@ static int apply_dir_move(struct send_ctx *sctx, struct pending_dir_move *pm) | |||
3174 | /* already deleted */ | 3275 | /* already deleted */ |
3175 | goto finish; | 3276 | goto finish; |
3176 | } | 3277 | } |
3177 | ret = can_rmdir(sctx, rmdir_ino, odi->gen, sctx->cur_ino + 1); | 3278 | ret = can_rmdir(sctx, rmdir_ino, odi->gen, sctx->cur_ino); |
3178 | if (ret < 0) | 3279 | if (ret < 0) |
3179 | goto out; | 3280 | goto out; |
3180 | if (!ret) | 3281 | if (!ret) |
@@ -3204,8 +3305,18 @@ finish: | |||
3204 | * and old parent(s). | 3305 | * and old parent(s). |
3205 | */ | 3306 | */ |
3206 | list_for_each_entry(cur, &pm->update_refs, list) { | 3307 | list_for_each_entry(cur, &pm->update_refs, list) { |
3207 | if (cur->dir == rmdir_ino) | 3308 | /* |
3309 | * The parent inode might have been deleted in the send snapshot | ||
3310 | */ | ||
3311 | ret = get_inode_info(sctx->send_root, cur->dir, NULL, | ||
3312 | NULL, NULL, NULL, NULL, NULL); | ||
3313 | if (ret == -ENOENT) { | ||
3314 | ret = 0; | ||
3208 | continue; | 3315 | continue; |
3316 | } | ||
3317 | if (ret < 0) | ||
3318 | goto out; | ||
3319 | |||
3209 | ret = send_utimes(sctx, cur->dir, cur->dir_gen); | 3320 | ret = send_utimes(sctx, cur->dir, cur->dir_gen); |
3210 | if (ret < 0) | 3321 | if (ret < 0) |
3211 | goto out; | 3322 | goto out; |
@@ -3325,6 +3436,7 @@ static int wait_for_dest_dir_move(struct send_ctx *sctx, | |||
3325 | u64 left_gen; | 3436 | u64 left_gen; |
3326 | u64 right_gen; | 3437 | u64 right_gen; |
3327 | int ret = 0; | 3438 | int ret = 0; |
3439 | struct waiting_dir_move *wdm; | ||
3328 | 3440 | ||
3329 | if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) | 3441 | if (RB_EMPTY_ROOT(&sctx->waiting_dir_moves)) |
3330 | return 0; | 3442 | return 0; |
@@ -3383,7 +3495,8 @@ static int wait_for_dest_dir_move(struct send_ctx *sctx, | |||
3383 | goto out; | 3495 | goto out; |
3384 | } | 3496 | } |
3385 | 3497 | ||
3386 | if (is_waiting_for_move(sctx, di_key.objectid)) { | 3498 | wdm = get_waiting_dir_move(sctx, di_key.objectid); |
3499 | if (wdm && !wdm->orphanized) { | ||
3387 | ret = add_pending_dir_move(sctx, | 3500 | ret = add_pending_dir_move(sctx, |
3388 | sctx->cur_ino, | 3501 | sctx->cur_ino, |
3389 | sctx->cur_inode_gen, | 3502 | sctx->cur_inode_gen, |
@@ -3470,7 +3583,8 @@ static int wait_for_parent_move(struct send_ctx *sctx, | |||
3470 | ret = is_ancestor(sctx->parent_root, | 3583 | ret = is_ancestor(sctx->parent_root, |
3471 | sctx->cur_ino, sctx->cur_inode_gen, | 3584 | sctx->cur_ino, sctx->cur_inode_gen, |
3472 | ino, path_before); | 3585 | ino, path_before); |
3473 | break; | 3586 | if (ret) |
3587 | break; | ||
3474 | } | 3588 | } |
3475 | 3589 | ||
3476 | fs_path_reset(path_before); | 3590 | fs_path_reset(path_before); |
@@ -3643,11 +3757,26 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
3643 | goto out; | 3757 | goto out; |
3644 | if (ret) { | 3758 | if (ret) { |
3645 | struct name_cache_entry *nce; | 3759 | struct name_cache_entry *nce; |
3760 | struct waiting_dir_move *wdm; | ||
3646 | 3761 | ||
3647 | ret = orphanize_inode(sctx, ow_inode, ow_gen, | 3762 | ret = orphanize_inode(sctx, ow_inode, ow_gen, |
3648 | cur->full_path); | 3763 | cur->full_path); |
3649 | if (ret < 0) | 3764 | if (ret < 0) |
3650 | goto out; | 3765 | goto out; |
3766 | |||
3767 | /* | ||
3768 | * If ow_inode has its rename operation delayed | ||
3769 | * make sure that its orphanized name is used in | ||
3770 | * the source path when performing its rename | ||
3771 | * operation. | ||
3772 | */ | ||
3773 | if (is_waiting_for_move(sctx, ow_inode)) { | ||
3774 | wdm = get_waiting_dir_move(sctx, | ||
3775 | ow_inode); | ||
3776 | ASSERT(wdm); | ||
3777 | wdm->orphanized = true; | ||
3778 | } | ||
3779 | |||
3651 | /* | 3780 | /* |
3652 | * Make sure we clear our orphanized inode's | 3781 | * Make sure we clear our orphanized inode's |
3653 | * name from the name cache. This is because the | 3782 | * name from the name cache. This is because the |
@@ -3663,6 +3792,19 @@ verbose_printk("btrfs: process_recorded_refs %llu\n", sctx->cur_ino); | |||
3663 | name_cache_delete(sctx, nce); | 3792 | name_cache_delete(sctx, nce); |
3664 | kfree(nce); | 3793 | kfree(nce); |
3665 | } | 3794 | } |
3795 | |||
3796 | /* | ||
3797 | * ow_inode might currently be an ancestor of | ||
3798 | * cur_ino, therefore compute valid_path (the | ||
3799 | * current path of cur_ino) again because it | ||
3800 | * might contain the pre-orphanization name of | ||
3801 | * ow_inode, which is no longer valid. | ||
3802 | */ | ||
3803 | fs_path_reset(valid_path); | ||
3804 | ret = get_cur_path(sctx, sctx->cur_ino, | ||
3805 | sctx->cur_inode_gen, valid_path); | ||
3806 | if (ret < 0) | ||
3807 | goto out; | ||
3666 | } else { | 3808 | } else { |
3667 | ret = send_unlink(sctx, cur->full_path); | 3809 | ret = send_unlink(sctx, cur->full_path); |
3668 | if (ret < 0) | 3810 | if (ret < 0) |
@@ -5602,7 +5744,10 @@ static int changed_ref(struct send_ctx *sctx, | |||
5602 | { | 5744 | { |
5603 | int ret = 0; | 5745 | int ret = 0; |
5604 | 5746 | ||
5605 | BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); | 5747 | if (sctx->cur_ino != sctx->cmp_key->objectid) { |
5748 | inconsistent_snapshot_error(sctx, result, "reference"); | ||
5749 | return -EIO; | ||
5750 | } | ||
5606 | 5751 | ||
5607 | if (!sctx->cur_inode_new_gen && | 5752 | if (!sctx->cur_inode_new_gen && |
5608 | sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) { | 5753 | sctx->cur_ino != BTRFS_FIRST_FREE_OBJECTID) { |
@@ -5627,7 +5772,10 @@ static int changed_xattr(struct send_ctx *sctx, | |||
5627 | { | 5772 | { |
5628 | int ret = 0; | 5773 | int ret = 0; |
5629 | 5774 | ||
5630 | BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); | 5775 | if (sctx->cur_ino != sctx->cmp_key->objectid) { |
5776 | inconsistent_snapshot_error(sctx, result, "xattr"); | ||
5777 | return -EIO; | ||
5778 | } | ||
5631 | 5779 | ||
5632 | if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { | 5780 | if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { |
5633 | if (result == BTRFS_COMPARE_TREE_NEW) | 5781 | if (result == BTRFS_COMPARE_TREE_NEW) |
@@ -5651,7 +5799,10 @@ static int changed_extent(struct send_ctx *sctx, | |||
5651 | { | 5799 | { |
5652 | int ret = 0; | 5800 | int ret = 0; |
5653 | 5801 | ||
5654 | BUG_ON(sctx->cur_ino != sctx->cmp_key->objectid); | 5802 | if (sctx->cur_ino != sctx->cmp_key->objectid) { |
5803 | inconsistent_snapshot_error(sctx, result, "extent"); | ||
5804 | return -EIO; | ||
5805 | } | ||
5655 | 5806 | ||
5656 | if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { | 5807 | if (!sctx->cur_inode_new_gen && !sctx->cur_inode_deleted) { |
5657 | if (result != BTRFS_COMPARE_TREE_DELETED) | 5808 | if (result != BTRFS_COMPARE_TREE_DELETED) |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index d31a0c4f56be..fff3f3efa436 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -4469,7 +4469,8 @@ static int btrfs_log_trailing_hole(struct btrfs_trans_handle *trans, | |||
4469 | static int btrfs_check_ref_name_override(struct extent_buffer *eb, | 4469 | static int btrfs_check_ref_name_override(struct extent_buffer *eb, |
4470 | const int slot, | 4470 | const int slot, |
4471 | const struct btrfs_key *key, | 4471 | const struct btrfs_key *key, |
4472 | struct inode *inode) | 4472 | struct inode *inode, |
4473 | u64 *other_ino) | ||
4473 | { | 4474 | { |
4474 | int ret; | 4475 | int ret; |
4475 | struct btrfs_path *search_path; | 4476 | struct btrfs_path *search_path; |
@@ -4528,7 +4529,16 @@ static int btrfs_check_ref_name_override(struct extent_buffer *eb, | |||
4528 | search_path, parent, | 4529 | search_path, parent, |
4529 | name, this_name_len, 0); | 4530 | name, this_name_len, 0); |
4530 | if (di && !IS_ERR(di)) { | 4531 | if (di && !IS_ERR(di)) { |
4531 | ret = 1; | 4532 | struct btrfs_key di_key; |
4533 | |||
4534 | btrfs_dir_item_key_to_cpu(search_path->nodes[0], | ||
4535 | di, &di_key); | ||
4536 | if (di_key.type == BTRFS_INODE_ITEM_KEY) { | ||
4537 | ret = 1; | ||
4538 | *other_ino = di_key.objectid; | ||
4539 | } else { | ||
4540 | ret = -EAGAIN; | ||
4541 | } | ||
4532 | goto out; | 4542 | goto out; |
4533 | } else if (IS_ERR(di)) { | 4543 | } else if (IS_ERR(di)) { |
4534 | ret = PTR_ERR(di); | 4544 | ret = PTR_ERR(di); |
@@ -4722,16 +4732,71 @@ again: | |||
4722 | if ((min_key.type == BTRFS_INODE_REF_KEY || | 4732 | if ((min_key.type == BTRFS_INODE_REF_KEY || |
4723 | min_key.type == BTRFS_INODE_EXTREF_KEY) && | 4733 | min_key.type == BTRFS_INODE_EXTREF_KEY) && |
4724 | BTRFS_I(inode)->generation == trans->transid) { | 4734 | BTRFS_I(inode)->generation == trans->transid) { |
4735 | u64 other_ino = 0; | ||
4736 | |||
4725 | ret = btrfs_check_ref_name_override(path->nodes[0], | 4737 | ret = btrfs_check_ref_name_override(path->nodes[0], |
4726 | path->slots[0], | 4738 | path->slots[0], |
4727 | &min_key, inode); | 4739 | &min_key, inode, |
4740 | &other_ino); | ||
4728 | if (ret < 0) { | 4741 | if (ret < 0) { |
4729 | err = ret; | 4742 | err = ret; |
4730 | goto out_unlock; | 4743 | goto out_unlock; |
4731 | } else if (ret > 0) { | 4744 | } else if (ret > 0) { |
4732 | err = 1; | 4745 | struct btrfs_key inode_key; |
4733 | btrfs_set_log_full_commit(root->fs_info, trans); | 4746 | struct inode *other_inode; |
4734 | goto out_unlock; | 4747 | |
4748 | if (ins_nr > 0) { | ||
4749 | ins_nr++; | ||
4750 | } else { | ||
4751 | ins_nr = 1; | ||
4752 | ins_start_slot = path->slots[0]; | ||
4753 | } | ||
4754 | ret = copy_items(trans, inode, dst_path, path, | ||
4755 | &last_extent, ins_start_slot, | ||
4756 | ins_nr, inode_only, | ||
4757 | logged_isize); | ||
4758 | if (ret < 0) { | ||
4759 | err = ret; | ||
4760 | goto out_unlock; | ||
4761 | } | ||
4762 | ins_nr = 0; | ||
4763 | btrfs_release_path(path); | ||
4764 | inode_key.objectid = other_ino; | ||
4765 | inode_key.type = BTRFS_INODE_ITEM_KEY; | ||
4766 | inode_key.offset = 0; | ||
4767 | other_inode = btrfs_iget(root->fs_info->sb, | ||
4768 | &inode_key, root, | ||
4769 | NULL); | ||
4770 | /* | ||
4771 | * If the other inode that had a conflicting dir | ||
4772 | * entry was deleted in the current transaction, | ||
4773 | * we don't need to do more work nor fallback to | ||
4774 | * a transaction commit. | ||
4775 | */ | ||
4776 | if (IS_ERR(other_inode) && | ||
4777 | PTR_ERR(other_inode) == -ENOENT) { | ||
4778 | goto next_key; | ||
4779 | } else if (IS_ERR(other_inode)) { | ||
4780 | err = PTR_ERR(other_inode); | ||
4781 | goto out_unlock; | ||
4782 | } | ||
4783 | /* | ||
4784 | * We are safe logging the other inode without | ||
4785 | * acquiring its i_mutex as long as we log with | ||
4786 | * the LOG_INODE_EXISTS mode. We're safe against | ||
4787 | * concurrent renames of the other inode as well | ||
4788 | * because during a rename we pin the log and | ||
4789 | * update the log with the new name before we | ||
4790 | * unpin it. | ||
4791 | */ | ||
4792 | err = btrfs_log_inode(trans, root, other_inode, | ||
4793 | LOG_INODE_EXISTS, | ||
4794 | 0, LLONG_MAX, ctx); | ||
4795 | iput(other_inode); | ||
4796 | if (err) | ||
4797 | goto out_unlock; | ||
4798 | else | ||
4799 | goto next_key; | ||
4735 | } | 4800 | } |
4736 | } | 4801 | } |
4737 | 4802 | ||
@@ -4799,7 +4864,7 @@ next_slot: | |||
4799 | ins_nr = 0; | 4864 | ins_nr = 0; |
4800 | } | 4865 | } |
4801 | btrfs_release_path(path); | 4866 | btrfs_release_path(path); |
4802 | 4867 | next_key: | |
4803 | if (min_key.offset < (u64)-1) { | 4868 | if (min_key.offset < (u64)-1) { |
4804 | min_key.offset++; | 4869 | min_key.offset++; |
4805 | } else if (min_key.type < max_key.type) { | 4870 | } else if (min_key.type < max_key.type) { |
@@ -4993,8 +5058,12 @@ static noinline int check_parent_dirs_for_sync(struct btrfs_trans_handle *trans, | |||
4993 | if (!parent || d_really_is_negative(parent) || sb != parent->d_sb) | 5058 | if (!parent || d_really_is_negative(parent) || sb != parent->d_sb) |
4994 | break; | 5059 | break; |
4995 | 5060 | ||
4996 | if (IS_ROOT(parent)) | 5061 | if (IS_ROOT(parent)) { |
5062 | inode = d_inode(parent); | ||
5063 | if (btrfs_must_commit_transaction(trans, inode)) | ||
5064 | ret = 1; | ||
4997 | break; | 5065 | break; |
5066 | } | ||
4998 | 5067 | ||
4999 | parent = dget_parent(parent); | 5068 | parent = dget_parent(parent); |
5000 | dput(old_parent); | 5069 | dput(old_parent); |