diff options
Diffstat (limited to 'fs/sysfs/symlink.c')
-rw-r--r-- | fs/sysfs/symlink.c | 36 |
1 files changed, 33 insertions, 3 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index b93ec51fa7ac..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); |
@@ -261,3 +290,4 @@ const struct inode_operations sysfs_symlink_inode_operations = { | |||
261 | 290 | ||
262 | EXPORT_SYMBOL_GPL(sysfs_create_link); | 291 | EXPORT_SYMBOL_GPL(sysfs_create_link); |
263 | EXPORT_SYMBOL_GPL(sysfs_remove_link); | 292 | EXPORT_SYMBOL_GPL(sysfs_remove_link); |
293 | EXPORT_SYMBOL_GPL(sysfs_rename_link); | ||