There is a number of pseudo file systems in the kernel
that are basically copies of debugfs, all implementing the
same boilerplate code, just with different bugs.
This adds yet another copy to the kernel in the libfs directory,
with generalized helpers that can be used by any of them.
The most interesting function here is the new "struct dentry *
simple_register_filesystem(struct simple_fs_type *type)", which
returns the root directory of a new file system that can then
be passed to simple_create_file() and similar functions as a
parent.
Signed-off-by: Arnd Bergman <[EMAIL PROTECTED]>
Index: linux-2.6/fs/libfs.c
===
--- linux-2.6.orig/fs/libfs.c
+++ linux-2.6/fs/libfs.c
@@ -263,11 +263,6 @@ int simple_link(struct dentry *old_dentr
return 0;
}
-static inline int simple_positive(struct dentry *dentry)
-{
- return dentry->d_inode && !d_unhashed(dentry);
-}
-
int simple_empty(struct dentry *dentry)
{
struct dentry *child;
@@ -409,109 +404,6 @@ int simple_write_end(struct file *file,
return copied;
}
-/*
- * the inodes created here are not hashed. If you use iunique to generate
- * unique inode values later for this filesystem, then you must take care
- * to pass it an appropriate max_reserved value to avoid collisions.
- */
-int simple_fill_super(struct super_block *s, int magic, struct tree_descr
*files)
-{
- struct inode *inode;
- struct dentry *root;
- struct dentry *dentry;
- int i;
-
- s->s_blocksize = PAGE_CACHE_SIZE;
- s->s_blocksize_bits = PAGE_CACHE_SHIFT;
- s->s_magic = magic;
- s->s_op = &simple_super_operations;
- s->s_time_gran = 1;
-
- inode = new_inode(s);
- if (!inode)
- return -ENOMEM;
- /*
-* because the root inode is 1, the files array must not contain an
-* entry at index 1
-*/
- inode->i_ino = 1;
- inode->i_mode = S_IFDIR | 0755;
- inode->i_uid = inode->i_gid = 0;
- inode->i_blocks = 0;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_op = &simple_dir_inode_operations;
- inode->i_fop = &simple_dir_operations;
- inode->i_nlink = 2;
- root = d_alloc_root(inode);
- if (!root) {
- iput(inode);
- return -ENOMEM;
- }
- for (i = 0; !files->name || files->name[0]; i++, files++) {
- if (!files->name)
- continue;
-
- /* warn if it tries to conflict with the root inode */
- if (unlikely(i == 1))
- printk(KERN_WARNING "%s: %s passed in a files array"
- "with an index of 1!\n", __func__,
- s->s_type->name);
-
- dentry = d_alloc_name(root, files->name);
- if (!dentry)
- goto out;
- inode = new_inode(s);
- if (!inode)
- goto out;
- inode->i_mode = S_IFREG | files->mode;
- inode->i_uid = inode->i_gid = 0;
- inode->i_blocks = 0;
- inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
- inode->i_fop = files->ops;
- inode->i_ino = i;
- d_add(dentry, inode);
- }
- s->s_root = root;
- return 0;
-out:
- d_genocide(root);
- dput(root);
- return -ENOMEM;
-}
-
-static DEFINE_SPINLOCK(pin_fs_lock);
-
-int simple_pin_fs(struct file_system_type *type, struct vfsmount **mount, int
*count)
-{
- struct vfsmount *mnt = NULL;
- spin_lock(&pin_fs_lock);
- if (unlikely(!*mount)) {
- spin_unlock(&pin_fs_lock);
- mnt = vfs_kern_mount(type, 0, type->name, NULL);
- if (IS_ERR(mnt))
- return PTR_ERR(mnt);
- spin_lock(&pin_fs_lock);
- if (!*mount)
- *mount = mnt;
- }
- mntget(*mount);
- ++*count;
- spin_unlock(&pin_fs_lock);
- mntput(mnt);
- return 0;
-}
-
-void simple_release_fs(struct vfsmount **mount, int *count)
-{
- struct vfsmount *mnt;
- spin_lock(&pin_fs_lock);
- mnt = *mount;
- if (!--*count)
- *mount = NULL;
- spin_unlock(&pin_fs_lock);
- mntput(mnt);
-}
-
ssize_t simple_read_from_buffer(void __user *to, size_t count, loff_t *ppos,
const void *from, size_t available)
{
@@ -786,14 +678,11 @@ EXPORT_SYMBOL(simple_dir_inode_operation
EXPORT_SYMBOL(simple_dir_operations);
EXPORT_SYMBOL(simple_empty);
EXPORT_SYMBOL(d_alloc_name);
-EXPORT_SYMBOL(simple_fill_super);
EXPORT_SYMBOL(simple_getattr);
EXPORT_SYMBOL(simple_link);
EXPORT_SYMBOL(simple_lookup);
-EXPORT_SYMBOL(simple_pin_fs);
EXPORT_SYMBOL(simple_prepare_write);
EXPORT_SYMBOL(simple_readpag