Commit 0e735872fb4b157a2fc94d4443f367e9aeb533a6
Exists in
master
and in
4 other branches
Merge branch 'for-chris' of git://git.kernel.org/pub/scm/linux/kernel/git/arne/b…
…trfs-unstable-arne into for-linus
Showing 2 changed files Side-by-side Diff
fs/btrfs/disk-io.c
... | ... | @@ -1668,8 +1668,6 @@ |
1668 | 1668 | init_waitqueue_head(&fs_info->scrub_pause_wait); |
1669 | 1669 | init_rwsem(&fs_info->scrub_super_lock); |
1670 | 1670 | fs_info->scrub_workers_refcnt = 0; |
1671 | - btrfs_init_workers(&fs_info->scrub_workers, "scrub", | |
1672 | - fs_info->thread_pool_size, &fs_info->generic_worker); | |
1673 | 1671 | |
1674 | 1672 | sb->s_blocksize = 4096; |
1675 | 1673 | sb->s_blocksize_bits = blksize_bits(4096); |
fs/btrfs/scrub.c
... | ... | @@ -16,13 +16,7 @@ |
16 | 16 | * Boston, MA 021110-1307, USA. |
17 | 17 | */ |
18 | 18 | |
19 | -#include <linux/sched.h> | |
20 | -#include <linux/pagemap.h> | |
21 | -#include <linux/writeback.h> | |
22 | 19 | #include <linux/blkdev.h> |
23 | -#include <linux/rbtree.h> | |
24 | -#include <linux/slab.h> | |
25 | -#include <linux/workqueue.h> | |
26 | 20 | #include "ctree.h" |
27 | 21 | #include "volumes.h" |
28 | 22 | #include "disk-io.h" |
29 | 23 | |
... | ... | @@ -804,18 +798,12 @@ |
804 | 798 | |
805 | 799 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
806 | 800 | if (ret < 0) |
807 | - goto out; | |
801 | + goto out_noplug; | |
808 | 802 | |
809 | - l = path->nodes[0]; | |
810 | - slot = path->slots[0]; | |
811 | - btrfs_item_key_to_cpu(l, &key, slot); | |
812 | - if (key.objectid != logical) { | |
813 | - ret = btrfs_previous_item(root, path, 0, | |
814 | - BTRFS_EXTENT_ITEM_KEY); | |
815 | - if (ret < 0) | |
816 | - goto out; | |
817 | - } | |
818 | - | |
803 | + /* | |
804 | + * we might miss half an extent here, but that doesn't matter, | |
805 | + * as it's only the prefetch | |
806 | + */ | |
819 | 807 | while (1) { |
820 | 808 | l = path->nodes[0]; |
821 | 809 | slot = path->slots[0]; |
... | ... | @@ -824,7 +812,7 @@ |
824 | 812 | if (ret == 0) |
825 | 813 | continue; |
826 | 814 | if (ret < 0) |
827 | - goto out; | |
815 | + goto out_noplug; | |
828 | 816 | |
829 | 817 | break; |
830 | 818 | } |
831 | 819 | |
... | ... | @@ -906,15 +894,20 @@ |
906 | 894 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
907 | 895 | if (ret < 0) |
908 | 896 | goto out; |
909 | - | |
910 | - l = path->nodes[0]; | |
911 | - slot = path->slots[0]; | |
912 | - btrfs_item_key_to_cpu(l, &key, slot); | |
913 | - if (key.objectid != logical) { | |
897 | + if (ret > 0) { | |
914 | 898 | ret = btrfs_previous_item(root, path, 0, |
915 | 899 | BTRFS_EXTENT_ITEM_KEY); |
916 | 900 | if (ret < 0) |
917 | 901 | goto out; |
902 | + if (ret > 0) { | |
903 | + /* there's no smaller item, so stick with the | |
904 | + * larger one */ | |
905 | + btrfs_release_path(path); | |
906 | + ret = btrfs_search_slot(NULL, root, &key, | |
907 | + path, 0, 0); | |
908 | + if (ret < 0) | |
909 | + goto out; | |
910 | + } | |
918 | 911 | } |
919 | 912 | |
920 | 913 | while (1) { |
... | ... | @@ -989,6 +982,7 @@ |
989 | 982 | |
990 | 983 | out: |
991 | 984 | blk_finish_plug(&plug); |
985 | +out_noplug: | |
992 | 986 | btrfs_free_path(path); |
993 | 987 | return ret < 0 ? ret : 0; |
994 | 988 | } |
... | ... | @@ -1064,8 +1058,15 @@ |
1064 | 1058 | while (1) { |
1065 | 1059 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
1066 | 1060 | if (ret < 0) |
1067 | - goto out; | |
1068 | - ret = 0; | |
1061 | + break; | |
1062 | + if (ret > 0) { | |
1063 | + if (path->slots[0] >= | |
1064 | + btrfs_header_nritems(path->nodes[0])) { | |
1065 | + ret = btrfs_next_leaf(root, path); | |
1066 | + if (ret) | |
1067 | + break; | |
1068 | + } | |
1069 | + } | |
1069 | 1070 | |
1070 | 1071 | l = path->nodes[0]; |
1071 | 1072 | slot = path->slots[0]; |
... | ... | @@ -1075,7 +1076,7 @@ |
1075 | 1076 | if (found_key.objectid != sdev->dev->devid) |
1076 | 1077 | break; |
1077 | 1078 | |
1078 | - if (btrfs_key_type(&key) != BTRFS_DEV_EXTENT_KEY) | |
1079 | + if (btrfs_key_type(&found_key) != BTRFS_DEV_EXTENT_KEY) | |
1079 | 1080 | break; |
1080 | 1081 | |
1081 | 1082 | if (found_key.offset >= end) |
... | ... | @@ -1104,7 +1105,7 @@ |
1104 | 1105 | cache = btrfs_lookup_block_group(fs_info, chunk_offset); |
1105 | 1106 | if (!cache) { |
1106 | 1107 | ret = -ENOENT; |
1107 | - goto out; | |
1108 | + break; | |
1108 | 1109 | } |
1109 | 1110 | ret = scrub_chunk(sdev, chunk_tree, chunk_objectid, |
1110 | 1111 | chunk_offset, length); |
1111 | 1112 | |
... | ... | @@ -1116,9 +1117,13 @@ |
1116 | 1117 | btrfs_release_path(path); |
1117 | 1118 | } |
1118 | 1119 | |
1119 | -out: | |
1120 | 1120 | btrfs_free_path(path); |
1121 | - return ret; | |
1121 | + | |
1122 | + /* | |
1123 | + * ret can still be 1 from search_slot or next_leaf, | |
1124 | + * that's not an error | |
1125 | + */ | |
1126 | + return ret < 0 ? ret : 0; | |
1122 | 1127 | } |
1123 | 1128 | |
1124 | 1129 | static noinline_for_stack int scrub_supers(struct scrub_dev *sdev) |
1125 | 1130 | |
... | ... | @@ -1155,8 +1160,12 @@ |
1155 | 1160 | struct btrfs_fs_info *fs_info = root->fs_info; |
1156 | 1161 | |
1157 | 1162 | mutex_lock(&fs_info->scrub_lock); |
1158 | - if (fs_info->scrub_workers_refcnt == 0) | |
1163 | + if (fs_info->scrub_workers_refcnt == 0) { | |
1164 | + btrfs_init_workers(&fs_info->scrub_workers, "scrub", | |
1165 | + fs_info->thread_pool_size, &fs_info->generic_worker); | |
1166 | + fs_info->scrub_workers.idle_thresh = 4; | |
1159 | 1167 | btrfs_start_workers(&fs_info->scrub_workers, 1); |
1168 | + } | |
1160 | 1169 | ++fs_info->scrub_workers_refcnt; |
1161 | 1170 | mutex_unlock(&fs_info->scrub_lock); |
1162 | 1171 |