/* * CVF extensions for fat-based filesystems * * written 1997,1998 by Frank Gockel * * please do not remove the next line, dmsdos needs it for verifying patches * CVF-FAT-VERSION-ID: 1.2.0 * */ #include #include #include #include #include #include #include #ifdef CONFIG_KMOD #include #endif #define MAX_CVF_FORMATS 3 struct buffer_head *default_fat_bread(struct super_block *,int); struct buffer_head *default_fat_getblk(struct super_block *, int); struct buffer_head *bigblock_fat_bread(struct super_block *, int); void default_fat_brelse(struct super_block *, struct buffer_head *); void bigblock_fat_brelse(struct super_block *, struct buffer_head *); void default_fat_mark_buffer_dirty (struct super_block *, struct buffer_head *); void bigblock_fat_mark_buffer_dirty (struct super_block *, struct buffer_head *); void default_fat_set_uptodate (struct super_block *, struct buffer_head *,int); void bigblock_fat_set_uptodate (struct super_block *, struct buffer_head *,int); int default_fat_is_uptodate(struct super_block *, struct buffer_head *); int bigblock_fat_is_uptodate(struct super_block *, struct buffer_head *); int default_fat_access(struct super_block *sb,int nr,int new_value); void default_fat_ll_rw_block ( struct super_block *sb, int opr, int nbreq, struct buffer_head *bh[32]); void bigblock_fat_ll_rw_block ( struct super_block *sb, int opr, int nbreq, struct buffer_head *bh[32]); int default_fat_bmap(struct inode *inode,int block); ssize_t default_fat_file_write( struct file *filp, const char *buf, size_t count, loff_t *ppos); struct cvf_format default_cvf = { 0, /* version - who cares? */ "plain", 0, /* flags - who cares? */ NULL, NULL, NULL, default_fat_bread, default_fat_getblk, default_fat_brelse, default_fat_mark_buffer_dirty, default_fat_set_uptodate, default_fat_is_uptodate, default_fat_ll_rw_block, default_fat_access, NULL, default_fat_bmap, generic_file_read, default_fat_file_write, NULL, NULL }; struct cvf_format bigblock_cvf = { 0, /* version - who cares? */ "big_blocks", 0, /* flags - who cares? */ NULL, NULL, NULL, bigblock_fat_bread, bigblock_fat_bread, bigblock_fat_brelse, bigblock_fat_mark_buffer_dirty, bigblock_fat_set_uptodate, bigblock_fat_is_uptodate, bigblock_fat_ll_rw_block, default_fat_access, NULL, default_fat_bmap, NULL, default_fat_file_write, NULL, NULL }; struct cvf_format *cvf_formats[MAX_CVF_FORMATS]; int cvf_format_use_count[MAX_CVF_FORMATS]; int register_cvf_format(struct cvf_format*cvf_format) { int i,j; for(i=0;icvf_version==cvf_format->cvf_version) { printk("register_cvf_format: version %d already registered\n", cvf_format->cvf_version); return -1; } } } cvf_formats[i]=cvf_format; cvf_format_use_count[i]=0; printk("CVF format %s (version id %d) successfully registered.\n", cvf_format->cvf_version_text,cvf_format->cvf_version); return 0; } } printk("register_cvf_format: too many formats\n"); return -1; } int unregister_cvf_format(struct cvf_format*cvf_format) { int i; for(i=0;icvf_version==cvf_format->cvf_version) { if(cvf_format_use_count[i]) { printk("unregister_cvf_format: format %d in use, cannot remove!\n", cvf_formats[i]->cvf_version); return -1; } printk("CVF format %s (version id %d) successfully unregistered.\n", cvf_formats[i]->cvf_version_text,cvf_formats[i]->cvf_version); cvf_formats[i]=NULL; return 0; } } } printk("unregister_cvf_format: format %d is not registered\n", cvf_format->cvf_version); return -1; } void dec_cvf_format_use_count_by_version(int version) { int i; for(i=0;icvf_version==version) { --cvf_format_use_count[i]; if(cvf_format_use_count[i]<0) { cvf_format_use_count[i]=0; printk(KERN_EMERG "FAT FS/CVF: This is a bug in cvf_version_use_count\n"); } return; } } } printk("dec_cvf_format_use_count_by_version: version %d not found ???\n", version); } int detect_cvf(struct super_block*sb,char*force) { int i; int found=0; int found_i=-1; if(force) if(strcmp(force,"autoload")==0) { #ifdef CONFIG_KMOD request_module("cvf_autoload"); force=NULL; #else printk("cannot autoload CVF modules: kmod support is not compiled into kernel\n"); return -1; #endif } #ifdef CONFIG_KMOD if(force) if(*force) request_module(force); #endif if(force) { if(*force) { for(i=0;icvf_version_text,force)) return i; } } printk("CVF format %s unknown (module not loaded?)\n",force); return -1; } } for(i=0;idetect_cvf(sb)) { ++found; found_i=i; } } } if(found==1)return found_i; if(found>1)printk("CVF detection ambiguous, please use cvf_format=xxx option\n"); return -1; }