diff options
Diffstat (limited to 'block/blktrace.c')
-rw-r--r-- | block/blktrace.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/block/blktrace.c b/block/blktrace.c index 8d3a27780260..eb9651ccb241 100644 --- a/block/blktrace.c +++ b/block/blktrace.c | |||
@@ -244,6 +244,7 @@ err: | |||
244 | static void blk_trace_cleanup(struct blk_trace *bt) | 244 | static void blk_trace_cleanup(struct blk_trace *bt) |
245 | { | 245 | { |
246 | relay_close(bt->rchan); | 246 | relay_close(bt->rchan); |
247 | debugfs_remove(bt->msg_file); | ||
247 | debugfs_remove(bt->dropped_file); | 248 | debugfs_remove(bt->dropped_file); |
248 | blk_remove_tree(bt->dir); | 249 | blk_remove_tree(bt->dir); |
249 | free_percpu(bt->sequence); | 250 | free_percpu(bt->sequence); |
@@ -291,6 +292,44 @@ static const struct file_operations blk_dropped_fops = { | |||
291 | .read = blk_dropped_read, | 292 | .read = blk_dropped_read, |
292 | }; | 293 | }; |
293 | 294 | ||
295 | static int blk_msg_open(struct inode *inode, struct file *filp) | ||
296 | { | ||
297 | filp->private_data = inode->i_private; | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | static ssize_t blk_msg_write(struct file *filp, const char __user *buffer, | ||
303 | size_t count, loff_t *ppos) | ||
304 | { | ||
305 | char *msg; | ||
306 | struct blk_trace *bt; | ||
307 | |||
308 | if (count > BLK_TN_MAX_MSG) | ||
309 | return -EINVAL; | ||
310 | |||
311 | msg = kmalloc(count, GFP_KERNEL); | ||
312 | if (msg == NULL) | ||
313 | return -ENOMEM; | ||
314 | |||
315 | if (copy_from_user(msg, buffer, count)) { | ||
316 | kfree(msg); | ||
317 | return -EFAULT; | ||
318 | } | ||
319 | |||
320 | bt = filp->private_data; | ||
321 | __trace_note_message(bt, "%s", msg); | ||
322 | kfree(msg); | ||
323 | |||
324 | return count; | ||
325 | } | ||
326 | |||
327 | static const struct file_operations blk_msg_fops = { | ||
328 | .owner = THIS_MODULE, | ||
329 | .open = blk_msg_open, | ||
330 | .write = blk_msg_write, | ||
331 | }; | ||
332 | |||
294 | /* | 333 | /* |
295 | * Keep track of how many times we encountered a full subbuffer, to aid | 334 | * Keep track of how many times we encountered a full subbuffer, to aid |
296 | * the user space app in telling how many lost events there were. | 335 | * the user space app in telling how many lost events there were. |
@@ -380,6 +419,10 @@ int do_blk_trace_setup(struct request_queue *q, char *name, dev_t dev, | |||
380 | if (!bt->dropped_file) | 419 | if (!bt->dropped_file) |
381 | goto err; | 420 | goto err; |
382 | 421 | ||
422 | bt->msg_file = debugfs_create_file("msg", 0222, dir, bt, &blk_msg_fops); | ||
423 | if (!bt->msg_file) | ||
424 | goto err; | ||
425 | |||
383 | bt->rchan = relay_open("trace", dir, buts->buf_size, | 426 | bt->rchan = relay_open("trace", dir, buts->buf_size, |
384 | buts->buf_nr, &blk_relay_callbacks, bt); | 427 | buts->buf_nr, &blk_relay_callbacks, bt); |
385 | if (!bt->rchan) | 428 | if (!bt->rchan) |
@@ -409,6 +452,8 @@ err: | |||
409 | if (dir) | 452 | if (dir) |
410 | blk_remove_tree(dir); | 453 | blk_remove_tree(dir); |
411 | if (bt) { | 454 | if (bt) { |
455 | if (bt->msg_file) | ||
456 | debugfs_remove(bt->msg_file); | ||
412 | if (bt->dropped_file) | 457 | if (bt->dropped_file) |
413 | debugfs_remove(bt->dropped_file); | 458 | debugfs_remove(bt->dropped_file); |
414 | free_percpu(bt->sequence); | 459 | free_percpu(bt->sequence); |