[Ocfs2-commits] jlbec commits r1972 - trunk/fs/usysfs

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Mar 14 11:22:54 CST 2005


Author: jlbec
Signed-off-by: zab
Date: 2005-03-14 11:22:52 -0600 (Mon, 14 Mar 2005)
New Revision: 1972

Modified:
   trunk/fs/usysfs/bobtest.c
   trunk/fs/usysfs/dir.c
   trunk/fs/usysfs/inode.c
   trunk/fs/usysfs/mount.c
   trunk/fs/usysfs/symlink.c
   trunk/fs/usysfs/usysfs.h
   trunk/fs/usysfs/usysfs_internal.h
Log:

o Add usysfs_symlink().  Doesn't unlink yet!

Signed-off-by: zab



Modified: trunk/fs/usysfs/bobtest.c
===================================================================
--- trunk/fs/usysfs/bobtest.c	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/bobtest.c	2005-03-14 17:22:52 UTC (rev 1972)
@@ -422,12 +422,23 @@
 	kfree(to_jerry(kobj));
 }
 
+static int jerry_allow_link(struct kobject *src, struct kobject *target)
+{
+	int ret = 0;
+
+	if (target->ktype != &uktype_bob.ktype)
+		ret = -EINVAL;
+
+	return ret;
+}
+
 static struct ukobj_type uktype_jerry = {
 	.ktype	= {
 		.release	= jerry_release,
 		.sysfs_ops	= &jerry_sysfs_ops,
 		.default_attrs	= jerry_attrs,
 	},
+	.allow_link = jerry_allow_link,
 	.owner	= THIS_MODULE,
 };
 

Modified: trunk/fs/usysfs/dir.c
===================================================================
--- trunk/fs/usysfs/dir.c	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/dir.c	2005-03-14 17:22:52 UTC (rev 1972)
@@ -51,6 +51,7 @@
 
 	memset(sd, 0, sizeof(*sd));
 	atomic_set(&sd->s_count, 1);
+	INIT_LIST_HEAD(&sd->s_links);
 	INIT_LIST_HEAD(&sd->s_children);
 	list_add(&sd->s_sibling, &parent_sd->s_children);
 	sd->s_element = element;
@@ -146,6 +147,22 @@
 	return error;
 }
 
+int usysfs_create_link(struct usysfs_symlink *sl, struct dentry *parent,
+		       struct dentry *dentry)
+{
+	int err = 0;
+	umode_t mode = S_IFLNK | S_IRWXUGO;
+
+	err = usysfs_create(dentry, mode, init_symlink);
+	if (!err) {
+		err = usysfs_make_dirent(parent->d_fsdata, dentry, sl,
+					 mode, USYSFS_KOBJ_LINK);
+		if (!err)
+			dentry->d_op = &usysfs_dentry_ops;
+	}
+	return err;
+}
+
 static void remove_dir(struct dentry * d)
 {
 	struct dentry * parent = dget(d->d_parent);
@@ -221,20 +238,6 @@
 	return 0;
 }
 
-static int usysfs_attach_link(struct usysfs_dirent * sd, struct dentry * dentry)
-{
-	int err = 0;
-
-	err = usysfs_create(dentry, S_IFLNK|S_IRWXUGO, init_symlink);
-	if (!err) {
-		dentry->d_op = &usysfs_dentry_ops;
-		dentry->d_fsdata = usysfs_get(sd);
-		sd->s_dentry = dentry;
-		d_rehash(dentry);
-	}
-	return err;
-}
-
 static struct dentry * usysfs_lookup(struct inode *dir, struct dentry *dentry,
 				struct nameidata *nd)
 {
@@ -251,10 +254,7 @@
 				continue;
 
 			found = 1;
-			if (sd->s_type & USYSFS_KOBJ_LINK)
-				err = usysfs_attach_link(sd, dentry);
-			else
-				err = usysfs_attach_attr(sd, dentry);
+			err = usysfs_attach_attr(sd, dentry);
 			break;
 		}
 	}
