Skip to content

Commit

Permalink
Merge branch 'for-linus' of git://git.kernel.dk/linux-2.6-block
Browse files Browse the repository at this point in the history
* 'for-linus' of git://git.kernel.dk/linux-2.6-block: (41 commits)
  Revert "Seperate read and write statistics of in_flight requests"
  cfq-iosched: don't delay async queue if it hasn't dispatched at all
  block: Topology ioctls
  cfq-iosched: use assigned slice sync value, not default
  cfq-iosched: rename 'desktop' sysfs entry to 'low_latency'
  cfq-iosched: implement slower async initiate and queue ramp up
  cfq-iosched: delay async IO dispatch, if sync IO was just done
  cfq-iosched: add a knob for desktop interactiveness
  Add a tracepoint for block request remapping
  block: allow large discard requests
  block: use normal I/O path for discard requests
  swapfile: avoid NULL pointer dereference in swapon when s_bdev is NULL
  fs/bio.c: move EXPORT* macros to line after function
  Add missing blk_trace_remove_sysfs to be in pair with blk_trace_init_sysfs
  cciss: fix build when !PROC_FS
  block: Do not clamp max_hw_sectors for stacking devices
  block: Set max_sectors correctly for stacking devices
  cciss: cciss_host_attr_groups should be const
  cciss: Dynamically allocate the drive_info_struct for each logical drive.
  cciss: Add usage_count attribute to each logical drive in /sys
  ...
  • Loading branch information
torvalds committed Oct 4, 2009
2 parents 8a0382f + 0f78ab9 commit 58e57fb
Show file tree
Hide file tree
Showing 26 changed files with 999 additions and 480 deletions.
28 changes: 28 additions & 0 deletions Documentation/ABI/testing/sysfs-bus-pci-devices-cciss
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,31 @@ Date: March 2009
Kernel Version: 2.6.30
Contact: [email protected]
Description: A symbolic link to /sys/block/cciss!cXdY

Where: /sys/bus/pci/devices/<dev>/ccissX/rescan
Date: August 2009
Kernel Version: 2.6.31
Contact: [email protected]
Description: Kicks of a rescan of the controller to discover logical
drive topology changes.

Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/lunid
Date: August 2009
Kernel Version: 2.6.31
Contact: [email protected]
Description: Displays the 8-byte LUN ID used to address logical
drive Y of controller X.

Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/raid_level
Date: August 2009
Kernel Version: 2.6.31
Contact: [email protected]
Description: Displays the RAID level of logical drive Y of
controller X.

Where: /sys/bus/pci/devices/<dev>/ccissX/cXdY/usage_count
Date: August 2009
Kernel Version: 2.6.31
Contact: [email protected]
Description: Displays the usage count (number of opens) of logical drive Y
of controller X.
45 changes: 36 additions & 9 deletions block/blk-barrier.c
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,7 @@ static void blkdev_discard_end_io(struct bio *bio, int err)

if (bio->bi_private)
complete(bio->bi_private);
__free_page(bio_page(bio));

bio_put(bio);
}
Expand All @@ -372,30 +373,50 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
struct request_queue *q = bdev_get_queue(bdev);
int type = flags & DISCARD_FL_BARRIER ?
DISCARD_BARRIER : DISCARD_NOBARRIER;
struct bio *bio;
struct page *page;
int ret = 0;

if (!q)
return -ENXIO;

if (!q->prepare_discard_fn)
if (!blk_queue_discard(q))
return -EOPNOTSUPP;

