diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/symlink.c | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index f71246bebfe4..44bca5f49cd5 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -28,6 +28,7 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, | |||
28 | struct sysfs_dirent *target_sd = NULL; | 28 | struct sysfs_dirent *target_sd = NULL; |
29 | struct sysfs_dirent *sd = NULL; | 29 | struct sysfs_dirent *sd = NULL; |
30 | struct sysfs_addrm_cxt acxt; | 30 | struct sysfs_addrm_cxt acxt; |
31 | enum kobj_ns_type ns_type; | ||
31 | int error; | 32 | int error; |
32 | 33 | ||
33 | BUG_ON(!name); | 34 | BUG_ON(!name); |
@@ -58,16 +59,28 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, | |||
58 | if (!sd) | 59 | if (!sd) |
59 | goto out_put; | 60 | goto out_put; |
60 | 61 | ||
61 | if (sysfs_ns_type(parent_sd)) | 62 | ns_type = sysfs_ns_type(parent_sd); |
63 | if (ns_type) | ||
62 | sd->s_ns = target->ktype->namespace(target); | 64 | sd->s_ns = target->ktype->namespace(target); |
63 | sd->s_symlink.target_sd = target_sd; | 65 | sd->s_symlink.target_sd = target_sd; |
64 | target_sd = NULL; /* reference is now owned by the symlink */ | 66 | target_sd = NULL; /* reference is now owned by the symlink */ |
65 | 67 | ||
66 | sysfs_addrm_start(&acxt, parent_sd); | 68 | sysfs_addrm_start(&acxt, parent_sd); |
67 | if (warn) | 69 | /* Symlinks must be between directories with the same ns_type */ |
68 | error = sysfs_add_one(&acxt, sd); | 70 | if (ns_type == sysfs_ns_type(sd->s_symlink.target_sd->s_parent)) { |
69 | else | 71 | if (warn) |
70 | error = __sysfs_add_one(&acxt, sd); | 72 | error = sysfs_add_one(&acxt, sd); |
73 | else | ||
74 | error = __sysfs_add_one(&acxt, sd); | ||
75 | } else { | ||
76 | error = -EINVAL; | ||
77 | WARN(1, KERN_WARNING | ||
78 | "sysfs: symlink across ns_types %s/%s -> %s/%s\n", | ||
79 | parent_sd->s_name, | ||
80 | sd->s_name, | ||
81 | sd->s_symlink.target_sd->s_parent->s_name, | ||
82 | sd->s_symlink.target_sd->s_name); | ||
83 | } | ||
71 | sysfs_addrm_finish(&acxt); | 84 | sysfs_addrm_finish(&acxt); |
72 | 85 | ||
73 | if (error) | 86 | if (error) |