linux-old/fs/fat/cvf.c
<<
>>
Prefs
   1/* 
   2 * CVF extensions for fat-based filesystems
   3 *
   4 * written 1997,1998 by Frank Gockel <gockel@sent13.uni-duisburg.de>
   5 *
   6 * please do not remove the next line, dmsdos needs it for verifying patches
   7 * CVF-FAT-VERSION-ID: 1.2.0
   8 *
   9 */
  10 
  11#include<linux/sched.h>
  12#include<linux/fs.h>
  13#include<linux/msdos_fs.h>
  14#include<linux/msdos_fs_sb.h>
  15#include<linux/string.h>
  16#include<linux/fat_cvf.h>
  17#include<linux/config.h>
  18#ifdef CONFIG_KMOD
  19#include<linux/kmod.h>
  20#endif
  21
  22#define MAX_CVF_FORMATS 3
  23
  24struct buffer_head *default_fat_bread(struct super_block *,int);
  25struct buffer_head *default_fat_getblk(struct super_block *, int);
  26void default_fat_brelse(struct super_block *, struct buffer_head *);
  27void default_fat_mark_buffer_dirty (struct super_block *, struct buffer_head *);
  28void default_fat_set_uptodate (struct super_block *, struct buffer_head *,int);
  29int default_fat_is_uptodate(struct super_block *, struct buffer_head *);
  30int default_fat_access(struct super_block *sb,int nr,int new_value);
  31void default_fat_ll_rw_block (struct super_block *sb, int opr, int nbreq,
  32                              struct buffer_head *bh[32]);
  33int default_fat_bmap(struct inode *inode,int block);
  34ssize_t default_fat_file_write(struct file *filp, const char *buf,
  35                               size_t count, loff_t *ppos);
  36
  37struct cvf_format default_cvf = {
  38        cvf_version:            0,      /* version - who cares? */      
  39        cvf_version_text:       "plain",
  40        flags:                  0,      /* flags - who cares? */
  41        cvf_bread:              default_fat_bread,
  42        cvf_getblk:             default_fat_getblk,
  43        cvf_brelse:             default_fat_brelse,
  44        cvf_mark_buffer_dirty:  default_fat_mark_buffer_dirty,
  45        cvf_set_uptodate:       default_fat_set_uptodate,
  46        cvf_is_uptodate:        default_fat_is_uptodate,
  47        cvf_ll_rw_block:        default_fat_ll_rw_block,
  48        fat_access:             default_fat_access,
  49        cvf_bmap:               default_fat_bmap,
  50        cvf_file_read:          generic_file_read,
  51        cvf_file_write:         default_fat_file_write,
  52};
  53
  54struct cvf_format *cvf_formats[MAX_CVF_FORMATS];
  55int cvf_format_use_count[MAX_CVF_FORMATS];
  56
  57int register_cvf_format(struct cvf_format*cvf_format)
  58{ int i,j;
  59
  60  for(i=0;i<MAX_CVF_FORMATS;++i)
  61  { if(cvf_formats[i]==NULL)
  62    { /* free slot found, now check version */
  63      for(j=0;j<MAX_CVF_FORMATS;++j)
  64      { if(cvf_formats[j])
  65        { if(cvf_formats[j]->cvf_version==cvf_format->cvf_version)
  66          { printk("register_cvf_format: version %d already registered\n",
  67                   cvf_format->cvf_version);
  68            return -1;
  69          }
  70        }
  71      }
  72      cvf_formats[i]=cvf_format;
  73      cvf_format_use_count[i]=0;
  74      printk("CVF format %s (version id %d) successfully registered.\n",
  75             cvf_format->cvf_version_text,cvf_format->cvf_version);
  76      return 0;
  77    }
  78  }
  79  
  80  printk("register_cvf_format: too many formats\n");
  81  return -1;
  82}
  83
  84int unregister_cvf_format(struct cvf_format*cvf_format)
  85{ int i;
  86
  87  for(i=0;i<MAX_CVF_FORMATS;++i)
  88  { if(cvf_formats[i])
  89    { if(cvf_formats[i]->cvf_version==cvf_format->cvf_version)
  90      { if(cvf_format_use_count[i])
  91        { printk("unregister_cvf_format: format %d in use, cannot remove!\n",
  92          cvf_formats[i]->cvf_version);
  93          return -1;
  94        }
  95      
  96        printk("CVF format %s (version id %d) successfully unregistered.\n",
  97        cvf_formats[i]->cvf_version_text,cvf_formats[i]->cvf_version);
  98        cvf_formats[i]=NULL;
  99        return 0;
 100      }
 101    }
 102  }
 103  
 104  printk("unregister_cvf_format: format %d is not registered\n",
 105         cvf_format->cvf_version);
 106  return -1;
 107}
 108
 109void dec_cvf_format_use_count_by_version(int version)
 110{ int i;
 111
 112  for(i=0;i<MAX_CVF_FORMATS;++i)
 113  { if(cvf_formats[i])
 114    { if(cvf_formats[i]->cvf_version==version)
 115      { --cvf_format_use_count[i];
 116        if(cvf_format_use_count[i]<0)
 117        { cvf_format_use_count[i]=0;
 118          printk(KERN_EMERG "FAT FS/CVF: This is a bug in cvf_version_use_count\n");
 119        }
 120        return;
 121      }
 122    }
 123  }
 124  
 125  printk("dec_cvf_format_use_count_by_version: version %d not found ???\n",
 126         version);
 127}
 128
 129int detect_cvf(struct super_block*sb,char*force)
 130{ int i;
 131  int found=0;
 132  int found_i=-1;
 133
 134  if(force)
 135    if(strcmp(force,"autoload")==0)
 136    {
 137#ifdef CONFIG_KMOD
 138      request_module("cvf_autoload");
 139      force=NULL;
 140#else
 141      printk("cannot autoload CVF modules: kmod support is not compiled into kernel\n");
 142      return -1;
 143#endif
 144    }
 145    
 146#ifdef CONFIG_KMOD
 147  if(force)
 148    if(*force)
 149      request_module(force);
 150#endif
 151
 152  if(force)
 153  { if(*force)
 154    { for(i=0;i<MAX_CVF_FORMATS;++i)
 155      { if(cvf_formats[i])
 156        { if(!strcmp(cvf_formats[i]->cvf_version_text,force))
 157            return i;
 158        }
 159      }
 160      printk("CVF format %s unknown (module not loaded?)\n",force);
 161      return -1;
 162    }
 163  }
 164
 165  for(i=0;i<MAX_CVF_FORMATS;++i)
 166  { if(cvf_formats[i])
 167    { if(cvf_formats[i]->detect_cvf(sb))
 168      { ++found;
 169        found_i=i;
 170      }
 171    }
 172  }
 173  
 174  if(found==1)return found_i;
 175  if(found>1)printk("CVF detection ambiguous, please use cvf_format=xxx option\n"); 
 176  return -1;
 177}
 178
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.