Skip to content

Commit ef6ebf3

Browse files
committed
Merge branch 'for-chris-4.11' of git://git.kernel.org/pub/scm/linux/kernel/git/fdmanana/linux into for-linus-4.11
2 parents 6288d6e + 263d399 commit ef6ebf3

File tree

7 files changed

+188
-30
lines changed

7 files changed

+188
-30
lines changed

fs/btrfs/ctree.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4159,6 +4159,9 @@ static noinline int push_for_double_split(struct btrfs_trans_handle *trans,
41594159

41604160
/* try to push all the items before our slot into the next leaf */
41614161
slot = path->slots[0];
4162+
space_needed = data_size;
4163+
if (slot > 0)
4164+
space_needed -= btrfs_leaf_free_space(fs_info, path->nodes[0]);
41624165
ret = push_leaf_left(trans, root, path, 1, space_needed, 0, slot);
41634166
if (ret < 0)
41644167
return ret;
@@ -4214,6 +4217,10 @@ static noinline int split_leaf(struct btrfs_trans_handle *trans,
42144217
if (wret < 0)
42154218
return wret;
42164219
if (wret) {
4220+
space_needed = data_size;
4221+
if (slot > 0)
4222+
space_needed -= btrfs_leaf_free_space(fs_info,
4223+
l);
42174224
wret = push_leaf_left(trans, root, path, space_needed,
42184225
space_needed, 0, (u32)-1);
42194226
if (wret < 0)

fs/btrfs/disk-io.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,11 +2205,9 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info)
22052205
btrfs_destroy_workqueue(fs_info->delalloc_workers);
22062206
btrfs_destroy_workqueue(fs_info->workers);
22072207
btrfs_destroy_workqueue(fs_info->endio_workers);
2208-
btrfs_destroy_workqueue(fs_info->endio_meta_workers);
22092208
btrfs_destroy_workqueue(fs_info->endio_raid56_workers);
22102209
btrfs_destroy_workqueue(fs_info->endio_repair_workers);
22112210
btrfs_destroy_workqueue(fs_info->rmw_workers);
2212-
btrfs_destroy_workqueue(fs_info->endio_meta_write_workers);
22132211
btrfs_destroy_workqueue(fs_info->endio_write_workers);
22142212
btrfs_destroy_workqueue(fs_info->endio_freespace_worker);
22152213
btrfs_destroy_workqueue(fs_info->submit_workers);
@@ -2219,6 +2217,13 @@ static void btrfs_stop_all_workers(struct btrfs_fs_info *fs_info)
22192217
btrfs_destroy_workqueue(fs_info->flush_workers);
22202218
btrfs_destroy_workqueue(fs_info->qgroup_rescan_workers);
22212219
btrfs_destroy_workqueue(fs_info->extent_workers);
2220+
/*
2221+
* Now that all other work queues are destroyed, we can safely destroy
2222+
* the queues used for metadata I/O, since tasks from those other work
2223+
* queues can do metadata I/O operations.
2224+
*/
2225+
btrfs_destroy_workqueue(fs_info->endio_meta_workers);
2226+
btrfs_destroy_workqueue(fs_info->endio_meta_write_workers);
22222227
}
22232228

22242229
static void free_root_extent_buffers(struct btrfs_root *root)
@@ -3261,14 +3266,14 @@ int open_ctree(struct super_block *sb,
32613266

32623267
fail_block_groups:
32633268
btrfs_put_block_group_cache(fs_info);
3264-
btrfs_free_block_groups(fs_info);
32653269

32663270
fail_tree_roots:
32673271
free_root_pointers(fs_info, 1);
32683272
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
32693273

32703274
fail_sb_buffer:
32713275
btrfs_stop_all_workers(fs_info);
3276+
btrfs_free_block_groups(fs_info);
32723277
fail_alloc:
32733278
fail_iput:
32743279
btrfs_mapping_tree_free(&fs_info->mapping_tree);
@@ -3977,15 +3982,15 @@ void close_ctree(struct btrfs_fs_info *fs_info)
39773982

39783983
btrfs_put_block_group_cache(fs_info);
39793984

3980-
btrfs_free_block_groups(fs_info);
3981-
39823985
/*
39833986
* we must make sure there is not any read request to
39843987
* submit after we stopping all workers.
39853988
*/
39863989
invalidate_inode_pages2(fs_info->btree_inode->i_mapping);
39873990
btrfs_stop_all_workers(fs_info);
39883991

3992+
btrfs_free_block_groups(fs_info);
3993+
39893994
clear_bit(BTRFS_FS_OPEN, &fs_info->flags);
39903995
free_root_pointers(fs_info, 1);
39913996

fs/btrfs/extent-tree.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9740,6 +9740,11 @@ void btrfs_put_block_group_cache(struct btrfs_fs_info *info)
97409740
}
97419741
}
97429742

