summaryrefslogtreecommitdiffstats
path: root/fs/sysfs/file.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 13:25:22 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2011-10-25 13:25:22 +0200
commit8a9ea3237e7eb5c25f09e429ad242ae5a3d5ea22 (patch)
treea0a63398a9983667d52cbbbf4e2405b4f22b1d83 /fs/sysfs/file.c
parent1be025d3cb40cd295123af2c394f7229ef9b30ca (diff)
parent8b3408f8ee994973869d8ba32c5bf482bc4ddca4 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1745 commits) dp83640: free packet queues on remove dp83640: use proper function to free transmit time stamping packets ipv6: Do not use routes from locally generated RAs |PATCH net-next] tg3: add tx_dropped counter be2net: don't create multiple RX/TX rings in multi channel mode be2net: don't create multiple TXQs in BE2 be2net: refactor VF setup/teardown code into be_vf_setup/clear() be2net: add vlan/rx-mode/flow-control config to be_setup() net_sched: cls_flow: use skb_header_pointer() ipv4: avoid useless call of the function check_peer_pmtu TCP: remove TCP_DEBUG net: Fix driver name for mdio-gpio.c ipv4: tcp: fix TOS value in ACK messages sent from TIME_WAIT rtnetlink: Add missing manual netlink notification in dev_change_net_namespaces ipv4: fix ipsec forward performance regression jme: fix irq storm after suspend/resume route: fix ICMP redirect validation net: hold sock reference while processing tx timestamps tcp: md5: add more const attributes Add ethtool -g support to virtio_net ... Fix up conflicts in: - drivers/net/Kconfig: The split-up generated a trivial conflict with removal of a stale reference to Documentation/networking/net-modules.txt. Remove it from the new location instead. - fs/sysfs/dir.c: Fairly nasty conflicts with the sysfs rb-tree usage, conflicting with Eric Biederman's changes for tagged directories.
Diffstat (limited to 'fs/sysfs/file.c')
-rw-r--r--fs/sysfs/file.c56
1 files changed, 51 insertions, 5 deletions
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 1ad8c93c1b8..d4e6080b4b2 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -466,9 +466,6 @@ void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
mutex_lock(&sysfs_mutex);
if (sd && dir)
- /* Only directories are tagged, so no need to pass
- * a tag explicitly.
- */
sd = sysfs_find_dirent(sd, NULL, dir);
if (sd && attr)
sd = sysfs_find_dirent(sd, NULL, attr);
@@ -488,17 +485,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 +622,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 +657,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)