aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c30
-rw-r--r--fs/btrfs/super.c13
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);
1342fail_sb_buffer: 1342fail_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);
1344fail_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);
1346fail_iput:
1347 iput(fs_info->btree_inode);
1348fail: 1348fail:
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)
67enum { 67enum {
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
73static match_table_t tokens = { 73static 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) {