diff options
Diffstat (limited to 'fs/sysfs/symlink.c')
-rw-r--r-- | fs/sysfs/symlink.c | 50 |
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 | */ | ||
136 | int 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 | |||
160 | out: | ||
161 | sysfs_put(sd); | ||
162 | return result; | ||
163 | } | ||
164 | |||
126 | static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, | 165 | static 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 | ||
212 | const struct inode_operations sysfs_symlink_inode_operations = { | 251 | const 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 | ||