diff options
Diffstat (limited to 'fs/sysfs/symlink.c')
| -rw-r--r-- | fs/sysfs/symlink.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 942f239a2132..f71246bebfe4 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
| @@ -58,6 +58,8 @@ static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target, | |||
| 58 | if (!sd) | 58 | if (!sd) |
| 59 | goto out_put; | 59 | goto out_put; |
| 60 | 60 | ||
| 61 | if (sysfs_ns_type(parent_sd)) | ||
| 62 | sd->s_ns = target->ktype->namespace(target); | ||
| 61 | sd->s_symlink.target_sd = target_sd; | 63 | sd->s_symlink.target_sd = target_sd; |
| 62 | target_sd = NULL; /* reference is now owned by the symlink */ | 64 | target_sd = NULL; /* reference is now owned by the symlink */ |
| 63 | 65 | ||
| @@ -107,6 +109,26 @@ int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target, | |||
| 107 | } | 109 | } |
| 108 | 110 | ||
| 109 | /** | 111 | /** |
| 112 | * sysfs_delete_link - remove symlink in object's directory. | ||
| 113 | * @kobj: object we're acting for. | ||
| 114 | * @targ: object we're pointing to. | ||
| 115 | * @name: name of the symlink to remove. | ||
| 116 | * | ||
| 117 | * Unlike sysfs_remove_link sysfs_delete_link has enough information | ||
| 118 | * to successfully delete symlinks in tagged directories. | ||
| 119 | */ | ||
| 120 | void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, | ||
| 121 | const char *name) | ||
| 122 | { | ||
| 123 | const void *ns = NULL; | ||
| 124 | spin_lock(&sysfs_assoc_lock); | ||
| 125 | if (targ->sd) | ||
| 126 | ns = targ->sd->s_ns; | ||
| 127 | spin_unlock(&sysfs_assoc_lock); | ||
| 128 | sysfs_hash_and_remove(kobj->sd, ns, name); | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 110 | * sysfs_remove_link - remove symlink in object's directory. | 132 | * sysfs_remove_link - remove symlink in object's directory. |
| 111 | * @kobj: object we're acting for. | 133 | * @kobj: object we're acting for. |
| 112 | * @name: name of the symlink to remove. | 134 | * @name: name of the symlink to remove. |
| @@ -121,7 +143,7 @@ void sysfs_remove_link(struct kobject * kobj, const char * name) | |||
| 121 | else | 143 | else |
| 122 | parent_sd = kobj->sd; | 144 | parent_sd = kobj->sd; |
| 123 | 145 | ||
| 124 | sysfs_hash_and_remove(parent_sd, name); | 146 | sysfs_hash_and_remove(parent_sd, NULL, name); |
| 125 | } | 147 | } |
| 126 | 148 | ||
| 127 | /** | 149 | /** |
| @@ -137,6 +159,7 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, | |||
| 137 | const char *old, const char *new) | 159 | const char *old, const char *new) |
| 138 | { | 160 | { |
| 139 | struct sysfs_dirent *parent_sd, *sd = NULL; | 161 | struct sysfs_dirent *parent_sd, *sd = NULL; |
| 162 | const void *old_ns = NULL, *new_ns = NULL; | ||
| 140 | int result; | 163 | int result; |
| 141 | 164 | ||
| 142 | if (!kobj) | 165 | if (!kobj) |
| @@ -144,8 +167,11 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, | |||
| 144 | else | 167 | else |
| 145 | parent_sd = kobj->sd; | 168 | parent_sd = kobj->sd; |
| 146 | 169 | ||
| 170 | if (targ->sd) | ||
| 171 | old_ns = targ->sd->s_ns; | ||
| 172 | |||
| 147 | result = -ENOENT; | 173 | result = -ENOENT; |
| 148 | sd = sysfs_get_dirent(parent_sd, old); | 174 | sd = sysfs_get_dirent(parent_sd, old_ns, old); |
| 149 | if (!sd) | 175 | if (!sd) |
| 150 | goto out; | 176 | goto out; |
| 151 | 177 | ||
| @@ -155,7 +181,10 @@ int sysfs_rename_link(struct kobject *kobj, struct kobject *targ, | |||
| 155 | if (sd->s_symlink.target_sd->s_dir.kobj != targ) | 181 | if (sd->s_symlink.target_sd->s_dir.kobj != targ) |
| 156 | goto out; | 182 | goto out; |
| 157 | 183 | ||
| 158 | result = sysfs_rename(sd, parent_sd, new); | 184 | if (sysfs_ns_type(parent_sd)) |
| 185 | new_ns = targ->ktype->namespace(targ); | ||
| 186 | |||
| 187 | result = sysfs_rename(sd, parent_sd, new_ns, new); | ||
| 159 | 188 | ||
| 160 | out: | 189 | out: |
| 161 | sysfs_put(sd); | 190 | sysfs_put(sd); |
