Commit a43b9aa9 authored by Patrick Mochel's avatar Patrick Mochel

Merge osdl.org:/home/mochel/src/kernel/devel/linux-2.5-virgin

into osdl.org:/home/mochel/src/kernel/devel/linux-2.5-core
parents cebce9d8 8083cc35
...@@ -96,9 +96,10 @@ static int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t ...@@ -96,9 +96,10 @@ static int sysfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t
if (!dentry->d_inode) { if (!dentry->d_inode) {
inode = sysfs_get_inode(dir->i_sb, mode, dev); inode = sysfs_get_inode(dir->i_sb, mode, dev);
if (inode) if (inode) {
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
else dget(dentry);
} else
error = -ENOSPC; error = -ENOSPC;
} else } else
error = -EEXIST; error = -EEXIST;
...@@ -135,14 +136,52 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char * ...@@ -135,14 +136,52 @@ static int sysfs_symlink(struct inode * dir, struct dentry *dentry, const char *
if (inode) { if (inode) {
int l = strlen(symname)+1; int l = strlen(symname)+1;
error = page_symlink(inode, symname, l); error = page_symlink(inode, symname, l);
if (!error) if (!error) {
d_instantiate(dentry, inode); d_instantiate(dentry, inode);
else dget(dentry);
} else
iput(inode); iput(inode);
} }
return error; return error;
} }
#define to_subsys(k) container_of(k,struct subsystem,kobj)
#define to_sattr(a) container_of(a,struct subsys_attribute,attr)
/**
* Subsystem file operations.
* These operations allow subsystems to have files that can be
* read/written.
*/
ssize_t subsys_attr_show(struct kobject * kobj, struct attribute * attr,
char * page, size_t count, loff_t off)
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
ssize_t ret = 0;
if (sattr->show)
ret = sattr->show(s,page,count,off);
return ret;
}
ssize_t subsys_attr_store(struct kobject * kobj, struct attribute * attr,
const char * page, size_t count, loff_t off)
{
struct subsystem * s = to_subsys(kobj);
struct subsys_attribute * sattr = to_sattr(attr);
ssize_t ret = 0;
if (sattr->store)
ret = sattr->store(s,page,count,off);
return ret;
}
static struct sysfs_ops subsys_sysfs_ops = {
.show = subsys_attr_show,
.store = subsys_attr_store,
};
/** /**
* sysfs_read_file - read an attribute. * sysfs_read_file - read an attribute.
* @file: file pointer. * @file: file pointer.
...@@ -263,9 +302,14 @@ static int check_perm(struct inode * inode, struct file * file) ...@@ -263,9 +302,14 @@ static int check_perm(struct inode * inode, struct file * file)
if (!kobj || !attr) if (!kobj || !attr)
goto Einval; goto Einval;
/* if the kobject has no subsystem, then it is a subsystem itself,
* so give it the subsys_sysfs_ops.
*/
if (kobj->subsys) if (kobj->subsys)
ops = kobj->subsys->sysfs_ops; ops = kobj->subsys->sysfs_ops;
else
ops = &subsys_sysfs_ops;
/* No sysfs operations, either from having no subsystem, /* No sysfs operations, either from having no subsystem,
* or the subsystem have no operations. * or the subsystem have no operations.
...@@ -571,8 +615,8 @@ static void hash_and_remove(struct dentry * dir, const char * name) ...@@ -571,8 +615,8 @@ static void hash_and_remove(struct dentry * dir, const char * name)
/* make sure dentry is really there */ /* make sure dentry is really there */
if (victim->d_inode && if (victim->d_inode &&
(victim->d_parent->d_inode == dir->d_inode)) { (victim->d_parent->d_inode == dir->d_inode)) {
d_invalidate(victim);
simple_unlink(dir->d_inode,victim); simple_unlink(dir->d_inode,victim);
d_delete(victim);
} }
} }
up(&dir->d_inode->i_sem); up(&dir->d_inode->i_sem);
...@@ -631,15 +675,15 @@ void sysfs_remove_dir(struct kobject * kobj) ...@@ -631,15 +675,15 @@ void sysfs_remove_dir(struct kobject * kobj)
struct dentry * d = list_entry(node,struct dentry,d_child); struct dentry * d = list_entry(node,struct dentry,d_child);
/* make sure dentry is still there */ /* make sure dentry is still there */
if (d->d_inode) { if (d->d_inode) {
d_invalidate(d);
simple_unlink(dentry->d_inode,d); simple_unlink(dentry->d_inode,d);
d_delete(dentry);
} }
} }
up(&dentry->d_inode->i_sem); up(&dentry->d_inode->i_sem);
d_invalidate(dentry); d_invalidate(dentry);
simple_rmdir(parent->d_inode,dentry); simple_rmdir(parent->d_inode,dentry);
d_delete(dentry);
up(&parent->d_inode->i_sem); up(&parent->d_inode->i_sem);
dput(parent); dput(parent);
} }
......
...@@ -60,4 +60,13 @@ static inline void subsys_put(struct subsystem * s) ...@@ -60,4 +60,13 @@ static inline void subsys_put(struct subsystem * s)
kobject_put(&s->kobj); kobject_put(&s->kobj);
} }
struct subsys_attribute {
struct attribute attr;
ssize_t (*show)(struct subsystem *, char *, size_t, loff_t);
ssize_t (*store)(struct subsystem *, const char *, size_t, loff_t);
};
extern int subsys_create_file(struct subsystem * , struct subsys_attribute *);
extern void subsys_remove_file(struct subsystem * , struct subsys_attribute *);
#endif /* _KOBJECT_H_ */ #endif /* _KOBJECT_H_ */
...@@ -229,6 +229,38 @@ void subsystem_unregister(struct subsystem * s) ...@@ -229,6 +229,38 @@ void subsystem_unregister(struct subsystem * s)
} }
/**
* subsystem_create_file - export sysfs attribute file.
* @s: subsystem.
* @a: subsystem attribute descriptor.
*/
int subsys_create_file(struct subsystem * s, struct subsys_attribute * a)
{
int error = 0;
if (subsys_get(s)) {
error = sysfs_create_file(&s->kobj,&a->attr);
subsys_put(s);
}
return error;
}
/**
* subsystem_remove_file - remove sysfs attribute file.
* @s: subsystem.
* @a: attribute desciptor.
*/
void subsys_remove_file(struct subsystem * s, struct subsys_attribute * a)
{
if (subsys_get(s)) {
sysfs_remove_file(&s->kobj,&a->attr);
subsys_put(s);
}
}
EXPORT_SYMBOL(kobject_init); EXPORT_SYMBOL(kobject_init);
EXPORT_SYMBOL(kobject_register); EXPORT_SYMBOL(kobject_register);
EXPORT_SYMBOL(kobject_unregister); EXPORT_SYMBOL(kobject_unregister);
...@@ -238,3 +270,5 @@ EXPORT_SYMBOL(kobject_put); ...@@ -238,3 +270,5 @@ EXPORT_SYMBOL(kobject_put);
EXPORT_SYMBOL(subsystem_init); EXPORT_SYMBOL(subsystem_init);
EXPORT_SYMBOL(subsystem_register); EXPORT_SYMBOL(subsystem_register);
EXPORT_SYMBOL(subsystem_unregister); EXPORT_SYMBOL(subsystem_unregister);
EXPORT_SYMBOL(subsys_create_file);
EXPORT_SYMBOL(subsys_remove_file);
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment