aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h1
-rw-r--r--fs/btrfs/disk-io.c9
2 files changed, 10 insertions, 0 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index a9377fb16c37..293464c0c6ba 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -522,6 +522,7 @@ struct btrfs_fs_info {
522 struct work_struct async_submit_work; 522 struct work_struct async_submit_work;
523 spinlock_t end_io_work_lock; 523 spinlock_t end_io_work_lock;
524 spinlock_t async_submit_work_lock; 524 spinlock_t async_submit_work_lock;
525 atomic_t nr_async_submits;
525 526
526#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) 527#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18)
527 struct work_struct trans_work; 528 struct work_struct trans_work;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 264f297260f8..373374340e9b 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -453,6 +453,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode,
453 453
454 spin_lock(&fs_info->async_submit_work_lock); 454 spin_lock(&fs_info->async_submit_work_lock);
455 list_add_tail(&async->list, &fs_info->async_submit_work_list); 455 list_add_tail(&async->list, &fs_info->async_submit_work_list);
456 atomic_inc(&fs_info->nr_async_submits);
456 spin_unlock(&fs_info->async_submit_work_lock); 457 spin_unlock(&fs_info->async_submit_work_lock);
457 458
458 queue_work(async_submit_workqueue, &fs_info->async_submit_work); 459 queue_work(async_submit_workqueue, &fs_info->async_submit_work);
@@ -906,10 +907,16 @@ static int btrfs_congested_fn(void *congested_data, int bdi_bits)
906{ 907{
907 struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data; 908 struct btrfs_fs_info *info = (struct btrfs_fs_info *)congested_data;
908 int ret = 0; 909 int ret = 0;
910 int limit = 256 * info->fs_devices->open_devices;
909 struct list_head *cur; 911 struct list_head *cur;
910 struct btrfs_device *device; 912 struct btrfs_device *device;
911 struct backing_dev_info *bdi; 913 struct backing_dev_info *bdi;
912 914
915 if ((bdi_bits & (1 << BDI_write_congested)) &&
916 atomic_read(&info->nr_async_submits) > limit) {
917 return 1;
918 }
919
913 list_for_each(cur, &info->fs_devices->devices) { 920 list_for_each(cur, &info->fs_devices->devices) {
914 device = list_entry(cur, struct btrfs_device, dev_list); 921 device = list_entry(cur, struct btrfs_device, dev_list);
915 if (!device->bdev) 922 if (!device->bdev)
@@ -1117,6 +1124,7 @@ static void btrfs_async_submit_work(struct work_struct *work)
1117 } 1124 }
1118 next = fs_info->async_submit_work_list.next; 1125 next = fs_info->async_submit_work_list.next;
1119 list_del(next); 1126 list_del(next);
1127 atomic_dec(&fs_info->nr_async_submits);
1120 spin_unlock(&fs_info->async_submit_work_lock); 1128 spin_unlock(&fs_info->async_submit_work_lock);
1121 1129
1122 async = list_entry(next, struct async_submit_bio, list); 1130 async = list_entry(next, struct async_submit_bio, list);
@@ -1179,6 +1187,7 @@ struct btrfs_root *open_ctree(struct super_block *sb,
1179 INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); 1187 INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
1180 INIT_LIST_HEAD(&fs_info->space_info); 1188 INIT_LIST_HEAD(&fs_info->space_info);
1181 btrfs_mapping_init(&fs_info->mapping_tree); 1189 btrfs_mapping_init(&fs_info->mapping_tree);
1190 atomic_set(&fs_info->nr_async_submits, 0);
1182 fs_info->sb = sb; 1191 fs_info->sb = sb;
1183 fs_info->max_extent = (u64)-1; 1192 fs_info->max_extent = (u64)-1;
1184 fs_info->max_inline = 8192 * 1024; 1193 fs_info->max_inline = 8192 * 1024;