*/
#include <linux/fs.h>
+#include <linux/mount.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <linux/namei.h>
+#include <asm/semaphore.h>
#include "sysfs.h"
{
struct sysfs_dirent * parent_sd = parent->d_fsdata;
struct sysfs_symlink * sl;
- int error = 0;
+ struct sysfs_dirent * sd;
+ int error;
error = -ENOMEM;
- sl = kmalloc(sizeof(*sl), GFP_KERNEL);
+ sl = kzalloc(sizeof(*sl), GFP_KERNEL);
if (!sl)
- goto exit1;
-
- sl->link_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
- if (!sl->link_name)
- goto exit2;
+ goto err_out;
- strcpy(sl->link_name, name);
sl->target_kobj = kobject_get(target);
- error = sysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO,
- SYSFS_KOBJ_LINK);
- if (!error)
- return 0;
+ sd = sysfs_new_dirent(name, sl, S_IFLNK|S_IRWXUGO, SYSFS_KOBJ_LINK);
+ if (!sd)
+ goto err_out;
+ sysfs_attach_dirent(sd, parent_sd, NULL);
+
+ return 0;
- kobject_put(target);
- kfree(sl->link_name);
-exit2:
- kfree(sl);
-exit1:
+ err_out:
+ if (sl) {
+ kobject_put(sl->target_kobj);
+ kfree(sl);
+ }
return error;
}
*/
int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
{
- struct dentry * dentry = kobj->dentry;
+ struct dentry *dentry = NULL;
int error = -EEXIST;
- BUG_ON(!kobj || !kobj->dentry || !name);
+ BUG_ON(!name);
+
+ if (!kobj) {
+ if (sysfs_mount && sysfs_mount->mnt_sb)
+ dentry = sysfs_mount->mnt_sb->s_root;
+ } else
+ dentry = kobj->dentry;
+
+ if (!dentry)
+ return -EFAULT;
mutex_lock(&dentry->d_inode->i_mutex);
if (!sysfs_dirent_exist(dentry->d_fsdata, name))
free_page((unsigned long)page);
}
-struct inode_operations sysfs_symlink_inode_operations = {
+const struct inode_operations sysfs_symlink_inode_operations = {
.readlink = generic_readlink,
.follow_link = sysfs_follow_link,
.put_link = sysfs_put_link,