Import 2.3.11pre4
[davej-history.git] / fs / fat / inode.c
blobb55bfd712ed2fca5e3fb1c3484d6289831e35232
1 /*
2 * linux/fs/fat/inode.c
4 * Written 1992,1993 by Werner Almesberger
5 * VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner
6 * Rewritten for the constant inumbers support by Al Viro
8 * Fixes:
10 * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
13 #include <linux/version.h>
14 #define __NO_VERSION__
15 #include <linux/module.h>
17 #include <linux/msdos_fs.h>
18 #include <linux/nls.h>
19 #include <linux/kernel.h>
20 #include <linux/sched.h>
21 #include <linux/errno.h>
22 #include <linux/string.h>
23 #include <linux/major.h>
24 #include <linux/blkdev.h>
25 #include <linux/fs.h>
26 #include <linux/stat.h>
27 #include <linux/locks.h>
28 #include <linux/fat_cvf.h>
29 #include <linux/malloc.h>
31 #include "msbuffer.h"
33 #include <asm/uaccess.h>
34 #include <asm/unaligned.h>
36 /* #define FAT_PARANOIA 1 */
37 #define DEBUG_LEVEL 0
38 #ifdef FAT_DEBUG
39 # define PRINTK(x) printk x
40 #else
41 # define PRINTK(x)
42 #endif
43 #if (DEBUG_LEVEL >= 1)
44 # define PRINTK1(x) printk x
45 #else
46 # define PRINTK1(x)
47 #endif
50 * New FAT inode stuff. We do the following:
51 * a) i_ino is constant and has nothing with on-disk location.
52 * b) FAT manages its own cache of directory entries.
53 * c) *This* cache is indexed by on-disk location.
54 * d) inode has an associated directory entry, all right, but
55 * it may be unhashed.
56 * e) currently entries are stored within struct inode. That should
57 * change.
58 * f) we deal with races in the following way:
59 * 1. readdir() and lookup() do FAT-dir-cache lookup.
60 * 2. rename() unhashes the F-d-c entry and rehashes it in
61 * a new place.
62 * 3. unlink() and rmdir() unhash F-d-c entry.
63 * 4. fat_write_inode() checks whether the thing is unhashed.
64 * If it is we silently return. If it isn't we do bread(),
65 * check if the location is still valid and retry if it
66 * isn't. Otherwise we do changes.
67 * 5. Spinlock is used to protect hash/unhash/location check/lookup
68 * 6. fat_clear_inode() unhashes the F-d-c entry.
69 * 7. lookup() and readdir() do igrab() if they find a F-d-c entry
70 * and consider negative result as cache miss.
73 #define FAT_HASH_BITS 8
74 #define FAT_HASH_SIZE (1UL << FAT_HASH_BITS)
75 #define FAT_HASH_MASK (FAT_HASH_SIZE-1)
76 static struct list_head fat_inode_hashtable[FAT_HASH_SIZE];
77 spinlock_t fat_inode_lock = SPIN_LOCK_UNLOCKED;
79 void fat_hash_init(void) {
80 int i;
81 for(i=0;i<FAT_HASH_SIZE;i++) {
82 INIT_LIST_HEAD(&fat_inode_hashtable[i]);
86 static inline unsigned long fat_hash(struct super_block *sb, int i_pos)
88 unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
89 tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS*2);
90 return tmp & FAT_HASH_MASK;
93 void fat_attach(struct inode *inode, int i_pos) {
94 spin_lock(&fat_inode_lock);
95 MSDOS_I(inode)->i_location = i_pos;
96 list_add(&MSDOS_I(inode)->i_fat_hash,
97 fat_inode_hashtable+fat_hash(inode->i_sb, i_pos));
98 spin_unlock(&fat_inode_lock);
101 void fat_detach(struct inode *inode) {
102 spin_lock(&fat_inode_lock);
103 MSDOS_I(inode)->i_location = 0;
104 list_del(&MSDOS_I(inode)->i_fat_hash);
105 INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
106 spin_unlock(&fat_inode_lock);
109 struct inode *fat_iget(struct super_block *sb, int i_pos) {
110 struct list_head *p = fat_inode_hashtable + fat_hash(sb, i_pos);
111 struct list_head *walk;
112 struct msdos_inode_info *i;
113 struct inode *inode = NULL;
114 spin_lock(&fat_inode_lock);
115 for(walk=p->next;walk!=p;walk=walk->next) {
116 i = list_entry(walk, struct msdos_inode_info, i_fat_hash);
117 if (i->i_fat_inode->i_sb != sb)
118 continue;
119 if (i->i_location != i_pos)
120 continue;
121 inode = igrab(i->i_fat_inode);
123 spin_unlock(&fat_inode_lock);
124 return inode;
127 static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de);
129 struct inode *fat_build_inode(struct super_block *sb,
130 struct msdos_dir_entry *de, int ino, int *res)
132 struct inode *inode;
133 *res = 0;
134 inode = fat_iget(sb, ino);
135 if (inode)
136 goto out;
137 inode = get_empty_inode();
138 *res = -ENOMEM;
139 if (!inode)
140 goto out;
141 *res = 0;
142 inode->i_sb = sb;
143 inode->i_dev = sb->s_dev;
144 inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
145 fat_fill_inode(inode, de);
146 fat_attach(inode, ino);
147 insert_inode_hash(inode);
148 out:
149 return inode;
152 void fat_delete_inode(struct inode *inode)
154 inode->i_size = 0;
155 fat_truncate(inode);
156 clear_inode(inode);
159 void fat_clear_inode(struct inode *inode)
161 spin_lock(&fat_inode_lock);
162 fat_cache_inval_inode(inode);
163 list_del(&MSDOS_I(inode)->i_fat_hash);
164 spin_unlock(&fat_inode_lock);
167 void fat_put_super(struct super_block *sb)
169 if (MSDOS_SB(sb)->cvf_format) {
170 dec_cvf_format_use_count_by_version(MSDOS_SB(sb)->cvf_format->cvf_version);
171 MSDOS_SB(sb)->cvf_format->unmount_cvf(sb);
173 if (MSDOS_SB(sb)->fat_bits == 32) {
174 fat_clusters_flush(sb);
176 fat_cache_inval_dev(sb->s_dev);
177 set_blocksize (sb->s_dev,BLOCK_SIZE);
178 if (MSDOS_SB(sb)->nls_disk) {
179 unload_nls(MSDOS_SB(sb)->nls_disk);
180 MSDOS_SB(sb)->nls_disk = NULL;
181 MSDOS_SB(sb)->options.codepage = 0;
183 if (MSDOS_SB(sb)->nls_io) {
184 unload_nls(MSDOS_SB(sb)->nls_io);
185 MSDOS_SB(sb)->nls_io = NULL;
188 * Note: the iocharset option might have been specified
189 * without enabling nls_io, so check for it here.
191 if (MSDOS_SB(sb)->options.iocharset) {
192 kfree(MSDOS_SB(sb)->options.iocharset);
193 MSDOS_SB(sb)->options.iocharset = NULL;
196 if (MSDOS_SB(sb)->put_super_callback)
197 MSDOS_SB(sb)->put_super_callback(sb);
198 MOD_DEC_USE_COUNT;
199 return;
203 static int parse_options(char *options,int *fat, int *blksize, int *debug,
204 struct fat_mount_options *opts,
205 char *cvf_format, char *cvf_options)
207 char *this_char,*value,save,*savep;
208 char *p;
209 int ret = 1, len;
211 opts->name_check = 'n';
212 opts->conversion = 'b';
213 opts->fs_uid = current->uid;
214 opts->fs_gid = current->gid;
215 opts->fs_umask = current->fs->umask;
216 opts->quiet = opts->sys_immutable = opts->dotsOK = opts->showexec = 0;
217 opts->codepage = 0;
218 opts->utf8 = 0;
219 opts->iocharset = NULL;
220 *debug = *fat = 0;
222 if (!options)
223 goto out;
224 save = 0;
225 savep = NULL;
226 for (this_char = strtok(options,","); this_char;
227 this_char = strtok(NULL,",")) {
228 if ((value = strchr(this_char,'=')) != NULL) {
229 save = *value;
230 savep = value;
231 *value++ = 0;
233 if (!strcmp(this_char,"check") && value) {
234 if (value[0] && !value[1] && strchr("rns",*value))
235 opts->name_check = *value;
236 else if (!strcmp(value,"relaxed"))
237 opts->name_check = 'r';
238 else if (!strcmp(value,"normal"))
239 opts->name_check = 'n';
240 else if (!strcmp(value,"strict"))
241 opts->name_check = 's';
242 else ret = 0;
244 else if (!strcmp(this_char,"conv") && value) {
245 if (value[0] && !value[1] && strchr("bta",*value))
246 opts->conversion = *value;
247 else if (!strcmp(value,"binary"))
248 opts->conversion = 'b';
249 else if (!strcmp(value,"text"))
250 opts->conversion = 't';
251 else if (!strcmp(value,"auto"))
252 opts->conversion = 'a';
253 else ret = 0;
255 else if (!strcmp(this_char,"dots")) {
256 opts->dotsOK = 1;
258 else if (!strcmp(this_char,"nodots")) {
259 opts->dotsOK = 0;
261 else if (!strcmp(this_char,"showexec")) {
262 opts->showexec = 1;
264 else if (!strcmp(this_char,"dotsOK") && value) {
265 if (!strcmp(value,"yes")) opts->dotsOK = 1;
266 else if (!strcmp(value,"no")) opts->dotsOK = 0;
267 else ret = 0;
269 else if (!strcmp(this_char,"uid")) {
270 if (!value || !*value) ret = 0;
271 else {
272 opts->fs_uid = simple_strtoul(value,&value,0);
273 if (*value) ret = 0;
276 else if (!strcmp(this_char,"gid")) {
277 if (!value || !*value) ret= 0;
278 else {
279 opts->fs_gid = simple_strtoul(value,&value,0);
280 if (*value) ret = 0;
283 else if (!strcmp(this_char,"umask")) {
284 if (!value || !*value) ret = 0;
285 else {
286 opts->fs_umask = simple_strtoul(value,&value,8);
287 if (*value) ret = 0;
290 else if (!strcmp(this_char,"debug")) {
291 if (value) ret = 0;
292 else *debug = 1;
294 else if (!strcmp(this_char,"fat")) {
295 if (!value || !*value) ret = 0;
296 else {
297 *fat = simple_strtoul(value,&value,0);
298 if (*value || (*fat != 12 && *fat != 16 &&
299 *fat != 32))
300 ret = 0;
303 else if (!strcmp(this_char,"quiet")) {
304 if (value) ret = 0;
305 else opts->quiet = 1;
307 else if (!strcmp(this_char,"blocksize")) {
308 if (*value) ret = 0;
309 else if (*blksize != 512 &&
310 *blksize != 1024 &&
311 *blksize != 2048) {
312 printk ("MSDOS FS: Invalid blocksize "
313 "(512, 1024, or 2048)\n");
316 else if (!strcmp(this_char,"sys_immutable")) {
317 if (value) ret = 0;
318 else opts->sys_immutable = 1;
320 else if (!strcmp(this_char,"codepage") && value) {
321 opts->codepage = simple_strtoul(value,&value,0);
322 if (*value) ret = 0;
323 else printk ("MSDOS FS: Using codepage %d\n",
324 opts->codepage);
326 else if (!strcmp(this_char,"iocharset") && value) {
327 p = value;
328 while (*value && *value != ',') value++;
329 len = value - p;
330 if (len) {
331 char * buffer = kmalloc(len+1, GFP_KERNEL);
332 if (buffer) {
333 opts->iocharset = buffer;
334 memcpy(buffer, p, len);
335 buffer[len] = 0;
336 printk("MSDOS FS: IO charset %s\n",
337 buffer);
338 } else
339 ret = 0;
342 else if (!strcmp(this_char,"cvf_format")) {
343 if (!value)
344 return 0;
345 strncpy(cvf_format,value,20);
347 else if (!strcmp(this_char,"cvf_options")) {
348 if (!value)
349 return 0;
350 strncpy(cvf_options,value,100);
353 if (this_char != options) *(this_char-1) = ',';
354 if (value) *savep = save;
355 if (ret == 0)
356 break;
358 out:
359 return ret;
362 static void fat_read_root(struct inode *inode)
364 struct super_block *sb = inode->i_sb;
365 int nr;
367 MSDOS_I(inode)->i_binary = 1;
368 INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
369 MSDOS_I(inode)->i_location = 0;
370 MSDOS_I(inode)->i_fat_inode = inode;
371 inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
372 inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
373 inode->i_version = ++event;
374 inode->i_mode = (S_IRWXUGO & ~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
375 inode->i_op = MSDOS_SB(sb)->dir_ops;
376 if (MSDOS_SB(sb)->fat_bits == 32) {
377 MSDOS_I(inode)->i_start = MSDOS_SB(sb)->root_cluster;
378 if ((nr = MSDOS_I(inode)->i_start) != 0) {
379 while (nr != -1) {
380 inode->i_size += SECTOR_SIZE*MSDOS_SB(sb)->cluster_size;
381 if (!(nr = fat_access(sb,nr,-1))) {
382 printk("Directory %ld: bad FAT\n",
383 inode->i_ino);
384 break;
388 } else {
389 MSDOS_I(inode)->i_start = 0;
390 inode->i_size = MSDOS_SB(sb)->dir_entries*
391 sizeof(struct msdos_dir_entry);
393 inode->i_blksize = MSDOS_SB(sb)->cluster_size* SECTOR_SIZE;
394 inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
395 inode->i_blksize*MSDOS_SB(sb)->cluster_size;
396 MSDOS_I(inode)->i_logstart = 0;
398 MSDOS_I(inode)->i_attrs = 0;
399 inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
400 MSDOS_I(inode)->i_ctime_ms = 0;
401 inode->i_nlink = fat_subdirs(inode)+2;
404 static struct super_operations fat_sops = {
405 NULL,
406 fat_write_inode,
407 NULL,
408 fat_delete_inode,
409 fat_notify_change,
410 fat_put_super,
411 NULL, /* write_super */
412 fat_statfs,
413 NULL, /* remount */
414 fat_clear_inode
418 * Read the super block of an MS-DOS FS.
420 * Note that this may be called from vfat_read_super
421 * with some fields already initialized.
423 struct super_block *
424 fat_read_super(struct super_block *sb, void *data, int silent,
425 struct inode_operations *fs_dir_inode_ops)
427 struct inode *root_inode;
428 struct buffer_head *bh;
429 struct fat_boot_sector *b;
430 char *p;
431 int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
432 int debug,error,fat,cp;
433 int blksize = 512;
434 int fat32;
435 struct fat_mount_options opts;
436 char buf[50];
437 int i;
438 char cvf_format[21];
439 char cvf_options[101];
441 cvf_format[0] = '\0';
442 cvf_options[0] = '\0';
443 MSDOS_SB(sb)->cvf_format = NULL;
444 MSDOS_SB(sb)->private_data = NULL;
446 MOD_INC_USE_COUNT;
447 MSDOS_SB(sb)->dir_ops = fs_dir_inode_ops;
448 MSDOS_SB(sb)->put_super_callback = NULL;
449 sb->s_op = &fat_sops;
450 if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
451 blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];
452 if (blksize != 512){
453 printk ("MSDOS: Hardware sector size is %d\n",blksize);
458 opts.isvfat = MSDOS_SB(sb)->options.isvfat;
459 if (!parse_options((char *) data, &fat, &blksize, &debug, &opts,
460 cvf_format, cvf_options)
461 || (blksize != 512 && blksize != 1024 && blksize != 2048))
462 goto out_fail;
463 /* N.B. we should parse directly into the sb structure */
464 memcpy(&(MSDOS_SB(sb)->options), &opts, sizeof(struct fat_mount_options));
466 fat_cache_init();
467 lock_super(sb);
468 if( blksize > 1024 )
470 /* Force the superblock to a larger size here. */
471 sb->s_blocksize = blksize;
472 set_blocksize(sb->s_dev, blksize);
474 else
476 /* The first read is always 1024 bytes */
477 sb->s_blocksize = 1024;
478 set_blocksize(sb->s_dev, 1024);
480 bh = fat_bread(sb, 0);
481 unlock_super(sb);
482 if (bh == NULL || !fat_is_uptodate(sb,bh)) {
483 fat_brelse (sb, bh);
484 goto out_no_bread;
488 * The DOS3 partition size limit is *not* 32M as many people think.
489 * Instead, it is 64K sectors (with the usual sector size being
490 * 512 bytes, leading to a 32M limit).
492 * DOS 3 partition managers got around this problem by faking a
493 * larger sector size, ie treating multiple physical sectors as
494 * a single logical sector.
496 * We can accommodate this scheme by adjusting our cluster size,
497 * fat_start, and data_start by an appropriate value.
499 * (by Drew Eckhardt)
502 #define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
503 /* don't divide by zero */
505 b = (struct fat_boot_sector *) bh->b_data;
506 logical_sector_size =
507 CF_LE_W(get_unaligned((unsigned short *) &b->sector_size));
508 sector_mult = logical_sector_size >> SECTOR_BITS;
509 MSDOS_SB(sb)->cluster_size = b->cluster_size*sector_mult;
510 MSDOS_SB(sb)->fats = b->fats;
511 MSDOS_SB(sb)->fat_start = CF_LE_W(b->reserved)*sector_mult;
512 if (!b->fat_length && b->fat32_length) {
513 struct fat_boot_fsinfo *fsinfo;
515 /* Must be FAT32 */
516 fat32 = 1;
517 MSDOS_SB(sb)->fat_length= CF_LE_W(b->fat32_length)*sector_mult;
518 MSDOS_SB(sb)->root_cluster = CF_LE_L(b->root_cluster);
520 /* MC - if info_sector is 0, don't multiply by 0 */
521 if(CF_LE_W(b->info_sector) == 0) {
522 MSDOS_SB(sb)->fsinfo_offset =
523 logical_sector_size + 0x1e0;
524 } else {
525 MSDOS_SB(sb)->fsinfo_offset =
526 (CF_LE_W(b->info_sector) * logical_sector_size)
527 + 0x1e0;
529 if (MSDOS_SB(sb)->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) {
530 printk("fat_read_super: Bad fsinfo_offset\n");
531 fat_brelse(sb, bh);
532 goto out_invalid;
534 fsinfo = (struct fat_boot_fsinfo *)
535 &bh->b_data[MSDOS_SB(sb)->fsinfo_offset];
536 if (CF_LE_L(fsinfo->signature) != 0x61417272) {
537 printk("fat_read_super: Did not find valid FSINFO "
538 "signature. Found 0x%x\n",
539 CF_LE_L(fsinfo->signature));
540 } else {
541 MSDOS_SB(sb)->free_clusters = CF_LE_L(fsinfo->free_clusters);
543 } else {
544 fat32 = 0;
545 MSDOS_SB(sb)->fat_length = CF_LE_W(b->fat_length)*sector_mult;
546 MSDOS_SB(sb)->root_cluster = 0;
547 MSDOS_SB(sb)->free_clusters = -1; /* Don't know yet */
549 MSDOS_SB(sb)->dir_start= CF_LE_W(b->reserved)*sector_mult+
550 b->fats*MSDOS_SB(sb)->fat_length;
551 MSDOS_SB(sb)->dir_entries =
552 CF_LE_W(get_unaligned((unsigned short *) &b->dir_entries));
553 MSDOS_SB(sb)->data_start = MSDOS_SB(sb)->dir_start+ROUND_TO_MULTIPLE((
554 MSDOS_SB(sb)->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
555 sector_mult);
556 data_sectors = CF_LE_W(get_unaligned((unsigned short *) &b->sectors));
557 if (!data_sectors) {
558 data_sectors = CF_LE_L(b->total_sect);
560 data_sectors = data_sectors * sector_mult - MSDOS_SB(sb)->data_start;
561 error = !b->cluster_size || !sector_mult;
562 if (!error) {
563 MSDOS_SB(sb)->clusters = b->cluster_size ? data_sectors/
564 b->cluster_size/sector_mult : 0;
565 MSDOS_SB(sb)->fat_bits = fat32 ? 32 :
566 (fat ? fat :
567 (MSDOS_SB(sb)->clusters > MSDOS_FAT12 ? 16 : 12));
568 fat_clusters = MSDOS_SB(sb)->fat_length*SECTOR_SIZE*8/
569 MSDOS_SB(sb)->fat_bits;
570 error = !MSDOS_SB(sb)->fats || (MSDOS_SB(sb)->dir_entries &
571 (MSDOS_DPS-1)) || MSDOS_SB(sb)->clusters+2 > fat_clusters+
572 MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))
573 || !b->secs_track || !b->heads;
575 fat_brelse(sb, bh);
576 set_blocksize(sb->s_dev, blksize);
578 This must be done after the brelse because the bh is a dummy
579 allocated by fat_bread (see buffer.c)
581 sb->s_blocksize = blksize; /* Using this small block size solves */
582 /* the misfit with buffer cache and cluster */
583 /* because clusters (DOS) are often aligned */
584 /* on odd sectors. */
585 sb->s_blocksize_bits = blksize == 512 ? 9 : (blksize == 1024 ? 10 : 11);
586 if (!strcmp(cvf_format,"none"))
587 i = -1;
588 else
589 i = detect_cvf(sb,cvf_format);
590 if (i >= 0)
591 error = cvf_formats[i]->mount_cvf(sb,cvf_options);
592 if (error || debug) {
593 /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
594 printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
595 "uid=%d,gid=%d,umask=%03o%s]\n",
596 MSDOS_SB(sb)->fat_bits,opts.name_check,
597 opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
598 MSDOS_CAN_BMAP(MSDOS_SB(sb)) ? ",bmap" : "");
599 printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
600 "se=%d,ts=%ld,ls=%d,rc=%ld,fc=%u]\n",
601 b->media,MSDOS_SB(sb)->cluster_size,
602 MSDOS_SB(sb)->fats,MSDOS_SB(sb)->fat_start,
603 MSDOS_SB(sb)->fat_length,
604 MSDOS_SB(sb)->dir_start,MSDOS_SB(sb)->dir_entries,
605 MSDOS_SB(sb)->data_start,
606 CF_LE_W(*(unsigned short *) &b->sectors),
607 (unsigned long)b->total_sect,logical_sector_size,
608 MSDOS_SB(sb)->root_cluster,MSDOS_SB(sb)->free_clusters);
609 printk ("Transaction block size = %d\n",blksize);
611 if (i<0) if (MSDOS_SB(sb)->clusters+2 > fat_clusters)
612 MSDOS_SB(sb)->clusters = fat_clusters-2;
613 if (error)
614 goto out_invalid;
616 sb->s_magic = MSDOS_SUPER_MAGIC;
617 /* set up enough so that it can read an inode */
618 init_waitqueue_head(&MSDOS_SB(sb)->fat_wait);
619 MSDOS_SB(sb)->fat_lock = 0;
620 MSDOS_SB(sb)->prev_free = 0;
622 cp = opts.codepage ? opts.codepage : 437;
623 sprintf(buf, "cp%d", cp);
624 MSDOS_SB(sb)->nls_disk = load_nls(buf);
625 if (! MSDOS_SB(sb)->nls_disk) {
626 /* Fail only if explicit charset specified */
627 if (opts.codepage != 0)
628 goto out_fail;
629 MSDOS_SB(sb)->options.codepage = 0; /* already 0?? */
630 MSDOS_SB(sb)->nls_disk = load_nls_default();
633 MSDOS_SB(sb)->nls_io = NULL;
634 if (MSDOS_SB(sb)->options.isvfat && !opts.utf8) {
635 p = opts.iocharset ? opts.iocharset : "iso8859-1";
636 MSDOS_SB(sb)->nls_io = load_nls(p);
637 if (! MSDOS_SB(sb)->nls_io) {
638 /* Fail only if explicit charset specified */
639 if (opts.iocharset)
640 goto out_unload_nls;
641 MSDOS_SB(sb)->nls_io = load_nls_default();
645 root_inode=get_empty_inode();
646 if (!root_inode)
647 goto out_unload_nls;
648 root_inode->i_sb = sb;
649 root_inode->i_dev = sb->s_dev;
650 root_inode->i_ino = MSDOS_ROOT_INO;
651 fat_read_root(root_inode);
652 insert_inode_hash(root_inode);
653 sb->s_root = d_alloc_root(root_inode);
654 if (!sb->s_root)
655 goto out_no_root;
656 if(i>=0) {
657 MSDOS_SB(sb)->cvf_format = cvf_formats[i];
658 ++cvf_format_use_count[i];
660 return sb;
662 out_no_root:
663 printk("get root inode failed\n");
664 iput(root_inode);
665 if (MSDOS_SB(sb)->nls_io)
666 unload_nls(MSDOS_SB(sb)->nls_io);
667 out_unload_nls:
668 unload_nls(MSDOS_SB(sb)->nls_disk);
669 goto out_fail;
670 out_invalid:
671 if (!silent)
672 printk("VFS: Can't find a valid MSDOS filesystem on dev %s.\n",
673 kdevname(sb->s_dev));
674 goto out_fail;
675 out_no_bread:
676 printk("FAT bread failed\n");
677 out_fail:
678 if (opts.iocharset) {
679 printk("VFS: freeing iocharset=%s\n", opts.iocharset);
680 kfree(opts.iocharset);
682 sb->s_dev = 0;
683 if(MSDOS_SB(sb)->private_data)kfree(MSDOS_SB(sb)->private_data);
684 MSDOS_SB(sb)->private_data=NULL;
686 MOD_DEC_USE_COUNT;
687 return NULL;
690 int fat_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
692 int free,nr;
693 struct statfs tmp;
695 if (MSDOS_SB(sb)->cvf_format &&
696 MSDOS_SB(sb)->cvf_format->cvf_statfs)
697 return MSDOS_SB(sb)->cvf_format->cvf_statfs(sb,buf,bufsiz);
699 lock_fat(sb);
700 if (MSDOS_SB(sb)->free_clusters != -1)
701 free = MSDOS_SB(sb)->free_clusters;
702 else {
703 free = 0;
704 for (nr = 2; nr < MSDOS_SB(sb)->clusters+2; nr++)
705 if (!fat_access(sb,nr,-1)) free++;
706 MSDOS_SB(sb)->free_clusters = free;
708 unlock_fat(sb);
709 tmp.f_type = sb->s_magic;
710 tmp.f_bsize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
711 tmp.f_blocks = MSDOS_SB(sb)->clusters;
712 tmp.f_bfree = free;
713 tmp.f_bavail = free;
714 tmp.f_files = 0;
715 tmp.f_ffree = 0;
716 tmp.f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
717 return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0;
721 int fat_bmap(struct inode *inode,int block)
723 struct msdos_sb_info *sb;
724 int cluster,offset;
726 sb = MSDOS_SB(inode->i_sb);
727 if (sb->cvf_format &&
728 sb->cvf_format->cvf_bmap)
729 return sb->cvf_format->cvf_bmap(inode,block);
730 if ((inode->i_ino == MSDOS_ROOT_INO) && (sb->fat_bits != 32)) {
731 return sb->dir_start + block;
733 cluster = block/sb->cluster_size;
734 offset = block % sb->cluster_size;
735 if (!(cluster = fat_get_cluster(inode,cluster))) return 0;
736 return (cluster-2)*sb->cluster_size+sb->data_start+offset;
739 static int is_exec(char *extension)
741 char *exe_extensions = "EXECOMBAT", *walk;
743 for (walk = exe_extensions; *walk; walk += 3)
744 if (!strncmp(extension, walk, 3))
745 return 1;
746 return 0;
749 /* doesn't deal with root inode */
750 static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
752 struct super_block *sb = inode->i_sb;
753 int nr;
755 MSDOS_I(inode)->i_binary = 1;
756 INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
757 MSDOS_I(inode)->i_location = 0;
758 MSDOS_I(inode)->i_fat_inode = inode;
759 inode->i_uid = MSDOS_SB(sb)->options.fs_uid;
760 inode->i_gid = MSDOS_SB(sb)->options.fs_gid;
761 inode->i_version = ++event;
762 if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
763 inode->i_mode = MSDOS_MKMODE(de->attr,S_IRWXUGO &
764 ~MSDOS_SB(sb)->options.fs_umask) | S_IFDIR;
765 inode->i_op = MSDOS_SB(inode->i_sb)->dir_ops;
767 MSDOS_I(inode)->i_start = CF_LE_W(de->start);
768 if (MSDOS_SB(sb)->fat_bits == 32) {
769 MSDOS_I(inode)->i_start |=
770 (CF_LE_W(de->starthi) << 16);
772 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
773 inode->i_nlink = fat_subdirs(inode);
774 /* includes .., compensating for "self" */
775 #ifdef DEBUG
776 if (!inode->i_nlink) {
777 printk("directory %d: i_nlink == 0\n",inode->i_ino);
778 inode->i_nlink = 1;
780 #endif
781 inode->i_size = 0;
782 if ((nr = MSDOS_I(inode)->i_start) != 0)
783 while (nr != -1) {
784 inode->i_size += SECTOR_SIZE*MSDOS_SB(inode->
785 i_sb)->cluster_size;
786 if (!(nr = fat_access(sb,nr,-1))) {
787 printk("Directory %ld: bad FAT\n",
788 inode->i_ino);
789 break;
792 } else { /* not a directory */
793 inode->i_mode = MSDOS_MKMODE(de->attr,
794 ((IS_NOEXEC(inode) ||
795 (MSDOS_SB(sb)->options.showexec &&
796 !is_exec(de->ext)))
797 ? S_IRUGO|S_IWUGO : S_IRWXUGO)
798 & ~MSDOS_SB(sb)->options.fs_umask) | S_IFREG;
799 if (MSDOS_SB(sb)->cvf_format)
800 inode->i_op = (MSDOS_SB(sb)->cvf_format->flags & CVF_USE_READPAGE)
801 ? &fat_file_inode_operations_readpage
802 : &fat_file_inode_operations_1024;
803 else
804 inode->i_op = (sb->s_blocksize == 1024 || sb->s_blocksize == 2048)
805 ? &fat_file_inode_operations_1024
806 : &fat_file_inode_operations;
807 MSDOS_I(inode)->i_start = CF_LE_W(de->start);
808 if (MSDOS_SB(sb)->fat_bits == 32) {
809 MSDOS_I(inode)->i_start |=
810 (CF_LE_W(de->starthi) << 16);
812 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
813 inode->i_nlink = 1;
814 inode->i_size = CF_LE_L(de->size);
816 if(de->attr & ATTR_SYS)
817 if (MSDOS_SB(sb)->options.sys_immutable)
818 inode->i_flags |= S_IMMUTABLE;
819 MSDOS_I(inode)->i_binary =
820 fat_is_binary(MSDOS_SB(sb)->options.conversion, de->ext);
821 MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
822 /* this is as close to the truth as we can get ... */
823 inode->i_blksize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
824 inode->i_blocks = (inode->i_size+inode->i_blksize-1)/
825 inode->i_blksize*MSDOS_SB(sb)->cluster_size;
826 inode->i_mtime = inode->i_atime =
827 date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
828 inode->i_ctime =
829 MSDOS_SB(sb)->options.isvfat
830 ? date_dos2unix(CF_LE_W(de->ctime),CF_LE_W(de->cdate))
831 : inode->i_mtime;
832 MSDOS_I(inode)->i_ctime_ms = de->ctime_ms;
835 void fat_write_inode(struct inode *inode)
837 struct super_block *sb = inode->i_sb;
838 struct buffer_head *bh;
839 struct msdos_dir_entry *raw_entry;
840 int i_pos;
842 retry:
843 i_pos = MSDOS_I(inode)->i_location;
844 if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) return;
845 if (!(bh = fat_bread(sb, i_pos >> MSDOS_DPB_BITS))) {
846 printk("dev = %s, ino = %d\n", kdevname(inode->i_dev), i_pos);
847 fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block");
848 return;
850 spin_lock(&fat_inode_lock);
851 if (i_pos != MSDOS_I(inode)->i_location) {
852 spin_unlock(&fat_inode_lock);
853 fat_brelse(sb, bh);
854 goto retry;
857 raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
858 [i_pos & (MSDOS_DPB-1)];
859 if (S_ISDIR(inode->i_mode)) {
860 raw_entry->attr = ATTR_DIR;
861 raw_entry->size = 0;
863 else {
864 raw_entry->attr = ATTR_NONE;
865 raw_entry->size = CT_LE_L(inode->i_size);
867 raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
868 MSDOS_I(inode)->i_attrs;
869 raw_entry->start = CT_LE_W(MSDOS_I(inode)->i_logstart);
870 raw_entry->starthi = CT_LE_W(MSDOS_I(inode)->i_logstart >> 16);
871 fat_date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date);
872 raw_entry->time = CT_LE_W(raw_entry->time);
873 raw_entry->date = CT_LE_W(raw_entry->date);
874 if (MSDOS_SB(sb)->options.isvfat) {
875 fat_date_unix2dos(inode->i_ctime,&raw_entry->ctime,&raw_entry->cdate);
876 raw_entry->ctime_ms = MSDOS_I(inode)->i_ctime_ms;
877 raw_entry->ctime = CT_LE_W(raw_entry->ctime);
878 raw_entry->cdate = CT_LE_W(raw_entry->cdate);
880 spin_unlock(&fat_inode_lock);
881 fat_mark_buffer_dirty(sb, bh, 1);
882 fat_brelse(sb, bh);
886 int fat_notify_change(struct dentry * dentry, struct iattr * attr)
888 struct super_block *sb = dentry->d_sb;
889 struct inode *inode = dentry->d_inode;
890 int error;
892 error = inode_change_ok(inode, attr);
893 if (error)
894 return MSDOS_SB(sb)->options.quiet ? 0 : error;
896 if (((attr->ia_valid & ATTR_UID) &&
897 (attr->ia_uid != MSDOS_SB(sb)->options.fs_uid)) ||
898 ((attr->ia_valid & ATTR_GID) &&
899 (attr->ia_gid != MSDOS_SB(sb)->options.fs_gid)) ||
900 ((attr->ia_valid & ATTR_MODE) &&
901 (attr->ia_mode & ~MSDOS_VALID_MODE)))
902 error = -EPERM;
904 if (error)
905 return MSDOS_SB(sb)->options.quiet ? 0 : error;
907 inode_setattr(inode, attr);
909 if (IS_NOEXEC(inode) && !S_ISDIR(inode->i_mode))
910 inode->i_mode &= S_IFMT | S_IRUGO | S_IWUGO;
911 else
912 inode->i_mode |= S_IXUGO;
914 inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
915 & ~MSDOS_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
916 ~MSDOS_SB(sb)->options.fs_umask;
917 return 0;
921 #ifdef MODULE
922 int init_module(void)
924 return init_fat_fs();
928 void cleanup_module(void)
930 /* Nothing to be done, really! */
931 return;
933 #endif