aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/file.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-10-01 17:42:08 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-05 20:27:40 -0400
commit49fe604781cbb03eb6ff12a7bc4ad8eef8b830c4 (patch)
tree7133e49e6c491130044498d6c22e5fb7d1a8006b /fs/sysfs/file.c
parent73d9714627adced2942e8d53ce0e73d9699a996c (diff)
sysfs: prepare open path for unified regular / bin file handling
sysfs bin file handling will be merged into the regular file support. This patch prepares the open path. This patch updates sysfs_open_file() such that it can handle both regular and bin files. This is a preparation and the new bin file path isn't used yet. Signed-off-by: Tejun Heo <tj@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r--fs/sysfs/file.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 02797a134cf8..417d005955d9 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -610,38 +610,40 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
610 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 610 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
611 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 611 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
612 struct sysfs_open_file *of; 612 struct sysfs_open_file *of;
613 const struct sysfs_ops *ops; 613 bool has_read, has_write;
614 int error = -EACCES; 614 int error = -EACCES;
615 615
616 /* need attr_sd for attr and ops, its parent for kobj */ 616 /* need attr_sd for attr and ops, its parent for kobj */
617 if (!sysfs_get_active(attr_sd)) 617 if (!sysfs_get_active(attr_sd))
618 return -ENODEV; 618 return -ENODEV;
619 619
620 /* every kobject with an attribute needs a ktype assigned */ 620 if (sysfs_is_bin(attr_sd)) {
621 ops = sysfs_file_ops(attr_sd); 621 struct bin_attribute *battr = attr_sd->s_bin_attr.bin_attr;
622 if (WARN(!ops, KERN_ERR
623 "missing sysfs attribute operations for kobject: %s\n",
624 kobject_name(kobj)))
625 goto err_out;
626 622
627 /* File needs write support. 623 has_read = battr->read || battr->mmap;
628 * The inode's perms must say it's ok, 624 has_write = battr->write || battr->mmap;
629 * and we must have a store method. 625 } else {
630 */ 626 const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);
631 if (file->f_mode & FMODE_WRITE) {
632 if (!(inode->i_mode & S_IWUGO) || !ops->store)
633 goto err_out;
634 }
635 627
636 /* File needs read support. 628 /* every kobject with an attribute needs a ktype assigned */
637 * The inode's perms must say it's ok, and we there 629 if (WARN(!ops, KERN_ERR
638 * must be a show method for it. 630 "missing sysfs attribute operations for kobject: %s\n",
639 */ 631 kobject_name(kobj)))
640 if (file->f_mode & FMODE_READ) {
641 if (!(inode->i_mode & S_IRUGO) || !ops->show)
642 goto err_out; 632 goto err_out;
633
634 has_read = ops->show;
635 has_write = ops->store;
643 } 636 }
644 637
638 /* check perms and supported operations */
639 if ((file->f_mode & FMODE_WRITE) &&
640 (!(inode->i_mode & S_IWUGO) || !has_write))
641 goto err_out;
642
643 if ((file->f_mode & FMODE_READ) &&
644 (!(inode->i_mode & S_IRUGO) || !has_read))
645 goto err_out;
646
645 /* allocate a sysfs_open_file for the file */ 647 /* allocate a sysfs_open_file for the file */
646 error = -ENOMEM; 648 error = -ENOMEM;
647 of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL); 649 of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
@@ -653,11 +655,14 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
653 of->file = file; 655 of->file = file;
654 656
655 /* 657 /*
656 * Always instantiate seq_file even if read access is not 658 * Always instantiate seq_file even if read access doesn't use
657 * implemented or requested. This unifies private data access and 659 * seq_file or is not requested. This unifies private data access
658 * most files are readable anyway. 660 * and readable regular files are the vast majority anyway.
659 */ 661 */
660 error = single_open(file, sysfs_seq_show, of); 662 if (sysfs_is_bin(attr_sd))
663 error = single_open(file, NULL, of);
664 else
665 error = single_open(file, sysfs_seq_show, of);
661 if (error) 666 if (error)
662 goto err_free; 667 goto err_free;
663 668
@@ -807,6 +812,9 @@ const struct file_operations sysfs_bin_operations = {
807 .write = sysfs_write_file, 812 .write = sysfs_write_file,
808 .llseek = generic_file_llseek, 813 .llseek = generic_file_llseek,
809 .mmap = sysfs_bin_mmap, 814 .mmap = sysfs_bin_mmap,
815 .open = sysfs_open_file,
816 .release = sysfs_release,
817 .poll = sysfs_poll,
810}; 818};
811 819
812int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd, 820int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,