Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Tejun Heo and committed by
Greg Kroah-Hartman
49fe6047 73d97146

+35 -27
+35 -27
fs/sysfs/file.c
··· 610 610 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 611 611 struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; 612 612 struct sysfs_open_file *of; 613 - const struct sysfs_ops *ops; 613 + bool has_read, has_write; 614 614 int error = -EACCES; 615 615 616 616 /* need attr_sd for attr and ops, its parent for kobj */ 617 617 if (!sysfs_get_active(attr_sd)) 618 618 return -ENODEV; 619 619 620 - /* every kobject with an attribute needs a ktype assigned */ 621 - ops = sysfs_file_ops(attr_sd); 622 - if (WARN(!ops, KERN_ERR 623 - "missing sysfs attribute operations for kobject: %s\n", 624 - kobject_name(kobj))) 620 + if (sysfs_is_bin(attr_sd)) { 621 + struct bin_attribute *battr = attr_sd->s_bin_attr.bin_attr; 622 + 623 + has_read = battr->read || battr->mmap; 624 + has_write = battr->write || battr->mmap; 625 + } else { 626 + const struct sysfs_ops *ops = sysfs_file_ops(attr_sd); 627 + 628 + /* every kobject with an attribute needs a ktype assigned */ 629 + if (WARN(!ops, KERN_ERR 630 + "missing sysfs attribute operations for kobject: %s\n", 631 + kobject_name(kobj))) 632 + goto err_out; 633 + 634 + has_read = ops->show; 635 + has_write = ops->store; 636 + } 637 + 638 + /* check perms and supported operations */ 639 + if ((file->f_mode & FMODE_WRITE) && 640 + (!(inode->i_mode & S_IWUGO) || !has_write)) 625 641 goto err_out; 626 642 627 - /* File needs write support. 628 - * The inode's perms must say it's ok, 629 - * and we must have a store method. 630 - */ 631 - if (file->f_mode & FMODE_WRITE) { 632 - if (!(inode->i_mode & S_IWUGO) || !ops->store) 633 - goto err_out; 634 - } 635 - 636 - /* File needs read support. 637 - * The inode's perms must say it's ok, and we there 638 - * must be a show method for it. 639 - */ 640 - if (file->f_mode & FMODE_READ) { 641 - if (!(inode->i_mode & S_IRUGO) || !ops->show) 642 - goto err_out; 643 - } 643 + if ((file->f_mode & FMODE_READ) && 644 + (!(inode->i_mode & S_IRUGO) || !has_read)) 645 + goto err_out; 644 646 645 647 /* allocate a sysfs_open_file for the file */ 646 648 error = -ENOMEM; ··· 655 653 of->file = file; 656 654 657 655 /* 658 - * Always instantiate seq_file even if read access is not 659 - * implemented or requested. This unifies private data access and 660 - * most files are readable anyway. 656 + * Always instantiate seq_file even if read access doesn't use 657 + * seq_file or is not requested. This unifies private data access 658 + * and readable regular files are the vast majority anyway. 661 659 */ 662 - error = single_open(file, sysfs_seq_show, of); 660 + if (sysfs_is_bin(attr_sd)) 661 + error = single_open(file, NULL, of); 662 + else 663 + error = single_open(file, sysfs_seq_show, of); 663 664 if (error) 664 665 goto err_free; 665 666 ··· 812 807 .write = sysfs_write_file, 813 808 .llseek = generic_file_llseek, 814 809 .mmap = sysfs_bin_mmap, 810 + .open = sysfs_open_file, 811 + .release = sysfs_release, 812 + .poll = sysfs_poll, 815 813 }; 816 814 817 815 int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,