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
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>
26 #include <linux/stat.h>
27 #include <linux/locks.h>
28 #include <linux/fat_cvf.h>
29 #include <linux/malloc.h>
33 #include <asm/uaccess.h>
34 #include <asm/unaligned.h>
36 /* #define FAT_PARANOIA 1 */
39 # define PRINTK(x) printk x
43 #if (DEBUG_LEVEL >= 1)
44 # define PRINTK1(x) printk x
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
56 * e) currently entries are stored within struct inode. That should
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
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) {
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
)
119 if (i
->i_location
!= i_pos
)
121 inode
= igrab(i
->i_fat_inode
);
123 spin_unlock(&fat_inode_lock
);
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
)
134 inode
= fat_iget(sb
, ino
);
137 inode
= get_empty_inode();
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
);
152 void fat_delete_inode(struct 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
);
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
;
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;
219 opts
->iocharset
= NULL
;
226 for (this_char
= strtok(options
,","); this_char
;
227 this_char
= strtok(NULL
,",")) {
228 if ((value
= strchr(this_char
,'=')) != NULL
) {
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';
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';
255 else if (!strcmp(this_char
,"dots")) {
258 else if (!strcmp(this_char
,"nodots")) {
261 else if (!strcmp(this_char
,"showexec")) {
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;
269 else if (!strcmp(this_char
,"uid")) {
270 if (!value
|| !*value
) ret
= 0;
272 opts
->fs_uid
= simple_strtoul(value
,&value
,0);
276 else if (!strcmp(this_char
,"gid")) {
277 if (!value
|| !*value
) ret
= 0;
279 opts
->fs_gid
= simple_strtoul(value
,&value
,0);
283 else if (!strcmp(this_char
,"umask")) {
284 if (!value
|| !*value
) ret
= 0;
286 opts
->fs_umask
= simple_strtoul(value
,&value
,8);
290 else if (!strcmp(this_char
,"debug")) {
294 else if (!strcmp(this_char
,"fat")) {
295 if (!value
|| !*value
) ret
= 0;
297 *fat
= simple_strtoul(value
,&value
,0);
298 if (*value
|| (*fat
!= 12 && *fat
!= 16 &&
303 else if (!strcmp(this_char
,"quiet")) {
305 else opts
->quiet
= 1;
307 else if (!strcmp(this_char
,"blocksize")) {
309 else if (*blksize
!= 512 &&
312 printk ("MSDOS FS: Invalid blocksize "
313 "(512, 1024, or 2048)\n");
316 else if (!strcmp(this_char
,"sys_immutable")) {
318 else opts
->sys_immutable
= 1;
320 else if (!strcmp(this_char
,"codepage") && value
) {
321 opts
->codepage
= simple_strtoul(value
,&value
,0);
323 else printk ("MSDOS FS: Using codepage %d\n",
326 else if (!strcmp(this_char
,"iocharset") && value
) {
328 while (*value
&& *value
!= ',') value
++;
331 char * buffer
= kmalloc(len
+1, GFP_KERNEL
);
333 opts
->iocharset
= buffer
;
334 memcpy(buffer
, p
, len
);
336 printk("MSDOS FS: IO charset %s\n",
342 else if (!strcmp(this_char
,"cvf_format")) {
345 strncpy(cvf_format
,value
,20);
347 else if (!strcmp(this_char
,"cvf_options")) {
350 strncpy(cvf_options
,value
,100);
353 if (this_char
!= options
) *(this_char
-1) = ',';
354 if (value
) *savep
= save
;
362 static void fat_read_root(struct inode
*inode
)
364 struct super_block
*sb
= inode
->i_sb
;
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) {
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",
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
= {
411 NULL
, /* write_super */
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.
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
;
431 int data_sectors
,logical_sector_size
,sector_mult
,fat_clusters
=0;
432 int debug
,error
,fat
,cp
;
435 struct fat_mount_options opts
;
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
;
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
)];
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))
463 /* N.B. we should parse directly into the sb structure */
464 memcpy(&(MSDOS_SB(sb
)->options
), &opts
, sizeof(struct fat_mount_options
));
470 /* Force the superblock to a larger size here. */
471 sb
->s_blocksize
= blksize
;
472 set_blocksize(sb
->s_dev
, blksize
);
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);
482 if (bh
== NULL
|| !fat_is_uptodate(sb
,bh
)) {
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.
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
;
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;
525 MSDOS_SB(sb
)->fsinfo_offset
=
526 (CF_LE_W(b
->info_sector
) * logical_sector_size
)
529 if (MSDOS_SB(sb
)->fsinfo_offset
+ sizeof(struct fat_boot_fsinfo
) > sb
->s_blocksize
) {
530 printk("fat_read_super: Bad fsinfo_offset\n");
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
));
541 MSDOS_SB(sb
)->free_clusters
= CF_LE_L(fsinfo
->free_clusters
);
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
,
556 data_sectors
= CF_LE_W(get_unaligned((unsigned short *) &b
->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
;
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 :
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
;
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"))
589 i
= detect_cvf(sb
,cvf_format
);
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;
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)
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 */
641 MSDOS_SB(sb
)->nls_io
= load_nls_default();
645 root_inode
=get_empty_inode();
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
);
657 MSDOS_SB(sb
)->cvf_format
= cvf_formats
[i
];
658 ++cvf_format_use_count
[i
];
663 printk("get root inode failed\n");
665 if (MSDOS_SB(sb
)->nls_io
)
666 unload_nls(MSDOS_SB(sb
)->nls_io
);
668 unload_nls(MSDOS_SB(sb
)->nls_disk
);
672 printk("VFS: Can't find a valid MSDOS filesystem on dev %s.\n",
673 kdevname(sb
->s_dev
));
676 printk("FAT bread failed\n");
678 if (opts
.iocharset
) {
679 printk("VFS: freeing iocharset=%s\n", opts
.iocharset
);
680 kfree(opts
.iocharset
);
683 if(MSDOS_SB(sb
)->private_data
)kfree(MSDOS_SB(sb
)->private_data
);
684 MSDOS_SB(sb
)->private_data
=NULL
;
690 int fat_statfs(struct super_block
*sb
,struct statfs
*buf
, int bufsiz
)
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
);
700 if (MSDOS_SB(sb
)->free_clusters
!= -1)
701 free
= MSDOS_SB(sb
)->free_clusters
;
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
;
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
;
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
;
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))
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
;
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" */
776 if (!inode
->i_nlink
) {
777 printk("directory %d: i_nlink == 0\n",inode
->i_ino
);
782 if ((nr
= MSDOS_I(inode
)->i_start
) != 0)
784 inode
->i_size
+= SECTOR_SIZE
*MSDOS_SB(inode
->
786 if (!(nr
= fat_access(sb
,nr
,-1))) {
787 printk("Directory %ld: bad FAT\n",
792 } else { /* not a directory */
793 inode
->i_mode
= MSDOS_MKMODE(de
->attr
,
794 ((IS_NOEXEC(inode
) ||
795 (MSDOS_SB(sb
)->options
.showexec
&&
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
;
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
;
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
));
829 MSDOS_SB(sb
)->options
.isvfat
830 ? date_dos2unix(CF_LE_W(de
->ctime
),CF_LE_W(de
->cdate
))
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
;
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");
850 spin_lock(&fat_inode_lock
);
851 if (i_pos
!= MSDOS_I(inode
)->i_location
) {
852 spin_unlock(&fat_inode_lock
);
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
;
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);
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
;
892 error
= inode_change_ok(inode
, attr
);
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
)))
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
;
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
;
922 int init_module(void)
924 return init_fat_fs();
928 void cleanup_module(void)
930 /* Nothing to be done, really! */