more debug output
[linux-2.4.git] / fs / fat / cvf.c
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
24 struct buffer_head *default_fat_bread(struct super_block *,int);
25 struct buffer_head *default_fat_getblk(struct super_block *, int);
26 void default_fat_brelse(struct super_block *, struct buffer_head *);
27 void default_fat_mark_buffer_dirty (struct super_block *, struct buffer_head *);
28 void default_fat_set_uptodate (struct super_block *, struct buffer_head *,int);
29 int default_fat_is_uptodate(struct super_block *, struct buffer_head *);
30 int default_fat_access(struct super_block *sb,int nr,int new_value);
31 void default_fat_ll_rw_block (struct super_block *sb, int opr, int nbreq,
32                               struct buffer_head *bh[32]);
33 int default_fat_bmap(struct inode *inode,int block);
34 ssize_t default_fat_file_write(struct file *filp, const char *buf,
35                                size_t count, loff_t *ppos);
36
37 struct 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
54 struct cvf_format *cvf_formats[MAX_CVF_FORMATS];
55 int cvf_format_use_count[MAX_CVF_FORMATS];
56
57 int 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
84 int 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
109 void 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
129 int 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 }