aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Du <duyuyang@gmail.com>2009-04-14 01:58:56 -0400
committerIngo Molnar <mingo@elte.hu>2009-04-16 04:10:57 -0400
commitd0deef5b14af7d5bbd0003a0a2a1a32326e20a6d (patch)
treede1d438935a4cc50dd9d7e0ccccc3cfc5c7e6c06
parent9cfe06f8cd5c8c3ad6ab323973e87dde670642b8 (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.c2
-rw-r--r--drivers/scsi/sg.c1
-rw-r--r--include/linux/blktrace_api.h24
-rw-r--r--kernel/trace/blktrace.c29
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
166extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *); 166extern int blk_trace_ioctl(struct block_device *, unsigned, char __user *);
167extern void blk_trace_shutdown(struct request_queue *); 167extern void blk_trace_shutdown(struct request_queue *);
168extern int do_blk_trace_setup(struct request_queue *q, 168extern 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);
170extern void __trace_note_message(struct blk_trace *, const char *fmt, ...); 171extern 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, ...);
193extern void blk_add_driver_data(struct request_queue *q, struct request *rq, 194extern void blk_add_driver_data(struct request_queue *q, struct request *rq,
194 void *data, size_t len); 195 void *data, size_t len);
195extern int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, 196extern 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);
197extern int blk_trace_startstop(struct request_queue *q, int start); 199extern int blk_trace_startstop(struct request_queue *q, int start);
198extern int blk_trace_remove(struct request_queue *q); 200extern int blk_trace_remove(struct request_queue *q);
@@ -200,15 +202,15 @@ extern int blk_trace_remove(struct request_queue *q);
200extern struct attribute_group blk_trace_attr_group; 202extern 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 */
409int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, 409int 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
507int blk_trace_setup(struct request_queue *q, char *name, dev_t dev, 519int 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;