mirror of
https://github.com/torvalds/linux
synced 2024-07-21 18:51:47 +00:00
sysfs: split out binary attribute handling from sysfs_add_file_mode_ns
Split adding binary attributes into a separate handler instead of overloading sysfs_add_file_mode_ns. Acked-by: Christian Brauner <christian.brauner@ubuntu.com> Acked-by: Tejun Heo <tj@kernel.org> Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://lore.kernel.org/r/20210913054121.616001-5-hch@lst.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
eaf501e0d8
commit
5cf3bb0d3a
120
fs/sysfs/file.c
120
fs/sysfs/file.c
|
@ -255,59 +255,38 @@ static const struct kernfs_ops sysfs_bin_kfops_mmap = {
|
||||||
};
|
};
|
||||||
|
|
||||||
int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
||||||
const struct attribute *attr, bool is_bin,
|
const struct attribute *attr, umode_t mode, kuid_t uid,
|
||||||
umode_t mode, kuid_t uid, kgid_t gid, const void *ns)
|
kgid_t gid, const void *ns)
|
||||||
{
|
{
|
||||||
|
struct kobject *kobj = parent->priv;
|
||||||
|
const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;
|
||||||
struct lock_class_key *key = NULL;
|
struct lock_class_key *key = NULL;
|
||||||
const struct kernfs_ops *ops;
|
const struct kernfs_ops *ops;
|
||||||
struct kernfs_node *kn;
|
struct kernfs_node *kn;
|
||||||
loff_t size;
|
|
||||||
|
|
||||||
if (!is_bin) {
|
/* every kobject with an attribute needs a ktype assigned */
|
||||||
struct kobject *kobj = parent->priv;
|
if (WARN(!sysfs_ops, KERN_ERR
|
||||||
const struct sysfs_ops *sysfs_ops = kobj->ktype->sysfs_ops;
|
"missing sysfs attribute operations for kobject: %s\n",
|
||||||
|
kobject_name(kobj)))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
/* every kobject with an attribute needs a ktype assigned */
|
if (sysfs_ops->show && sysfs_ops->store) {
|
||||||
if (WARN(!sysfs_ops, KERN_ERR
|
if (mode & SYSFS_PREALLOC)
|
||||||
"missing sysfs attribute operations for kobject: %s\n",
|
ops = &sysfs_prealloc_kfops_rw;
|
||||||
kobject_name(kobj)))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (sysfs_ops->show && sysfs_ops->store) {
|
|
||||||
if (mode & SYSFS_PREALLOC)
|
|
||||||
ops = &sysfs_prealloc_kfops_rw;
|
|
||||||
else
|
|
||||||
ops = &sysfs_file_kfops_rw;
|
|
||||||
} else if (sysfs_ops->show) {
|
|
||||||
if (mode & SYSFS_PREALLOC)
|
|
||||||
ops = &sysfs_prealloc_kfops_ro;
|
|
||||||
else
|
|
||||||
ops = &sysfs_file_kfops_ro;
|
|
||||||
} else if (sysfs_ops->store) {
|
|
||||||
if (mode & SYSFS_PREALLOC)
|
|
||||||
ops = &sysfs_prealloc_kfops_wo;
|
|
||||||
else
|
|
||||||
ops = &sysfs_file_kfops_wo;
|
|
||||||
} else
|
|
||||||
ops = &sysfs_file_kfops_empty;
|
|
||||||
|
|
||||||
size = PAGE_SIZE;
|
|
||||||
} else {
|
|
||||||
struct bin_attribute *battr = (void *)attr;
|
|
||||||
|
|
||||||
if (battr->mmap)
|
|
||||||
ops = &sysfs_bin_kfops_mmap;
|
|
||||||
else if (battr->read && battr->write)
|
|
||||||
ops = &sysfs_bin_kfops_rw;
|
|
||||||
else if (battr->read)
|
|
||||||
ops = &sysfs_bin_kfops_ro;
|
|
||||||
else if (battr->write)
|
|
||||||
ops = &sysfs_bin_kfops_wo;
|
|
||||||
else
|
else
|
||||||
ops = &sysfs_file_kfops_empty;
|
ops = &sysfs_file_kfops_rw;
|
||||||
|
} else if (sysfs_ops->show) {
|
||||||
size = battr->size;
|
if (mode & SYSFS_PREALLOC)
|
||||||
}
|
ops = &sysfs_prealloc_kfops_ro;
|
||||||
|
else
|
||||||
|
ops = &sysfs_file_kfops_ro;
|
||||||
|
} else if (sysfs_ops->store) {
|
||||||
|
if (mode & SYSFS_PREALLOC)
|
||||||
|
ops = &sysfs_prealloc_kfops_wo;
|
||||||
|
else
|
||||||
|
ops = &sysfs_file_kfops_wo;
|
||||||
|
} else
|
||||||
|
ops = &sysfs_file_kfops_empty;
|
||||||
|
|
||||||
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
if (!attr->ignore_lockdep)
|
if (!attr->ignore_lockdep)
|
||||||
|
@ -315,7 +294,42 @@ int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid,
|
kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid,
|
||||||
size, ops, (void *)attr, ns, key);
|
PAGE_SIZE, ops, (void *)attr, ns, key);
|
||||||
|
if (IS_ERR(kn)) {
|
||||||
|
if (PTR_ERR(kn) == -EEXIST)
|
||||||
|
sysfs_warn_dup(parent, attr->name);
|
||||||
|
return PTR_ERR(kn);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
|
||||||
|
const struct bin_attribute *battr, umode_t mode,
|
||||||
|
kuid_t uid, kgid_t gid, const void *ns)
|
||||||
|
{
|
||||||
|
const struct attribute *attr = &battr->attr;
|
||||||
|
struct lock_class_key *key = NULL;
|
||||||
|
const struct kernfs_ops *ops;
|
||||||
|
struct kernfs_node *kn;
|
||||||
|
|
||||||
|
if (battr->mmap)
|
||||||
|
ops = &sysfs_bin_kfops_mmap;
|
||||||
|
else if (battr->read && battr->write)
|
||||||
|
ops = &sysfs_bin_kfops_rw;
|
||||||
|
else if (battr->read)
|
||||||
|
ops = &sysfs_bin_kfops_ro;
|
||||||
|
else if (battr->write)
|
||||||
|
ops = &sysfs_bin_kfops_wo;
|
||||||
|
else
|
||||||
|
ops = &sysfs_file_kfops_empty;
|
||||||
|
|
||||||
|
#ifdef CONFIG_DEBUG_LOCK_ALLOC
|
||||||
|
if (!attr->ignore_lockdep)
|
||||||
|
key = attr->key ?: (struct lock_class_key *)&attr->skey;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
kn = __kernfs_create_file(parent, attr->name, mode & 0777, uid, gid,
|
||||||
|
battr->size, ops, (void *)attr, ns, key);
|
||||||
if (IS_ERR(kn)) {
|
if (IS_ERR(kn)) {
|
||||||
if (PTR_ERR(kn) == -EEXIST)
|
if (PTR_ERR(kn) == -EEXIST)
|
||||||
sysfs_warn_dup(parent, attr->name);
|
sysfs_warn_dup(parent, attr->name);
|
||||||
|
@ -340,9 +354,7 @@ int sysfs_create_file_ns(struct kobject *kobj, const struct attribute *attr,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
kobject_get_ownership(kobj, &uid, &gid);
|
kobject_get_ownership(kobj, &uid, &gid);
|
||||||
return sysfs_add_file_mode_ns(kobj->sd, attr, false, attr->mode,
|
return sysfs_add_file_mode_ns(kobj->sd, attr, attr->mode, uid, gid, ns);
|
||||||
uid, gid, ns);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
|
EXPORT_SYMBOL_GPL(sysfs_create_file_ns);
|
||||||
|
|
||||||
|
@ -385,8 +397,8 @@ int sysfs_add_file_to_group(struct kobject *kobj,
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
kobject_get_ownership(kobj, &uid, &gid);
|
kobject_get_ownership(kobj, &uid, &gid);
|
||||||
error = sysfs_add_file_mode_ns(parent, attr, false,
|
error = sysfs_add_file_mode_ns(parent, attr, attr->mode, uid, gid,
|
||||||
attr->mode, uid, gid, NULL);
|
NULL);
|
||||||
kernfs_put(parent);
|
kernfs_put(parent);
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
|
@ -555,8 +567,8 @@ int sysfs_create_bin_file(struct kobject *kobj,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
kobject_get_ownership(kobj, &uid, &gid);
|
kobject_get_ownership(kobj, &uid, &gid);
|
||||||
return sysfs_add_file_mode_ns(kobj->sd, &attr->attr, true,
|
return sysfs_add_bin_file_mode_ns(kobj->sd, attr, attr->attr.mode, uid,
|
||||||
attr->attr.mode, uid, gid, NULL);
|
gid, NULL);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
|
EXPORT_SYMBOL_GPL(sysfs_create_bin_file);
|
||||||
|
|
||||||
|
|
|
@ -61,8 +61,8 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
|
||||||
(*attr)->name, mode);
|
(*attr)->name, mode);
|
||||||
|
|
||||||
mode &= SYSFS_PREALLOC | 0664;
|
mode &= SYSFS_PREALLOC | 0664;
|
||||||
error = sysfs_add_file_mode_ns(parent, *attr, false,
|
error = sysfs_add_file_mode_ns(parent, *attr, mode, uid,
|
||||||
mode, uid, gid, NULL);
|
gid, NULL);
|
||||||
if (unlikely(error))
|
if (unlikely(error))
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -90,10 +90,9 @@ static int create_files(struct kernfs_node *parent, struct kobject *kobj,
|
||||||
(*bin_attr)->attr.name, mode);
|
(*bin_attr)->attr.name, mode);
|
||||||
|
|
||||||
mode &= SYSFS_PREALLOC | 0664;
|
mode &= SYSFS_PREALLOC | 0664;
|
||||||
error = sysfs_add_file_mode_ns(parent,
|
error = sysfs_add_bin_file_mode_ns(parent, *bin_attr,
|
||||||
&(*bin_attr)->attr, true,
|
mode, uid, gid,
|
||||||
mode,
|
NULL);
|
||||||
uid, gid, NULL);
|
|
||||||
if (error)
|
if (error)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -340,8 +339,8 @@ int sysfs_merge_group(struct kobject *kobj,
|
||||||
kobject_get_ownership(kobj, &uid, &gid);
|
kobject_get_ownership(kobj, &uid, &gid);
|
||||||
|
|
||||||
for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
|
for ((i = 0, attr = grp->attrs); *attr && !error; (++i, ++attr))
|
||||||
error = sysfs_add_file_mode_ns(parent, *attr, false,
|
error = sysfs_add_file_mode_ns(parent, *attr, (*attr)->mode,
|
||||||
(*attr)->mode, uid, gid, NULL);
|
uid, gid, NULL);
|
||||||
if (error) {
|
if (error) {
|
||||||
while (--i >= 0)
|
while (--i >= 0)
|
||||||
kernfs_remove_by_name(parent, (*--attr)->name);
|
kernfs_remove_by_name(parent, (*--attr)->name);
|
||||||
|
|
|
@ -28,9 +28,11 @@ void sysfs_warn_dup(struct kernfs_node *parent, const char *name);
|
||||||
* file.c
|
* file.c
|
||||||
*/
|
*/
|
||||||
int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
int sysfs_add_file_mode_ns(struct kernfs_node *parent,
|
||||||
const struct attribute *attr, bool is_bin,
|
const struct attribute *attr, umode_t amode, kuid_t uid,
|
||||||
umode_t amode, kuid_t uid, kgid_t gid,
|
kgid_t gid, const void *ns);
|
||||||
const void *ns);
|
int sysfs_add_bin_file_mode_ns(struct kernfs_node *parent,
|
||||||
|
const struct bin_attribute *battr, umode_t mode,
|
||||||
|
kuid_t uid, kgid_t gid, const void *ns);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* symlink.c
|
* symlink.c
|
||||||
|
|
Loading…
Reference in a new issue