block/io bits for 2.6.30-rc2
Subsystems (11)
Hi Linus,
Somewhat bigger than expected, but it should be safe. Please pull.
git://git.kernel.dk/linux-2.6-block.git for-linus
Christoph Hellwig (1):
block: move bio list helpers into bio.h
FUJITA Tomonori (1):
block: fix SG_IO to return a proper error value
Jens Axboe (13):
block: fix bad spelling of quiesce
Document and move the various READ/WRITE types
cfq-iosched: use rw_is_sync() to see if rw flags are sync or not
cfq-iosched: get rid of private SYNC/ASYNC defines
as-iosched: get rid of private REQ_SYNC/REQ_ASYNC defines
block: update biodoc.txt on plugging
buffer: switch do_emergency_thaw() away from pdflush_operation()
cfq-iosched: don't delay queue kick for a merged request
bio: add documentation to bio_alloc()
cfq-iosched: no need to save interrupts in cfq_kick_queue()
cfq-iosched: tweak kick logic a bit more
cfq-iosched: log responsible 'cfqq' in idle timer arm
cfq-iosched: add close cooperator code
Miklos Szeredi (6):
splice: split up __splice_from_pipe()
splice: remove i_mutex locking in splice_from_pipe()
splice: fix i_mutex locking in generic_splice_write()
ocfs2: fix i_mutex locking in ocfs2_splice_to_file()
splice: remove generic_file_splice_write_nolock()
splice: add helpers for locking pipe inode
Nick Piggin (2):
brd: support barriers
brd: fix cacheflushing
Nikanth Karthikesan (5):
block: Remove code handling bio_alloc failure with __GFP_WAIT
dio: Remove code handling bio_alloc failure with __GFP_WAIT
ext4: Remove code handling bio_alloc failure with __GFP_WAIT
gfs2: Remove code handling bio_alloc failure with __GFP_WAIT
swap: Remove code handling bio_alloc failure with __GFP_WAIT
Documentation/block/biodoc.txt | 19 +-- block/as-iosched.c | 116 ++++++------- block/blk-barrier.c | 3 - block/blk-sysfs.c | 4 +- block/blk.h | 4 +- block/cfq-iosched.c | 270 ++++++++++++++++++++++++----- block/elevator.c | 8 +- block/ioctl.c | 2 - block/scsi_ioctl.c | 6 +- drivers/block/brd.c | 5 +- drivers/md/dm-bio-list.h | 117 ------------- drivers/md/dm-delay.c | 2 - drivers/md/dm-mpath.c | 1 - drivers/md/dm-raid1.c | 1 - drivers/md/dm-region-hash.c | 1 - drivers/md/dm-snap.c | 1 - drivers/md/dm.c | 1 - drivers/md/raid1.c | 1 - drivers/md/raid10.c | 1 - fs/bio.c | 18 ++ fs/buffer.c | 11 +- fs/direct-io.c | 2 - fs/ext4/extents.c | 2 - fs/gfs2/ops_fstype.c | 5 - fs/inode.c | 36 ---- fs/ocfs2/file.c | 94 ++++++++--- fs/pipe.c | 42 ++++- fs/splice.c | 371 ++++++++++++++++++++-------------------- include/linux/bio.h | 109 ++++++++++++ include/linux/fs.h | 64 +++++++- include/linux/pipe_fs_i.h | 5 + include/linux/splice.h | 12 ++ kernel/power/swap.c | 2 - 33 files changed, 814 insertions(+), 522 deletions(-) delete mode 100644 drivers/md/dm-bio-list.h
---
Documentation/block/biodoc.txt +6 -13
@@ -1040,23 +1040,21 @@ Front merges are handled by the binary trees in AS and deadline schedulers. iii. Plugging the queue to batch requests in anticipation of opportunities for merge/sort optimizations -This is just the same as in 2.4 so far, though per-device unplugging -support is anticipated for 2.5. Also with a priority-based i/o scheduler, -such decisions could be based on request priorities. - Plugging is an approach that the current i/o scheduling algorithm resorts to so that it collects up enough requests in the queue to be able to take advantage of the sorting/merging logic in the elevator. If the queue is empty when a request comes in, then it plugs the request queue -(sort of like plugging the bottom of a vessel to get fluid to build up) +(sort of like plugging the bath tub of a vessel to get fluid to build up) till it fills up with a few more requests, before starting to service the requests. This provides an opportunity to merge/sort the requests before passing them down to the device. There are various conditions when the queue is unplugged (to open up the flow again), either through a scheduled task or could be on demand. For example wait_on_buffer sets the unplugging going -(by running tq_disk) so the read gets satisfied soon. So in the read case, -the queue gets explicitly unplugged as part of waiting for completion, -in fact all queues get unplugged as a side-effect. +through sync_buffer() running blk_run_address_space(mapping). Or the caller +can do it explicity through blk_unplug(bdev). So in the read case, +the queue gets explicitly unplugged as part of waiting for completion on that +buffer. For page driven IO, the address space ->sync_page() takes care of +doing the blk_run_address_space(). Aside: This is kind of controversial territory, as it's not clear if plugging is
@@ -1067,11 +1065,6 @@ Aside: multi-page bios being queued in one shot, we may not need to wait to merge a big request from the broken up pieces coming by. - Per-queue granularity unplugging (still a Todo) may help reduce some of the - concerns with just a single tq_disk flush approach. Something like - blk_kick_queue() to unplug a specific queue (right away ?) - or optionally, all queues, is in the plan. - 4.4 I/O contexts I/O contexts provide a dynamically allocated per process data area. They may be used in I/O schedulers, and in the block layer (could be used for IO statis,
block/as-iosched.c +57 -59
285 lines not on this page · raw message
block/blk-barrier.c +0 -3
@@ -319,9 +319,6 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)return -ENXIO ; bio =bio_alloc (GFP_KERNEL ,0 ); -if (!bio) -return -ENOMEM ; - bio->bi_end_io = bio_end_empty_barrier; bio->bi_private = &wait; bio->bi_bdev = bdev;
block/blk-sysfs.c +2 -2
@@ -209,14 +209,14 @@ static ssize_t queue_iostats_store(struct request_queue *q, const char *page,ssize_t ret =queue_var_store (&stats, page, count);spin_lock_irq (q->queue_lock); -elv_quisce_start (q); +elv_quiesce_start (q);if (stats)queue_flag_set (QUEUE_FLAG_IO_STAT , q);else queue_flag_clear (QUEUE_FLAG_IO_STAT , q); -elv_quisce_end (q); +elv_quiesce_end (q);spin_unlock_irq (q->queue_lock);return ret;
block/blk.h +2 -2
@@ -70,8 +70,8 @@ void blk_queue_congestion_threshold(struct request_queue *q);int blk_dev_init (void ); -void elv_quisce_start (struct request_queue *q); -void elv_quisce_end (struct request_queue *q); +void elv_quiesce_start (struct request_queue *q); +void elv_quiesce_end (struct request_queue *q);/*
block/cfq-iosched.c +225 -45
462 lines not on this page · raw message
block/elevator.c +4 -4
@@ -590,7 +590,7 @@ void elv_drain_elevator(struct request_queue *q)/* * Call with queue lock held, interrupts disabled */ -void elv_quisce_start (struct request_queue *q) +void elv_quiesce_start (struct request_queue *q) {queue_flag_set (QUEUE_FLAG_ELVSWITCH , q);
@@ -607,7 +607,7 @@ void elv_quisce_start(struct request_queue *q) } } -void elv_quisce_end (struct request_queue *q) +void elv_quiesce_end (struct request_queue *q) {queue_flag_clear (QUEUE_FLAG_ELVSWITCH , q); }
@@ -1126,7 +1126,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)* Turn on BYPASS and drain all requests w/ elevator private data */ spin_lock_irq (q->queue_lock); -elv_quisce_start (q); +elv_quiesce_start (q);/* * Remember old elevator.
@@ -1150,7 +1150,7 @@ static int elevator_switch(struct request_queue *q, struct elevator_type *new_e)*/ elevator_exit (old_elevator);spin_lock_irq (q->queue_lock); -elv_quisce_end (q); +elv_quiesce_end (q);spin_unlock_irq (q->queue_lock);blk_add_trace_msg (q,"elv switch: %s" , e->elevator_type->elevator_name);
block/ioctl.c +0 -2
@@ -146,8 +146,6 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,struct bio *bio; bio =bio_alloc (GFP_KERNEL ,0 ); -if (!bio) -return -ENOMEM ; bio->bi_end_io = blk_ioc_discard_endio; bio->bi_bdev = bdev;
block/scsi_ioctl.c +4 -2
@@ -217,7 +217,7 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,static int blk_complete_sghdr_rq (struct request *rq,struct sg_io_hdr *hdr,struct bio *bio) { -int ret =0 ; +int r, ret =0 ;/* * fill in all the output members
@@ -242,7 +242,9 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr, ret = -EFAULT ; } -blk_rq_unmap_user (bio); + r =blk_rq_unmap_user (bio); +if (!ret) + ret = r;blk_put_request (rq);return ret;
drivers/block/brd.c +4 -1
@@ -275,8 +275,10 @@ static int brd_do_bvec(struct brd_device *brd, struct page *page,if (rw ==READ ) {copy_from_brd (mem + off, brd, sector, len);flush_dcache_page (page); - }else + }else { +flush_dcache_page (page);copy_to_brd (brd, mem + off, sector, len); + }kunmap_atomic (mem,KM_USER0 ); out:
@@ -436,6 +438,7 @@ static struct brd_device *brd_alloc(int i)if (!brd->brd_queue) goto out_free_dev;blk_queue_make_request (brd->brd_queue, brd_make_request); +blk_queue_ordered (brd->brd_queue,QUEUE_ORDERED_TAG ,NULL );blk_queue_max_sectors (brd->brd_queue,1024 );blk_queue_bounce_limit (brd->brd_queue,BLK_BOUNCE_ANY );
drivers/md/dm-bio-list.h deleted +0 -117
117 lines not on this page · raw message
drivers/md/dm-delay.c +0 -2
@@ -15,8 +15,6 @@#include <linux/device-mapper.h> -#include "dm-bio-list.h" -#define DM_MSG_PREFIX "delay"struct delay_c {
drivers/md/dm-mpath.c +0 -1
@@ -8,7 +8,6 @@#include <linux/device-mapper.h> #include "dm-path-selector.h" -#include "dm-bio-list.h" #include "dm-bio-record.h" #include "dm-uevent.h"
drivers/md/dm-raid1.c +0 -1
@@ -5,7 +5,6 @@* This file is released under the GPL. */ -#include "dm-bio-list.h" #include "dm-bio-record.h" #include <linux/init.h>
drivers/md/dm-region-hash.c +0 -1
@@ -14,7 +14,6 @@#include <linux/vmalloc.h> #include "dm.h" -#include "dm-bio-list.h" #define DM_MSG_PREFIX "region hash"
drivers/md/dm-snap.c +0 -1
@@ -22,7 +22,6 @@#include <linux/workqueue.h> #include "dm-exception-store.h" -#include "dm-bio-list.h" #define DM_MSG_PREFIX "snapshots"
drivers/md/dm.c +0 -1
@@ -6,7 +6,6 @@*/ #include "dm.h" -#include "dm-bio-list.h" #include "dm-uevent.h" #include <linux/init.h>
drivers/md/raid1.c +0 -1
@@ -35,7 +35,6 @@#include <linux/blkdev.h> #include <linux/seq_file.h> #include "md.h" -#include "dm-bio-list.h" #include "raid1.h" #include "bitmap.h"
drivers/md/raid10.c +0 -1
@@ -22,7 +22,6 @@#include <linux/blkdev.h> #include <linux/seq_file.h> #include "md.h" -#include "dm-bio-list.h" #include "raid10.h" #include "bitmap.h"
fs/bio.c +18 -0
@@ -348,6 +348,24 @@ err:return NULL ; } +/** +* bio_alloc - allocate a bio for I/O +* @gfp_mask: the GFP_ mask given to the slab allocator +* @nr_iovecs: number of iovecs to pre-allocate +* +* Description: +* bio_alloc will allocate a bio and associated bio_vec array that can hold +* at least @nr_iovecs entries. Allocations will be done from the +* fs_bio_set. Also see @bio_alloc_bioset. +* +* If %__GFP_WAIT is set, then bio_alloc will always be able to allocate +* a bio. This is due to the mempool guarantees. To make this work, callers +* must never allocate more than 1 bio at the time from this pool. Callers +* that need to allocate more than 1 bio must always submit the previously +* allocate bio for IO before attempting to allocate a new one. Failure to +* do so can cause livelocks under memory pressure. +* +**/ struct bio *bio_alloc (gfp_t gfp_mask,int nr_iovecs) {struct bio *bio =bio_alloc_bioset (gfp_mask, nr_iovecs, fs_bio_set);
fs/buffer.c +9 -2
@@ -547,7 +547,7 @@ repeat:return err; } -void do_thaw_all (unsigned long unused) +void do_thaw_all (struct work_struct *work) {struct super_block *sb;char b[BDEVNAME_SIZE ];
@@ -567,6 +567,7 @@ restart: goto restart; }spin_unlock (&sb_lock); +kfree (work);printk (KERN_WARNING "Emergency Thaw complete\n" ); }
@@ -577,7 +578,13 @@ restart:*/ void emergency_thaw_all (void ) { -pdflush_operation (do_thaw_all,0 ); +struct work_struct *work; + + work =kmalloc (sizeof (*work),GFP_ATOMIC ); +if (work) { +INIT_WORK (work, do_thaw_all); +schedule_work (work); + } }/**
fs/direct-io.c +0 -2
@@ -307,8 +307,6 @@ dio_bio_alloc(struct dio *dio, struct block_device *bdev,struct bio *bio; bio =bio_alloc (GFP_KERNEL , nr_vecs); -if (bio ==NULL ) -return -ENOMEM ; bio->bi_bdev = bdev; bio->bi_sector = first_sector;
fs/ext4/extents.c +0 -2
@@ -2416,8 +2416,6 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) len = ee_len; bio =bio_alloc (GFP_NOIO , len); -if (!bio) -return -ENOMEM ; bio->bi_sector = ee_pblock; bio->bi_bdev = inode->i_sb->s_bdev;
fs/gfs2/ops_fstype.c +0 -5
@@ -272,11 +272,6 @@ static int gfs2_read_super(struct gfs2_sbd *sdp, sector_t sector)lock_page (page); bio =bio_alloc (GFP_NOFS ,1 ); -if (unlikely (!bio)) { -__free_page (page); -return -ENOBUFS ; - } - bio->bi_sector = sector * (sb->s_blocksize >>9 ); bio->bi_bdev = sb->s_bdev;bio_add_page (bio, page,PAGE_SIZE ,0 );
fs/inode.c +0 -36
@@ -1470,42 +1470,6 @@ static void __wait_on_freeing_inode(struct inode *inode)spin_lock (&inode_lock); } -/* -* We rarely want to lock two inodes that do not have a parent/child -* relationship (such as directory, child inode) simultaneously. The -* vast majority of file systems should be able to get along fine -* without this. Do not use these functions except as a last resort. -*/ -void inode_double_lock (struct inode *inode1,struct inode *inode2) -{ -if (inode1 ==NULL || inode2 ==NULL || inode1 == inode2) { -if (inode1) -mutex_lock (&inode1->i_mutex); -else if (inode2) -mutex_lock (&inode2->i_mutex); -return ; - } - -if (inode1 < inode2) { -mutex_lock_nested (&inode1->i_mutex,I_MUTEX_PARENT ); -mutex_lock_nested (&inode2->i_mutex,I_MUTEX_CHILD ); - }else { -mutex_lock_nested (&inode2->i_mutex,I_MUTEX_PARENT ); -mutex_lock_nested (&inode1->i_mutex,I_MUTEX_CHILD ); - } -} -EXPORT_SYMBOL (inode_double_lock); - -void inode_double_unlock (struct inode *inode1,struct inode *inode2) -{ -if (inode1) -mutex_unlock (&inode1->i_mutex); - -if (inode2 && inode2 != inode1) -mutex_unlock (&inode2->i_mutex); -} -EXPORT_SYMBOL (inode_double_unlock); -static __initdata unsigned long ihash_entries;static int __init set_ihash_entries (char *str) {
fs/ocfs2/file.c +74 -20
118 lines not on this page · raw message
fs/pipe.c +38 -4
56 lines not on this page · raw message
fs/splice.c +186 -185
519 lines not on this page · raw message
include/linux/bio.h +109 -0
115 lines not on this page · raw message
include/linux/fs.h +59 -5
88 lines not on this page · raw message
include/linux/pipe_fs_i.h +5 -0
@@ -134,6 +134,11 @@ struct pipe_buf_operations {memory allocation, whereas PIPE_BUF makes atomicity guarantees. */ #define PIPE_SIZE PAGE_SIZE +/* Pipe lock and unlock operations */ +void pipe_lock (struct pipe_inode_info *); +void pipe_unlock (struct pipe_inode_info *); +void pipe_double_lock (struct pipe_inode_info *,struct pipe_inode_info *); +/* Drop the inode semaphore and wait for a pipe event, atomically */ void pipe_wait (struct pipe_inode_info *pipe);
include/linux/splice.h +12 -0
@@ -36,6 +36,8 @@ struct splice_desc {void *data;/* cookie */ } u;loff_t pos;/* file position */ +size_t num_spliced;/* number of bytes already spliced */ +bool need_wakeup;/* need to wake up writer */ };struct partial_page {
@@ -66,6 +68,16 @@ extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, splice_actor *);extern ssize_t __splice_from_pipe (struct pipe_inode_info *,struct splice_desc *,splice_actor *); +extern int splice_from_pipe_feed (struct pipe_inode_info *,struct splice_desc *, +splice_actor *); +extern int splice_from_pipe_next (struct pipe_inode_info *, +struct splice_desc *); +extern void splice_from_pipe_begin (struct splice_desc *); +extern void splice_from_pipe_end (struct pipe_inode_info *, +struct splice_desc *); +extern int pipe_to_file (struct pipe_inode_info *,struct pipe_buffer *, +struct splice_desc *); +extern ssize_t splice_to_pipe (struct pipe_inode_info *,struct splice_pipe_desc *); extern ssize_t splice_direct_to_actor(struct file *, struct splice_desc *,
kernel/power/swap.c +0 -2
@@ -64,8 +64,6 @@ static int submit(int rw, pgoff_t page_off, struct page *page,struct bio *bio; bio =bio_alloc (__GFP_WAIT | __GFP_HIGH,1 ); -if (!bio) -return -ENOMEM ; bio->bi_sector = page_off * (PAGE_SIZE >>9 ); bio->bi_bdev = resume_bdev; bio->bi_end_io = end_swap_bio_read;
Signature · 1 line
Jens Axboe