diff options
-rw-r--r-- | fs/btrfs/ctree.h | 1 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 30 | ||||
-rw-r--r-- | fs/btrfs/super.c | 13 |
3 files changed, 28 insertions, 16 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 6c91a510c965..7ae4666103c0 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -532,6 +532,7 @@ struct btrfs_fs_info { | |||
532 | */ | 532 | */ |
533 | struct btrfs_workers workers; | 533 | struct btrfs_workers workers; |
534 | struct btrfs_workers endio_workers; | 534 | struct btrfs_workers endio_workers; |
535 | int thread_pool_size; | ||
535 | 536 | ||
536 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) | 537 | #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) |
537 | struct work_struct trans_work; | 538 | struct work_struct trans_work; |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 98ff4fbcb386..c6a710a668cb 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1117,6 +1117,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1117 | GFP_NOFS); | 1117 | GFP_NOFS); |
1118 | int ret; | 1118 | int ret; |
1119 | int err = -EINVAL; | 1119 | int err = -EINVAL; |
1120 | |||
1120 | struct btrfs_super_block *disk_super; | 1121 | struct btrfs_super_block *disk_super; |
1121 | 1122 | ||
1122 | if (!extent_root || !tree_root || !fs_info) { | 1123 | if (!extent_root || !tree_root || !fs_info) { |
@@ -1148,6 +1149,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1148 | fs_info->btree_inode = new_inode(sb); | 1149 | fs_info->btree_inode = new_inode(sb); |
1149 | fs_info->btree_inode->i_ino = 1; | 1150 | fs_info->btree_inode->i_ino = 1; |
1150 | fs_info->btree_inode->i_nlink = 1; | 1151 | fs_info->btree_inode->i_nlink = 1; |
1152 | fs_info->thread_pool_size = min(num_online_cpus() + 2, 8); | ||
1151 | 1153 | ||
1152 | sb->s_blocksize = 4096; | 1154 | sb->s_blocksize = 4096; |
1153 | sb->s_blocksize_bits = blksize_bits(4096); | 1155 | sb->s_blocksize_bits = blksize_bits(4096); |
@@ -1195,19 +1197,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1195 | mutex_init(&fs_info->trans_mutex); | 1197 | mutex_init(&fs_info->trans_mutex); |
1196 | mutex_init(&fs_info->fs_mutex); | 1198 | mutex_init(&fs_info->fs_mutex); |
1197 | 1199 | ||
1198 | /* we need to start all the end_io workers up front because the | ||
1199 | * queue work function gets called at interrupt time. The endio | ||
1200 | * workers don't normally start IO, so some number of them <= the | ||
1201 | * number of cpus is fine. They handle checksumming after a read. | ||
1202 | * | ||
1203 | * The other worker threads do start IO, so the max is larger than | ||
1204 | * the number of CPUs. FIXME, tune this for huge machines | ||
1205 | */ | ||
1206 | btrfs_init_workers(&fs_info->workers, num_online_cpus() * 2); | ||
1207 | btrfs_init_workers(&fs_info->endio_workers, num_online_cpus()); | ||
1208 | btrfs_start_workers(&fs_info->workers, 1); | ||
1209 | btrfs_start_workers(&fs_info->endio_workers, num_online_cpus()); | ||
1210 | |||
1211 | #if 0 | 1200 | #if 0 |
1212 | ret = add_hasher(fs_info, "crc32c"); | 1201 | ret = add_hasher(fs_info, "crc32c"); |
1213 | if (ret) { | 1202 | if (ret) { |
@@ -1238,6 +1227,17 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1238 | if (err) | 1227 | if (err) |
1239 | goto fail_sb_buffer; | 1228 | goto fail_sb_buffer; |
1240 | 1229 | ||
1230 | /* | ||
1231 | * we need to start all the end_io workers up front because the | ||
1232 | * queue work function gets called at interrupt time, and so it | ||
1233 | * cannot dynamically grow. | ||
1234 | */ | ||
1235 | btrfs_init_workers(&fs_info->workers, fs_info->thread_pool_size); | ||
1236 | btrfs_init_workers(&fs_info->endio_workers, fs_info->thread_pool_size); | ||
1237 | btrfs_start_workers(&fs_info->workers, 1); | ||
1238 | btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size); | ||
1239 | |||
1240 | |||
1241 | err = -EINVAL; | 1241 | err = -EINVAL; |
1242 | if (btrfs_super_num_devices(disk_super) > fs_devices->open_devices) { | 1242 | if (btrfs_super_num_devices(disk_super) > fs_devices->open_devices) { |
1243 | printk("Btrfs: wanted %llu devices, but found %llu\n", | 1243 | printk("Btrfs: wanted %llu devices, but found %llu\n", |
@@ -1341,10 +1341,10 @@ fail_sys_array: | |||
1341 | mutex_unlock(&fs_info->fs_mutex); | 1341 | mutex_unlock(&fs_info->fs_mutex); |
1342 | fail_sb_buffer: | 1342 | fail_sb_buffer: |
1343 | extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree); | 1343 | extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree); |
1344 | fail_iput: | ||
1345 | iput(fs_info->btree_inode); | ||
1346 | btrfs_stop_workers(&fs_info->workers); | 1344 | btrfs_stop_workers(&fs_info->workers); |
1347 | btrfs_stop_workers(&fs_info->endio_workers); | 1345 | btrfs_stop_workers(&fs_info->endio_workers); |
1346 | fail_iput: | ||
1347 | iput(fs_info->btree_inode); | ||
1348 | fail: | 1348 | fail: |
1349 | btrfs_close_devices(fs_info->fs_devices); | 1349 | btrfs_close_devices(fs_info->fs_devices); |
1350 | btrfs_mapping_tree_free(&fs_info->mapping_tree); | 1350 | btrfs_mapping_tree_free(&fs_info->mapping_tree); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f3274befd46a..196d0e280b19 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -67,7 +67,7 @@ static void btrfs_put_super (struct super_block * sb) | |||
67 | enum { | 67 | enum { |
68 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, | 68 | Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, |
69 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, | 69 | Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, |
70 | Opt_ssd, Opt_err, | 70 | Opt_ssd, Opt_thread_pool, Opt_err, |
71 | }; | 71 | }; |
72 | 72 | ||
73 | static match_table_t tokens = { | 73 | static match_table_t tokens = { |
@@ -80,6 +80,7 @@ static match_table_t tokens = { | |||
80 | {Opt_max_extent, "max_extent=%s"}, | 80 | {Opt_max_extent, "max_extent=%s"}, |
81 | {Opt_max_inline, "max_inline=%s"}, | 81 | {Opt_max_inline, "max_inline=%s"}, |
82 | {Opt_alloc_start, "alloc_start=%s"}, | 82 | {Opt_alloc_start, "alloc_start=%s"}, |
83 | {Opt_thread_pool, "thread_pool=%d"}, | ||
83 | {Opt_ssd, "ssd"}, | 84 | {Opt_ssd, "ssd"}, |
84 | {Opt_err, NULL} | 85 | {Opt_err, NULL} |
85 | }; | 86 | }; |
@@ -118,6 +119,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
118 | struct btrfs_fs_info *info = root->fs_info; | 119 | struct btrfs_fs_info *info = root->fs_info; |
119 | substring_t args[MAX_OPT_ARGS]; | 120 | substring_t args[MAX_OPT_ARGS]; |
120 | char *p, *num; | 121 | char *p, *num; |
122 | int intarg; | ||
121 | 123 | ||
122 | if (!options) | 124 | if (!options) |
123 | return 0; | 125 | return 0; |
@@ -166,6 +168,15 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
166 | printk(KERN_INFO "btrfs: turning off barriers\n"); | 168 | printk(KERN_INFO "btrfs: turning off barriers\n"); |
167 | btrfs_set_opt(info->mount_opt, NOBARRIER); | 169 | btrfs_set_opt(info->mount_opt, NOBARRIER); |
168 | break; | 170 | break; |
171 | case Opt_thread_pool: | ||
172 | intarg = 0; | ||
173 | match_int(&args[0], &intarg); | ||
174 | if (intarg) { | ||
175 | info->thread_pool_size = intarg; | ||
176 | printk(KERN_INFO "btrfs: thread pool %d\n", | ||
177 | info->thread_pool_size); | ||
178 | } | ||
179 | break; | ||
169 | case Opt_max_extent: | 180 | case Opt_max_extent: |
170 | num = match_strdup(&args[0]); | 181 | num = match_strdup(&args[0]); |
171 | if (num) { | 182 | if (num) { |