|
@@ -488,17 +488,56 @@ const struct file_operations sysfs_file_operations = {
|
|
|
.poll = sysfs_poll,
|
|
|
};
|
|
|
|
|
|
+int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr,
|
|
|
+ const void **pns)
|
|
|
+{
|
|
|
+ struct sysfs_dirent *dir_sd = kobj->sd;
|
|
|
+ const struct sysfs_ops *ops;
|
|
|
+ const void *ns = NULL;
|
|
|
+ int err;
|
|
|
+
|
|
|
+ err = 0;
|
|
|
+ if (!sysfs_ns_type(dir_sd))
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ err = -EINVAL;
|
|
|
+ if (!kobj->ktype)
|
|
|
+ goto out;
|
|
|
+ ops = kobj->ktype->sysfs_ops;
|
|
|
+ if (!ops)
|
|
|
+ goto out;
|
|
|
+ if (!ops->namespace)
|
|
|
+ goto out;
|
|
|
+
|
|
|
+ err = 0;
|
|
|
+ ns = ops->namespace(kobj, attr);
|
|
|
+out:
|
|
|
+ if (err) {
|
|
|
+ WARN(1, KERN_ERR "missing sysfs namespace attribute operation for "
|
|
|
+ "kobject: %s\n", kobject_name(kobj));
|
|
|
+ }
|
|
|
+ *pns = ns;
|
|
|
+ return err;
|
|
|
+}
|
|
|
+
|
|
|
int sysfs_add_file_mode(struct sysfs_dirent *dir_sd,
|
|
|
const struct attribute *attr, int type, mode_t amode)
|
|
|
{
|
|
|
umode_t mode = (amode & S_IALLUGO) | S_IFREG;
|
|
|
struct sysfs_addrm_cxt acxt;
|
|
|
struct sysfs_dirent *sd;
|
|
|
+ const void *ns;
|
|
|
int rc;
|
|
|
|
|
|
+ rc = sysfs_attr_ns(dir_sd->s_dir.kobj, attr, &ns);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
sd = sysfs_new_dirent(attr->name, mode, type);
|
|
|
if (!sd)
|
|
|
return -ENOMEM;
|
|
|
+
|
|
|
+ sd->s_ns = ns;
|
|
|
sd->s_attr.attr = (void *)attr;
|
|
|
sysfs_dirent_init_lockdep(sd);
|
|
|
|
|
@@ -586,12 +625,17 @@ int sysfs_chmod_file(struct kobject *kobj, const struct attribute *attr,
|
|
|
{
|
|
|
struct sysfs_dirent *sd;
|
|
|
struct iattr newattrs;
|
|
|
+ const void *ns;
|
|
|
int rc;
|
|
|
|
|
|
+ rc = sysfs_attr_ns(kobj, attr, &ns);
|
|
|
+ if (rc)
|
|
|
+ return rc;
|
|
|
+
|
|
|
mutex_lock(&sysfs_mutex);
|
|
|
|
|
|
rc = -ENOENT;
|
|
|
- sd = sysfs_find_dirent(kobj->sd, NULL, attr->name);
|
|
|
+ sd = sysfs_find_dirent(kobj->sd, ns, attr->name);
|
|
|
if (!sd)
|
|
|
goto out;
|
|
|
|
|
@@ -616,7 +660,12 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file);
|
|
|
|
|
|
void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
|
|
|
{
|
|
|
- sysfs_hash_and_remove(kobj->sd, NULL, attr->name);
|
|
|
+ const void *ns;
|
|
|
+
|
|
|
+ if (sysfs_attr_ns(kobj, attr, &ns))
|
|
|
+ return;
|
|
|
+
|
|
|
+ sysfs_hash_and_remove(kobj->sd, ns, attr->name);
|
|
|
}
|
|
|
|
|
|
void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr)
|