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