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

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Mon Mar 14 21:31:13 CST 2005


Author: jlbec
Signed-off-by: manish
Date: 2005-03-14 21:31:12 -0600 (Mon, 14 Mar 2005)
New Revision: 1973

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

o Make unlink work to match symlink.
o Fix the d_delete/d_drop mess.  Now call d_delete, and have
  d_op->d_delete force dentry removal.
o Remove a bunch of kernel call-ins from sysfs days.

Signed-off-by: manish



Modified: trunk/fs/usysfs/dir.c
===================================================================
--- trunk/fs/usysfs/dir.c	2005-03-14 17:22:52 UTC (rev 1972)
+++ trunk/fs/usysfs/dir.c	2005-03-15 03:31:12 UTC (rev 1973)
@@ -33,8 +33,19 @@
 	iput(inode);
 }
 
+/*
+ * We _must_ delete our dentries on last dput, as the chain-to-parent
+ * behavior is required to clear the parents of default_sets.
+ */
+static int usysfs_d_delete(struct dentry *dentry)
+{
+	return 1;
+}
+
 static struct dentry_operations usysfs_dentry_ops = {
 	.d_iput		= usysfs_d_iput,
+	/* simple_delete_dentry() isn't exported */
+	.d_delete	= usysfs_d_delete,
 };
 
 /*
@@ -289,11 +300,13 @@
 		if (sd->s_type & USYSFS_NOT_PINNED)
 			continue;
 		/* Eww, recursion */
-		if ((sd->s_type & USYSFS_DEFAULT_DIR) &&
-		    usysfs_empty_dir(sd->s_dentry))
-			continue;
-		
-		ret = -ENOTEMPTY;
+		if (sd->s_type & USYSFS_DEFAULT_DIR) {
+			ret = usysfs_empty_dir(sd->s_dentry);
+			if (!ret)
+			       	continue;
+		} else
+			ret = -ENOTEMPTY;
+
 		break;
 	}
 
@@ -374,19 +387,10 @@
 		child = sd->s_dentry;
 		down(&child->d_inode->i_sem);
 		usysfs_drop_set(sd->s_element);
+		child->d_inode->i_flags |= S_DEAD;
 		up(&child->d_inode->i_sem);
 
-		/*
-		 * This is important.  If the child is still hashed,
-		 * dput() will just put it somewhere safe.  So there
-		 * will not be a chain back to dput()ing the parent.
-		 * At least, not until umount.  This means dentries
-		 * hanging about.  Bad Idea Jeans.  d_delete() would
-		 * leave it hashed, but negative.  That's good for
-		 * stuff coming from the VFS, not for our hand-built
-		 * default_sets.  d_drop unhashes.  Bingo!
-		 */
-		d_drop(child);
+		d_delete(child);
 		dput(child);
 		usysfs_put(sd);
 	}
@@ -428,7 +432,7 @@
 			sd = child->d_fsdata;
 			sd->s_type = USYSFS_DEFAULT_DIR;
 		} else {
-			d_drop(child);
+			d_delete(child);
 			dput(child);
 		}
 	}
@@ -706,6 +710,7 @@
 	.mkdir		= usysfs_mkdir,
 	.rmdir		= usysfs_rmdir,
 	.symlink	= usysfs_symlink,
+	.unlink		= usysfs_unlink,
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
 	.lookup		= usysfs_lookup,
 #else
@@ -738,7 +743,7 @@
 				d_move(kobj->dentry, new_dentry);
 			}
 			else
-				d_drop(new_dentry);
+				d_delete(new_dentry);
 		} else
 			error = -EEXIST;
 		dput(new_dentry);
@@ -922,7 +927,7 @@
 	if (!err)
 		dentry = NULL;
 	else
-		d_drop(dentry);
+		d_delete(dentry);
 
 	up(&usysfs_sb->s_root->d_inode->i_sem);
 
