cvf.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #define MAX_CVF_FORMATS 3
  22. struct buffer_head *default_fat_bread(struct super_block *,int);
  23. struct buffer_head *default_fat_getblk(struct super_block *, int);
  24. void default_fat_brelse(struct super_block *, struct buffer_head *);
  25. void default_fat_mark_buffer_dirty (struct super_block *, struct buffer_head *);
  26. void default_fat_set_uptodate (struct super_block *, struct buffer_head *,int);
  27. int default_fat_is_uptodate(struct super_block *, struct buffer_head *);
  28. int default_fat_access(struct super_block *sb,int nr,int new_value);
  29. void default_fat_ll_rw_block (struct super_block *sb, int opr, int nbreq,
  30.       struct buffer_head *bh[32]);
  31. int default_fat_bmap(struct inode *inode,int block);
  32. ssize_t default_fat_file_write(struct file *filp, const char *buf,
  33.        size_t count, loff_t *ppos);
  34. struct cvf_format default_cvf = {
  35. cvf_version:  0, /* version - who cares? */
  36. cvf_version_text:  "plain",
  37. flags: 0, /* flags - who cares? */
  38. cvf_bread: default_fat_bread,
  39. cvf_getblk: default_fat_getblk,
  40. cvf_brelse: default_fat_brelse,
  41. cvf_mark_buffer_dirty: default_fat_mark_buffer_dirty,
  42. cvf_set_uptodate: default_fat_set_uptodate,
  43. cvf_is_uptodate: default_fat_is_uptodate,
  44. cvf_ll_rw_block: default_fat_ll_rw_block,
  45. fat_access: default_fat_access,
  46. cvf_bmap: default_fat_bmap,
  47. cvf_file_read: generic_file_read,
  48. cvf_file_write: default_fat_file_write,
  49. };
  50. struct cvf_format *cvf_formats[MAX_CVF_FORMATS];
  51. int cvf_format_use_count[MAX_CVF_FORMATS];
  52. int register_cvf_format(struct cvf_format*cvf_format)
  53. { int i,j;
  54.   for(i=0;i<MAX_CVF_FORMATS;++i)
  55.   { if(cvf_formats[i]==NULL)
  56.     { /* free slot found, now check version */
  57.       for(j=0;j<MAX_CVF_FORMATS;++j)
  58.       { if(cvf_formats[j])
  59.         { if(cvf_formats[j]->cvf_version==cvf_format->cvf_version)
  60.           { printk("register_cvf_format: version %d already registeredn",
  61.                    cvf_format->cvf_version);
  62.             return -1;
  63.           }
  64.         }
  65.       }
  66.       cvf_formats[i]=cvf_format;
  67.       cvf_format_use_count[i]=0;
  68.       printk("CVF format %s (version id %d) successfully registered.n",
  69.              cvf_format->cvf_version_text,cvf_format->cvf_version);
  70.       return 0;
  71.     }
  72.   }
  73.   
  74.   printk("register_cvf_format: too many formatsn");
  75.   return -1;
  76. }
  77. int unregister_cvf_format(struct cvf_format*cvf_format)
  78. { int i;
  79.   for(i=0;i<MAX_CVF_FORMATS;++i)
  80.   { if(cvf_formats[i])
  81.     { if(cvf_formats[i]->cvf_version==cvf_format->cvf_version)
  82.       { if(cvf_format_use_count[i])
  83.         { printk("unregister_cvf_format: format %d in use, cannot remove!n",
  84.           cvf_formats[i]->cvf_version);
  85.           return -1;
  86.         }
  87.       
  88.         printk("CVF format %s (version id %d) successfully unregistered.n",
  89.         cvf_formats[i]->cvf_version_text,cvf_formats[i]->cvf_version);
  90.         cvf_formats[i]=NULL;
  91.         return 0;
  92.       }
  93.     }
  94.   }
  95.   
  96.   printk("unregister_cvf_format: format %d is not registeredn",
  97.          cvf_format->cvf_version);
  98.   return -1;
  99. }
  100. void dec_cvf_format_use_count_by_version(int version)
  101. { int i;
  102.   for(i=0;i<MAX_CVF_FORMATS;++i)
  103.   { if(cvf_formats[i])
  104.     { if(cvf_formats[i]->cvf_version==version)
  105.       { --cvf_format_use_count[i];
  106.         if(cvf_format_use_count[i]<0)
  107.         { cvf_format_use_count[i]=0;
  108.           printk(KERN_EMERG "FAT FS/CVF: This is a bug in cvf_version_use_countn");
  109.         }
  110.         return;
  111.       }
  112.     }
  113.   }
  114.   
  115.   printk("dec_cvf_format_use_count_by_version: version %d not found ???n",
  116.          version);
  117. }
  118. int detect_cvf(struct super_block*sb,char*force)
  119. { int i;
  120.   int found=0;
  121.   int found_i=-1;
  122.   if(force)
  123.     if(strcmp(force,"autoload")==0)
  124.     {
  125. #ifdef CONFIG_KMOD
  126.       request_module("cvf_autoload");
  127.       force=NULL;
  128. #else
  129.       printk("cannot autoload CVF modules: kmod support is not compiled into kerneln");
  130.       return -1;
  131. #endif
  132.     }
  133.     
  134. #ifdef CONFIG_KMOD
  135.   if(force)
  136.     if(*force)
  137.       request_module(force);
  138. #endif
  139.   if(force)
  140.   { if(*force)
  141.     { for(i=0;i<MAX_CVF_FORMATS;++i)
  142.       { if(cvf_formats[i])
  143.         { if(!strcmp(cvf_formats[i]->cvf_version_text,force))
  144.             return i;
  145.         }
  146.       }
  147.       printk("CVF format %s unknown (module not loaded?)n",force);
  148.       return -1;
  149.     }
  150.   }
  151.   for(i=0;i<MAX_CVF_FORMATS;++i)
  152.   { if(cvf_formats[i])
  153.     { if(cvf_formats[i]->detect_cvf(sb))
  154.       { ++found;
  155.         found_i=i;
  156.       }
  157.     }
  158.   }
  159.   
  160.   if(found==1)return found_i;
  161.   if(found>1)printk("CVF detection ambiguous, please use cvf_format=xxx optionn"); 
  162.   return -1;
  163. }