aboutsummaryrefslogtreecommitdiffstats
path: root/fs/sysfs/symlink.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-06-13 15:27:23 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2007-07-11 19:09:08 -0400
commit3007e997de91ec59af39a3f9c91595b31ae6e08b (patch)
tree4ed4df3ef3a249d2a4b562e36876fc8d4a3fabd9 /fs/sysfs/symlink.c
parent5f9953237f684ea1778adb9d26162da00b282225 (diff)
sysfs: use sysfs_mutex to protect the sysfs_dirent tree
As kobj sysfs dentries and inodes are gonna be made reclaimable, i_mutex can't be used to protect sysfs_dirent tree. Use sysfs_mutex globally instead. As the whole tree is protected with sysfs_mutex, there is no reason to keep sysfs_rename_sem. Drop it. While at it, add docbook comments to functions which require sysfs_mutex locking. Signed-off-by: Tejun Heo <htejun@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'fs/sysfs/symlink.c')
-rw-r--r--fs/sysfs/symlink.c51
1 files changed, 26 insertions, 25 deletions
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
index cbd95a4109de..683316f0aa96 100644
--- a/fs/sysfs/symlink.c
+++ b/fs/sysfs/symlink.c
@@ -44,20 +44,6 @@ static void fill_object_path(struct sysfs_dirent *sd, char *buffer, int length)
44 } 44 }
45} 45}
46 46
47static int sysfs_add_link(struct sysfs_dirent * parent_sd, const char * name,
48 struct sysfs_dirent * target_sd)
49{
50 struct sysfs_dirent * sd;
51
52 sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
53 if (!sd)
54 return -ENOMEM;
55
56 sd->s_elem.symlink.target_sd = target_sd;
57 sysfs_attach_dirent(sd, parent_sd, NULL);
58 return 0;
59}
60
61/** 47/**
62 * sysfs_create_link - create symlink between two objects. 48 * sysfs_create_link - create symlink between two objects.
63 * @kobj: object whose directory we're creating the link in. 49 * @kobj: object whose directory we're creating the link in.
@@ -68,7 +54,8 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
68{ 54{
69 struct sysfs_dirent *parent_sd = NULL; 55 struct sysfs_dirent *parent_sd = NULL;
70 struct sysfs_dirent *target_sd = NULL; 56 struct sysfs_dirent *target_sd = NULL;
71 int error = -EEXIST; 57 struct sysfs_dirent *sd = NULL;
58 int error;
72 59
73 BUG_ON(!name); 60 BUG_ON(!name);
74 61
@@ -78,8 +65,9 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
78 } else 65 } else
79 parent_sd = kobj->sd; 66 parent_sd = kobj->sd;
80 67
68 error = -EFAULT;
81 if (!parent_sd) 69 if (!parent_sd)
82 return -EFAULT; 70 goto out_put;
83 71
84 /* target->sd can go away beneath us but is protected with 72 /* target->sd can go away beneath us but is protected with
85 * sysfs_assoc_lock. Fetch target_sd from it. 73 * sysfs_assoc_lock. Fetch target_sd from it.
@@ -89,17 +77,30 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
89 target_sd = sysfs_get(target->sd); 77 target_sd = sysfs_get(target->sd);
90 spin_unlock(&sysfs_assoc_lock); 78 spin_unlock(&sysfs_assoc_lock);
91 79
80 error = -ENOENT;
92 if (!target_sd) 81 if (!target_sd)
93 return -ENOENT; 82 goto out_put;
83
84 error = -ENOMEM;
85 sd = sysfs_new_dirent(name, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
86 if (!sd)
87 goto out_put;
88 sd->s_elem.symlink.target_sd = target_sd;
94 89
95 mutex_lock(&parent_sd->s_dentry->d_inode->i_mutex); 90 mutex_lock(&sysfs_mutex);
96 if (!sysfs_find_dirent(parent_sd, name)) 91 error = -EEXIST;
97 error = sysfs_add_link(parent_sd, name, target_sd); 92 if (sysfs_find_dirent(parent_sd, name))
98 mutex_unlock(&parent_sd->s_dentry->d_inode->i_mutex); 93 goto out_unlock;
94 sysfs_attach_dirent(sd, parent_sd, NULL);
95 mutex_unlock(&sysfs_mutex);
99 96
100 if (error) 97 return 0;
101 sysfs_put(target_sd);
102 98
99 out_unlock:
100 mutex_unlock(&sysfs_mutex);
101 out_put:
102 sysfs_put(target_sd);
103 sysfs_put(sd);
103 return error; 104 return error;
104} 105}
105 106
@@ -144,9 +145,9 @@ static int sysfs_getlink(struct dentry *dentry, char * path)
144 struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd; 145 struct sysfs_dirent *target_sd = sd->s_elem.symlink.target_sd;
145 int error; 146 int error;
146 147
147 down_read(&sysfs_rename_sem); 148 mutex_lock(&sysfs_mutex);
148 error = sysfs_get_target_path(parent_sd, target_sd, path); 149 error = sysfs_get_target_path(parent_sd, target_sd, path);
149 up_read(&sysfs_rename_sem); 150 mutex_unlock(&sysfs_mutex);
150 151
151 return error; 152 return error;
152} 153}