aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorAlexey Dobriyan <adobriyan@sw.ru>2008-04-29 04:01:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-29 11:06:19 -0400
commit352ced8e594091d74b92da9bcf07aea81d37ac55 (patch)
treea0e5f67be54a2d1138837787fc126e6807156418 /drivers/scsi
parent4a5cdb5b8f10998603e1e44adec1e56c234babfe (diff)
proc: switch /proc/scsi/device_info to seq_file interface
Note 1: 0644 should be used, but root bypasses permissions, so writing to /proc/scsi/device_info still works. Note 2: looks like scsi_dev_info_list is unprotected Note 3: probably make proc whine about "unwriteable but with ->write hook" entries. Probably. Signed-off-by: Alexey Dobriyan <adobriyan@sw.ru> Cc: James Bottomley <James.Bottomley@SteelEye.com> Cc: Mike Christie <michaelc@cs.wisc.edu> Cc: Matthew Wilcox <matthew@wil.cx> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/scsi_devinfo.c77
1 files changed, 44 insertions, 33 deletions
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
index b8de041bc0ae..a235802f2981 100644
--- a/drivers/scsi/scsi_devinfo.c
+++ b/drivers/scsi/scsi_devinfo.c
@@ -449,37 +449,40 @@ int scsi_get_device_flags(struct scsi_device *sdev,
449} 449}
450 450
451#ifdef CONFIG_SCSI_PROC_FS 451#ifdef CONFIG_SCSI_PROC_FS
452/* 452static int devinfo_seq_show(struct seq_file *m, void *v)
453 * proc_scsi_dev_info_read: dump the scsi_dev_info_list via
454 * /proc/scsi/device_info
455 */
456static int proc_scsi_devinfo_read(char *buffer, char **start,
457 off_t offset, int length)
458{ 453{
459 struct scsi_dev_info_list *devinfo; 454 struct scsi_dev_info_list *devinfo =
460 int size, len = 0; 455 list_entry(v, struct scsi_dev_info_list, dev_info_list);
461 off_t begin = 0;
462 off_t pos = 0;
463 456
464 list_for_each_entry(devinfo, &scsi_dev_info_list, dev_info_list) { 457 seq_printf(m, "'%.8s' '%.16s' 0x%x\n",
465 size = sprintf(buffer + len, "'%.8s' '%.16s' 0x%x\n",
466 devinfo->vendor, devinfo->model, devinfo->flags); 458 devinfo->vendor, devinfo->model, devinfo->flags);
467 len += size; 459 return 0;
468 pos = begin + len; 460}
469 if (pos < offset) { 461
470 len = 0; 462static void * devinfo_seq_start(struct seq_file *m, loff_t *pos)
471 begin = pos; 463{
472 } 464 return seq_list_start(&scsi_dev_info_list, *pos);
473 if (pos > offset + length) 465}
474 goto stop_output;
475 }
476 466
477stop_output: 467static void * devinfo_seq_next(struct seq_file *m, void *v, loff_t *pos)
478 *start = buffer + (offset - begin); /* Start of wanted data */ 468{
479 len -= (offset - begin); /* Start slop */ 469 return seq_list_next(v, &scsi_dev_info_list, pos);
480 if (len > length) 470}
481 len = length; /* Ending slop */ 471
482 return (len); 472static void devinfo_seq_stop(struct seq_file *m, void *v)
473{
474}
475
476static const struct seq_operations scsi_devinfo_seq_ops = {
477 .start = devinfo_seq_start,
478 .next = devinfo_seq_next,
479 .stop = devinfo_seq_stop,
480 .show = devinfo_seq_show,
481};
482
483static int proc_scsi_devinfo_open(struct inode *inode, struct file *file)
484{
485 return seq_open(file, &scsi_devinfo_seq_ops);
483} 486}
484 487
485/* 488/*
@@ -489,11 +492,12 @@ stop_output:
489 * integer value of flag to the scsi device info list. 492 * integer value of flag to the scsi device info list.
490 * To use, echo "vendor:model:flag" > /proc/scsi/device_info 493 * To use, echo "vendor:model:flag" > /proc/scsi/device_info
491 */ 494 */
492static int proc_scsi_devinfo_write(struct file *file, const char __user *buf, 495static ssize_t proc_scsi_devinfo_write(struct file *file,
493 unsigned long length, void *data) 496 const char __user *buf,
497 size_t length, loff_t *ppos)
494{ 498{
495 char *buffer; 499 char *buffer;
496 int err = length; 500 ssize_t err = length;
497 501
498 if (!buf || length>PAGE_SIZE) 502 if (!buf || length>PAGE_SIZE)
499 return -EINVAL; 503 return -EINVAL;
@@ -517,6 +521,15 @@ out:
517 free_page((unsigned long)buffer); 521 free_page((unsigned long)buffer);
518 return err; 522 return err;
519} 523}
524
525static const struct file_operations scsi_devinfo_proc_fops = {
526 .owner = THIS_MODULE,
527 .open = proc_scsi_devinfo_open,
528 .read = seq_read,
529 .write = proc_scsi_devinfo_write,
530 .llseek = seq_lseek,
531 .release = seq_release,
532};
520#endif /* CONFIG_SCSI_PROC_FS */ 533#endif /* CONFIG_SCSI_PROC_FS */
521 534
522module_param_string(dev_flags, scsi_dev_flags, sizeof(scsi_dev_flags), 0); 535module_param_string(dev_flags, scsi_dev_flags, sizeof(scsi_dev_flags), 0);
@@ -577,15 +590,13 @@ int __init scsi_init_devinfo(void)
577 } 590 }
578 591
579#ifdef CONFIG_SCSI_PROC_FS 592#ifdef CONFIG_SCSI_PROC_FS
580 p = create_proc_entry("scsi/device_info", 0, NULL); 593 p = proc_create("scsi/device_info", 0, NULL, &scsi_devinfo_proc_fops);
581 if (!p) { 594 if (!p) {
582 error = -ENOMEM; 595 error = -ENOMEM;
583 goto out; 596 goto out;
584 } 597 }
585 598
586 p->owner = THIS_MODULE; 599 p->owner = THIS_MODULE;
587 p->get_info = proc_scsi_devinfo_read;
588 p->write_proc = proc_scsi_devinfo_write;
589#endif /* CONFIG_SCSI_PROC_FS */ 600#endif /* CONFIG_SCSI_PROC_FS */
590 601
591 out: 602 out: