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); |
