diff options
-rw-r--r-- | fs/btrfs/disk-io.c | 38 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/super.c | 8 |
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); | |||
72 | static void btrfs_error_commit_super(struct btrfs_root *root); | 72 | static 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 | */ |
79 | struct end_io_wq { | 79 | struct 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 | ||
90 | static struct kmem_cache *btrfs_end_io_wq_cache; | ||
91 | |||
92 | int __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 | |||
104 | void 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 | ||
691 | static void end_workqueue_bio(struct bio *bio, int err) | 711 | static 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) | |||
736 | int btrfs_bio_wq_end_io(struct btrfs_fs_info *info, struct bio *bio, | 756 | int 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) | |||
1723 | static void end_workqueue_fn(struct btrfs_work *work) | 1743 | static 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 *)); |
143 | int btrfs_calc_num_tolerated_disk_barrier_failures( | 143 | int btrfs_calc_num_tolerated_disk_barrier_failures( |
144 | struct btrfs_fs_info *fs_info); | 144 | struct btrfs_fs_info *fs_info); |
145 | int __init btrfs_end_io_wq_init(void); | ||
146 | void btrfs_end_io_wq_exit(void); | ||
145 | 147 | ||
146 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | 148 | #ifdef CONFIG_DEBUG_LOCK_ALLOC |
147 | void btrfs_init_lockdep(void); | 149 | void 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 | ||
2022 | unregister_ioctl: | 2026 | unregister_ioctl: |
2023 | btrfs_interface_exit(); | 2027 | btrfs_interface_exit(); |
2028 | free_end_io_wq: | ||
2029 | btrfs_end_io_wq_exit(); | ||
2024 | free_prelim_ref: | 2030 | free_prelim_ref: |
2025 | btrfs_prelim_ref_exit(); | 2031 | btrfs_prelim_ref_exit(); |
2026 | free_delayed_ref: | 2032 | free_delayed_ref: |