diff options
author | Tejun Heo <tj@kernel.org> | 2013-11-23 17:21:50 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-11-27 16:57:56 -0500 |
commit | 5d0e26bb59a680a5d97db5b6629941603e8de229 (patch) | |
tree | 221776b29c3cdc947c5e8637856a111d1dc05368 /fs | |
parent | 879f40d193bb3c6c13930e88e3e9d5d7baf84d19 (diff) |
sysfs, kernfs: introduce kernfs_create_link()
Separate out kernfs symlink interface - kernfs_create_link() - which
takes and returns sysfs_dirents, from sysfs_do_create_link_sd().
sysfs_do_create_link_sd() now just determines the parent and target
sysfs_dirents and invokes the new interface and handles dup warning.
This patch doesn't introduce behavior changes.
v2: Dummy implementation for !CONFIG_SYSFS updated to return -ENOSYS.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/sysfs/symlink.c | 76 |
1 files changed, 46 insertions, 30 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 71583fc8100a..41138e91947a 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -21,14 +21,48 @@ | |||
21 | 21 | ||
22 | #include "sysfs.h" | 22 | #include "sysfs.h" |
23 | 23 | ||
24 | /** | ||
25 | * kernfs_create_link - create a symlink | ||
26 | * @parent: directory to create the symlink in | ||
27 | * @name: name of the symlink | ||
28 | * @target: target node for the symlink to point to | ||
29 | * | ||
30 | * Returns the created node on success, ERR_PTR() value on error. | ||
31 | */ | ||
32 | struct sysfs_dirent *kernfs_create_link(struct sysfs_dirent *parent, | ||
33 | const char *name, | ||
34 | struct sysfs_dirent *target) | ||
35 | { | ||
36 | struct sysfs_dirent *sd; | ||
37 | struct sysfs_addrm_cxt acxt; | ||
38 | int error; | ||
39 | |||
40 | sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); | ||
41 | if (!sd) | ||
42 | return ERR_PTR(-ENOMEM); | ||
43 | |||
44 | if (parent->s_flags & SYSFS_FLAG_NS) | ||
45 | sd->s_ns = target->s_ns; | ||
46 | sd->s_symlink.target_sd = target; | ||
47 | sysfs_get(target); /* ref owned by symlink */ | ||
48 | |||
49 | sysfs_addrm_start(&acxt); | ||
50 | error = __sysfs_add_one(&acxt, sd, parent); | ||
51 | sysfs_addrm_finish(&acxt); | ||
52 | |||
53 | if (!error) | ||
54 | return sd; | ||
55 | |||
56 | sysfs_put(sd); | ||
57 | return ERR_PTR(error); | ||
58 | } | ||
59 | |||
60 | |||
24 | static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, | 61 | static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, |
25 | struct kobject *target, | 62 | struct kobject *target, |
26 | const char *name, int warn) | 63 | const char *name, int warn) |
27 | { | 64 | { |
28 | struct sysfs_dirent *target_sd = NULL; | 65 | struct sysfs_dirent *sd, *target_sd = NULL; |
29 | struct sysfs_dirent *sd = NULL; | ||
30 | struct sysfs_addrm_cxt acxt; | ||
31 | int error; | ||
32 | 66 | ||
33 | BUG_ON(!name || !parent_sd); | 67 | BUG_ON(!name || !parent_sd); |
34 | 68 | ||
@@ -42,36 +76,18 @@ static int sysfs_do_create_link_sd(struct sysfs_dirent *parent_sd, | |||
42 | target_sd = sysfs_get(target->sd); | 76 | target_sd = sysfs_get(target->sd); |
43 | spin_unlock(&sysfs_symlink_target_lock); | 77 | spin_unlock(&sysfs_symlink_target_lock); |
44 | 78 | ||
45 | error = -ENOENT; | ||
46 | if (!target_sd) | 79 | if (!target_sd) |
47 | goto out_put; | 80 | return -ENOENT; |
48 | 81 | ||
49 | error = -ENOMEM; | 82 | sd = kernfs_create_link(parent_sd, name, target_sd); |
50 | sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK); | 83 | sysfs_put(target_sd); |
51 | if (!sd) | ||
52 | goto out_put; | ||
53 | |||
54 | if (parent_sd->s_flags & SYSFS_FLAG_NS) | ||
55 | sd->s_ns = target_sd->s_ns; | ||
56 | sd->s_symlink.target_sd = target_sd; | ||
57 | target_sd = NULL; /* reference is now owned by the symlink */ | ||
58 | |||
59 | sysfs_addrm_start(&acxt); | ||
60 | if (warn) | ||
61 | error = sysfs_add_one(&acxt, sd, parent_sd); | ||
62 | else | ||
63 | error = __sysfs_add_one(&acxt, sd, parent_sd); | ||
64 | sysfs_addrm_finish(&acxt); | ||
65 | |||
66 | if (error) | ||
67 | goto out_put; | ||
68 | 84 | ||
69 | return 0; | 85 | if (!IS_ERR(sd)) |
86 | return 0; | ||
70 | 87 | ||
71 | out_put: | 88 | if (warn && PTR_ERR(sd) == -EEXIST) |
72 | sysfs_put(target_sd); | 89 | sysfs_warn_dup(parent_sd, name); |
73 | sysfs_put(sd); | 90 | return PTR_ERR(sd); |
74 | return error; | ||
75 | } | 91 | } |
76 | 92 | ||
77 | /** | 93 | /** |