diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/file.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 352f966a1174..da25aeb0e062 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -428,6 +428,41 @@ int sysfs_update_file(struct kobject * kobj, const struct attribute * attr) | |||
428 | 428 | ||
429 | 429 | ||
430 | /** | 430 | /** |
431 | * sysfs_chmod_file - update the modified mode value on an object attribute. | ||
432 | * @kobj: object we're acting for. | ||
433 | * @attr: attribute descriptor. | ||
434 | * @mode: file permissions. | ||
435 | * | ||
436 | */ | ||
437 | int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) | ||
438 | { | ||
439 | struct dentry *dir = kobj->dentry; | ||
440 | struct dentry *victim; | ||
441 | struct sysfs_dirent *sd; | ||
442 | umode_t umode = (mode & S_IALLUGO) | S_IFREG; | ||
443 | int res = -ENOENT; | ||
444 | |||
445 | down(&dir->d_inode->i_sem); | ||
446 | victim = sysfs_get_dentry(dir, attr->name); | ||
447 | if (!IS_ERR(victim)) { | ||
448 | if (victim->d_inode && | ||
449 | (victim->d_parent->d_inode == dir->d_inode)) { | ||
450 | sd = victim->d_fsdata; | ||
451 | attr->mode = mode; | ||
452 | sd->s_mode = umode; | ||
453 | victim->d_inode->i_mode = umode; | ||
454 | dput(victim); | ||
455 | res = 0; | ||
456 | } | ||
457 | } | ||
458 | up(&dir->d_inode->i_sem); | ||
459 | |||
460 | return res; | ||
461 | } | ||
462 | EXPORT_SYMBOL_GPL(sysfs_chmod_file); | ||
463 | |||
464 | |||
465 | /** | ||
431 | * sysfs_remove_file - remove an object attribute. | 466 | * sysfs_remove_file - remove an object attribute. |
432 | * @kobj: object we're acting for. | 467 | * @kobj: object we're acting for. |
433 | * @attr: attribute descriptor. | 468 | * @attr: attribute descriptor. |