aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bio.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/bio.c b/fs/bio.c
index 84da88539046..73922abba832 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -19,12 +19,14 @@
19#include <linux/swap.h> 19#include <linux/swap.h>
20#include <linux/bio.h> 20#include <linux/bio.h>
21#include <linux/blkdev.h> 21#include <linux/blkdev.h>
22#include <linux/iocontext.h>
22#include <linux/slab.h> 23#include <linux/slab.h>
23#include <linux/init.h> 24#include <linux/init.h>
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/export.h> 26#include <linux/export.h>
26#include <linux/mempool.h> 27#include <linux/mempool.h>
27#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/cgroup.h>
28#include <scsi/sg.h> /* for struct sg_iovec */ 30#include <scsi/sg.h> /* for struct sg_iovec */
29 31
30#include <trace/events/block.h> 32#include <trace/events/block.h>
@@ -418,6 +420,7 @@ void bio_put(struct bio *bio)
418 * last put frees it 420 * last put frees it
419 */ 421 */
420 if (atomic_dec_and_test(&bio->bi_cnt)) { 422 if (atomic_dec_and_test(&bio->bi_cnt)) {
423 bio_disassociate_task(bio);
421 bio->bi_next = NULL; 424 bio->bi_next = NULL;
422 bio->bi_destructor(bio); 425 bio->bi_destructor(bio);
423 } 426 }
@@ -1646,6 +1649,64 @@ bad:
1646} 1649}
1647EXPORT_SYMBOL(bioset_create); 1650EXPORT_SYMBOL(bioset_create);
1648 1651
1652#ifdef CONFIG_BLK_CGROUP
1653/**
1654 * bio_associate_current - associate a bio with %current
1655 * @bio: target bio
1656 *
1657 * Associate @bio with %current if it hasn't been associated yet. Block
1658 * layer will treat @bio as if it were issued by %current no matter which
1659 * task actually issues it.
1660 *
1661 * This function takes an extra reference of @task's io_context and blkcg
1662 * which will be put when @bio is released. The caller must own @bio,
1663 * ensure %current->io_context exists, and is responsible for synchronizing
1664 * calls to this function.
1665 */
1666int bio_associate_current(struct bio *bio)
1667{
1668 struct io_context *ioc;
1669 struct cgroup_subsys_state *css;
1670
1671 if (bio->bi_ioc)
1672 return -EBUSY;
1673
1674 ioc = current->io_context;
1675 if (!ioc)
1676 return -ENOENT;
1677
1678 /* acquire active ref on @ioc and associate */
1679 get_io_context_active(ioc);
1680 bio->bi_ioc = ioc;
1681
1682 /* associate blkcg if exists */
1683 rcu_read_lock();
1684 css = task_subsys_state(current, blkio_subsys_id);
1685 if (css && css_tryget(css))
1686 bio->bi_css = css;
1687 rcu_read_unlock();
1688
1689 return 0;
1690}
1691
1692/**
1693 * bio_disassociate_task - undo bio_associate_current()
1694 * @bio: target bio
1695 */
1696void bio_disassociate_task(struct bio *bio)
1697{
1698 if (bio->bi_ioc) {
1699 put_io_context(bio->bi_ioc);
1700 bio->bi_ioc = NULL;
1701 }
1702 if (bio->bi_css) {
1703 css_put(bio->bi_css);
1704 bio->bi_css = NULL;
1705 }
1706}
1707
1708#endif /* CONFIG_BLK_CGROUP */
1709
1649static void __init biovec_init_slabs(void) 1710static void __init biovec_init_slabs(void)
1650{ 1711{
1651 int i; 1712 int i;