diff options
| author | Tejun Heo <tj@kernel.org> | 2013-10-01 17:41:57 -0400 | 
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-10-05 17:04:34 -0700 | 
| commit | 375b611e60f7c1ce6913417ca254efe5523f1a72 (patch) | |
| tree | af7c2f99afad20b6e5742175b39687c1fb010ae6 /fs/sysfs/file.c | |
| parent | aea585ef8fa6516395022e9d2fed6ec5014128bc (diff) | |
sysfs: remove sysfs_buffer->ops
Currently, sysfs_ops is fetched during sysfs_open_file() and cached in
sysfs_buffer->ops to be used while the file is open.  This patch
removes the caching and makes each operation directly fetch sysfs_ops.
This patch doesn't introduce any behavior difference and is to prepare
for merging regular and bin file supports.
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.c | 33 | 
1 files changed, 21 insertions, 12 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index e2fafc0a9b36..7dfcc3317490 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c @@ -45,12 +45,23 @@ struct sysfs_open_dirent {  struct sysfs_buffer {  	size_t			count;  	char			*page; -	const struct sysfs_ops	*ops;  	struct mutex		mutex;  	int			event;  	struct list_head	list;  }; +/* + * Determine ktype->sysfs_ops for the given sysfs_dirent.  This function + * must be called while holding an active reference. + */ +static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd) +{ +	struct kobject *kobj = sd->s_parent->s_dir.kobj; + +	lockdep_assert_held(sd); +	return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; +} +  /**   *	fill_read_buffer - allocate and fill buffer from object.   *	@dentry:	dentry pointer. @@ -66,7 +77,7 @@ static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)  {  	struct sysfs_dirent *attr_sd = dentry->d_fsdata;  	struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; -	const struct sysfs_ops *ops = buffer->ops; +	const struct sysfs_ops *ops;  	int ret = 0;  	ssize_t count; @@ -80,6 +91,8 @@ static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer)  		return -ENODEV;  	buffer->event = atomic_read(&attr_sd->s_attr.open->event); + +	ops = sysfs_file_ops(attr_sd);  	count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page);  	sysfs_put_active(attr_sd); @@ -191,13 +204,14 @@ static int flush_write_buffer(struct dentry *dentry,  {  	struct sysfs_dirent *attr_sd = dentry->d_fsdata;  	struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; -	const struct sysfs_ops *ops = buffer->ops; +	const struct sysfs_ops *ops;  	int rc;  	/* need attr_sd for attr and ops, its parent for kobj */  	if (!sysfs_get_active(attr_sd))  		return -ENODEV; +	ops = sysfs_file_ops(attr_sd);  	rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count);  	sysfs_put_active(attr_sd); @@ -205,7 +219,6 @@ static int flush_write_buffer(struct dentry *dentry,  	return rc;  } -  /**   *	sysfs_write_file - write an attribute.   *	@file:	file pointer @@ -334,14 +347,11 @@ static int sysfs_open_file(struct inode *inode, struct file *file)  		return -ENODEV;  	/* every kobject with an attribute needs a ktype assigned */ -	if (kobj->ktype && kobj->ktype->sysfs_ops) -		ops = kobj->ktype->sysfs_ops; -	else { -		WARN(1, KERN_ERR -		     "missing sysfs attribute operations for kobject: %s\n", -		     kobject_name(kobj)); +	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; -	}  	/* File needs write support.  	 * The inode's perms must say it's ok, @@ -370,7 +380,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file)  		goto err_out;  	mutex_init(&buffer->mutex); -	buffer->ops = ops;  	file->private_data = buffer;  	/* make sure we have open dirent struct */  | 
