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 /kernel/trace/blktrace.c | |
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>
Diffstat (limited to 'kernel/trace/blktrace.c')
-rw-r--r-- | kernel/trace/blktrace.c | 29 |
1 files changed, 21 insertions, 8 deletions
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; |