2005-04-17 02:20:36 +04:00
/*
* mount . c - operations for initializing and mounting sysfs .
*/
# define DEBUG
# include <linux/fs.h>
# include <linux/mount.h>
# include <linux/pagemap.h>
# include <linux/init.h>
# include "sysfs.h"
/* Random magic number */
# define SYSFS_MAGIC 0x62656572
struct vfsmount * sysfs_mount ;
struct super_block * sysfs_sb = NULL ;
kmem_cache_t * sysfs_dir_cachep ;
static struct super_operations sysfs_ops = {
. statfs = simple_statfs ,
. drop_inode = generic_delete_inode ,
} ;
static struct sysfs_dirent sysfs_root = {
. s_sibling = LIST_HEAD_INIT ( sysfs_root . s_sibling ) ,
. s_children = LIST_HEAD_INIT ( sysfs_root . s_children ) ,
. s_element = NULL ,
. s_type = SYSFS_ROOT ,
2005-05-31 09:09:52 +04:00
. s_iattr = NULL ,
2005-04-17 02:20:36 +04:00
} ;
static int sysfs_fill_super ( struct super_block * sb , void * data , int silent )
{
struct inode * inode ;
struct dentry * root ;
sb - > s_blocksize = PAGE_CACHE_SIZE ;
sb - > s_blocksize_bits = PAGE_CACHE_SHIFT ;
sb - > s_magic = SYSFS_MAGIC ;
sb - > s_op = & sysfs_ops ;
sb - > s_time_gran = 1 ;
sysfs_sb = sb ;
2005-05-31 09:09:52 +04:00
inode = sysfs_new_inode ( S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO ,
& sysfs_root ) ;
2005-04-17 02:20:36 +04:00
if ( inode ) {
inode - > i_op = & sysfs_dir_inode_operations ;
inode - > i_fop = & sysfs_dir_operations ;
/* directory inodes start off with i_nlink == 2 (for "." entry) */
inode - > i_nlink + + ;
} else {
pr_debug ( " sysfs: could not get root inode \n " ) ;
return - ENOMEM ;
}
root = d_alloc_root ( inode ) ;
if ( ! root ) {
pr_debug ( " %s: could not get root dentry! \n " , __FUNCTION__ ) ;
iput ( inode ) ;
return - ENOMEM ;
}
root - > d_fsdata = & sysfs_root ;
sb - > s_root = root ;
return 0 ;
}
static struct super_block * sysfs_get_sb ( struct file_system_type * fs_type ,
int flags , const char * dev_name , void * data )
{
return get_sb_single ( fs_type , flags , data , sysfs_fill_super ) ;
}
static struct file_system_type sysfs_fs_type = {
. name = " sysfs " ,
. get_sb = sysfs_get_sb ,
. kill_sb = kill_litter_super ,
} ;
int __init sysfs_init ( void )
{
int err = - ENOMEM ;
sysfs_dir_cachep = kmem_cache_create ( " sysfs_dir_cache " ,
sizeof ( struct sysfs_dirent ) ,
0 , 0 , NULL , NULL ) ;
if ( ! sysfs_dir_cachep )
goto out ;
err = register_filesystem ( & sysfs_fs_type ) ;
if ( ! err ) {
sysfs_mount = kern_mount ( & sysfs_fs_type ) ;
if ( IS_ERR ( sysfs_mount ) ) {
printk ( KERN_ERR " sysfs: could not mount! \n " ) ;
err = PTR_ERR ( sysfs_mount ) ;
sysfs_mount = NULL ;
unregister_filesystem ( & sysfs_fs_type ) ;
goto out_err ;
}
} else
goto out_err ;
out :
return err ;
out_err :
kmem_cache_destroy ( sysfs_dir_cachep ) ;
sysfs_dir_cachep = NULL ;
goto out ;
}