aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c38
-rw-r--r--fs/btrfs/disk-io.h2
-rw-r--r--fs/btrfs/super.c8
3 files changed, 38 insertions, 10 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index d7cb58ed2946..2f075ef20050 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -72,11 +72,11 @@ static int btrfs_cleanup_transaction(struct btrfs_root *root);
72static void btrfs_error_commit_super(struct btrfs_root *root); 72static void btrfs_error_commit_super(struct btrfs_root *root);
73 73
74/* 74/*
75 * end_io_wq structs are used to do processing in task context when an IO is 75 * btrfs_end_io_wq structs are used to do processing in task context when an IO
76 * complete. This is used during reads to verify checksums, and it is used 76 * is complete. This is used during reads to verify checksums, and it is used
77 * by writes to insert metadata for new file extents after IO is complete. 77 * by writes to insert metadata for new file extents after IO is complete.
78 */ 78 */
79struct end_io_wq { 79struct btrfs_end_io_wq {
80 struct bio *bio; 80 struct bio *bio;
81 bio_end_io_t *end_io; 81 bio_end_io_t *end_io;
82 void *private; 82 void *private;
@@ -87,6 +87,26 @@ struct end_io_wq {
87 struct btrfs_work work; 87 struct btrfs_work work;
88}; 88};
89 89
90static struct kmem_cache *btrfs_end_io_wq_cache;
91
92int __init btrfs_end_io_wq_init(void)
93{
94 btrfs_end_io_wq_cache = kmem_cache_create("btrfs_end_io_wq",
95 sizeof(struct btrfs_end_io_wq),
96 0,
97 SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD,
98 NULL);
99 if (!btrfs_end_io_wq_cache)
100 return -ENOMEM;
101 return 0;
102}
103
104void btrfs_end_io_wq_exit(void)
105{
106 if (btrfs_end_io_wq_cache)
107 kmem_cache_destroy(btrfs_end_io_wq_cache);
108}
109
90/* 110/*
91 * async submit bios are used to offload expensive checksumming 111 * async submit bios are used to offload expensive checksumming
92 * onto the worker threads. They checksum file and metadata bios 112 * onto the worker threads. They checksum file and metadata bios
@@ -690,7 +710,7 @@ static int btree_io_failed_hook(struct page *page, int failed_mirror)
690 710
691static void end_workqueue_bio(struct bio *bio, int err) 711static void end_workqueue_bio(struct bio *bio, int err)
692{ 712{
693 struct end_io_wq *end_io_wq = bio->bi_private; 713 struct btrfs_end_io_wq *end_io_wq = bio->bi_private;
694 struct btrfs_fs_info *fs_info; 714 struct btrfs_fs_info *fs_info;
695 struct btrfs_workqueue *wq; 715 struct btrfs_workqueue *wq;
696 btrfs_work_func_t func; 716 btrfs_work_func_t func;
@@ -736,9 +756,9 @@ static void end_workqueue_bio(struct bio *bio, int err)
736int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, 756int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio,
737 enum btrfs_wq_endio_type metadata) 757 enum btrfs_wq_endio_type metadata)
738{ 758{
739 struct end_io_wq *end_io_wq; 759 struct btrfs_end_io_wq *end_io_wq;
740 760
741 end_io_wq = kmalloc(sizeof(*end_io_wq), GFP_NOFS); 761 end_io_wq = kmem_cache_alloc(btrfs_end_io_wq_cache, GFP_NOFS);
742 if (!end_io_wq) 762 if (!end_io_wq)
743 return -ENOMEM; 763 return -ENOMEM;
744 764
@@ -1723,16 +1743,16 @@ static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
1723static void end_workqueue_fn(struct btrfs_work *work) 1743static void end_workqueue_fn(struct btrfs_work *work)
1724{ 1744{
1725 struct bio *bio; 1745 struct bio *bio;
1726 struct end_io_wq *end_io_wq; 1746 struct btrfs_end_io_wq *end_io_wq;
1727 int error; 1747 int error;
1728 1748
1729 end_io_wq = container_of(work, struct end_io_wq, work); 1749 end_io_wq = container_of(work, struct btrfs_end_io_wq, work);
1730 bio = end_io_wq->bio; 1750 bio = end_io_wq->bio;
1731 1751
1732 error = end_io_wq->error; 1752 error = end_io_wq->error;
1733 bio->bi_private = end_io_wq->private; 1753 bio->bi_private = end_io_wq->private;
1734 bio->bi_end_io = end_io_wq->end_io; 1754 bio->bi_end_io = end_io_wq->end_io;
1735 kfree(end_io_wq); 1755 kmem_cache_free(btrfs_end_io_wq_cache, end_io_wq);
1736 bio_endio_nodec(bio, error); 1756 bio_endio_nodec(bio, error);
1737} 1757}
1738 1758
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h
index 84da438fd9a3..9ac233923ca3 100644
--- a/fs/btrfs/disk-io.h
+++ b/fs/btrfs/disk-io.h
@@ -142,6 +142,8 @@ int btree_lock_page_hook(struct page *page, void *data,
142 void (*flush_fn)(void *)); 142 void (*flush_fn)(void *));
143int btrfs_calc_num_tolerated_disk_barrier_failures( 143int btrfs_calc_num_tolerated_disk_barrier_failures(
144 struct btrfs_fs_info *fs_info); 144 struct btrfs_fs_info *fs_info);
145int __init btrfs_end_io_wq_init(void);
146void btrfs_end_io_wq_exit(void);
145 147
146#ifdef CONFIG_DEBUG_LOCK_ALLOC 148#ifdef CONFIG_DEBUG_LOCK_ALLOC
147void btrfs_init_lockdep(void); 149void btrfs_init_lockdep(void);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index b915d7704f19..4685b9704f15 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -2001,10 +2001,14 @@ static int __init init_btrfs_fs(void)
2001 if (err) 2001 if (err)
2002 goto free_delayed_ref; 2002 goto free_delayed_ref;
2003 2003
2004 err = btrfs_interface_init(); 2004 err = btrfs_end_io_wq_init();
2005 if (err) 2005 if (err)
2006 goto free_prelim_ref; 2006 goto free_prelim_ref;
2007 2007
2008 err = btrfs_interface_init();
2009 if (err)
2010 goto free_end_io_wq;
2011
2008 btrfs_init_lockdep(); 2012 btrfs_init_lockdep();
2009 2013
2010 btrfs_print_info(); 2014 btrfs_print_info();
@@ -2021,6 +2025,8 @@ static int __init init_btrfs_fs(void)
2021 2025
2022unregister_ioctl: 2026unregister_ioctl:
2023 btrfs_interface_exit(); 2027 btrfs_interface_exit();
2028free_end_io_wq:
2029 btrfs_end_io_wq_exit();
2024free_prelim_ref: 2030free_prelim_ref:
2025 btrfs_prelim_ref_exit(); 2031 btrfs_prelim_ref_exit();
2026free_delayed_ref: 2032free_delayed_ref: