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

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

* 'for-2.6.25' of git://git.kernel.dk/linux-2.6-block:
block: implement drain buffers
__bio_clone: don't calculate hw/phys segment counts
block: allow queue dma_alignment of zero
blktrace: Add blktrace ioctls to SCSI generic devices

+123 -24
+14 -10
block/blktrace.c
··· 235 235 kfree(bt); 236 236 } 237 237 238 - static int blk_trace_remove(struct request_queue *q) 238 + int blk_trace_remove(struct request_queue *q) 239 239 { 240 240 struct blk_trace *bt; 241 241 ··· 249 249 250 250 return 0; 251 251 } 252 + EXPORT_SYMBOL_GPL(blk_trace_remove); 252 253 253 254 static int blk_dropped_open(struct inode *inode, struct file *filp) 254 255 { ··· 317 316 /* 318 317 * Setup everything required to start tracing 319 318 */ 320 - int do_blk_trace_setup(struct request_queue *q, struct block_device *bdev, 319 + int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, 321 320 struct blk_user_trace_setup *buts) 322 321 { 323 322 struct blk_trace *old_bt, *bt = NULL; 324 323 struct dentry *dir = NULL; 325 - char b[BDEVNAME_SIZE]; 326 324 int ret, i; 327 325 328 326 if (!buts->buf_size || !buts->buf_nr) 329 327 return -EINVAL; 330 328 331 - strcpy(buts->name, bdevname(bdev, b)); 329 + strcpy(buts->name, name); 332 330 333 331 /* 334 332 * some device names have larger paths - convert the slashes ··· 352 352 goto err; 353 353 354 354 bt->dir = dir; 355 - bt->dev = bdev->bd_dev; 355 + bt->dev = dev; 356 356 atomic_set(&bt->dropped, 0); 357 357 358 358 ret = -EIO; ··· 399 399 return ret; 400 400 } 401 401 402 - static int blk_trace_setup(struct request_queue *q, struct block_device *bdev, 403 - char __user *arg) 402 + int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, 403 + char __user *arg) 404 404 { 405 405 struct blk_user_trace_setup buts; 406 406 int ret; ··· 409 409 if (ret) 410 410 return -EFAULT; 411 411 412 - ret = do_blk_trace_setup(q, bdev, &buts); 412 + ret = do_blk_trace_setup(q, name, dev, &buts); 413 413 if (ret) 414 414 return ret; 415 415 ··· 418 418 419 419 return 0; 420 420 } 421 + EXPORT_SYMBOL_GPL(blk_trace_setup); 421 422 422 - static int blk_trace_startstop(struct request_queue *q, int start) 423 + int blk_trace_startstop(struct request_queue *q, int start) 423 424 { 424 425 struct blk_trace *bt; 425 426 int ret; ··· 453 452 454 453 return ret; 455 454 } 455 + EXPORT_SYMBOL_GPL(blk_trace_startstop); 456 456 457 457 /** 458 458 * blk_trace_ioctl: - handle the ioctls associated with tracing ··· 466 464 { 467 465 struct request_queue *q; 468 466 int ret, start = 0; 467 + char b[BDEVNAME_SIZE]; 469 468 470 469 q = bdev_get_queue(bdev); 471 470 if (!q) ··· 476 473 477 474 switch (cmd) { 478 475 case BLKTRACESETUP: 479 - ret = blk_trace_setup(q, bdev, arg); 476 + strcpy(b, bdevname(bdev, b)); 477 + ret = blk_trace_setup(q, b, bdev->bd_dev, arg); 480 478 break; 481 479 case BLKTRACESTART: 482 480 start = 1;
+4 -1
block/compat_ioctl.c
··· 545 545 struct blk_user_trace_setup buts; 546 546 struct compat_blk_user_trace_setup cbuts; 547 547 struct request_queue *q; 548 + char b[BDEVNAME_SIZE]; 548 549 int ret; 549 550 550 551 q = bdev_get_queue(bdev); ··· 554 553 555 554 if (copy_from_user(&cbuts, arg, sizeof(cbuts))) 556 555 return -EFAULT; 556 + 557 + strcpy(b, bdevname(bdev, b)); 557 558 558 559 buts = (struct blk_user_trace_setup) { 559 560 .act_mask = cbuts.act_mask, ··· 568 565 memcpy(&buts.name, &cbuts.name, 32); 569 566 570 567 mutex_lock(&bdev->bd_mutex); 571 - ret = do_blk_trace_setup(q, bdev, &buts); 568 + ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts); 572 569 mutex_unlock(&bdev->bd_mutex); 573 570 if (ret) 574 571 return ret;
+25 -1
block/elevator.c
··· 741 741 q->boundary_rq = NULL; 742 742 } 743 743 744 - if ((rq->cmd_flags & REQ_DONTPREP) || !q->prep_rq_fn) 744 + if (rq->cmd_flags & REQ_DONTPREP) 745 + break; 746 + 747 + if (q->dma_drain_size && rq->data_len) { 748 + /* 749 + * make sure space for the drain appears we 750 + * know we can do this because max_hw_segments 751 + * has been adjusted to be one fewer than the 752 + * device can handle 753 + */ 754 + rq->nr_phys_segments++; 755 + rq->nr_hw_segments++; 756 + } 757 + 758 + if (!q->prep_rq_fn) 745 759 break; 746 760 747 761 ret = q->prep_rq_fn(q, rq); ··· 768 754 * avoid resource deadlock. REQ_STARTED will 769 755 * prevent other fs requests from passing this one. 770 756 */ 757 + if (q->dma_drain_size && rq->data_len && 758 + !(rq->cmd_flags & REQ_DONTPREP)) { 759 + /* 760 + * remove the space for the drain we added 761 + * so that we don't add it again 762 + */ 763 + --rq->nr_phys_segments; 764 + --rq->nr_hw_segments; 765 + } 766 + 771 767 rq = NULL; 772 768 break; 773 769 } else if (ret == BLKPREP_KILL) {
+49
block/ll_rw_blk.c
··· 721 721 EXPORT_SYMBOL(blk_queue_stack_limits); 722 722 723 723 /** 724 + * blk_queue_dma_drain - Set up a drain buffer for excess dma. 725 + * 726 + * @q: the request queue for the device 727 + * @buf: physically contiguous buffer 728 + * @size: size of the buffer in bytes 729 + * 730 + * Some devices have excess DMA problems and can't simply discard (or 731 + * zero fill) the unwanted piece of the transfer. They have to have a 732 + * real area of memory to transfer it into. The use case for this is 733 + * ATAPI devices in DMA mode. If the packet command causes a transfer 734 + * bigger than the transfer size some HBAs will lock up if there 735 + * aren't DMA elements to contain the excess transfer. What this API 736 + * does is adjust the queue so that the buf is always appended 737 + * silently to the scatterlist. 738 + * 739 + * Note: This routine adjusts max_hw_segments to make room for 740 + * appending the drain buffer. If you call 741 + * blk_queue_max_hw_segments() or blk_queue_max_phys_segments() after 742 + * calling this routine, you must set the limit to one fewer than your 743 + * device can support otherwise there won't be room for the drain 744 + * buffer. 745 + */ 746 + int blk_queue_dma_drain(struct request_queue *q, void *buf, 747 + unsigned int size) 748 + { 749 + if (q->max_hw_segments < 2 || q->max_phys_segments < 2) 750 + return -EINVAL; 751 + /* make room for appending the drain */ 752 + --q->max_hw_segments; 753 + --q->max_phys_segments; 754 + q->dma_drain_buffer = buf; 755 + q->dma_drain_size = size; 756 + 757 + return 0; 758 + } 759 + 760 + EXPORT_SYMBOL_GPL(blk_queue_dma_drain); 761 + 762 + /** 724 763 * blk_queue_segment_boundary - set boundary rules for segment merging 725 764 * @q: the request queue for the device 726 765 * @mask: the memory boundary mask ··· 1412 1373 } 1413 1374 bvprv = bvec; 1414 1375 } /* segments in rq */ 1376 + 1377 + if (q->dma_drain_size) { 1378 + sg->page_link &= ~0x02; 1379 + sg = sg_next(sg); 1380 + sg_set_page(sg, virt_to_page(q->dma_drain_buffer), 1381 + q->dma_drain_size, 1382 + ((unsigned long)q->dma_drain_buffer) & 1383 + (PAGE_SIZE - 1)); 1384 + nsegs++; 1385 + } 1415 1386 1416 1387 if (sg) 1417 1388 sg_mark_end(sg);
+12
drivers/scsi/sg.c
··· 48 48 #include <linux/blkdev.h> 49 49 #include <linux/delay.h> 50 50 #include <linux/scatterlist.h> 51 + #include <linux/blktrace_api.h> 51 52 52 53 #include "scsi.h" 53 54 #include <scsi/scsi_dbg.h> ··· 1068 1067 case BLKSECTGET: 1069 1068 return put_user(sdp->device->request_queue->max_sectors * 512, 1070 1069 ip); 1070 + case BLKTRACESETUP: 1071 + return blk_trace_setup(sdp->device->request_queue, 1072 + sdp->disk->disk_name, 1073 + sdp->device->sdev_gendev.devt, 1074 + (char *)arg); 1075 + case BLKTRACESTART: 1076 + return blk_trace_startstop(sdp->device->request_queue, 1); 1077 + case BLKTRACESTOP: 1078 + return blk_trace_startstop(sdp->device->request_queue, 0); 1079 + case BLKTRACETEARDOWN: 1080 + return blk_trace_remove(sdp->device->request_queue); 1071 1081 default: 1072 1082 if (read_only) 1073 1083 return -EPERM; /* don't know so take safe approach */
+4 -4
fs/bio.c
··· 248 248 */ 249 249 void __bio_clone(struct bio *bio, struct bio *bio_src) 250 250 { 251 - struct request_queue *q = bdev_get_queue(bio_src->bi_bdev); 252 - 253 251 memcpy(bio->bi_io_vec, bio_src->bi_io_vec, 254 252 bio_src->bi_max_vecs * sizeof(struct bio_vec)); 255 253 254 + /* 255 + * most users will be overriding ->bi_bdev with a new target, 256 + * so we don't set nor calculate new physical/hw segment counts here 257 + */ 256 258 bio->bi_sector = bio_src->bi_sector; 257 259 bio->bi_bdev = bio_src->bi_bdev; 258 260 bio->bi_flags |= 1 << BIO_CLONED; ··· 262 260 bio->bi_vcnt = bio_src->bi_vcnt; 263 261 bio->bi_size = bio_src->bi_size; 264 262 bio->bi_idx = bio_src->bi_idx; 265 - bio_phys_segments(q, bio); 266 - bio_hw_segments(q, bio); 267 263 } 268 264 269 265 /**
+5 -6
include/linux/blkdev.h
··· 356 356 unsigned int max_segment_size; 357 357 358 358 unsigned long seg_boundary_mask; 359 + void *dma_drain_buffer; 360 + unsigned int dma_drain_size; 359 361 unsigned int dma_alignment; 360 362 361 363 struct blk_queue_tag *queue_tags; ··· 694 692 extern void blk_queue_max_segment_size(struct request_queue *, unsigned int); 695 693 extern void blk_queue_hardsect_size(struct request_queue *, unsigned short); 696 694 extern void blk_queue_stack_limits(struct request_queue *t, struct request_queue *b); 695 + extern int blk_queue_dma_drain(struct request_queue *q, void *buf, 696 + unsigned int size); 697 697 extern void blk_queue_segment_boundary(struct request_queue *, unsigned long); 698 698 extern void blk_queue_prep_rq(struct request_queue *, prep_rq_fn *pfn); 699 699 extern void blk_queue_merge_bvec(struct request_queue *, merge_bvec_fn *); ··· 772 768 773 769 static inline int queue_dma_alignment(struct request_queue *q) 774 770 { 775 - int retval = 511; 776 - 777 - if (q && q->dma_alignment) 778 - retval = q->dma_alignment; 779 - 780 - return retval; 771 + return q ? q->dma_alignment : 511; 781 772 } 782 773 783 774 /* assumes size > 256 */
+10 -2
include/linux/blktrace_api.h
··· 148 148 extern void blk_trace_shutdown(struct request_queue *); 149 149 extern void __blk_add_trace(struct blk_trace *, sector_t, int, int, u32, int, int, void *); 150 150 extern int do_blk_trace_setup(struct request_queue *q, 151 - struct block_device *bdev, struct blk_user_trace_setup *buts); 151 + char *name, dev_t dev, struct blk_user_trace_setup *buts); 152 152 153 153 154 154 /** ··· 282 282 __blk_add_trace(bt, from, bio->bi_size, bio->bi_rw, BLK_TA_REMAP, !bio_flagged(bio, BIO_UPTODATE), sizeof(r), &r); 283 283 } 284 284 285 + extern int blk_trace_setup(request_queue_t *q, char *name, dev_t dev, 286 + char __user *arg); 287 + extern int blk_trace_startstop(request_queue_t *q, int start); 288 + extern int blk_trace_remove(request_queue_t *q); 289 + 285 290 #else /* !CONFIG_BLK_DEV_IO_TRACE */ 286 291 #define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) 287 292 #define blk_trace_shutdown(q) do { } while (0) ··· 295 290 #define blk_add_trace_generic(q, rq, rw, what) do { } while (0) 296 291 #define blk_add_trace_pdu_int(q, what, bio, pdu) do { } while (0) 297 292 #define blk_add_trace_remap(q, bio, dev, f, t) do {} while (0) 298 - #define do_blk_trace_setup(q, bdev, buts) (-ENOTTY) 293 + #define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY) 294 + #define blk_trace_setup(q, name, dev, arg) (-ENOTTY) 295 + #define blk_trace_startstop(q, start) (-ENOTTY) 296 + #define blk_trace_remove(q) (-ENOTTY) 299 297 #endif /* CONFIG_BLK_DEV_IO_TRACE */ 300 298 #endif /* __KERNEL__ */ 301 299 #endif