aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/symlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/sysfs/symlink.c')
-rw-r--r--fs/sysfs/symlink.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index c5081ad77026..b93ec51fa7ac 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -11,6 +11,7 @@
11 */ 11 */
12 12
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/gfp.h>
14#include <linux/mount.h> 15#include <linux/mount.h>
15#include <linux/module.h> 16#include <linux/module.h>
16#include <linux/kobject.h> 17#include <linux/kobject.h>
@@ -123,6 +124,44 @@ void sysfs_remove_link(struct kobject * kobj, const char * name)
123 sysfs_hash_and_remove(parent_sd, name); 124 sysfs_hash_and_remove(parent_sd, name);
124} 125}
125 126
127/**
128 * sysfs_rename_link - rename symlink in object's directory.
129 * @kobj: object we're acting for.
130 * @targ: object we're pointing to.
131 * @old: previous name of the symlink.
132 * @new: new name of the symlink.
133 *
134 * A helper function for the common rename symlink idiom.
135 */
136int sysfs_rename_link(struct kobject *kobj, struct kobject *targ,
137 const char *old, const char *new)
138{
139 struct sysfs_dirent *parent_sd, *sd = NULL;
140 int result;
141
142 if (!kobj)
143 parent_sd = &sysfs_root;
144 else
145 parent_sd = kobj->sd;
146
147 result = -ENOENT;
148 sd = sysfs_get_dirent(parent_sd, old);
149 if (!sd)
150 goto out;
151
152 result = -EINVAL;
153 if (sysfs_type(sd) != SYSFS_KOBJ_LINK)
154 goto out;
155 if (sd->s_symlink.target_sd->s_dir.kobj != targ)
156 goto out;
157
158 result = sysfs_rename(sd, parent_sd, new);
159
160out:
161 sysfs_put(sd);
162 return result;
163}
164
126static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, 165static int sysfs_get_target_path(struct sysfs_dirent *parent_sd,
127 struct sysfs_dirent *target_sd, char *path) 166 struct sysfs_dirent *target_sd, char *path)
128{ 167{
@@ -210,10 +249,13 @@ static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *co
210} 249}
211 250
212const struct inode_operations sysfs_symlink_inode_operations = { 251const struct inode_operations sysfs_symlink_inode_operations = {
213 .setxattr = sysfs_setxattr, 252 .setxattr = sysfs_setxattr,
214 .readlink = generic_readlink, 253 .readlink = generic_readlink,
215 .follow_link = sysfs_follow_link, 254 .follow_link = sysfs_follow_link,
216 .put_link = sysfs_put_link, 255 .put_link = sysfs_put_link,
256 .setattr = sysfs_setattr,
257 .getattr = sysfs_getattr,
258 .permission = sysfs_permission,
217}; 259};
218 260
219 261