aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-06-13 14:45:17 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-11 19:09:06 -0400
commit7b595756ec1f49e0049a9e01a1298d53a7faaa15 (patch)
treecd06687ab3e5c7a5a4ef91903dff207a18c4db76 /fs/sysfs
parentdbde0fcf9f8f6d477af3c32d9979e789ee680cde (diff)
sysfs: kill unnecessary attribute->owner
sysfs is now completely out of driver/module lifetime game. After deletion, a sysfs node doesn't access anything outside sysfs proper, so there's no reason to hold onto the attribute owners. Note that often the wrong modules were accounted for as owners leading to accessing removed modules. This patch kills now unnecessary attribute->owner. Note that with this change, userland holding a sysfs node does not prevent the backing module from being unloaded. For more info regarding lifetime rule cleanup, please read the following message. http://article.gmane.org/gmane.linux.kernel/510293 (tweaked by Greg to not delete the field just yet, to make it easier to merge things properly.) Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Cornelia Huck <cornelia.huck@de.ibm.com> Cc: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/sysfs')
-rw-r--r--fs/sysfs/bin.c19
-rw-r--r--fs/sysfs/file.c21
2 files changed, 10 insertions, 30 deletions
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 618b8aea6a7b..3c5574a40b09 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -175,25 +175,20 @@ static int open(struct inode * inode, struct file * file)
175 if (!sysfs_get_active(attr_sd)) 175 if (!sysfs_get_active(attr_sd))
176 return -ENODEV; 176 return -ENODEV;
177 177
178 /* Grab the module reference for this attribute */
179 error = -ENODEV;
180 if (!try_module_get(attr->attr.owner))
181 goto err_sput;
182
183 error = -EACCES; 178 error = -EACCES;
184 if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap)) 179 if ((file->f_mode & FMODE_WRITE) && !(attr->write || attr->mmap))
185 goto err_mput; 180 goto err_out;
186 if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap)) 181 if ((file->f_mode & FMODE_READ) && !(attr->read || attr->mmap))
187 goto err_mput; 182 goto err_out;
188 183
189 error = -ENOMEM; 184 error = -ENOMEM;
190 bb = kzalloc(sizeof(*bb), GFP_KERNEL); 185 bb = kzalloc(sizeof(*bb), GFP_KERNEL);
191 if (!bb) 186 if (!bb)
192 goto err_mput; 187 goto err_out;
193 188
194 bb->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); 189 bb->buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
195 if (!bb->buffer) 190 if (!bb->buffer)
196 goto err_mput; 191 goto err_out;
197 192
198 mutex_init(&bb->mutex); 193 mutex_init(&bb->mutex);
199 file->private_data = bb; 194 file->private_data = bb;
@@ -203,9 +198,7 @@ static int open(struct inode * inode, struct file * file)
203 sysfs_get(attr_sd); 198 sysfs_get(attr_sd);
204 return 0; 199 return 0;
205 200
206 err_mput: 201 err_out:
207 module_put(attr->attr.owner);
208 err_sput:
209 sysfs_put_active(attr_sd); 202 sysfs_put_active(attr_sd);
210 kfree(bb); 203 kfree(bb);
211 return error; 204 return error;
@@ -214,13 +207,11 @@ static int open(struct inode * inode, struct file * file)
214static int release(struct inode * inode, struct file * file) 207static int release(struct inode * inode, struct file * file)
215{ 208{
216 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 209 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
217 struct bin_attribute *attr = attr_sd->s_elem.bin_attr.bin_attr;
218 struct bin_buffer *bb = file->private_data; 210 struct bin_buffer *bb = file->private_data;
219 211
220 if (bb->mmapped) 212 if (bb->mmapped)
221 sysfs_put_active_two(attr_sd); 213 sysfs_put_active_two(attr_sd);
222 sysfs_put(attr_sd); 214 sysfs_put(attr_sd);
223 module_put(attr->attr.owner);
224 kfree(bb->buffer); 215 kfree(bb->buffer);
225 kfree(bb); 216 kfree(bb);
226 return 0; 217 return 0;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index d673d9b5d33f..a84b734f7b29 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -241,7 +241,6 @@ sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t
241static int sysfs_open_file(struct inode *inode, struct file *file) 241static int sysfs_open_file(struct inode *inode, struct file *file)
242{ 242{
243 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; 243 struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata;
244 struct attribute *attr = attr_sd->s_elem.attr.attr;
245 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj; 244 struct kobject *kobj = attr_sd->s_parent->s_elem.dir.kobj;
246 struct sysfs_buffer * buffer; 245 struct sysfs_buffer * buffer;
247 struct sysfs_ops * ops = NULL; 246 struct sysfs_ops * ops = NULL;
@@ -251,11 +250,6 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
251 if (!sysfs_get_active_two(attr_sd)) 250 if (!sysfs_get_active_two(attr_sd))
252 return -ENODEV; 251 return -ENODEV;
253 252
254 /* Grab the module reference for this attribute */
255 error = -ENODEV;
256 if (!try_module_get(attr->owner))
257 goto err_sput;
258
259 /* if the kobject has no ktype, then we assume that it is a subsystem 253 /* if the kobject has no ktype, then we assume that it is a subsystem
260 * itself, and use ops for it. 254 * itself, and use ops for it.
261 */ 255 */
@@ -272,7 +266,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
272 * or the subsystem have no operations. 266 * or the subsystem have no operations.
273 */ 267 */
274 if (!ops) 268 if (!ops)
275 goto err_mput; 269 goto err_out;
276 270
277 /* File needs write support. 271 /* File needs write support.
278 * The inode's perms must say it's ok, 272 * The inode's perms must say it's ok,
@@ -280,7 +274,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
280 */ 274 */
281 if (file->f_mode & FMODE_WRITE) { 275 if (file->f_mode & FMODE_WRITE) {
282 if (!(inode->i_mode & S_IWUGO) || !ops->store) 276 if (!(inode->i_mode & S_IWUGO) || !ops->store)
283 goto err_mput; 277 goto err_out;
284 } 278 }
285 279
286 /* File needs read support. 280 /* File needs read support.
@@ -289,7 +283,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
289 */ 283 */
290 if (file->f_mode & FMODE_READ) { 284 if (file->f_mode & FMODE_READ) {
291 if (!(inode->i_mode & S_IRUGO) || !ops->show) 285 if (!(inode->i_mode & S_IRUGO) || !ops->show)
292 goto err_mput; 286 goto err_out;
293 } 287 }
294 288
295 /* No error? Great, allocate a buffer for the file, and store it 289 /* No error? Great, allocate a buffer for the file, and store it
@@ -298,7 +292,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
298 error = -ENOMEM; 292 error = -ENOMEM;
299 buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL); 293 buffer = kzalloc(sizeof(struct sysfs_buffer), GFP_KERNEL);
300 if (!buffer) 294 if (!buffer)
301 goto err_mput; 295 goto err_out;
302 296
303 init_MUTEX(&buffer->sem); 297 init_MUTEX(&buffer->sem);
304 buffer->needs_read_fill = 1; 298 buffer->needs_read_fill = 1;
@@ -310,9 +304,7 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
310 sysfs_get(attr_sd); 304 sysfs_get(attr_sd);
311 return 0; 305 return 0;
312 306
313 err_mput: 307 err_out:
314 module_put(attr->owner);
315 err_sput:
316 sysfs_put_active_two(attr_sd); 308 sysfs_put_active_two(attr_sd);
317 return error; 309 return error;
318} 310}
@@ -320,12 +312,9 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
320static int sysfs_release(struct inode * inode, struct file * filp) 312static int sysfs_release(struct inode * inode, struct file * filp)
321{ 313{
322 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; 314 struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata;
323 struct attribute *attr = attr_sd->s_elem.attr.attr;
324 struct sysfs_buffer *buffer = filp->private_data; 315 struct sysfs_buffer *buffer = filp->private_data;
325 316
326 sysfs_put(attr_sd); 317 sysfs_put(attr_sd);
327 /* After this point, attr should not be accessed. */
328 module_put(attr->owner);
329 318
330 if (buffer) { 319 if (buffer) {
331 if (buffer->page) 320 if (buffer->page)