2005-04-17 02:20:36 +04:00
/*
* linux / fs / sysv / inode . c
*
* minix / inode . c
* Copyright ( C ) 1991 , 1992 Linus Torvalds
*
* xenix / inode . c
* Copyright ( C ) 1992 Doug Evans
*
* coh / inode . c
* Copyright ( C ) 1993 Pascal Haible , Bruno Haible
*
* sysv / inode . c
* Copyright ( C ) 1993 Paul B . Monday
*
* sysv / inode . c
* Copyright ( C ) 1993 Bruno Haible
* Copyright ( C ) 1997 , 1998 Krzysztof G . Baranowski
*
* This file contains code for read / parsing the superblock .
*/
# include <linux/module.h>
# include <linux/init.h>
# include <linux/slab.h>
# include <linux/buffer_head.h>
# include "sysv.h"
/*
* The following functions try to recognize specific filesystems .
*
* We recognize :
* - Xenix FS by its magic number .
* - SystemV FS by its magic number .
* - Coherent FS by its funny fname / fpack field .
* - SCO AFS by s_nfree = = 0xffff
* - V7 FS has no distinguishing features .
*
* We discriminate among SystemV4 and SystemV2 FS by the assumption that
* the time stamp is not < 01 - 01 - 1980.
*/
enum {
JAN_1_1980 = ( 10 * 365 + 2 ) * 24 * 60 * 60
} ;
2012-02-06 21:45:27 +04:00
static void detected_xenix ( struct sysv_sb_info * sbi , unsigned * max_links )
2005-04-17 02:20:36 +04:00
{
struct buffer_head * bh1 = sbi - > s_bh1 ;
struct buffer_head * bh2 = sbi - > s_bh2 ;
struct xenix_super_block * sbd1 ;
struct xenix_super_block * sbd2 ;
if ( bh1 ! = bh2 )
sbd1 = sbd2 = ( struct xenix_super_block * ) bh1 - > b_data ;
else {
/* block size = 512, so bh1 != bh2 */
sbd1 = ( struct xenix_super_block * ) bh1 - > b_data ;
sbd2 = ( struct xenix_super_block * ) ( bh2 - > b_data - 512 ) ;
}
2012-02-06 21:45:27 +04:00
* max_links = XENIX_LINK_MAX ;
2005-04-17 02:20:36 +04:00
sbi - > s_fic_size = XENIX_NICINOD ;
sbi - > s_flc_size = XENIX_NICFREE ;
sbi - > s_sbd1 = ( char * ) sbd1 ;
sbi - > s_sbd2 = ( char * ) sbd2 ;
sbi - > s_sb_fic_count = & sbd1 - > s_ninode ;
sbi - > s_sb_fic_inodes = & sbd1 - > s_inode [ 0 ] ;
sbi - > s_sb_total_free_inodes = & sbd2 - > s_tinode ;
sbi - > s_bcache_count = & sbd1 - > s_nfree ;
sbi - > s_bcache = & sbd1 - > s_free [ 0 ] ;
sbi - > s_free_blocks = & sbd2 - > s_tfree ;
sbi - > s_sb_time = & sbd2 - > s_time ;
sbi - > s_firstdatazone = fs16_to_cpu ( sbi , sbd1 - > s_isize ) ;
sbi - > s_nzones = fs32_to_cpu ( sbi , sbd1 - > s_fsize ) ;
}
2012-02-06 21:45:27 +04:00
static void detected_sysv4 ( struct sysv_sb_info * sbi , unsigned * max_links )
2005-04-17 02:20:36 +04:00
{
struct sysv4_super_block * sbd ;
struct buffer_head * bh1 = sbi - > s_bh1 ;
struct buffer_head * bh2 = sbi - > s_bh2 ;
if ( bh1 = = bh2 )
sbd = ( struct sysv4_super_block * ) ( bh1 - > b_data + BLOCK_SIZE / 2 ) ;
else
sbd = ( struct sysv4_super_block * ) bh2 - > b_data ;
2012-02-06 21:45:27 +04:00
* max_links = SYSV_LINK_MAX ;
2005-04-17 02:20:36 +04:00
sbi - > s_fic_size = SYSV_NICINOD ;
sbi - > s_flc_size = SYSV_NICFREE ;
sbi - > s_sbd1 = ( char * ) sbd ;
sbi - > s_sbd2 = ( char * ) sbd ;
sbi - > s_sb_fic_count = & sbd - > s_ninode ;
sbi - > s_sb_fic_inodes = & sbd - > s_inode [ 0 ] ;
sbi - > s_sb_total_free_inodes = & sbd - > s_tinode ;
sbi - > s_bcache_count = & sbd - > s_nfree ;
sbi - > s_bcache = & sbd - > s_free [ 0 ] ;
sbi - > s_free_blocks = & sbd - > s_tfree ;
sbi - > s_sb_time = & sbd - > s_time ;
sbi - > s_sb_state = & sbd - > s_state ;
sbi - > s_firstdatazone = fs16_to_cpu ( sbi , sbd - > s_isize ) ;
sbi - > s_nzones = fs32_to_cpu ( sbi , sbd - > s_fsize ) ;
}
2012-02-06 21:45:27 +04:00
static void detected_sysv2 ( struct sysv_sb_info * sbi , unsigned * max_links )
2005-04-17 02:20:36 +04:00
{
struct sysv2_super_block * sbd ;
struct buffer_head * bh1 = sbi - > s_bh1 ;
struct buffer_head * bh2 = sbi - > s_bh2 ;
if ( bh1 = = bh2 )
sbd = ( struct sysv2_super_block * ) ( bh1 - > b_data + BLOCK_SIZE / 2 ) ;
else
sbd = ( struct sysv2_super_block * ) bh2 - > b_data ;
2012-02-06 21:45:27 +04:00
* max_links = SYSV_LINK_MAX ;
2005-04-17 02:20:36 +04:00
sbi - > s_fic_size = SYSV_NICINOD ;
sbi - > s_flc_size = SYSV_NICFREE ;
sbi - > s_sbd1 = ( char * ) sbd ;
sbi - > s_sbd2 = ( char * ) sbd ;
sbi - > s_sb_fic_count = & sbd - > s_ninode ;
sbi - > s_sb_fic_inodes = & sbd - > s_inode [ 0 ] ;
sbi - > s_sb_total_free_inodes = & sbd - > s_tinode ;
sbi - > s_bcache_count = & sbd - > s_nfree ;
sbi - > s_bcache = & sbd - > s_free [ 0 ] ;
sbi - > s_free_blocks = & sbd - > s_tfree ;
sbi - > s_sb_time = & sbd - > s_time ;
sbi - > s_sb_state = & sbd - > s_state ;
sbi - > s_firstdatazone = fs16_to_cpu ( sbi , sbd - > s_isize ) ;
sbi - > s_nzones = fs32_to_cpu ( sbi , sbd - > s_fsize ) ;
}
2012-02-06 21:45:27 +04:00
static void detected_coherent ( struct sysv_sb_info * sbi , unsigned * max_links )
2005-04-17 02:20:36 +04:00
{
struct coh_super_block * sbd ;
struct buffer_head * bh1 = sbi - > s_bh1 ;
sbd = ( struct coh_super_block * ) bh1 - > b_data ;
2012-02-06 21:45:27 +04:00
* max_links = COH_LINK_MAX ;
2005-04-17 02:20:36 +04:00
sbi - > s_fic_size = COH_NICINOD ;
sbi - > s_flc_size = COH_NICFREE ;
sbi - > s_sbd1 = ( char * ) sbd ;
sbi - > s_sbd2 = ( char * ) sbd ;
sbi - > s_sb_fic_count = & sbd - > s_ninode ;
sbi - > s_sb_fic_inodes = & sbd - > s_inode [ 0 ] ;
sbi - > s_sb_total_free_inodes = & sbd - > s_tinode ;
sbi - > s_bcache_count = & sbd - > s_nfree ;
sbi - > s_bcache = & sbd - > s_free [ 0 ] ;
sbi - > s_free_blocks = & sbd - > s_tfree ;
sbi - > s_sb_time = & sbd - > s_time ;
sbi - > s_firstdatazone = fs16_to_cpu ( sbi , sbd - > s_isize ) ;
sbi - > s_nzones = fs32_to_cpu ( sbi , sbd - > s_fsize ) ;
}
2012-02-06 21:45:27 +04:00
static void detected_v7 ( struct sysv_sb_info * sbi , unsigned * max_links )
2005-04-17 02:20:36 +04:00
{
struct buffer_head * bh2 = sbi - > s_bh2 ;
struct v7_super_block * sbd = ( struct v7_super_block * ) bh2 - > b_data ;
2012-02-06 21:45:27 +04:00
* max_links = V7_LINK_MAX ;
2005-04-17 02:20:36 +04:00
sbi - > s_fic_size = V7_NICINOD ;
sbi - > s_flc_size = V7_NICFREE ;
sbi - > s_sbd1 = ( char * ) sbd ;
sbi - > s_sbd2 = ( char * ) sbd ;
sbi - > s_sb_fic_count = & sbd - > s_ninode ;
sbi - > s_sb_fic_inodes = & sbd - > s_inode [ 0 ] ;
sbi - > s_sb_total_free_inodes = & sbd - > s_tinode ;
sbi - > s_bcache_count = & sbd - > s_nfree ;
sbi - > s_bcache = & sbd - > s_free [ 0 ] ;
sbi - > s_free_blocks = & sbd - > s_tfree ;
sbi - > s_sb_time = & sbd - > s_time ;
sbi - > s_firstdatazone = fs16_to_cpu ( sbi , sbd - > s_isize ) ;
sbi - > s_nzones = fs32_to_cpu ( sbi , sbd - > s_fsize ) ;
}
static int detect_xenix ( struct sysv_sb_info * sbi , struct buffer_head * bh )
{
struct xenix_super_block * sbd = ( struct xenix_super_block * ) bh - > b_data ;
if ( * ( __le32 * ) & sbd - > s_magic = = cpu_to_le32 ( 0x2b5544 ) )
sbi - > s_bytesex = BYTESEX_LE ;
else if ( * ( __be32 * ) & sbd - > s_magic = = cpu_to_be32 ( 0x2b5544 ) )
sbi - > s_bytesex = BYTESEX_BE ;
else
return 0 ;
switch ( fs32_to_cpu ( sbi , sbd - > s_type ) ) {
case 1 :
sbi - > s_type = FSTYPE_XENIX ;
return 1 ;
case 2 :
sbi - > s_type = FSTYPE_XENIX ;
return 2 ;
default :
return 0 ;
}
}
static int detect_sysv ( struct sysv_sb_info * sbi , struct buffer_head * bh )
{
struct super_block * sb = sbi - > s_sb ;
/* All relevant fields are at the same offsets in R2 and R4 */
struct sysv4_super_block * sbd ;
u32 type ;
sbd = ( struct sysv4_super_block * ) ( bh - > b_data + BLOCK_SIZE / 2 ) ;
if ( * ( __le32 * ) & sbd - > s_magic = = cpu_to_le32 ( 0xfd187e20 ) )
sbi - > s_bytesex = BYTESEX_LE ;
else if ( * ( __be32 * ) & sbd - > s_magic = = cpu_to_be32 ( 0xfd187e20 ) )
sbi - > s_bytesex = BYTESEX_BE ;
else
return 0 ;
type = fs32_to_cpu ( sbi , sbd - > s_type ) ;
if ( fs16_to_cpu ( sbi , sbd - > s_nfree ) = = 0xffff ) {
sbi - > s_type = FSTYPE_AFS ;
sbi - > s_forced_ro = 1 ;
if ( ! ( sb - > s_flags & MS_RDONLY ) ) {
printk ( " SysV FS: SCO EAFS on %s detected, "
" forcing read-only mode. \n " ,
sb - > s_id ) ;
}
return type ;
}
if ( fs32_to_cpu ( sbi , sbd - > s_time ) < JAN_1_1980 ) {
/* this is likely to happen on SystemV2 FS */
if ( type > 3 | | type < 1 )
return 0 ;
sbi - > s_type = FSTYPE_SYSV2 ;
return type ;
}
if ( ( type > 3 | | type < 1 ) & & ( type > 0x30 | | type < 0x10 ) )
return 0 ;
/* On Interactive Unix (ISC) Version 4.0/3.x s_type field = 0x10,
0x20 or 0x30 indicates that symbolic links and the 14 - character
filename limit is gone . Due to lack of information about this
feature read - only mode seems to be a reasonable approach . . . - KGB */
if ( type > = 0x10 ) {
printk ( " SysV FS: can't handle long file names on %s, "
" forcing read-only mode. \n " , sb - > s_id ) ;
sbi - > s_forced_ro = 1 ;
}
sbi - > s_type = FSTYPE_SYSV4 ;
return type > = 0x10 ? type > > 4 : type ;
}
static int detect_coherent ( struct sysv_sb_info * sbi , struct buffer_head * bh )
{
struct coh_super_block * sbd ;
sbd = ( struct coh_super_block * ) ( bh - > b_data + BLOCK_SIZE / 2 ) ;
if ( ( memcmp ( sbd - > s_fname , " noname " , 6 ) & & memcmp ( sbd - > s_fname , " xxxxx " , 6 ) )
| | ( memcmp ( sbd - > s_fpack , " nopack " , 6 ) & & memcmp ( sbd - > s_fpack , " xxxxx \n " , 6 ) ) )
return 0 ;
sbi - > s_bytesex = BYTESEX_PDP ;
sbi - > s_type = FSTYPE_COH ;
return 1 ;
}
static int detect_sysv_odd ( struct sysv_sb_info * sbi , struct buffer_head * bh )
{
int size = detect_sysv ( sbi , bh ) ;
return size > 2 ? 0 : size ;
}
static struct {
int block ;
int ( * test ) ( struct sysv_sb_info * , struct buffer_head * ) ;
} flavours [ ] = {
{ 1 , detect_xenix } ,
{ 0 , detect_sysv } ,
{ 0 , detect_coherent } ,
{ 9 , detect_sysv_odd } ,
{ 15 , detect_sysv_odd } ,
{ 18 , detect_sysv } ,
} ;
static char * flavour_names [ ] = {
[ FSTYPE_XENIX ] = " Xenix " ,
[ FSTYPE_SYSV4 ] = " SystemV " ,
[ FSTYPE_SYSV2 ] = " SystemV Release 2 " ,
[ FSTYPE_COH ] = " Coherent " ,
[ FSTYPE_V7 ] = " V7 " ,
[ FSTYPE_AFS ] = " AFS " ,
} ;
2012-02-06 21:45:27 +04:00
static void ( * flavour_setup [ ] ) ( struct sysv_sb_info * , unsigned * ) = {
2005-04-17 02:20:36 +04:00
[ FSTYPE_XENIX ] = detected_xenix ,
[ FSTYPE_SYSV4 ] = detected_sysv4 ,
[ FSTYPE_SYSV2 ] = detected_sysv2 ,
[ FSTYPE_COH ] = detected_coherent ,
[ FSTYPE_V7 ] = detected_v7 ,
[ FSTYPE_AFS ] = detected_sysv4 ,
} ;
static int complete_read_super ( struct super_block * sb , int silent , int size )
{
struct sysv_sb_info * sbi = SYSV_SB ( sb ) ;
struct inode * root_inode ;
char * found = flavour_names [ sbi - > s_type ] ;
u_char n_bits = size + 8 ;
int bsize = 1 < < n_bits ;
int bsize_4 = bsize > > 2 ;
sbi - > s_firstinodezone = 2 ;
2012-02-06 21:45:27 +04:00
flavour_setup [ sbi - > s_type ] ( sbi , & sb - > s_max_links ) ;
2005-04-17 02:20:36 +04:00
sbi - > s_truncate = 1 ;
sbi - > s_ndatazones = sbi - > s_nzones - sbi - > s_firstdatazone ;
sbi - > s_inodes_per_block = bsize > > 6 ;
sbi - > s_inodes_per_block_1 = ( bsize > > 6 ) - 1 ;
sbi - > s_inodes_per_block_bits = n_bits - 6 ;
sbi - > s_ind_per_block = bsize_4 ;
sbi - > s_ind_per_block_2 = bsize_4 * bsize_4 ;
sbi - > s_toobig_block = 10 + bsize_4 * ( 1 + bsize_4 * ( 1 + bsize_4 ) ) ;
sbi - > s_ind_per_block_bits = n_bits - 2 ;
sbi - > s_ninodes = ( sbi - > s_firstdatazone - sbi - > s_firstinodezone )
< < sbi - > s_inodes_per_block_bits ;
if ( ! silent )
printk ( " VFS: Found a %s FS (block size = %ld) on device %s \n " ,
found , sb - > s_blocksize , sb - > s_id ) ;
sb - > s_magic = SYSV_MAGIC_BASE + sbi - > s_type ;
/* set up enough so that it can read an inode */
sb - > s_op = & sysv_sops ;
2010-12-18 19:16:30 +03:00
if ( sbi - > s_forced_ro )
sb - > s_flags | = MS_RDONLY ;
if ( sbi - > s_truncate )
sb - > s_d_op = & sysv_dentry_operations ;
2008-02-07 11:15:47 +03:00
root_inode = sysv_iget ( sb , SYSV_ROOT_INO ) ;
if ( IS_ERR ( root_inode ) ) {
2005-04-17 02:20:36 +04:00
printk ( " SysV FS: get root inode failed \n " ) ;
return 0 ;
}
2012-01-09 07:15:13 +04:00
sb - > s_root = d_make_root ( root_inode ) ;
2005-04-17 02:20:36 +04:00
if ( ! sb - > s_root ) {
printk ( " SysV FS: get root dentry failed \n " ) ;
return 0 ;
}
return 1 ;
}
static int sysv_fill_super ( struct super_block * sb , void * data , int silent )
{
struct buffer_head * bh1 , * bh = NULL ;
struct sysv_sb_info * sbi ;
unsigned long blocknr ;
int size = 0 , i ;
2006-10-11 12:22:05 +04:00
BUILD_BUG_ON ( 1024 ! = sizeof ( struct xenix_super_block ) ) ;
BUILD_BUG_ON ( 512 ! = sizeof ( struct sysv4_super_block ) ) ;
BUILD_BUG_ON ( 512 ! = sizeof ( struct sysv2_super_block ) ) ;
BUILD_BUG_ON ( 500 ! = sizeof ( struct coh_super_block ) ) ;
BUILD_BUG_ON ( 64 ! = sizeof ( struct sysv_inode ) ) ;
2005-04-17 02:20:36 +04:00
2006-09-27 12:49:37 +04:00
sbi = kzalloc ( sizeof ( struct sysv_sb_info ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! sbi )
return - ENOMEM ;
sbi - > s_sb = sb ;
sbi - > s_block_base = 0 ;
2012-10-06 14:41:46 +04:00
mutex_init ( & sbi - > s_lock ) ;
2005-04-17 02:20:36 +04:00
sb - > s_fs_info = sbi ;
2006-03-24 14:15:34 +03:00
2005-04-17 02:20:36 +04:00
sb_set_blocksize ( sb , BLOCK_SIZE ) ;
2006-03-24 14:15:34 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( flavours ) & & ! size ; i + + ) {
2005-04-17 02:20:36 +04:00
brelse ( bh ) ;
bh = sb_bread ( sb , flavours [ i ] . block ) ;
if ( ! bh )
continue ;
size = flavours [ i ] . test ( SYSV_SB ( sb ) , bh ) ;
}
if ( ! size )
goto Eunknown ;
switch ( size ) {
case 1 :
blocknr = bh - > b_blocknr < < 1 ;
brelse ( bh ) ;
sb_set_blocksize ( sb , 512 ) ;
bh1 = sb_bread ( sb , blocknr ) ;
bh = sb_bread ( sb , blocknr + 1 ) ;
break ;
case 2 :
bh1 = bh ;
break ;
case 3 :
blocknr = bh - > b_blocknr > > 1 ;
brelse ( bh ) ;
sb_set_blocksize ( sb , 2048 ) ;
bh1 = bh = sb_bread ( sb , blocknr ) ;
break ;
default :
goto Ebadsize ;
}
if ( bh & & bh1 ) {
sbi - > s_bh1 = bh1 ;
sbi - > s_bh2 = bh ;
if ( complete_read_super ( sb , silent , size ) )
return 0 ;
}
brelse ( bh1 ) ;
brelse ( bh ) ;
sb_set_blocksize ( sb , BLOCK_SIZE ) ;
printk ( " oldfs: cannot read superblock \n " ) ;
failed :
kfree ( sbi ) ;
return - EINVAL ;
Eunknown :
brelse ( bh ) ;
if ( ! silent )
printk ( " VFS: unable to find oldfs superblock on device %s \n " ,
sb - > s_id ) ;
goto failed ;
Ebadsize :
brelse ( bh ) ;
if ( ! silent )
printk ( " VFS: oldfs: unsupported block size (%dKb) \n " ,
1 < < ( size - 2 ) ) ;
goto failed ;
}
2010-08-11 05:03:34 +04:00
static int v7_sanity_check ( struct super_block * sb , struct buffer_head * bh )
2005-04-17 02:20:36 +04:00
{
struct v7_super_block * v7sb ;
struct sysv_inode * v7i ;
2010-08-11 05:03:34 +04:00
struct buffer_head * bh2 ;
struct sysv_sb_info * sbi ;
sbi = sb - > s_fs_info ;
/* plausibility check on superblock */
v7sb = ( struct v7_super_block * ) bh - > b_data ;
if ( fs16_to_cpu ( sbi , v7sb - > s_nfree ) > V7_NICFREE | |
fs16_to_cpu ( sbi , v7sb - > s_ninode ) > V7_NICINOD | |
fs32_to_cpu ( sbi , v7sb - > s_fsize ) > V7_MAXSIZE )
return 0 ;
/* plausibility check on root inode: it is a directory,
with a nonzero size that is a multiple of 16 */
bh2 = sb_bread ( sb , 2 ) ;
if ( bh2 = = NULL )
return 0 ;
v7i = ( struct sysv_inode * ) ( bh2 - > b_data + 64 ) ;
if ( ( fs16_to_cpu ( sbi , v7i - > i_mode ) & ~ 0777 ) ! = S_IFDIR | |
( fs32_to_cpu ( sbi , v7i - > i_size ) = = 0 ) | |
( fs32_to_cpu ( sbi , v7i - > i_size ) & 017 ) | |
( fs32_to_cpu ( sbi , v7i - > i_size ) > V7_NFILES *
sizeof ( struct sysv_dir_entry ) ) ) {
brelse ( bh2 ) ;
return 0 ;
}
brelse ( bh2 ) ;
return 1 ;
}
static int v7_fill_super ( struct super_block * sb , void * data , int silent )
{
struct sysv_sb_info * sbi ;
struct buffer_head * bh ;
2005-04-17 02:20:36 +04:00
if ( 440 ! = sizeof ( struct v7_super_block ) )
panic ( " V7 FS: bad super-block size " ) ;
if ( 64 ! = sizeof ( struct sysv_inode ) )
panic ( " sysv fs: bad i-node size " ) ;
2006-09-27 12:49:37 +04:00
sbi = kzalloc ( sizeof ( struct sysv_sb_info ) , GFP_KERNEL ) ;
2005-04-17 02:20:36 +04:00
if ( ! sbi )
return - ENOMEM ;
sbi - > s_sb = sb ;
sbi - > s_block_base = 0 ;
sbi - > s_type = FSTYPE_V7 ;
sb - > s_fs_info = sbi ;
sb_set_blocksize ( sb , 512 ) ;
if ( ( bh = sb_bread ( sb , 1 ) ) = = NULL ) {
if ( ! silent )
printk ( " VFS: unable to read V7 FS superblock on "
" device %s. \n " , sb - > s_id ) ;
goto failed ;
}
2010-08-11 05:03:34 +04:00
/* Try PDP-11 UNIX */
sbi - > s_bytesex = BYTESEX_PDP ;
if ( v7_sanity_check ( sb , bh ) )
goto detected ;
2005-04-17 02:20:36 +04:00
2010-08-11 05:03:34 +04:00
/* Try PC/IX, v7/x86 */
sbi - > s_bytesex = BYTESEX_LE ;
if ( v7_sanity_check ( sb , bh ) )
goto detected ;
2005-04-17 02:20:36 +04:00
2010-08-11 05:03:34 +04:00
goto failed ;
detected :
2005-04-17 02:20:36 +04:00
sbi - > s_bh1 = bh ;
sbi - > s_bh2 = bh ;
if ( complete_read_super ( sb , silent , 1 ) )
return 0 ;
failed :
2010-08-11 05:03:34 +04:00
printk ( KERN_ERR " VFS: could not find a valid V7 on %s. \n " ,
sb - > s_id ) ;
2005-04-17 02:20:36 +04:00
brelse ( bh ) ;
kfree ( sbi ) ;
return - EINVAL ;
}
/* Every kernel module contains stuff like this. */
2010-07-25 00:46:55 +04:00
static struct dentry * sysv_mount ( struct file_system_type * fs_type ,
int flags , const char * dev_name , void * data )
2005-04-17 02:20:36 +04:00
{
2010-07-25 00:46:55 +04:00
return mount_bdev ( fs_type , flags , dev_name , data , sysv_fill_super ) ;
2005-04-17 02:20:36 +04:00
}
2010-07-25 00:46:55 +04:00
static struct dentry * v7_mount ( struct file_system_type * fs_type ,
int flags , const char * dev_name , void * data )
2005-04-17 02:20:36 +04:00
{
2010-07-25 00:46:55 +04:00
return mount_bdev ( fs_type , flags , dev_name , data , v7_fill_super ) ;
2005-04-17 02:20:36 +04:00
}
static struct file_system_type sysv_fs_type = {
. owner = THIS_MODULE ,
. name = " sysv " ,
2010-07-25 00:46:55 +04:00
. mount = sysv_mount ,
2005-04-17 02:20:36 +04:00
. kill_sb = kill_block_super ,
. fs_flags = FS_REQUIRES_DEV ,
} ;
static struct file_system_type v7_fs_type = {
. owner = THIS_MODULE ,
. name = " v7 " ,
2010-07-25 00:46:55 +04:00
. mount = v7_mount ,
2005-04-17 02:20:36 +04:00
. kill_sb = kill_block_super ,
. fs_flags = FS_REQUIRES_DEV ,
} ;
static int __init init_sysv_fs ( void )
{
int error ;
error = sysv_init_icache ( ) ;
if ( error )
goto out ;
error = register_filesystem ( & sysv_fs_type ) ;
if ( error )
goto destroy_icache ;
error = register_filesystem ( & v7_fs_type ) ;
if ( error )
goto unregister ;
return 0 ;
unregister :
unregister_filesystem ( & sysv_fs_type ) ;
destroy_icache :
sysv_destroy_icache ( ) ;
out :
return error ;
}
static void __exit exit_sysv_fs ( void )
{
unregister_filesystem ( & sysv_fs_type ) ;
unregister_filesystem ( & v7_fs_type ) ;
sysv_destroy_icache ( ) ;
}
module_init ( init_sysv_fs )
module_exit ( exit_sysv_fs )
2010-07-19 21:16:40 +04:00
MODULE_ALIAS ( " v7 " ) ;
2005-04-17 02:20:36 +04:00
MODULE_LICENSE ( " GPL " ) ;