[Ocfs2-commits] jlbec commits r2073 - trunk/fs/configfs
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Tue Mar 29 18:09:25 CST 2005
Author: jlbec
Signed-off-by: manish
Signed-off-by: mfasheh
Date: 2005-03-29 18:09:23 -0600 (Tue, 29 Mar 2005)
New Revision: 2073
Modified:
trunk/fs/configfs/Makefile
trunk/fs/configfs/configfs.h
trunk/fs/configfs/dir.c
Log:
o Move the object linkage outside of the dcache muddling.
o Properly lock subsys->su_sem around make+link and unlink+drop.
Signed-off-by: manish
Signed-off-by: mfasheh
Modified: trunk/fs/configfs/Makefile
===================================================================
--- trunk/fs/configfs/Makefile 2005-03-29 22:31:33 UTC (rev 2072)
+++ trunk/fs/configfs/Makefile 2005-03-30 00:09:23 UTC (rev 2073)
@@ -23,8 +23,8 @@
HEADERS = \
uobject.h \
- usysfs.h \
- usysfs_internal.h \
+ configfs.h \
+ configfs_internal.h \
compatinclude/linux/compat.h \
compatinclude/linux/kref.h \
compatinclude/linux/compat_libfs.h
Modified: trunk/fs/configfs/configfs.h
===================================================================
--- trunk/fs/configfs/configfs.h 2005-03-29 22:31:33 UTC (rev 2072)
+++ trunk/fs/configfs/configfs.h 2005-03-30 00:09:23 UTC (rev 2073)
@@ -67,7 +67,7 @@
struct configfs_set_operations {
struct uobject *(*make_object)(struct uset *uset, const char *name);
struct uset *(*make_set)(struct uset *uset, const char *name);
- int (*commit)(struct uobject *uobj);
+ int (*commit_object)(struct uobject *uobj);
void (*drop_object)(struct uset *uset, struct uobject *uobj);
};
Modified: trunk/fs/configfs/dir.c
===================================================================
--- trunk/fs/configfs/dir.c 2005-03-29 22:31:33 UTC (rev 2072)
+++ trunk/fs/configfs/dir.c 2005-03-30 00:09:23 UTC (rev 2073)
@@ -38,7 +38,6 @@
#include "configfs_internal.h"
DECLARE_RWSEM(configfs_rename_sem);
-static spinlock_t configfs_linkage_lock = SPIN_LOCK_UNLOCKED;
static void configfs_d_iput(struct dentry * dentry,
struct inode * inode)
@@ -488,20 +487,17 @@
}
/*
- * Remove an object from its uset and decrement the refcount.
- * This is used by both rmdir() and by mkdir() on error.
- * It expects a valid reference to be held on uobj in addition to
- * the reference from link_obj().
+ * All of link_obj/unlink_obj/link_set/unlink_set require that
+ * subsys->su_sem is held.
*/
+
static void unlink_obj(struct uobject *uobj)
{
struct uset *set;
set = uobj->uset;
if (set) {
- spin_lock(&configfs_linkage_lock);
list_del_init(&uobj->entry);
- spin_unlock(&configfs_linkage_lock);
uobj->uset = NULL;
uobj->parent = NULL;
@@ -513,16 +509,47 @@
static void link_obj(struct uobject *parent_uobj, struct uobject *uobj)
{
+ /* Parent seems redundant with set, but it makes certain
+ * traversals much nicer. */
+ uobj->parent = parent_uobj;
uobj->uset = uset_get(to_uset(parent_uobj));
-
- spin_lock(&configfs_linkage_lock);
list_add_tail(&uobj->entry, &uobj->uset->list);
- spin_unlock(&configfs_linkage_lock);
- uobj->parent = parent_uobj;
uobject_get(uobj);
}
+static void unlink_set(struct uset *uset)
+{
+ int i;
+ struct uset *new_set;
+
+ if (uset->default_sets) {
+ for (i = 0; uset->default_sets[i]; i++) {
+ new_set = uset->default_sets[i];
+ unlink_set(new_set);
+ }
+ }
+
+ uset->subsys = NULL;
+ unlink_obj(&uset->uobj);
+}
+
+static void link_set(struct uset *parent_uset, struct uset *uset)
+{
+ int i;
+ struct uset *new_set;
+
+ link_obj(&parent_uset->uobj, &uset->uobj);
+ uset->subsys = parent_uset->subsys;
+
+ if (uset->default_sets) {
+ for (i = 0; uset->default_sets[i]; i++) {
+ new_set = uset->default_sets[i];
+ link_set(uset, new_set);
+ }
+ }
+}
+
/*
* The goal is that configfs_attach_object() (and
* configfs_attach_set()) can be called from either the VFS or this
@@ -544,13 +571,11 @@
{
int ret;
- link_obj(parent_uobj, uobj);
ret = configfs_create_dir(uobj, dentry);
if (!ret) {
ret = populate_attrs(uobj);
if (ret) {
configfs_remove_dir(uobj);
- unlink_obj(uobj);
d_delete(dentry);
}
}
@@ -562,7 +587,6 @@
{
detach_attrs(uobj);
configfs_remove_dir(uobj);
- unlink_obj(uobj);
}
static int configfs_attach_set(struct uobject *parent_uobj,
@@ -621,6 +645,7 @@
struct uset *uset;
struct uobject *uobj;
struct uobject *parent_uobj;
+ struct configfs_subsystem *subsys;
struct configfs_dirent *sd;
struct uobj_type *uktype;
struct module *owner;
@@ -635,6 +660,8 @@
parent_uobj = configfs_get_uobject(dentry->d_parent);
uktype = parent_uobj->ktype;
+ subsys = to_uset(parent_uobj)->subsys;
+ BUG_ON(!subsys);
if (!uktype || !uktype->set_ops ||
(!uktype->set_ops->make_set &&
@@ -649,13 +676,24 @@
return -ENOMEM;
}
snprintf(name, dentry->d_name.len + 1, "%s", dentry->d_name.name);
+
+ down(&subsys->su_sem);
+ uset = NULL;
+ uobj = NULL;
if (uktype->set_ops->make_set) {
- uset = uktype->set_ops->make_set(to_uset(parent_uobj), name);
- uobj = uset ? &uset->uobj : NULL;
+ uset = uktype->set_ops->make_set(to_uset(parent_uobj),
+ name);
+ if (uset) {
+ link_set(to_uset(parent_uobj), uset);
+ uobj = &uset->uobj;
+ }
} else {
- uset = NULL;
uobj = uktype->set_ops->make_object(to_uset(parent_uobj), name);
+ if (uobj)
+ link_obj(parent_uobj, uobj);
}
+ up(&subsys->su_sem);
+
kfree(name);
if (!uobj) {
uobject_put(parent_uobj);
@@ -667,16 +705,25 @@
if (uktype) {
owner = uktype->owner;
if (try_module_get(owner)) {
- if (uset)
+ if (uset) {
ret = configfs_attach_set(parent_uobj,
uobj,
dentry);
- else
+ } else {
ret = configfs_attach_object(parent_uobj,
uobj,
dentry);
+ }
+
if (ret) {
+ down(&subsys->su_sem);
+ if (uset)
+ unlink_set(uset);
+ else
+ unlink_obj(uobj);
client_drop_object(parent_uobj, uobj);
+ up(&subsys->su_sem);
+
uobject_put(parent_uobj);
module_put(owner);
}
@@ -690,6 +737,7 @@
{
struct uobject *parent_uobj;
struct uobject *uobj;
+ struct configfs_subsystem *subsys;
struct configfs_dirent *sd;
struct module *owner = NULL;
int ret;
@@ -702,12 +750,14 @@
return -EPERM;
parent_uobj = configfs_get_uobject(dentry->d_parent);
+ subsys = to_uset(parent_uobj)->subsys;
+ BUG_ON(!subsys);
if (!parent_uobj->ktype) {
uobject_put(parent_uobj);
return -EINVAL;
}
-
+
ret = configfs_empty_dir(dentry);
if (ret) {
uobject_put(parent_uobj);
@@ -722,12 +772,20 @@
if (uobj->ktype)
owner = uobj->ktype->owner;
- if (sd->s_type & CONFIGFS_USET_DIR)
+ if (sd->s_type & CONFIGFS_USET_DIR) {
configfs_detach_set(uobj);
- else
+
+ down(&subsys->su_sem);
+ unlink_set(to_uset(uobj));
+ } else {
configfs_detach_object(uobj);
+ down(&subsys->su_sem);
+ unlink_obj(uobj);
+ }
+
client_drop_object(parent_uobj, uobj);
+ up(&subsys->su_sem);
/* Drop our reference from above */
uobject_put(uobj);
@@ -947,6 +1005,10 @@
if (!set->uobj.k_name)
set->uobj.k_name = set->uobj.name;
+ sd = configfs_sb->s_root->d_fsdata;
+ link_set(to_uset(sd->s_element), set);
+ set->subsys = subsys;
+
down(&configfs_sb->s_root->d_inode->i_sem);
name.name = set->uobj.k_name;
@@ -960,7 +1022,6 @@
d_add(dentry, NULL);
- sd = configfs_sb->s_root->d_fsdata;
err = configfs_attach_set(sd->s_element, &set->uobj, dentry);
if (!err)
dentry = NULL;
@@ -972,6 +1033,7 @@
if (dentry) {
dput(dentry);
out_release:
+ unlink_set(set);
configfs_release_fs();
}
@@ -1002,6 +1064,8 @@
up(&configfs_sb->s_root->d_inode->i_sem);
dput(dentry);
+
+ unlink_set(set);
configfs_release_fs();
}
More information about the Ocfs2-commits
mailing list