Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-linus' of git://git.kernel.dk/linux-block

Pull block fixes from Jens Axboe:
"Four smaller fixes for the current series. This contains:

- A fix for clones of discard bio's, that can cause data corruption.
From Martin.

- A fix for null_blk, where in certain queue modes it could access a
request after it had been freed. From Mike Krinkin.

- An error handling leak fix for blkcg, from Tejun.

- Also from Tejun, export of the functions that a file system needs
to implement cgroup writeback support"

* 'for-linus' of git://git.kernel.dk/linux-block:
block: Do a full clone when splitting discard bios
block: export bio_associate_*() and wbc_account_io()
blkcg: fix gendisk reference leak in blkg_conf_prep()
null_blk: fix use-after-free problem

+29 -13
+14 -3
block/bio.c
··· 1831 1831 * Allocates and returns a new bio which represents @sectors from the start of 1832 1832 * @bio, and updates @bio to represent the remaining sectors. 1833 1833 * 1834 - * The newly allocated bio will point to @bio's bi_io_vec; it is the caller's 1835 - * responsibility to ensure that @bio is not freed before the split. 1834 + * Unless this is a discard request the newly allocated bio will point 1835 + * to @bio's bi_io_vec; it is the caller's responsibility to ensure that 1836 + * @bio is not freed before the split. 1836 1837 */ 1837 1838 struct bio *bio_split(struct bio *bio, int sectors, 1838 1839 gfp_t gfp, struct bio_set *bs) ··· 1843 1842 BUG_ON(sectors <= 0); 1844 1843 BUG_ON(sectors >= bio_sectors(bio)); 1845 1844 1846 - split = bio_clone_fast(bio, gfp, bs); 1845 + /* 1846 + * Discards need a mutable bio_vec to accommodate the payload 1847 + * required by the DSM TRIM and UNMAP commands. 1848 + */ 1849 + if (bio->bi_rw & REQ_DISCARD) 1850 + split = bio_clone_bioset(bio, gfp, bs); 1851 + else 1852 + split = bio_clone_fast(bio, gfp, bs); 1853 + 1847 1854 if (!split) 1848 1855 return NULL; 1849 1856 ··· 2018 2009 bio->bi_css = blkcg_css; 2019 2010 return 0; 2020 2011 } 2012 + EXPORT_SYMBOL_GPL(bio_associate_blkcg); 2021 2013 2022 2014 /** 2023 2015 * bio_associate_current - associate a bio with %current ··· 2049 2039 bio->bi_css = task_get_css(current, blkio_cgrp_id); 2050 2040 return 0; 2051 2041 } 2042 + EXPORT_SYMBOL_GPL(bio_associate_current); 2052 2043 2053 2044 /** 2054 2045 * bio_disassociate_task - undo bio_associate_current()
+5 -1
block/blk-cgroup.c
··· 718 718 return -EINVAL; 719 719 720 720 disk = get_gendisk(MKDEV(major, minor), &part); 721 - if (!disk || part) 721 + if (!disk) 722 722 return -EINVAL; 723 + if (part) { 724 + put_disk(disk); 725 + return -EINVAL; 726 + } 723 727 724 728 rcu_read_lock(); 725 729 spin_lock_irq(disk->queue->queue_lock);
+9 -9
drivers/block/null_blk.c
··· 240 240 while ((entry = llist_del_all(&cq->list)) != NULL) { 241 241 entry = llist_reverse_order(entry); 242 242 do { 243 + struct request_queue *q = NULL; 244 + 243 245 cmd = container_of(entry, struct nullb_cmd, ll_list); 244 246 entry = entry->next; 247 + if (cmd->rq) 248 + q = cmd->rq->q; 245 249 end_cmd(cmd); 246 250 247 - if (cmd->rq) { 248 - struct request_queue *q = cmd->rq->q; 249 - 250 - if (!q->mq_ops && blk_queue_stopped(q)) { 251 - spin_lock(q->queue_lock); 252 - if (blk_queue_stopped(q)) 253 - blk_start_queue(q); 254 - spin_unlock(q->queue_lock); 255 - } 251 + if (q && !q->mq_ops && blk_queue_stopped(q)) { 252 + spin_lock(q->queue_lock); 253 + if (blk_queue_stopped(q)) 254 + blk_start_queue(q); 255 + spin_unlock(q->queue_lock); 256 256 } 257 257 } while (entry); 258 258 }
+1
fs/fs-writeback.c
··· 702 702 else 703 703 wbc->wb_tcand_bytes -= min(bytes, wbc->wb_tcand_bytes); 704 704 } 705 + EXPORT_SYMBOL_GPL(wbc_account_io); 705 706 706 707 /** 707 708 * inode_congested - test whether an inode is congested