Skip to content

Commit

Permalink
sysfs: prepare open path for unified regular / bin file handling
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Tejun Heo authored and Greg Kroah-Hartman committed Oct 6, 2013
1 parent 73d9714 commit 49fe604
Showing 1 changed file with 33 additions and 25 deletions.
58 changes: 33 additions & 25 deletions fs/sysfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,38 +610,40 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
struct kobject *kobj = attr_sd->s_parent->s_dir.kobj;
struct sysfs_open_file *of;
const struct sysfs_ops *ops;
bool has_read, has_write;
int error = -EACCES;

/* need attr_sd for attr and ops, its parent for kobj */
if (!sysfs_get_active(attr_sd))
return -ENODEV;

/* every kobject with an attribute needs a ktype assigned */
ops = sysfs_file_ops(attr_sd);
if (WARN(!ops, KERN_ERR
"missing sysfs attribute operations for kobject: %s\n",
kobject_name(kobj)))
goto err_out;
if (sysfs_is_bin(attr_sd)) {
struct bin_attribute *battr = attr_sd->s_bin_attr.bin_attr;

/* File needs write support.
* The inode's perms must say it's ok,
* and we must have a store method.
*/
if (file->f_mode & FMODE_WRITE) {
if (!(inode->i_mode & S_IWUGO) || !ops->store)
goto err_out;
}
has_read = battr->read || battr->mmap;
has_write = battr->write || battr->mmap;
} else {
const struct sysfs_ops *ops = sysfs_file_ops(attr_sd);

/* File needs read support.
* The inode's perms must say it's ok, and we there
* must be a show method for it.
*/
if (file->f_mode & FMODE_READ) {
if (!(inode->i_mode & S_IRUGO) || !ops->show)
/* every kobject with an attribute needs a ktype assigned */
if (WARN(!ops, KERN_ERR
"missing sysfs attribute operations for kobject: %s\n",
kobject_name(kobj)))
goto err_out;

has_read = ops->show;
has_write = ops->store;
}

/* check perms and supported operations */
if ((file->f_mode & FMODE_WRITE) &&
(!(inode->i_mode & S_IWUGO) || !has_write))
goto err_out;

if ((file->f_mode & FMODE_READ) &&
(!(inode->i_mode & S_IRUGO) || !has_read))
goto err_out;

/* allocate a sysfs_open_file for the file */
error = -ENOMEM;
of = kzalloc(sizeof(struct sysfs_open_file), GFP_KERNEL);
Expand All @@ -653,11 +655,14 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
of->file = file;

/*
* Always instantiate seq_file even if read access is not
* implemented or requested. This unifies private data access and
* most files are readable anyway.
* Always instantiate seq_file even if read access doesn't use
* seq_file or is not requested. This unifies private data access
* and readable regular files are the vast majority anyway.
*/
error = single_open(file, sysfs_seq_show, of);
if (sysfs_is_bin(attr_sd))
error = single_open(file, NULL, of);
else
error = single_open(file, sysfs_seq_show, of);
if (error)
goto err_free;

Expand Down Expand Up @@ -807,6 +812,9 @@ const struct file_operations sysfs_bin_operations = {
.write = sysfs_write_file,
.llseek = generic_file_llseek,
.mmap = sysfs_bin_mmap,
.open = sysfs_open_file,
.release = sysfs_release,
.poll = sysfs_poll,
};

int sysfs_add_file_mode_ns(struct sysfs_dirent *dir_sd,
Expand Down

0 comments on commit 49fe604

Please sign in to comment.