diff options
Diffstat (limited to 'fs/sysfs/symlink.c')
-rw-r--r-- | fs/sysfs/symlink.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 4ce687f0b5d0..3eac20c63c41 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -1,5 +1,13 @@ | |||
1 | /* | 1 | /* |
2 | * symlink.c - operations for sysfs symlinks. | 2 | * fs/sysfs/symlink.c - sysfs symlink implementation |
3 | * | ||
4 | * Copyright (c) 2001-3 Patrick Mochel | ||
5 | * Copyright (c) 2007 SUSE Linux Products GmbH | ||
6 | * Copyright (c) 2007 Tejun Heo <teheo@suse.de> | ||
7 | * | ||
8 | * This file is released under the GPLv2. | ||
9 | * | ||
10 | * Please see Documentation/filesystems/sysfs.txt for more information. | ||
3 | */ | 11 | */ |
4 | 12 | ||
5 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
@@ -7,7 +15,7 @@ | |||
7 | #include <linux/module.h> | 15 | #include <linux/module.h> |
8 | #include <linux/kobject.h> | 16 | #include <linux/kobject.h> |
9 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
10 | #include <asm/semaphore.h> | 18 | #include <linux/mutex.h> |
11 | 19 | ||
12 | #include "sysfs.h" | 20 | #include "sysfs.h" |
13 | 21 | ||
@@ -60,10 +68,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
60 | 68 | ||
61 | BUG_ON(!name); | 69 | BUG_ON(!name); |
62 | 70 | ||
63 | if (!kobj) { | 71 | if (!kobj) |
64 | if (sysfs_mount && sysfs_mount->mnt_sb) | 72 | parent_sd = &sysfs_root; |
65 | parent_sd = sysfs_mount->mnt_sb->s_root->d_fsdata; | 73 | else |
66 | } else | ||
67 | parent_sd = kobj->sd; | 74 | parent_sd = kobj->sd; |
68 | 75 | ||
69 | error = -EFAULT; | 76 | error = -EFAULT; |
@@ -87,20 +94,15 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char | |||
87 | if (!sd) | 94 | if (!sd) |
88 | goto out_put; | 95 | goto out_put; |
89 | 96 | ||
90 | sd->s_elem.symlink.target_sd = target_sd; | 97 | sd->s_symlink.target_sd = target_sd; |
91 | target_sd = NULL; /* reference is now owned by the symlink */ | 98 | target_sd = NULL; /* reference is now owned by the symlink */ |
92 | 99 | ||
93 | sysfs_addrm_start(&acxt, parent_sd); | 100 | sysfs_addrm_start(&acxt, parent_sd); |
101 | error = sysfs_add_one(&acxt, sd); | ||
102 | sysfs_addrm_finish(&acxt); | ||
94 | 103 | ||
95 | if (!sysfs_find_dirent(parent_sd, name)) { | 104 | if (error) |
96 | sysfs_add_one(&acxt, sd); | ||
97 | sysfs_link_sibling(sd); | ||
98 | } | ||
99 | |||
100 | if (!sysfs_addrm_finish(&acxt)) { | ||
101 | error = -EEXIST; | ||
102 | goto out_put; | 105 | goto out_put; |
103 | } | ||
104 | 106 | ||
105 | return 0; | 107 | return 0; |
106 | 108 | ||
@@ -148,7 +150,7 @@ static int sysfs_getlink(struct dentry *dentry, char * path) | |||
148 | { | 150 | { |
149 | struct sysfs_dirent *sd = dentry->d_fsdata; | 151 | struct sysfs_dirent *sd = dentry->d_fsdata; |
150 | struct sysfs_dirent *parent_sd = sd->s_parent; | 152 | struct sysfs_dirent *parent_sd = sd->s_parent; |
151 | struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd; | 153 | struct sysfs_dirent *target_sd = sd->s_symlink.target_sd; |
152 | int error; | 154 | int error; |
153 | 155 | ||
154 | mutex_lock(&sysfs_mutex); | 156 | mutex_lock(&sysfs_mutex); |