9743+
/*
9744+
* Must be called only after stopping all workers, since we could have block
9745+
* group caching kthreads running, and therefore they could race with us if we
9746+
* freed the block groups before stopping them.
9747+
*/
97439748
int btrfs_free_block_groups(struct btrfs_fs_info *info)
97449749
{
97459750
struct btrfs_block_group_cache *block_group;
@@ -9779,9 +9784,6 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
97799784
list_del(&block_group->list);
97809785
up_write(&block_group->space_info->groups_sem);
97819786

9782-
if (block_group->cached == BTRFS_CACHE_STARTED)
9783-
wait_block_group_cache_done(block_group);
9784-
97859787
/*
97869788
* We haven't cached this block group, which means we could
97879789
* possibly have excluded extents on this block group.
@@ -9791,6 +9793,7 @@ int btrfs_free_block_groups(struct btrfs_fs_info *info)
97919793
free_excluded_extents(info, block_group);
97929794

97939795
btrfs_remove_free_space_cache(block_group);
9796+
ASSERT(block_group->cached != BTRFS_CACHE_STARTED);
97949797
ASSERT(list_empty(&block_group->dirty_list));
97959798
ASSERT(list_empty(&block_group->io_list));
97969799
ASSERT(list_empty(&block_group->bg_list));

fs/btrfs/file-item.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,33 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
643643

644644
/* delete the entire item, it is inside our range */
645645
if (key.offset >= bytenr && csum_end <= end_byte) {
646-
ret = btrfs_del_item(trans, root, path);
646+
int del_nr = 1;
647+
648+
/*
649+
* Check how many csum items preceding this one in this
650+
* leaf correspond to our range and then delete them all
651+
* at once.
652+
*/
653+
if (key.offset > bytenr && path->slots[0] > 0) {
654+
int slot = path->slots[0] - 1;
655+
656+
while (slot >= 0) {
657+
struct btrfs_key pk;
658+
659+
btrfs_item_key_to_cpu(leaf, &pk, slot);
660+
if (pk.offset < bytenr ||
661+
pk.type != BTRFS_EXTENT_CSUM_KEY ||
662+
pk.objectid !=
663+
BTRFS_EXTENT_CSUM_OBJECTID)
664+
break;
665+
path->slots[0] = slot;
666+
del_nr++;
667+
key.offset = pk.offset;
668+
slot--;
669+
}
670+
}
671+
ret = btrfs_del_items(trans, root, path,
672+
path->slots[0], del_nr);
647673
if (ret)
648674
goto out;
649675
if (key.offset == bytenr)

fs/btrfs/inode.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,10 +1331,16 @@ static noinline int run_delalloc_nocow(struct inode *inode,
13311331
* either valid or do not exist.
13321332
*/
13331333
if (csum_exist_in_range(fs_info, disk_bytenr,
1334-
num_bytes))
1334+
num_bytes)) {
1335+
if (!nolock)
1336+
btrfs_end_write_no_snapshoting(root);
13351337
goto out_check;
1336-
if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr))
1338+
}
1339+
if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) {
1340+
if (!nolock)
1341+
btrfs_end_write_no_snapshoting(root);
13371342
goto out_check;
1343+
}
13381344
nocow = 1;
13391345
} else if (extent_type == BTRFS_FILE_EXTENT_INLINE) {
13401346
extent_end = found_key.offset +
@@ -4412,19 +4418,8 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
44124418
if (found_type > min_type) {
44134419
del_item = 1;
44144420
} else {
4415-
if (item_end < new_size) {
4416-
/*
4417-
* With NO_HOLES mode, for the following mapping
4418-
*
4419-
* [0-4k][hole][8k-12k]
4420-
*
4421-
* if truncating isize down to 6k, it ends up
4422-
* isize being 8k.
4423-
*/
4424-
if (btrfs_fs_incompat(root->fs_info, NO_HOLES))
4425-
last_size = new_size;
4421+
if (item_end < new_size)
44264422
break;
4427-
}
44284423
if (found_key.offset >= new_size)
44294424
del_item = 1;
44304425
else
@@ -4607,8 +4602,12 @@ int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
46074602
btrfs_abort_transaction(trans, ret);
46084603
}
46094604
error:
4610-
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID)
4605+
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
4606+
ASSERT(last_size >= new_size);
4607+
if (!err && last_size > new_size)
4608+
last_size = new_size;
46114609
btrfs_ordered_update_i_size(inode, last_size, NULL);
4610+
}
46124611

