[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