summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/sysfs/file.c13
-rw-r--r--fs/sysfs/inode.c21
-rw-r--r--fs/sysfs/sysfs.h1
-rw-r--r--include/linux/kernfs.h8
4 files changed, 32 insertions, 11 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 4b70240343f..04dcfbd0951 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -924,19 +924,16 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
struct iattr newattrs;
int rc;
- mutex_lock(&sysfs_mutex);
-
- rc = -ENOENT;
- sd = sysfs_find_dirent(kobj->sd, attr->name, NULL);
+ sd = sysfs_get_dirent(kobj->sd, attr->name);
if (!sd)
- goto out;
+ return -ENOENT;
newattrs.ia_mode = (mode & S_IALLUGO) | (sd->s_mode & ~S_IALLUGO);
newattrs.ia_valid = ATTR_MODE;
- rc = sysfs_sd_setattr(sd, &newattrs);
- out:
- mutex_unlock(&sysfs_mutex);
+ rc = kernfs_setattr(sd, &newattrs);
+
+ sysfs_put(sd);
return rc;
}
EXPORT_SYMBOL_GPL(sysfs_chmod_file);
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index f797e377c64..edef1f49fd8 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -67,7 +67,7 @@ static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd)
return attrs;
}
-int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr)
+static int __kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr)
{
struct sysfs_inode_attrs *sd_attrs;
struct iattr *iattrs;
@@ -102,6 +102,23 @@ int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr)
return 0;
}
+/**
+ * kernfs_setattr - set iattr on a node
+ * @sd: target node
+ * @iattr: iattr to set
+ *
+ * Returns 0 on success, -errno on failure.
+ */
+int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr)
+{
+ int ret;
+
+ mutex_lock(&sysfs_mutex);
+ ret = __kernfs_setattr(sd, iattr);
+ mutex_unlock(&sysfs_mutex);
+ return ret;
+}
+
int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
{
struct inode *inode = dentry->d_inode;
@@ -116,7 +133,7 @@ int sysfs_setattr(struct dentry *dentry, struct iattr *iattr)
if (error)
goto out;
- error = sysfs_sd_setattr(sd, iattr);
+ error = __kernfs_setattr(sd, iattr);
if (error)
goto out;
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index 5259efd16d2..1c6dc6c507f 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -192,7 +192,6 @@ static inline void __sysfs_put(struct sysfs_dirent *sd)
*/
struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd);
void sysfs_evict_inode(struct inode *inode);
-int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr);
int sysfs_permission(struct inode *inode, int mask);
int sysfs_setattr(struct dentry *dentry, struct iattr *iattr);
int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 803d9600cf7..8cb67387571 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -10,6 +10,9 @@
#include <linux/kernel.h>
#include <linux/err.h>
+struct file;
+struct iattr;
+
struct sysfs_dirent;
#ifdef CONFIG_SYSFS
@@ -22,6 +25,7 @@ int kernfs_remove_by_name_ns(struct sysfs_dirent *parent, const char *name,
const void *ns);
int kernfs_rename_ns(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent,
const char *new_name, const void *new_ns);
+int kernfs_setattr(struct sysfs_dirent *sd, const struct iattr *iattr);
#else /* CONFIG_SYSFS */
@@ -41,6 +45,10 @@ static inline int kernfs_rename_ns(struct sysfs_dirent *sd,
const char *new_name, const void *new_ns)
{ return -ENOSYS; }
+static inline int kernfs_setattr(struct sysfs_dirent *sd,
+ const struct iattr *iattr)
+{ return -ENOSYS; }
+
#endif /* CONFIG_SYSFS */
static inline int kernfs_remove_by_name(struct sysfs_dirent *parent,