while (nr_sects && !ret) {
struct bio *bio = bio_alloc(gfp_mask, 0);
if (!bio)
return -ENOMEM;
unsigned int sector_size = q->limits.logical_block_size;
unsigned int max_discard_sectors =
min(q->limits.max_discard_sectors, UINT_MAX >> 9);

bio = bio_alloc(gfp_mask, 1);
if (!bio)
goto out;
bio->bi_sector = sector;
bio->bi_end_io = blkdev_discard_end_io;
bio->bi_bdev = bdev;
if (flags & DISCARD_FL_WAIT)
bio->bi_private = &wait;

bio->bi_sector = sector;
/*
* Add a zeroed one-sector payload as that's what
* our current implementations need. If we'll ever need
* more the interface will need revisiting.
*/
page = alloc_page(GFP_KERNEL | __GFP_ZERO);
if (!page)
goto out_free_bio;
if (bio_add_pc_page(q, bio, page, sector_size, 0) < sector_size)
goto out_free_page;

if (nr_sects > queue_max_hw_sectors(q)) {
bio->bi_size = queue_max_hw_sectors(q) << 9;
nr_sects -= queue_max_hw_sectors(q);
sector += queue_max_hw_sectors(q);
/*
* And override the bio size - the way discard works we
* touch many more blocks on disk than the actual payload
* length.
*/
if (nr_sects > max_discard_sectors) {
bio->bi_size = max_discard_sectors << 9;
nr_sects -= max_discard_sectors;
sector += max_discard_sectors;
} else {
bio->bi_size = nr_sects << 9;
nr_sects = 0;
Expand All @@ -414,5 +435,11 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
bio_put(bio);
}
return ret;
out_free_page:
__free_page(page);
out_free_bio:
bio_put(bio);
out:
return -ENOMEM;
}
EXPORT_SYMBOL(blkdev_issue_discard);
21 changes: 15 additions & 6 deletions block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "blk.h"

EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap);
EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete);

static int __make_request(struct request_queue *q, struct bio *bio);
Expand Down Expand Up @@ -69,7 +70,7 @@ static void drive_stat_acct(struct request *rq, int new_io)
part_stat_inc(cpu, part, merges[rw]);
else {
part_round_stats(cpu, part);
part_inc_in_flight(part, rw);
part_inc_in_flight(part);
}

part_stat_unlock();
Expand Down Expand Up @@ -1031,7 +1032,7 @@ static void part_round_stats_single(int cpu, struct hd_struct *part,

if (part->in_flight) {
__part_stat_add(cpu, part, time_in_queue,
part_in_flight(part) * (now - part->stamp));
part->in_flight * (now - part->stamp));
__part_stat_add(cpu, part, io_ticks, (now - part->stamp));
}
part->stamp = now;
Expand Down Expand Up @@ -1124,7 +1125,6 @@ void init_request_from_bio(struct request *req, struct bio *bio)
req->cmd_flags |= REQ_DISCARD;
if (bio_rw_flagged(bio, BIO_RW_BARRIER))
req->cmd_flags |= REQ_SOFTBARRIER;
req->q->prepare_discard_fn(req->q, req);
} else if (unlikely(bio_rw_flagged(bio, BIO_RW_BARRIER)))
req->cmd_flags |= REQ_HARDBARRIER;

Expand Down Expand Up @@ -1437,7 +1437,8 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;
}

if (unlikely(nr_sectors > queue_max_hw_sectors(q))) {
if (unlikely(!bio_rw_flagged(bio, BIO_RW_DISCARD) &&
nr_sectors > queue_max_hw_sectors(q))) {
printk(KERN_ERR "bio too big device %s (%u > %u)\n",
bdevname(bio->bi_bdev, b),
bio_sectors(bio),
Expand Down Expand Up @@ -1470,7 +1471,7 @@ static inline void __generic_make_request(struct bio *bio)
goto end_io;

if (bio_rw_flagged(bio, BIO_RW_DISCARD) &&
!q->prepare_discard_fn) {
!blk_queue_discard(q)) {
err = -EOPNOTSUPP;
goto end_io;
}
Expand Down Expand Up @@ -1738,7 +1739,7 @@ static void blk_account_io_done(struct request *req)
part_stat_inc(cpu, part, ios[rw]);
part_stat_add(cpu, part, ticks[rw], duration);
part_round_stats(cpu, part);
part_dec_in_flight(part, rw);
part_dec_in_flight(part);

part_stat_unlock();
}
Expand Down Expand Up @@ -2491,6 +2492,14 @@ int kblockd_schedule_work(struct request_queue *q, struct work_struct *work)
}
EXPORT_SYMBOL(kblockd_schedule_work);

int kblockd_schedule_delayed_work(struct request_queue *q,
struct delayed_work *work,
unsigned long delay)
{
return queue_delayed_work(kblockd_workqueue, work, delay);
}
EXPORT_SYMBOL(kblockd_schedule_delayed_work);

int __init blk_dev_init(void)
{
BUILD_BUG_ON(__REQ_NR_BITS > 8 *
Expand Down
2 changes: 1 addition & 1 deletion block/blk-merge.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ static void blk_account_io_merge(struct request *req)
part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));

part_round_stats(cpu, part);
part_dec_in_flight(part, rq_data_dir(req));
part_dec_in_flight(part);

part_stat_unlock();
}
Expand Down
34 changes: 16 additions & 18 deletions block/blk-settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,23 +33,6 @@ void blk_queue_prep_rq(struct request_queue *q, prep_rq_fn *pfn)
}
EXPORT_SYMBOL(blk_queue_prep_rq);