46134612
btrfs_free_path(path);
46144613

fs/btrfs/send.c

Lines changed: 119 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,6 +1681,9 @@ static int is_inode_existent(struct send_ctx *sctx, u64 ino, u64 gen)
16811681
{
16821682
int ret;
16831683

1684+
if (ino == BTRFS_FIRST_FREE_OBJECTID)
1685+
return 1;
1686+
16841687
ret = get_cur_inode_state(sctx, ino, gen);
16851688
if (ret < 0)
16861689
goto out;
@@ -1866,7 +1869,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
18661869
* not deleted and then re-created, if it was then we have no overwrite
18671870
* and we can just unlink this entry.
18681871
*/
1869-
if (sctx->parent_root) {
1872+
if (sctx->parent_root && dir != BTRFS_FIRST_FREE_OBJECTID) {
18701873
ret = get_inode_info(sctx->parent_root, dir, NULL, &gen, NULL,
18711874
NULL, NULL, NULL);
18721875
if (ret < 0 && ret != -ENOENT)
@@ -1934,6 +1937,19 @@ static int did_overwrite_ref(struct send_ctx *sctx,
19341937
if (ret <= 0)
19351938
goto out;
19361939

1940+
if (dir != BTRFS_FIRST_FREE_OBJECTID) {
1941+
ret = get_inode_info(sctx->send_root, dir, NULL, &gen, NULL,
1942+
NULL, NULL, NULL);
1943+
if (ret < 0 && ret != -ENOENT)
1944+
goto out;
1945+
if (ret) {
1946+
ret = 0;
1947+
goto out;
1948+
}
1949+
if (gen != dir_gen)
1950+
goto out;
1951+
}
1952+
19371953
/* check if the ref was overwritten by another ref */
19381954
ret = lookup_dir_item_inode(sctx->send_root, dir, name, name_len,
19391955
&ow_inode, &other_type);
@@ -3556,6 +3572,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
35563572
{
35573573
int ret = 0;
35583574
u64 ino = parent_ref->dir;
3575+
u64 ino_gen = parent_ref->dir_gen;
35593576
u64 parent_ino_before, parent_ino_after;
35603577
struct fs_path *path_before = NULL;
35613578
struct fs_path *path_after = NULL;
@@ -3576,6 +3593,8 @@ static int wait_for_parent_move(struct send_ctx *sctx,
35763593
* at get_cur_path()).
35773594
*/
35783595
while (ino > BTRFS_FIRST_FREE_OBJECTID) {
3596+
u64 parent_ino_after_gen;
3597+
35793598
if (is_waiting_for_move(sctx, ino)) {
35803599
/*
35813600
* If the current inode is an ancestor of ino in the
@@ -3598,7 +3617,7 @@ static int wait_for_parent_move(struct send_ctx *sctx,
35983617
fs_path_reset(path_after);
35993618

36003619
ret = get_first_ref(sctx->send_root, ino, &parent_ino_after,
3601-
NULL, path_after);
3620+
&parent_ino_after_gen, path_after);
36023621
if (ret < 0)
36033622
goto out;
36043623
ret = get_first_ref(sctx->parent_root, ino, &parent_ino_before,
@@ -3615,10 +3634,20 @@ static int wait_for_parent_move(struct send_ctx *sctx,
36153634
if (ino > sctx->cur_ino &&
36163635
(parent_ino_before != parent_ino_after || len1 != len2 ||
36173636
memcmp(path_before->start, path_after->start, len1))) {
3618-
ret = 1;
3619-
break;
3637+
u64 parent_ino_gen;
3638+
3639+
ret = get_inode_info(sctx->parent_root, ino, NULL,
3640+
&parent_ino_gen, NULL, NULL, NULL,
3641+
NULL);
3642+
if (ret < 0)
3643+
goto out;
3644+
if (ino_gen == parent_ino_gen) {
3645+
ret = 1;
3646+
break;
3647+
}
36203648
}
36213649
ino = parent_ino_after;
3650+
ino_gen = parent_ino_after_gen;
36223651
}
36233652

36243653
out:
@@ -5277,6 +5306,81 @@ static int get_last_extent(struct send_ctx *sctx, u64 offset)
52775306
return ret;
52785307
}
52795308

5309+
static int range_is_hole_in_parent(struct send_ctx *sctx,
5310+
const u64 start,
5311+
const u64 end)
5312+
{
5313+
struct btrfs_path *path;
5314+
struct btrfs_key key;
5315+
struct btrfs_root *root = sctx->parent_root;
5316+
u64 search_start = start;
5317+
int ret;
5318+
5319+
path = alloc_path_for_send();
5320+
if (!path)
5321+
return -ENOMEM;
5322+
5323+
key.objectid = sctx->cur_ino;
5324+
key.type = BTRFS_EXTENT_DATA_KEY;
5325+
key.offset = search_start;
5326+
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
5327+
if (ret < 0)
5328+
goto out;
5329+
if (ret > 0 && path->slots[0] > 0)
5330+
path->slots[0]--;
5331+
5332+
while (search_start < end) {
5333+
struct extent_buffer *leaf = path->nodes[0];
5334+
int slot = path->slots[0];
5335+
struct btrfs_file_extent_item *fi;
5336+
u64 extent_end;
5337+
5338+
if (slot >= btrfs_header_nritems(leaf)) {
5339+
ret = btrfs_next_leaf(root, path);
5340+
if (ret < 0)
5341+
goto out;
5342+
else if (ret > 0)
5343+
break;
5344+
continue;
5345+
}
5346+
5347+
btrfs_item_key_to_cpu(leaf, &key, slot);
5348+
if (key.objectid < sctx->cur_ino ||
5349+
key.type < BTRFS_EXTENT_DATA_KEY)
5350+
goto next;
5351+
if (key.objectid > sctx->cur_ino ||
5352+
key.type > BTRFS_EXTENT_DATA_KEY ||
5353+
key.offset >= end)
5354+
break;
5355+
5356+
fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
5357+
if (btrfs_file_extent_type(leaf, fi) ==
5358+
BTRFS_FILE_EXTENT_INLINE) {
5359+
u64 size = btrfs_file_extent_inline_len(leaf, slot, fi);
5360+
5361+
extent_end = ALIGN(key.offset + size,
5362+
root->fs_info->sectorsize);
5363+
} else {
5364+
extent_end = key.offset +
5365+
btrfs_file_extent_num_bytes(leaf, fi);
5366+
}
5367+
if (extent_end <= start)
5368+
goto next;
5369+
if (btrfs_file_extent_disk_bytenr(leaf, fi) == 0) {
5370+
search_start = extent_end;
5371+
goto next;
5372+
}
5373+
ret = 0;
5374+
goto out;
5375+
next:
5376+
path->slots[0]++;
5377+
}
5378+
ret = 1;
5379+
out:
5380+
btrfs_free_path(path);
5381+
return ret;
5382+
}
5383+
52805384
static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
52815385
struct btrfs_key *key)
52825386
{
@@ -5321,8 +5425,17 @@ static int maybe_send_hole(struct send_ctx *sctx, struct btrfs_path *path,
53215425
return ret;
53225426
}
53235427

5324-
if (sctx->cur_inode_last_extent < key->offset)
5325-
ret = send_hole(sctx, key->offset);
5428+
if (sctx->cur_inode_last_extent < key->offset) {
5429+
ret = range_is_hole_in_parent(sctx,
5430+
sctx->cur_inode_last_extent,
5431+
key->offset);
5432+
if (ret < 0)
5433+
return ret;
5434+
else if (ret == 0)
5435+
ret = send_hole(sctx, key->offset);
5436+
else
5437+
ret = 0;
5438+
}
53265439
sctx->cur_inode_last_extent = extent_end;
53275440
return ret;
53285441
}

0 commit comments

Comments
 (0)