@@ -937,22 +942,27 @@
 
 void usysfs_unregister_subsystem(struct kset *k)
 {
-	if (k->kobj.dentry->d_parent != usysfs_sb->s_root) {
+	struct dentry *dentry = k->kobj.dentry;
+
+	if (dentry->d_parent != usysfs_sb->s_root) {
 		printk(KERN_ERR "usysfs: Tried to unregister non-subsystem!\n");
 		return;
 	}
 
 	down(&usysfs_sb->s_root->d_inode->i_sem);
-	if (usysfs_empty_dir(k->kobj.dentry)) {
+	down(&dentry->d_inode->i_sem);
+	if (usysfs_empty_dir(dentry)) {
 		printk(KERN_ERR "usysfs: Tried to unregister non-empty subsystem!\n");
 	}
 	usysfs_drop_set(&k->kobj);
-	/* See comment in drop_sets() regarding d_drop() */
-	d_drop(k->kobj.dentry);
+	dentry->d_inode->i_flags |= S_DEAD;
+	up(&dentry->d_inode->i_sem);
 
+	d_delete(dentry);
+
 	up(&usysfs_sb->s_root->d_inode->i_sem);
 
-	dput(k->kobj.dentry);
+	dput(dentry);
 	usysfs_release_fs();
 }
 

Modified: trunk/fs/usysfs/file.c
===================================================================
--- trunk/fs/usysfs/file.c	2005-03-14 17:22:52 UTC (rev 1972)
+++ trunk/fs/usysfs/file.c	2005-03-15 03:31:12 UTC (rev 1973)
@@ -389,66 +389,3 @@
 
 }
 
-
-/**
- * usysfs_update_file - update the modified timestamp on an object attribute.
- * @kobj: object we're acting for.
- * @attr: attribute descriptor.
- *
- * Also call dnotify for the dentry, which lots of userspace programs
- * use.
- */
-int usysfs_update_file(struct kobject * kobj, const struct attribute * attr)
-{
-	struct dentry * dir = kobj->dentry;
-	struct dentry * victim;
-	int res = -ENOENT;
-
-	down(&dir->d_inode->i_sem);
-	victim = usysfs_get_dentry(dir, attr->name);
-	if (!IS_ERR(victim)) {
-		/* make sure dentry is really there */
-		if (victim->d_inode && 
-		    (victim->d_parent->d_inode == dir->d_inode)) {
-			victim->d_inode->i_mtime = CURRENT_TIME;
-			dnotify_parent(victim, DN_MODIFY);
-
-			/**
-			 * Drop reference from initial usysfs_get_dentry().
-			 */
-			dput(victim);
-			res = 0;
-		} else
-			d_drop(victim);
-		
-		/**
-		 * Drop the reference acquired from usysfs_get_dentry() above.
-		 */
-		dput(victim);
-	}
-	up(&dir->d_inode->i_sem);
-
-	return res;
-}
-
-
-/**
- *	usysfs_remove_file - remove an object attribute.
- *	@kobj:	object we're acting for.
- *	@attr:	attribute descriptor.
- *
- *	Hash the attribute name and kill the victim.
- */
-
-void usysfs_remove_file(struct kobject * kobj, const struct attribute * attr)
-{
-	usysfs_hash_and_remove(kobj->dentry,attr->name);
-}
-
-
-#if 0
-EXPORT_SYMBOL_GPL(usysfs_create_file);
-EXPORT_SYMBOL_GPL(usysfs_remove_file);
-EXPORT_SYMBOL_GPL(usysfs_update_file);
-#endif 
-

Modified: trunk/fs/usysfs/inode.c
===================================================================
--- trunk/fs/usysfs/inode.c	2005-03-14 17:22:52 UTC (rev 1972)
+++ trunk/fs/usysfs/inode.c	2005-03-15 03:31:12 UTC (rev 1973)
@@ -74,8 +74,8 @@
 		error = init(inode);
 	if (!error) {
 		d_instantiate(dentry, inode);
-		if (S_ISDIR(mode))
-			dget(dentry);  /* pin only directory dentry in core */
+		if (S_ISDIR(mode) || S_ISLNK(mode))
+			dget(dentry);  /* pin link and directory dentries in core */
 	} else
 		iput(inode);
  Done:

Modified: trunk/fs/usysfs/symlink.c
===================================================================
--- trunk/fs/usysfs/symlink.c	2005-03-14 17:22:52 UTC (rev 1972)
+++ trunk/fs/usysfs/symlink.c	2005-03-15 03:31:12 UTC (rev 1973)
@@ -64,7 +64,7 @@
 		ret = usysfs_create_link(sl, parent_kobj->dentry,
 					 dentry);
 		if (ret) {
-			list_del(&sl->sl_list);
+			list_del_init(&sl->sl_list);
 			kobject_put(kobj);
 			kfree(sl);
 		}
@@ -96,9 +96,9 @@
 {
 	int ret;
 	struct nameidata nd;
-	struct kobject *parent_kobj = NULL;
+	struct kobject *parent_kobj;
 	struct kobject *target_kobj;
-	struct ukobj_type *uktype = NULL;
+	struct ukobj_type *uktype;
 
 	ret = -EPERM;  /* What lack-of-symlink returns */
 	if (dentry->d_parent == usysfs_sb->s_root)
@@ -128,15 +128,52 @@
 	return ret;
 }
 
-/**
- *	usysfs_remove_link - remove symlink in object's directory.
- *	@kobj:	object we're acting for.
- *	@name:	name of the symlink to remove.
- */
+int usysfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct usysfs_dirent *sd = dentry->d_fsdata;
+	struct usysfs_symlink *sl;
+	struct kobject *parent_kobj;
+	struct ukobj_type *uktype;
+	int ret;
 
-void usysfs_remove_link(struct kobject * kobj, char * name)
-{
-	usysfs_hash_and_remove(kobj->dentry,name);
+	ret = -EPERM;  /* What lack-of-symlink returns */
+	if (!(sd->s_type & USYSFS_KOBJ_LINK))
+		goto out;
+
+	if (dentry->d_parent == usysfs_sb->s_root)
+		BUG();
+
+	sl = sd->s_element;
+
+	parent_kobj = usysfs_get_kobject(dentry->d_parent);
+	uktype = to_uktype(parent_kobj->ktype);
+
+	list_del_init(&sd->s_sibling);
+	usysfs_drop_dentry(sd, dentry->d_parent);
+	dput(dentry);
+	usysfs_put(sd);
+
+	/*
+	 * drop_link() must be called before
+	 * list_del_init(&sl->sl_list), so that the order of
+	 * drop_link(this, target) and drop_object(target) is preserved.
+	 */
+	if (uktype && uktype->drop_link)
+		uktype->drop_link(parent_kobj, sl->sl_target);
+
+	/* FIXME: Needs lock */
+	list_del_init(&sl->sl_list);
+
+	/* Put reference from create_link() */
+	kobject_put(sl->sl_target);
+	kfree(sl);
+
+	kobject_put(parent_kobj);
+
+	ret = 0;
+
+out:
+	return ret;
 }
 
 static int usysfs_get_target_path(struct kobject * kobj, struct kobject * target,

Modified: trunk/fs/usysfs/usysfs.h
===================================================================
--- trunk/fs/usysfs/usysfs.h	2005-03-14 17:22:52 UTC (rev 1972)
+++ trunk/fs/usysfs/usysfs.h	2005-03-15 03:31:12 UTC (rev 1973)
@@ -50,6 +50,7 @@
 	struct kobj_type ktype;
 	struct module *owner;
 	int (*allow_link)(struct kobject *src, struct kobject *target);
+	int (*drop_link)(struct kobject *src, struct kobject *target);
 	struct kobject *(*make_object)(struct kset *kset, const char *name);
 	struct kset *(*make_kset)(struct kset *kset, const char *name);
 	int (*commit)(struct kobject *kobj);
@@ -150,12 +151,6 @@
 extern int
 usysfs_create_file(struct kobject *, const struct attribute *);
 
-extern int
-usysfs_update_file(struct kobject *, const struct attribute *);
-
-extern void
-usysfs_remove_file(struct kobject *, const struct attribute *);
-
 int usysfs_create_bin_file(struct kobject * kobj, struct bin_attribute * attr);
 int usysfs_remove_bin_file(struct kobject * kobj, struct bin_attribute * attr);
 
@@ -173,27 +168,7 @@
 	return 0;
 }
 
-static inline int usysfs_update_file(struct kobject * k, const struct attribute * a)
-{
-	return 0;
-}
 
-static inline void usysfs_remove_file(struct kobject * k, const struct attribute * a)
-{
-	;
-}
-
-static inline int usysfs_create_link(struct kobject * k, struct kobject * t, char * n)
-{
-	return 0;
-}
-
-static inline void usysfs_remove_link(struct kobject * k, char * name)
-{
-	;
-}
-
-
 static inline int usysfs_create_bin_file(struct kobject * k, struct bin_attribute * a)
 {
 	return 0;

Modified: trunk/fs/usysfs/usysfs_internal.h
===================================================================
--- trunk/fs/usysfs/usysfs_internal.h	2005-03-14 17:22:52 UTC (rev 1972)
+++ trunk/fs/usysfs/usysfs_internal.h	2005-03-15 03:31:12 UTC (rev 1973)
@@ -44,6 +44,7 @@
 
 extern int usysfs_symlink(struct inode *dir, struct dentry *dentry,
 			  const char *symname);
+extern int usysfs_unlink(struct inode *dir, struct dentry *dentry);
 
 struct usysfs_symlink {
 	struct list_head sl_list;
@@ -92,14 +93,6 @@
 
 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