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 20:04:34 -0400 |
| commit | 375b611e60f7c1ce6913417ca254efe5523f1a72 (patch) | |
| tree | af7c2f99afad20b6e5742175b39687c1fb010ae6 /fs/sysfs | |
| 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')
| -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 { | |||
| 45 | struct sysfs_buffer { | 45 | struct sysfs_buffer { |
| 46 | size_t count; | 46 | size_t count; |
| 47 | char *page; | 47 | char *page; |
| 48 | const struct sysfs_ops *ops; | ||
| 49 | struct mutex mutex; | 48 | struct mutex mutex; |
| 50 | int event; | 49 | int event; |
| 51 | struct list_head list; | 50 | struct list_head list; |
| 52 | }; | 51 | }; |
| 53 | 52 | ||
| 53 | /* | ||
| 54 | * Determine ktype->sysfs_ops for the given sysfs_dirent. This function | ||
| 55 | * must be called while holding an active reference. | ||
| 56 | */ | ||
| 57 | static const struct sysfs_ops *sysfs_file_ops(struct sysfs_dirent *sd) | ||
| 58 | { | ||
| 59 | struct kobject *kobj = sd->s_parent->s_dir.kobj; | ||
| 60 | |||
| 61 | lockdep_assert_held(sd); | ||
| 62 | return kobj->ktype ? kobj->ktype->sysfs_ops : NULL; | ||
| 63 | } | ||
| 64 | |||
| 54 | /** | 65 | /** |
| 55 | * fill_read_buffer - allocate and fill buffer from object. | 66 | * fill_read_buffer - allocate and fill buffer from object. |
| 56 | * @dentry: dentry pointer. | 67 | * @dentry: dentry pointer. |
| @@ -66,7 +77,7 @@ static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer) | |||
| 66 | { | 77 | { |
| 67 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 78 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; |
| 68 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 79 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
| 69 | const struct sysfs_ops *ops = buffer->ops; | 80 | const struct sysfs_ops *ops; |
| 70 | int ret = 0; | 81 | int ret = 0; |
| 71 | ssize_t count; | 82 | ssize_t count; |
| 72 | 83 | ||
| @@ -80,6 +91,8 @@ static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer) | |||
| 80 | return -ENODEV; | 91 | return -ENODEV; |
| 81 | 92 | ||
| 82 | buffer->event = atomic_read(&attr_sd->s_attr.open->event); | 93 | buffer->event = atomic_read(&attr_sd->s_attr.open->event); |
| 94 | |||
| 95 | ops = sysfs_file_ops(attr_sd); | ||
| 83 | count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); | 96 | count = ops->show(kobj, attr_sd->s_attr.attr, buffer->page); |
| 84 | 97 | ||
| 85 | sysfs_put_active(attr_sd); | 98 | sysfs_put_active(attr_sd); |
| @@ -191,13 +204,14 @@ static int flush_write_buffer(struct dentry *dentry, | |||
| 191 | { | 204 | { |
| 192 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 205 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; |
| 193 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 206 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
| 194 | const struct sysfs_ops *ops = buffer->ops; | 207 | const struct sysfs_ops *ops; |
| 195 | int rc; | 208 | int rc; |
| 196 | 209 | ||
| 197 | /* need attr_sd for attr and ops, its parent for kobj */ | 210 | /* need attr_sd for attr and ops, its parent for kobj */ |
| 198 | if (!sysfs_get_active(attr_sd)) | 211 | if (!sysfs_get_active(attr_sd)) |
| 199 | return -ENODEV; | 212 | return -ENODEV; |
| 200 | 213 | ||
| 214 | ops = sysfs_file_ops(attr_sd); | ||
| 201 | rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); | 215 | rc = ops->store(kobj, attr_sd->s_attr.attr, buffer->page, count); |
| 202 | 216 | ||
| 203 | sysfs_put_active(attr_sd); | 217 | sysfs_put_active(attr_sd); |
| @@ -205,7 +219,6 @@ static int flush_write_buffer(struct dentry *dentry, | |||
| 205 | return rc; | 219 | return rc; |
| 206 | } | 220 | } |
| 207 | 221 | ||
| 208 | |||
| 209 | /** | 222 | /** |
| 210 | * sysfs_write_file - write an attribute. | 223 | * sysfs_write_file - write an attribute. |
| 211 | * @file: file pointer | 224 | * @file: file pointer |
| @@ -334,14 +347,11 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
| 334 | return -ENODEV; | 347 | return -ENODEV; |
| 335 | 348 | ||
| 336 | /* every kobject with an attribute needs a ktype assigned */ | 349 | /* every kobject with an attribute needs a ktype assigned */ |
| 337 | if (kobj->ktype && kobj->ktype->sysfs_ops) | 350 | ops = sysfs_file_ops(attr_sd); |
| 338 | ops = kobj->ktype->sysfs_ops; | 351 | if (WARN(!ops, KERN_ERR |
| 339 | else { | 352 | "missing sysfs attribute operations for kobject: %s\n", |
| 340 | WARN(1, KERN_ERR | 353 | kobject_name(kobj))) |
| 341 | "missing sysfs attribute operations for kobject: %s\n", | ||
| 342 | kobject_name(kobj)); | ||
| 343 | goto err_out; | 354 | goto err_out; |
| 344 | } | ||
| 345 | 355 | ||
| 346 | /* File needs write support. | 356 | /* File needs write support. |
| 347 | * The inode's perms must say it's ok, | 357 | * The inode's perms must say it's ok, |
| @@ -370,7 +380,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
| 370 | goto err_out; | 380 | goto err_out; |
| 371 | 381 | ||
| 372 | mutex_init(&buffer->mutex); | 382 | mutex_init(&buffer->mutex); |
| 373 | buffer->ops = ops; | ||
| 374 | file->private_data = buffer; | 383 | file->private_data = buffer; |
| 375 | 384 | ||
| 376 | /* make sure we have open dirent struct */ | 385 | /* make sure we have open dirent struct */ |