@@ -278,7 +278,13 @@
 {
 	struct usysfs_dirent *parent_sd = dentry->d_fsdata;
 	struct usysfs_dirent *sd;
+	int ret;
+	
+	ret = -EBUSY;
+	if (!list_empty(&parent_sd->s_links))
+		goto out;
 
+	ret = 0;
 	list_for_each_entry(sd, &parent_sd->s_children, s_sibling) {
 		if (sd->s_type & USYSFS_NOT_PINNED)
 			continue;
@@ -286,11 +292,13 @@
 		if ((sd->s_type & USYSFS_DEFAULT_DIR) &&
 		    usysfs_empty_dir(sd->s_dentry))
 			continue;
-
-		return 0;
+		
+		ret = -ENOTEMPTY;
+		break;
 	}
 
-	return 1;
+out:
+	return ret;
 }
 
 static void drop_attrs(struct kobject * kobj)
@@ -640,6 +648,7 @@
 	struct ukobj_type *uktype, *child_uktype;
 	struct usysfs_dirent *sd;
 	struct module *owner = NULL;
+	int ret;
 
 	if (dentry->d_parent == usysfs_sb->s_root)
 		return -EPERM;
@@ -656,9 +665,10 @@
 		return -EINVAL;
 	}
 
-	if (!usysfs_empty_dir(dentry)) {
+	ret = usysfs_empty_dir(dentry);
+	if (ret) {
 		kobject_put(parent_kobj);
-		return -ENOTEMPTY;
+		return ret;
 	}
 
 	kobj = usysfs_get_kobject(dentry);
@@ -695,6 +705,7 @@
 struct inode_operations usysfs_dir_inode_operations = {
 	.mkdir		= usysfs_mkdir,
 	.rmdir		= usysfs_rmdir,
+	.symlink	= usysfs_symlink,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 	.lookup		= usysfs_lookup,
 #else
@@ -932,7 +943,7 @@
 	}
 
 	down(&usysfs_sb->s_root->d_inode->i_sem);
-	if (!usysfs_empty_dir(k->kobj.dentry)) {
+	if (usysfs_empty_dir(k->kobj.dentry)) {
 		printk(KERN_ERR "usysfs: Tried to unregister non-empty subsystem!\n");
 	}
 	usysfs_drop_set(&k->kobj);

Modified: trunk/fs/usysfs/inode.c
===================================================================
--- trunk/fs/usysfs/inode.c	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/inode.c	2005-03-14 17:22:52 UTC (rev 1972)
@@ -99,7 +99,6 @@
 {
 	struct attribute * attr;
 	struct bin_attribute * bin_attr;
-	struct usysfs_symlink  * sl;
 
 	if (!sd || !sd->s_element)
 		BUG();
@@ -107,6 +106,7 @@
 	switch (sd->s_type) {
 		case USYSFS_DIR:
 		case USYSFS_DEFAULT_DIR:
+		case USYSFS_KOBJ_LINK:
 			/* Always have a dentry so use that */
 			return sd->s_dentry->d_name.name;
 
@@ -117,10 +117,6 @@
 		case USYSFS_KOBJ_BIN_ATTR:
 			bin_attr = sd->s_element;
 			return bin_attr->attr.name;
-
-		case USYSFS_KOBJ_LINK:
-			sl = sd->s_element;
-			return sl->link_name;
 	}
 	return NULL;
 }

Modified: trunk/fs/usysfs/mount.c
===================================================================
--- trunk/fs/usysfs/mount.c	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/mount.c	2005-03-14 17:22:52 UTC (rev 1972)
@@ -43,6 +43,11 @@
 	},
 };
 
+int usysfs_is_root(struct kobject *kobj)
+{
+	return kobj == &usysfs_root_set.kset.kobj;
+}
+
 static struct usysfs_dirent usysfs_root = {
 	.s_sibling	= LIST_HEAD_INIT(usysfs_root.s_sibling),
 	.s_children	= LIST_HEAD_INIT(usysfs_root.s_children),

Modified: trunk/fs/usysfs/symlink.c
===================================================================
--- trunk/fs/usysfs/symlink.c	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/symlink.c	2005-03-14 17:22:52 UTC (rev 1972)
@@ -17,7 +17,7 @@
 {
 	struct kobject * p = kobj;
 	int depth = 0;
-	do { depth++; } while ((p = p->parent));
+	do { depth++; } while ((p = p->parent) && !usysfs_is_root(p));
 	return depth;
 }
 
@@ -28,7 +28,7 @@
 	do {
 		length += strlen(kobject_name(p)) + 1;
 		p = p->parent;
-	} while (p);
+	} while (p && !usysfs_is_root(p));
 	return length;
 }
 
