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) |
