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 | |
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')
-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 */ |