@@ -37,7 +37,7 @@
 	struct kobject * p;
 
 	--length;
-	for (p = kobj; p; p = p->parent) {
+	for (p = kobj; p && !usysfs_is_root(p); p = p->parent) {
 		int cur = strlen(kobject_name(p));
 
 		/* back up enough to print this bus id with '/' */
@@ -47,53 +47,48 @@
 	}
 }
 
-static int usysfs_add_link(struct dentry * parent, char * name, struct kobject * target)
+static int create_link(struct kobject *parent_kobj,
+ 		       struct kobject *kobj,
+		       struct dentry *dentry)
 {
-	struct usysfs_dirent * parent_sd = parent->d_fsdata;
-	struct usysfs_symlink * sl;
-	int error = 0;
+	struct usysfs_dirent *target_sd = kobj->dentry->d_fsdata;
+	struct usysfs_symlink *sl;
+	int ret;
 
-	error = -ENOMEM;
-	sl = kmalloc(sizeof(*sl), GFP_KERNEL);
-	if (!sl)
-		goto exit1;
+	ret = -ENOMEM;
+	sl = kmalloc(sizeof(struct usysfs_symlink), GFP_KERNEL);
+	if (sl) {
+		sl->sl_target = kobject_get(kobj);
+		/* FIXME: needs a lock, I'd bet */
+		list_add(&sl->sl_list, &target_sd->s_links);
+		ret = usysfs_create_link(sl, parent_kobj->dentry,
+					 dentry);
+		if (ret) {
+			list_del(&sl->sl_list);
+			kobject_put(kobj);
+			kfree(sl);
+		}
+	}
 
-	sl->link_name = kmalloc(strlen(name) + 1, GFP_KERNEL);
-	if (!sl->link_name)
-		goto exit2;
-
-	strcpy(sl->link_name, name);
-	sl->target_kobj = kobject_get(target);
-
-	error = usysfs_make_dirent(parent_sd, NULL, sl, S_IFLNK|S_IRWXUGO,
-				USYSFS_KOBJ_LINK);
-	if (!error)
-		return 0;
-
-	kfree(sl->link_name);
-exit2:
-	kfree(sl);
-exit1:
-	return error;
+	return ret;
 }
 
-/**
- *	usysfs_create_link - create symlink between two objects.
- *	@kobj:	object whose directory we're creating the link in.
- *	@target:	object we're pointing to.
- *	@name:		name of the symlink.
- */
-int usysfs_create_link(struct kobject * kobj, struct kobject * target, char * name)
+
+static int get_target(const char *symname, struct nameidata *nd,
+		      struct kobject **target)
 {
-	struct dentry * dentry = kobj->dentry;
-	int error = 0;
+	int ret;
 
-	BUG_ON(!kobj || !kobj->dentry || !name);
+	ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, nd);
+	if (!ret) {
+		*target = usysfs_get_kobject(nd->dentry);
+		if (!*target) {
+			ret = -ENOENT;
+			path_release(nd);
+		}
+	}
 
-	down(&dentry->d_inode->i_sem);
-	error = usysfs_add_link(dentry, name, target);
-	up(&dentry->d_inode->i_sem);
-	return error;
+	return ret;
 }
 
 
@@ -101,46 +96,35 @@
 {
 	int ret;
 	struct nameidata nd;
-	struct kobject *parent_kobj;
+	struct kobject *parent_kobj = NULL;
 	struct kobject *target_kobj;
-	struct ukobj_type *uktype;
+	struct ukobj_type *uktype = NULL;
 
+	ret = -EPERM;  /* What lack-of-symlink returns */
 	if (dentry->d_parent == usysfs_sb->s_root)
-		return -EPERM;
+		goto out;
 
 	parent_kobj = usysfs_get_kobject(dentry->d_parent);
 	uktype = to_uktype(parent_kobj->ktype);
 
-	if (!uktype || !uktype->allow_link) {
-		kobject_put(parent_kobj);
-		return -EPERM;  /* What lack-of-symlink returns */
-	}
+	if (!uktype || !uktype->allow_link)
+		goto out_put;
 
-	ret = path_lookup(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &nd);
-	if (ret) {
-		kobject_put(parent_kobj);
-		return ret;
-	}
+	ret = get_target(symname, &nd, &target_kobj);
+	if (ret)
+		goto out_put;
 
-	ret = -ENOENT;
-	target_kobj = usysfs_get_kobject(nd.dentry);
-	if (!target_kobj)
-		goto out_release;
-
 	ret = uktype->allow_link(parent_kobj, target_kobj);
-	if (ret)
-		goto out_target;
+	if (!ret)
+		ret = create_link(parent_kobj, target_kobj, dentry);
 
-	return 0;
-
-out_target:
 	kobject_put(target_kobj);
-
-out_release:
 	path_release(&nd);
 
+out_put:
 	kobject_put(parent_kobj);
 
+out:
 	return ret;
 }
 