/**
* blk_queue_set_discard - set a discard_sectors function for queue
* @q: queue
* @dfn: prepare_discard function
*
* It's possible for a queue to register a discard callback which is used
* to transform a discard request into the appropriate type for the
* hardware. If none is registered, then discard requests are failed
* with %EOPNOTSUPP.
*
*/
void blk_queue_set_discard(struct request_queue *q, prepare_discard_fn *dfn)
{
q->prepare_discard_fn = dfn;
}
EXPORT_SYMBOL(blk_queue_set_discard);

/**
* blk_queue_merge_bvec - set a merge_bvec function for queue
* @q: queue
Expand Down Expand Up @@ -111,7 +94,9 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->max_hw_segments = MAX_HW_SEGMENTS;
lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
lim->max_segment_size = MAX_SEGMENT_SIZE;
lim->max_sectors = lim->max_hw_sectors = SAFE_MAX_SECTORS;
lim->max_sectors = BLK_DEF_MAX_SECTORS;
lim->max_hw_sectors = INT_MAX;
lim->max_discard_sectors = SAFE_MAX_SECTORS;
lim->logical_block_size = lim->physical_block_size = lim->io_min = 512;
lim->bounce_pfn = (unsigned long)(BLK_BOUNCE_ANY >> PAGE_SHIFT);
lim->alignment_offset = 0;
Expand Down Expand Up @@ -164,6 +149,7 @@ void blk_queue_make_request(struct request_queue *q, make_request_fn *mfn)
q->unplug_timer.data = (unsigned long)q;

blk_set_default_limits(&q->limits);
blk_queue_max_sectors(q, SAFE_MAX_SECTORS);

/*
* If the caller didn't supply a lock, fall back to our embedded
Expand Down Expand Up @@ -253,6 +239,18 @@ void blk_queue_max_hw_sectors(struct request_queue *q, unsigned int max_sectors)
}
EXPORT_SYMBOL(blk_queue_max_hw_sectors);

/**
* blk_queue_max_discard_sectors - set max sectors for a single discard
* @q: the request queue for the device
* @max_discard: maximum number of sectors to discard
**/
void blk_queue_max_discard_sectors(struct request_queue *q,
unsigned int max_discard_sectors)
{
q->limits.max_discard_sectors = max_discard_sectors;
}
EXPORT_SYMBOL(blk_queue_max_discard_sectors);

/**
* blk_queue_max_phys_segments - set max phys segments for a request for this queue
* @q: the request queue for the device
Expand Down
11 changes: 6 additions & 5 deletions block/blk-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,7 @@ int blk_register_queue(struct gendisk *disk)
if (ret) {
kobject_uevent(&q->kobj, KOBJ_REMOVE);
kobject_del(&q->kobj);
blk_trace_remove_sysfs(disk_to_dev(disk));
return ret;
}

Expand All @@ -465,11 +466,11 @@ void blk_unregister_queue(struct gendisk *disk)
if (WARN_ON(!q))
return;

if (q->request_fn) {
if (q->request_fn)
elv_unregister_queue(q);

kobject_uevent(&q->kobj, KOBJ_REMOVE);
kobject_del(&q->kobj);
kobject_put(&disk_to_dev(disk)->kobj);
}
kobject_uevent(&q->kobj, KOBJ_REMOVE);
kobject_del(&q->kobj);
blk_trace_remove_sysfs(disk_to_dev(disk));
kobject_put(&disk_to_dev(disk)->kobj);
}
Loading

0 comments on commit 58e57fb

Please sign in to comment.