diff options
author | Shawn Du <duyuyang@gmail.com> | 2009-04-14 01:58:56 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-04-16 04:10:57 -0400 |
commit | d0deef5b14af7d5bbd0003a0a2a1a32326e20a6d (patch) | |
tree | de1d438935a4cc50dd9d7e0ccccc3cfc5c7e6c06 | |
parent | 9cfe06f8cd5c8c3ad6ab323973e87dde670642b8 (diff) |
blktrace: support per-partition tracing
Though one can specify '-d /dev/sda1' when using blktrace, it still
traces the whole sda.
To support per-partition tracing, when we start tracing, we initialize
bt->start_lba and bt->end_lba to the start and end sector of that
partition.
Note some actions are per device, thus we don't filter 0-sector events.
The original patch and discussion can be found here:
http://marc.info/?l=linux-btrace&m=122949374214540&w=2
Signed-off-by: Shawn Du <duyuyang@gmail.com>
Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Acked-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jens Axboe <jens.axboe@oracle.com>
LKML-Reference: <49E42620.4050701@cn.fujitsu.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | block/compat_ioctl.c | 2 | ||||
-rw-r--r-- | drivers/scsi/sg.c | 1 | ||||
-rw-r--r-- | include/linux/blktrace_api.h | 24 | ||||
-rw-r--r-- | kernel/trace/blktrace.c | 29 |
4 files changed, 36 insertions, 20 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c index f87615dea46b..f8c218cd08e1 100644 --- a/block/compat_ioctl.c +++ b/block/compat_ioctl.c | |||
@@ -568,7 +568,7 @@ static int compat_blk_trace_setup(struct block_device *bdev, char __user *arg) | |||
568 | memcpy(&buts.name, &cbuts.name, 32); | 568 | memcpy(&buts.name, &cbuts.name, 32); |
569 | 569 | ||
570 | mutex_lock(&bdev->bd_mutex); | 570 | mutex_lock(&bdev->bd_mutex); |
571 | ret = do_blk_trace_setup(q, b, bdev->bd_dev, &buts); | 571 | ret = do_blk_trace_setup(q, b, bdev->bd_dev, bdev, &buts); |
572 | mutex_unlock(&bdev->bd_mutex); | 572 | mutex_unlock(&bdev->bd_mutex); |
573 | if (ret) | 573 | if (ret) |
574 | return ret; | 574 | return ret; |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 82312df9b0bf..49c98730bb8d 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -1065,6 +1065,7 @@ sg_ioctl(struct inode *inode, struct file *filp, | |||
1065 | return blk_trace_setup(sdp->device->request_queue, | 1065 | return blk_trace_setup(sdp->device->request_queue, |
1066 | sdp->disk->disk_name, | 1066 | sdp->disk->disk_name, |
1067 | MKDEV(SCSI_GENERIC_MAJOR, sdp->index), | 1067 | MKDEV(SCSI_GENERIC_MAJOR, sdp->index), |
1068 | NULL, | ||
1068 | (char *)arg); | 1069 | (char *)arg); |
1069 | case BLKTRACESTART: | 1070 | case BLKTRACESTART: |
1070 | return blk_trace_startstop(sdp->device->request_queue, 1); | 1071 | return blk_trace_startstop(sdp->device->request_queue, 1); |
diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index d960889e92ef..267edc4017ee 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h | |||
@@ -165,8 +165,9 @@ struct blk_trace { | |||
165 | 165 | ||
166 | extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); | 166 | extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); |
167 | extern void blk_trace_shutdown(struct request_queue *); | 167 | extern void blk_trace_shutdown(struct request_queue *); |
168 | extern int do_blk_trace_setup(struct request_queue *q, | 168 | extern int do_blk_trace_setup(struct request_queue *q, char *name, |
169 | char *name, dev_t dev, struct blk_user_trace_setup *buts); | 169 | dev_t dev, struct block_device *bdev, |
170 | struct blk_user_trace_setup *buts); | ||
170 | extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); | 171 | extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); |
171 | 172 | ||
172 | /** | 173 | /** |
@@ -193,6 +194,7 @@ extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); | |||
193 | extern void blk_add_driver_data(struct request_queue *q, struct request *rq, | 194 | extern void blk_add_driver_data(struct request_queue *q, struct request *rq, |
194 | void *data, size_t len); | 195 | void *data, size_t len); |
195 | extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | 196 | extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, |
197 | struct block_device *bdev, | ||
196 | char __user *arg); | 198 | char __user *arg); |
197 | extern int blk_trace_startstop(struct request_queue *q, int start); | 199 | extern int blk_trace_startstop(struct request_queue *q, int start); |
198 | extern int blk_trace_remove(struct request_queue *q); | 200 | extern int blk_trace_remove(struct request_queue *q); |
@@ -200,15 +202,15 @@ extern int blk_trace_remove(struct request_queue *q); | |||
200 | extern struct attribute_group blk_trace_attr_group; | 202 | extern struct attribute_group blk_trace_attr_group; |
201 | 203 | ||
202 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ | 204 | #else /* !CONFIG_BLK_DEV_IO_TRACE */ |
203 | #define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) | 205 | # define blk_trace_ioctl(bdev, cmd, arg) (-ENOTTY) |
204 | #define blk_trace_shutdown(q) do { } while (0) | 206 | # define blk_trace_shutdown(q) do { } while (0) |
205 | #define do_blk_trace_setup(q, name, dev, buts) (-ENOTTY) | 207 | # define do_blk_trace_setup(q, name, dev, bdev, buts) (-ENOTTY) |
206 | #define blk_add_driver_data(q, rq, data, len) do {} while (0) | 208 | # define blk_add_driver_data(q, rq, data, len) do {} while (0) |
207 | #define blk_trace_setup(q, name, dev, arg) (-ENOTTY) | 209 | # define blk_trace_setup(q, name, dev, bdev, arg) (-ENOTTY) |
208 | #define blk_trace_startstop(q, start) (-ENOTTY) | 210 | # define blk_trace_startstop(q, start) (-ENOTTY) |
209 | #define blk_trace_remove(q) (-ENOTTY) | 211 | # define blk_trace_remove(q) (-ENOTTY) |
210 | #define blk_add_trace_msg(q, fmt, ...) do { } while (0) | 212 | # define blk_add_trace_msg(q, fmt, ...) do { } while (0) |
211 | |||
212 | #endif /* CONFIG_BLK_DEV_IO_TRACE */ | 213 | #endif /* CONFIG_BLK_DEV_IO_TRACE */ |
214 | |||
213 | #endif /* __KERNEL__ */ | 215 | #endif /* __KERNEL__ */ |
214 | #endif | 216 | #endif |
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 2b98195b338b..e932654cf590 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c | |||
@@ -147,7 +147,7 @@ static int act_log_check(struct blk_trace *bt, u32 what, sector_t sector, | |||
147 | { | 147 | { |
148 | if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0) | 148 | if (((bt->act_mask << BLK_TC_SHIFT) & what) == 0) |
149 | return 1; | 149 | return 1; |
150 | if (sector < bt->start_lba || sector > bt->end_lba) | 150 | if (sector && (sector < bt->start_lba || sector > bt->end_lba)) |
151 | return 1; | 151 | return 1; |
152 | if (bt->pid && pid != bt->pid) | 152 | if (bt->pid && pid != bt->pid) |
153 | return 1; | 153 | return 1; |
@@ -192,7 +192,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes, | |||
192 | what |= MASK_TC_BIT(rw, DISCARD); | 192 | what |= MASK_TC_BIT(rw, DISCARD); |
193 | 193 | ||
194 | pid = tsk->pid; | 194 | pid = tsk->pid; |
195 | if (unlikely(act_log_check(bt, what, sector, pid))) | 195 | if (act_log_check(bt, what, sector, pid)) |
196 | return; | 196 | return; |
197 | cpu = raw_smp_processor_id(); | 197 | cpu = raw_smp_processor_id(); |
198 | 198 | ||
@@ -407,11 +407,13 @@ static struct rchan_callbacks blk_relay_callbacks = { | |||
407 | * Setup everything required to start tracing | 407 | * Setup everything required to start tracing |
408 | */ | 408 | */ |
409 | int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | 409 | int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, |
410 | struct blk_user_trace_setup *buts) | 410 | struct block_device *bdev, |
411 | struct blk_user_trace_setup *buts) | ||
411 | { | 412 | { |
412 | struct blk_trace *old_bt, *bt = NULL; | 413 | struct blk_trace *old_bt, *bt = NULL; |
413 | struct dentry *dir = NULL; | 414 | struct dentry *dir = NULL; |
414 | int ret, i; | 415 | int ret, i; |
416 | struct hd_struct *part = NULL; | ||
415 | 417 | ||
416 | if (!buts->buf_size || !buts->buf_nr) | 418 | if (!buts->buf_size || !buts->buf_nr) |
417 | return -EINVAL; | 419 | return -EINVAL; |
@@ -480,11 +482,21 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
480 | if (!bt->act_mask) | 482 | if (!bt->act_mask) |
481 | bt->act_mask = (u16) -1; | 483 | bt->act_mask = (u16) -1; |
482 | 484 | ||
483 | bt->start_lba = buts->start_lba; | 485 | if (bdev) |
484 | bt->end_lba = buts->end_lba; | 486 | part = bdev->bd_part; |
485 | if (!bt->end_lba) | 487 | |
488 | if (part) { | ||
489 | bt->start_lba = part->start_sect; | ||
490 | bt->end_lba = part->start_sect + part->nr_sects; | ||
491 | } else | ||
486 | bt->end_lba = -1ULL; | 492 | bt->end_lba = -1ULL; |
487 | 493 | ||
494 | /* overwrite with user settings */ | ||
495 | if (buts->start_lba) | ||
496 | bt->start_lba = buts->start_lba; | ||
497 | if (buts->end_lba) | ||
498 | bt->end_lba = buts->end_lba; | ||
499 | |||
488 | bt->pid = buts->pid; | 500 | bt->pid = buts->pid; |
489 | bt->trace_state = Blktrace_setup; | 501 | bt->trace_state = Blktrace_setup; |
490 | 502 | ||
@@ -505,6 +517,7 @@ err: | |||
505 | } | 517 | } |
506 | 518 | ||
507 | int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | 519 | int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, |
520 | struct block_device *bdev, | ||
508 | char __user *arg) | 521 | char __user *arg) |
509 | { | 522 | { |
510 | struct blk_user_trace_setup buts; | 523 | struct blk_user_trace_setup buts; |
@@ -514,7 +527,7 @@ int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
514 | if (ret) | 527 | if (ret) |
515 | return -EFAULT; | 528 | return -EFAULT; |
516 | 529 | ||
517 | ret = do_blk_trace_setup(q, name, dev, &buts); | 530 | ret = do_blk_trace_setup(q, name, dev, bdev, &buts); |
518 | if (ret) | 531 | if (ret) |
519 | return ret; | 532 | return ret; |
520 | 533 | ||
@@ -582,7 +595,7 @@ int blk_trace_ioctl(struct block_device *bdev, unsigned cmd, char __user *arg) | |||
582 | switch (cmd) { | 595 | switch (cmd) { |
583 | case BLKTRACESETUP: | 596 | case BLKTRACESETUP: |
584 | bdevname(bdev, b); | 597 | bdevname(bdev, b); |
585 | ret = blk_trace_setup(q, b, bdev->bd_dev, arg); | 598 | ret = blk_trace_setup(q, b, bdev->bd_dev, bdev, arg); |
586 | break; | 599 | break; |
587 | case BLKTRACESTART: | 600 | case BLKTRACESTART: |
588 | start = 1; | 601 | start = 1; |