@@ -265,9 +249,3 @@
 #endif
 };
 
-
-#if 0
-EXPORT_SYMBOL_GPL(usysfs_create_link);
-EXPORT_SYMBOL_GPL(usysfs_remove_link);
-#endif
-

Modified: trunk/fs/usysfs/usysfs.h
===================================================================
--- trunk/fs/usysfs/usysfs.h	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/usysfs.h	2005-03-14 17:22:52 UTC (rev 1972)
@@ -126,6 +126,7 @@
 	atomic_t		s_count;
 	struct list_head	s_sibling;
 	struct list_head	s_children;
+	struct list_head	s_links;
 	void 			* s_element;
 	int			s_type;
 	umode_t			s_mode;
@@ -155,12 +156,6 @@
 extern void
 usysfs_remove_file(struct kobject *, const struct attribute *);
 
-extern int 
-usysfs_create_link(struct kobject * kobj, struct kobject * target, char * name);
-
-extern void
-usysfs_remove_link(struct kobject *, char * name);
-
 int usysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
 int usysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
 

Modified: trunk/fs/usysfs/usysfs_internal.h
===================================================================
--- trunk/fs/usysfs/usysfs_internal.h	2005-03-11 22:44:37 UTC (rev 1971)
+++ trunk/fs/usysfs/usysfs_internal.h	2005-03-14 17:22:52 UTC (rev 1972)
@@ -1,3 +1,9 @@
+/* -*- mode: c; c-basic-offset:8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * usysfs_internal.h - Internal stuff for usysfs
+ */
+
 #include <linux/version.h>
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
 #include "linux/compat_libfs.h"
@@ -3,7 +9,10 @@
 #endif
 #include <linux/slab.h>
+#include <linux/list.h>
 
 extern struct vfsmount * usysfs_mount;
 
+extern int usysfs_is_root(struct kobject *kobj);
+
 extern struct inode * usysfs_new_inode(mode_t mode);
 extern int usysfs_create(struct dentry *, int mode, int (*init)(struct inode *));
@@ -33,11 +42,18 @@
 extern struct inode_operations usysfs_dir_inode_operations;
 extern struct inode_operations usysfs_symlink_inode_operations;
 
+extern int usysfs_symlink(struct inode *dir, struct dentry *dentry,
+			  const char *symname);
+
 struct usysfs_symlink {
-	char * link_name;
-	struct kobject * target_kobj;
+	struct list_head sl_list;
+	struct kobject *sl_target;
 };
 
+extern int usysfs_create_link(struct usysfs_symlink *sl,
+			      struct dentry *parent,
+			      struct dentry *dentry);
+
 static inline struct kobject * to_kobj(struct dentry * dentry)
 {
 	struct usysfs_dirent * sd = dentry->d_fsdata;
@@ -65,7 +81,7 @@
 		struct usysfs_dirent * sd = dentry->d_fsdata;
 		if (sd->s_type & USYSFS_KOBJ_LINK) {
 			struct usysfs_symlink * sl = sd->s_element;
-			kobj = kobject_get(sl->target_kobj);
+			kobj = kobject_get(sl->sl_target);
 		} else
 			kobj = kobject_get(sd->s_element);
 	}
@@ -76,12 +92,14 @@
 
 static inline void release_usysfs_dirent(struct usysfs_dirent * sd)
 {
+#if 0 /* I'm handling symlinks as explicit objects now */
 	if (sd->s_type & USYSFS_KOBJ_LINK) {
 		struct usysfs_symlink * sl = sd->s_element;
 		kfree(sl->link_name);
 		kobject_put(sl->target_kobj);
 		kfree(sl);
 	}
+#endif
 	kfree(sd);
 }
 



More information about the Ocfs2-commits mailing list