4 * Written 1992,1993 by Werner Almesberger
5 * VFAT extensions by Gordon Chaffee, merged with msdos fs by Henrik Storner
9 * Max Cohan: Fixed invalid FSINFO offset when info_sector is 0
12 #include <linux/version.h>
13 #define __NO_VERSION__
14 #include <linux/module.h>
16 #include <linux/msdos_fs.h>
17 #include <linux/nls.h>
18 #include <linux/kernel.h>
19 #include <linux/sched.h>
20 #include <linux/errno.h>
21 #include <linux/string.h>
22 #include <linux/major.h>
23 #include <linux/blkdev.h>
25 #include <linux/stat.h>
26 #include <linux/locks.h>
27 #include <linux/fat_cvf.h>
28 #include <linux/malloc.h>
32 #include <asm/uaccess.h>
33 #include <asm/unaligned.h>
35 /* #define FAT_PARANOIA 1 */
38 # define PRINTK(x) printk x
42 #if (DEBUG_LEVEL >= 1)
43 # define PRINTK1(x) printk x
48 void fat_put_inode(struct inode
*inode
)
51 * Check whether we're a dependent of other inodes ...
53 if (inode
->i_count
<= 1) {
55 printk("fat_put_inode: last use for (%p,%ld), i_count=%d\n",
56 inode
, inode
->i_ino
, inode
->i_count
);
59 if (MSDOS_I(inode
)->i_busy
)
60 fat_cache_inval_inode(inode
);
65 void fat_delete_inode(struct inode
*inode
)
68 * Make sure there are no active dependencies ...
70 fat_cache_inval_inode(inode
);
77 void fat_put_super(struct super_block
*sb
)
79 if (MSDOS_SB(sb
)->cvf_format
) {
80 dec_cvf_format_use_count_by_version(MSDOS_SB(sb
)->cvf_format
->cvf_version
);
81 MSDOS_SB(sb
)->cvf_format
->unmount_cvf(sb
);
83 if (MSDOS_SB(sb
)->fat_bits
== 32) {
84 fat_clusters_flush(sb
);
86 fat_cache_inval_dev(sb
->s_dev
);
87 set_blocksize (sb
->s_dev
,BLOCK_SIZE
);
88 if (MSDOS_SB(sb
)->nls_disk
) {
89 unload_nls(MSDOS_SB(sb
)->nls_disk
);
90 MSDOS_SB(sb
)->nls_disk
= NULL
;
91 MSDOS_SB(sb
)->options
.codepage
= 0;
93 if (MSDOS_SB(sb
)->nls_io
) {
94 unload_nls(MSDOS_SB(sb
)->nls_io
);
95 MSDOS_SB(sb
)->nls_io
= NULL
;
98 * Note: the iocharset option might have been specified
99 * without enabling nls_io, so check for it here.
101 if (MSDOS_SB(sb
)->options
.iocharset
) {
102 kfree(MSDOS_SB(sb
)->options
.iocharset
);
103 MSDOS_SB(sb
)->options
.iocharset
= NULL
;
111 static int parse_options(char *options
,int *fat
, int *blksize
, int *debug
,
112 struct fat_mount_options
*opts
,
113 char *cvf_format
, char *cvf_options
)
115 char *this_char
,*value
,save
,*savep
;
119 opts
->name_check
= 'n';
120 opts
->conversion
= 'b';
121 opts
->fs_uid
= current
->uid
;
122 opts
->fs_gid
= current
->gid
;
123 opts
->fs_umask
= current
->fs
->umask
;
124 opts
->quiet
= opts
->sys_immutable
= opts
->dotsOK
= opts
->showexec
= 0;
127 opts
->iocharset
= NULL
;
134 for (this_char
= strtok(options
,","); this_char
;
135 this_char
= strtok(NULL
,",")) {
136 if ((value
= strchr(this_char
,'=')) != NULL
) {
141 if (!strcmp(this_char
,"check") && value
) {
142 if (value
[0] && !value
[1] && strchr("rns",*value
))
143 opts
->name_check
= *value
;
144 else if (!strcmp(value
,"relaxed"))
145 opts
->name_check
= 'r';
146 else if (!strcmp(value
,"normal"))
147 opts
->name_check
= 'n';
148 else if (!strcmp(value
,"strict"))
149 opts
->name_check
= 's';
152 else if (!strcmp(this_char
,"conv") && value
) {
153 if (value
[0] && !value
[1] && strchr("bta",*value
))
154 opts
->conversion
= *value
;
155 else if (!strcmp(value
,"binary"))
156 opts
->conversion
= 'b';
157 else if (!strcmp(value
,"text"))
158 opts
->conversion
= 't';
159 else if (!strcmp(value
,"auto"))
160 opts
->conversion
= 'a';
163 else if (!strcmp(this_char
,"dots")) {
166 else if (!strcmp(this_char
,"nodots")) {
169 else if (!strcmp(this_char
,"showexec")) {
172 else if (!strcmp(this_char
,"dotsOK") && value
) {
173 if (!strcmp(value
,"yes")) opts
->dotsOK
= 1;
174 else if (!strcmp(value
,"no")) opts
->dotsOK
= 0;
177 else if (!strcmp(this_char
,"uid")) {
178 if (!value
|| !*value
) ret
= 0;
180 opts
->fs_uid
= simple_strtoul(value
,&value
,0);
184 else if (!strcmp(this_char
,"gid")) {
185 if (!value
|| !*value
) ret
= 0;
187 opts
->fs_gid
= simple_strtoul(value
,&value
,0);
191 else if (!strcmp(this_char
,"umask")) {
192 if (!value
|| !*value
) ret
= 0;
194 opts
->fs_umask
= simple_strtoul(value
,&value
,8);
198 else if (!strcmp(this_char
,"debug")) {
202 else if (!strcmp(this_char
,"fat")) {
203 if (!value
|| !*value
) ret
= 0;
205 *fat
= simple_strtoul(value
,&value
,0);
206 if (*value
|| (*fat
!= 12 && *fat
!= 16 &&
211 else if (!strcmp(this_char
,"quiet")) {
213 else opts
->quiet
= 1;
215 else if (!strcmp(this_char
,"blocksize")) {
217 else if (*blksize
!= 512 &&
220 printk ("MSDOS FS: Invalid blocksize "
221 "(512, 1024, or 2048)\n");
224 else if (!strcmp(this_char
,"sys_immutable")) {
226 else opts
->sys_immutable
= 1;
228 else if (!strcmp(this_char
,"codepage") && value
) {
229 opts
->codepage
= simple_strtoul(value
,&value
,0);
231 else printk ("MSDOS FS: Using codepage %d\n",
234 else if (!strcmp(this_char
,"iocharset") && value
) {
236 while (*value
&& *value
!= ',') value
++;
239 char * buffer
= kmalloc(len
+1, GFP_KERNEL
);
241 opts
->iocharset
= buffer
;
242 memcpy(buffer
, p
, len
);
244 printk("MSDOS FS: IO charset %s\n",
250 else if (!strcmp(this_char
,"cvf_format")) {
253 strncpy(cvf_format
,value
,20);
255 else if (!strcmp(this_char
,"cvf_options")) {
258 strncpy(cvf_options
,value
,100);
261 if (this_char
!= options
) *(this_char
-1) = ',';
262 if (value
) *savep
= save
;
271 * Read the super block of an MS-DOS FS.
273 * Note that this may be called from vfat_read_super
274 * with some fields already initialized.
277 fat_read_super(struct super_block
*sb
, void *data
, int silent
)
279 struct inode
*root_inode
;
280 struct buffer_head
*bh
;
281 struct fat_boot_sector
*b
;
283 int data_sectors
,logical_sector_size
,sector_mult
,fat_clusters
=0;
284 int debug
,error
,fat
,cp
;
287 struct fat_mount_options opts
;
291 char cvf_options
[101];
293 cvf_format
[0] = '\0';
294 cvf_options
[0] = '\0';
295 MSDOS_SB(sb
)->cvf_format
= NULL
;
296 MSDOS_SB(sb
)->private_data
= NULL
;
299 if (hardsect_size
[MAJOR(sb
->s_dev
)] != NULL
){
300 blksize
= hardsect_size
[MAJOR(sb
->s_dev
)][MINOR(sb
->s_dev
)];
302 printk ("MSDOS: Hardware sector size is %d\n",blksize
);
307 opts
.isvfat
= MSDOS_SB(sb
)->options
.isvfat
;
308 if (!parse_options((char *) data
, &fat
, &blksize
, &debug
, &opts
,
309 cvf_format
, cvf_options
)
310 || (blksize
!= 512 && blksize
!= 1024 && blksize
!= 2048))
312 /* N.B. we should parse directly into the sb structure */
313 memcpy(&(MSDOS_SB(sb
)->options
), &opts
, sizeof(struct fat_mount_options
));
319 /* Force the superblock to a larger size here. */
320 sb
->s_blocksize
= blksize
;
321 set_blocksize(sb
->s_dev
, blksize
);
325 /* The first read is always 1024 bytes */
326 sb
->s_blocksize
= 1024;
327 set_blocksize(sb
->s_dev
, 1024);
329 bh
= fat_bread(sb
, 0);
331 if (bh
== NULL
|| !fat_is_uptodate(sb
,bh
)) {
335 set_blocksize(sb
->s_dev
, blksize
);
338 * The DOS3 partition size limit is *not* 32M as many people think.
339 * Instead, it is 64K sectors (with the usual sector size being
340 * 512 bytes, leading to a 32M limit).
342 * DOS 3 partition managers got around this problem by faking a
343 * larger sector size, ie treating multiple physical sectors as
344 * a single logical sector.
346 * We can accommodate this scheme by adjusting our cluster size,
347 * fat_start, and data_start by an appropriate value.
352 #define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
353 /* don't divide by zero */
355 b
= (struct fat_boot_sector
*) bh
->b_data
;
356 logical_sector_size
=
357 CF_LE_W(get_unaligned((unsigned short *) &b
->sector_size
));
358 sector_mult
= logical_sector_size
>> SECTOR_BITS
;
359 MSDOS_SB(sb
)->cluster_size
= b
->cluster_size
*sector_mult
;
360 MSDOS_SB(sb
)->fats
= b
->fats
;
361 MSDOS_SB(sb
)->fat_start
= CF_LE_W(b
->reserved
)*sector_mult
;
362 if (!b
->fat_length
&& b
->fat32_length
) {
363 struct fat_boot_fsinfo
*fsinfo
;
367 MSDOS_SB(sb
)->fat_length
= CF_LE_W(b
->fat32_length
)*sector_mult
;
368 MSDOS_SB(sb
)->root_cluster
= CF_LE_L(b
->root_cluster
);
369 CF_LE_W(b
->info_sector
), logical_sector_size
);
371 /* MC - if info_sector is 0, don't multiply by 0 */
372 if(CF_LE_W(b
->info_sector
) == 0) {
373 MSDOS_SB(sb
)->fsinfo_offset
=
374 logical_sector_size
+ 0x1e0;
376 MSDOS_SB(sb
)->fsinfo_offset
=
377 (CF_LE_W(b
->info_sector
) * logical_sector_size
)
380 if (MSDOS_SB(sb
)->fsinfo_offset
+ sizeof(struct fat_boot_fsinfo
) > sb
->s_blocksize
) {
381 printk("fat_read_super: Bad fsinfo_offset\n");
385 fsinfo
= (struct fat_boot_fsinfo
*)
386 &bh
->b_data
[MSDOS_SB(sb
)->fsinfo_offset
];
387 if (CF_LE_L(fsinfo
->signature
) != 0x61417272) {
388 printk("fat_read_super: Did not find valid FSINFO "
389 "signature. Found 0x%x\n",
390 CF_LE_L(fsinfo
->signature
));
392 MSDOS_SB(sb
)->free_clusters
= CF_LE_L(fsinfo
->free_clusters
);
396 MSDOS_SB(sb
)->fat_length
= CF_LE_W(b
->fat_length
)*sector_mult
;
397 MSDOS_SB(sb
)->root_cluster
= 0;
398 MSDOS_SB(sb
)->free_clusters
= -1; /* Don't know yet */
400 MSDOS_SB(sb
)->dir_start
= CF_LE_W(b
->reserved
)*sector_mult
+
401 b
->fats
*MSDOS_SB(sb
)->fat_length
;
402 MSDOS_SB(sb
)->dir_entries
=
403 CF_LE_W(get_unaligned((unsigned short *) &b
->dir_entries
));
404 MSDOS_SB(sb
)->data_start
= MSDOS_SB(sb
)->dir_start
+ROUND_TO_MULTIPLE((
405 MSDOS_SB(sb
)->dir_entries
<< MSDOS_DIR_BITS
) >> SECTOR_BITS
,
407 data_sectors
= CF_LE_W(get_unaligned((unsigned short *) &b
->sectors
));
409 data_sectors
= CF_LE_L(b
->total_sect
);
411 data_sectors
= data_sectors
* sector_mult
- MSDOS_SB(sb
)->data_start
;
412 error
= !b
->cluster_size
|| !sector_mult
;
414 MSDOS_SB(sb
)->clusters
= b
->cluster_size
? data_sectors
/
415 b
->cluster_size
/sector_mult
: 0;
416 MSDOS_SB(sb
)->fat_bits
= fat32
? 32 :
418 (MSDOS_SB(sb
)->clusters
> MSDOS_FAT12
? 16 : 12));
419 fat_clusters
= MSDOS_SB(sb
)->fat_length
*SECTOR_SIZE
*8/
420 MSDOS_SB(sb
)->fat_bits
;
421 error
= !MSDOS_SB(sb
)->fats
|| (MSDOS_SB(sb
)->dir_entries
&
422 (MSDOS_DPS
-1)) || MSDOS_SB(sb
)->clusters
+2 > fat_clusters
+
423 MSDOS_MAX_EXTRA
|| (logical_sector_size
& (SECTOR_SIZE
-1))
424 || !b
->secs_track
|| !b
->heads
;
428 This must be done after the brelse because the bh is a dummy
429 allocated by fat_bread (see buffer.c)
431 sb
->s_blocksize
= blksize
; /* Using this small block size solves */
432 /* the misfit with buffer cache and cluster */
433 /* because clusters (DOS) are often aligned */
434 /* on odd sectors. */
435 sb
->s_blocksize_bits
= blksize
== 512 ? 9 : (blksize
== 1024 ? 10 : 11);
436 if (!strcmp(cvf_format
,"none"))
439 i
= detect_cvf(sb
,cvf_format
);
441 error
= cvf_formats
[i
]->mount_cvf(sb
,cvf_options
);
442 if (error
|| debug
) {
443 /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
444 printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
445 "uid=%d,gid=%d,umask=%03o%s]\n",
446 MSDOS_SB(sb
)->fat_bits
,opts
.name_check
,
447 opts
.conversion
,opts
.fs_uid
,opts
.fs_gid
,opts
.fs_umask
,
448 MSDOS_CAN_BMAP(MSDOS_SB(sb
)) ? ",bmap" : "");
449 printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
450 "se=%d,ts=%ld,ls=%d,rc=%ld,fc=%u]\n",
451 b
->media
,MSDOS_SB(sb
)->cluster_size
,
452 MSDOS_SB(sb
)->fats
,MSDOS_SB(sb
)->fat_start
,
453 MSDOS_SB(sb
)->fat_length
,
454 MSDOS_SB(sb
)->dir_start
,MSDOS_SB(sb
)->dir_entries
,
455 MSDOS_SB(sb
)->data_start
,
456 CF_LE_W(*(unsigned short *) &b
->sectors
),
457 (unsigned long)b
->total_sect
,logical_sector_size
,
458 MSDOS_SB(sb
)->root_cluster
,MSDOS_SB(sb
)->free_clusters
);
459 printk ("Transaction block size = %d\n",blksize
);
461 if (i
<0) if (MSDOS_SB(sb
)->clusters
+2 > fat_clusters
)
462 MSDOS_SB(sb
)->clusters
= fat_clusters
-2;
466 sb
->s_magic
= MSDOS_SUPER_MAGIC
;
467 /* set up enough so that it can read an inode */
468 MSDOS_SB(sb
)->fat_wait
= NULL
;
469 MSDOS_SB(sb
)->fat_lock
= 0;
470 MSDOS_SB(sb
)->prev_free
= 0;
472 cp
= opts
.codepage
? opts
.codepage
: 437;
473 sprintf(buf
, "cp%d", cp
);
474 MSDOS_SB(sb
)->nls_disk
= load_nls(buf
);
475 if (! MSDOS_SB(sb
)->nls_disk
) {
476 /* Fail only if explicit charset specified */
477 if (opts
.codepage
!= 0)
479 MSDOS_SB(sb
)->options
.codepage
= 0; /* already 0?? */
480 MSDOS_SB(sb
)->nls_disk
= load_nls_default();
483 MSDOS_SB(sb
)->nls_io
= NULL
;
484 if (MSDOS_SB(sb
)->options
.isvfat
&& !opts
.utf8
) {
485 p
= opts
.iocharset
? opts
.iocharset
: "iso8859-1";
486 MSDOS_SB(sb
)->nls_io
= load_nls(p
);
487 if (! MSDOS_SB(sb
)->nls_io
) {
488 /* Fail only if explicit charset specified */
491 MSDOS_SB(sb
)->nls_io
= load_nls_default();
495 root_inode
= iget(sb
, MSDOS_ROOT_INO
);
498 sb
->s_root
= d_alloc_root(root_inode
, NULL
);
502 MSDOS_SB(sb
)->cvf_format
= cvf_formats
[i
];
503 ++cvf_format_use_count
[i
];
508 printk("get root inode failed\n");
510 if (MSDOS_SB(sb
)->nls_io
)
511 unload_nls(MSDOS_SB(sb
)->nls_io
);
513 unload_nls(MSDOS_SB(sb
)->nls_disk
);
517 printk("VFS: Can't find a valid MSDOS filesystem on dev %s.\n",
518 kdevname(sb
->s_dev
));
521 printk("FAT bread failed\n");
523 if (opts
.iocharset
) {
524 printk("VFS: freeing iocharset=%s\n", opts
.iocharset
);
525 kfree(opts
.iocharset
);
528 if(MSDOS_SB(sb
)->private_data
)kfree(MSDOS_SB(sb
)->private_data
);
529 MSDOS_SB(sb
)->private_data
=NULL
;
535 int fat_statfs(struct super_block
*sb
,struct statfs
*buf
, int bufsiz
)
540 if (MSDOS_SB(sb
)->cvf_format
&&
541 MSDOS_SB(sb
)->cvf_format
->cvf_statfs
)
542 return MSDOS_SB(sb
)->cvf_format
->cvf_statfs(sb
,buf
,bufsiz
);
545 if (MSDOS_SB(sb
)->free_clusters
!= -1)
546 free
= MSDOS_SB(sb
)->free_clusters
;
549 for (nr
= 2; nr
< MSDOS_SB(sb
)->clusters
+2; nr
++)
550 if (!fat_access(sb
,nr
,-1)) free
++;
551 MSDOS_SB(sb
)->free_clusters
= free
;
554 tmp
.f_type
= sb
->s_magic
;
555 tmp
.f_bsize
= MSDOS_SB(sb
)->cluster_size
*SECTOR_SIZE
;
556 tmp
.f_blocks
= MSDOS_SB(sb
)->clusters
;
561 tmp
.f_namelen
= MSDOS_SB(sb
)->options
.isvfat
? 260 : 12;
562 return copy_to_user(buf
, &tmp
, bufsiz
) ? -EFAULT
: 0;
566 int fat_bmap(struct inode
*inode
,int block
)
568 struct msdos_sb_info
*sb
;
571 sb
= MSDOS_SB(inode
->i_sb
);
572 if (sb
->cvf_format
&&
573 sb
->cvf_format
->cvf_bmap
)
574 return sb
->cvf_format
->cvf_bmap(inode
,block
);
575 if ((inode
->i_ino
== MSDOS_ROOT_INO
) && (sb
->fat_bits
!= 32)) {
576 return sb
->dir_start
+ block
;
578 cluster
= block
/sb
->cluster_size
;
579 offset
= block
% sb
->cluster_size
;
580 if (!(cluster
= fat_get_cluster(inode
,cluster
))) return 0;
581 return (cluster
-2)*sb
->cluster_size
+sb
->data_start
+offset
;
584 static int is_exec(char *extension
)
586 char *exe_extensions
= "EXECOMBAT", *walk
;
588 for (walk
= exe_extensions
; *walk
; walk
+= 3)
589 if (!strncmp(extension
, walk
, 3))
594 void fat_read_inode(struct inode
*inode
, struct inode_operations
*fs_dir_inode_ops
)
596 struct super_block
*sb
= inode
->i_sb
;
597 struct buffer_head
*bh
;
598 struct msdos_dir_entry
*raw_entry
;
601 PRINTK1(("fat_read_inode: inode=%p, ino=%ld, sb->dir_start=0x%x\n",
602 inode
, inode
->i_ino
, MSDOS_SB(sb
)->dir_start
));
603 MSDOS_I(inode
)->i_busy
= 0;
604 MSDOS_I(inode
)->i_binary
= 1;
605 inode
->i_uid
= MSDOS_SB(sb
)->options
.fs_uid
;
606 inode
->i_gid
= MSDOS_SB(sb
)->options
.fs_gid
;
607 inode
->i_version
= ++event
;
608 if (inode
->i_ino
== MSDOS_ROOT_INO
) {
609 inode
->i_mode
= (S_IRWXUGO
& ~MSDOS_SB(sb
)->options
.fs_umask
) |
611 inode
->i_op
= fs_dir_inode_ops
;
612 if (MSDOS_SB(sb
)->fat_bits
== 32) {
613 MSDOS_I(inode
)->i_start
= MSDOS_SB(sb
)->root_cluster
;
614 if ((nr
= MSDOS_I(inode
)->i_start
) != 0) {
616 inode
->i_size
+= SECTOR_SIZE
*MSDOS_SB(sb
)->cluster_size
;
617 if (!(nr
= fat_access(sb
,nr
,-1))) {
618 printk("Directory %ld: bad FAT\n",
625 MSDOS_I(inode
)->i_start
= 0;
626 inode
->i_size
= MSDOS_SB(sb
)->dir_entries
*
627 sizeof(struct msdos_dir_entry
);
629 inode
->i_blksize
= MSDOS_SB(sb
)->cluster_size
*
631 inode
->i_blocks
= (inode
->i_size
+inode
->i_blksize
-1)/
632 inode
->i_blksize
*MSDOS_SB(sb
)->cluster_size
;
633 MSDOS_I(inode
)->i_logstart
= 0;
635 MSDOS_I(inode
)->i_attrs
= 0;
636 inode
->i_mtime
= inode
->i_atime
= inode
->i_ctime
= 0;
637 MSDOS_I(inode
)->i_ctime_ms
= 0;
638 inode
->i_nlink
= fat_subdirs(inode
)+2;
639 /* subdirs (neither . nor ..) plus . and "self" */
642 if (!(bh
= fat_bread(sb
, inode
->i_ino
>> MSDOS_DPB_BITS
))) {
643 printk("dev = %s, ino = %ld\n",
644 kdevname(inode
->i_dev
), inode
->i_ino
);
645 fat_fs_panic(sb
, "fat_read_inode: unable to read i-node block");
648 raw_entry
= &((struct msdos_dir_entry
*) (bh
->b_data
))
649 [inode
->i_ino
& (MSDOS_DPB
-1)];
650 if ((raw_entry
->attr
& ATTR_DIR
) && !IS_FREE(raw_entry
->name
)) {
651 inode
->i_mode
= MSDOS_MKMODE(raw_entry
->attr
,S_IRWXUGO
&
652 ~MSDOS_SB(sb
)->options
.fs_umask
) | S_IFDIR
;
653 inode
->i_op
= fs_dir_inode_ops
;
655 MSDOS_I(inode
)->i_start
= CF_LE_W(raw_entry
->start
);
656 if (MSDOS_SB(sb
)->fat_bits
== 32) {
657 MSDOS_I(inode
)->i_start
|=
658 (CF_LE_W(raw_entry
->starthi
) << 16);
660 MSDOS_I(inode
)->i_logstart
= MSDOS_I(inode
)->i_start
;
661 inode
->i_nlink
= fat_subdirs(inode
);
662 /* includes .., compensating for "self" */
664 if (!inode
->i_nlink
) {
665 printk("directory %d: i_nlink == 0\n",inode
->i_ino
);
670 if ((nr
= MSDOS_I(inode
)->i_start
) != 0)
672 inode
->i_size
+= SECTOR_SIZE
*MSDOS_SB(inode
->
674 if (!(nr
= fat_access(sb
,nr
,-1))) {
675 printk("Directory %ld: bad FAT\n",
680 } else { /* not a directory */
681 inode
->i_mode
= MSDOS_MKMODE(raw_entry
->attr
,
682 ((IS_NOEXEC(inode
) ||
683 (MSDOS_SB(sb
)->options
.showexec
&&
684 !is_exec(raw_entry
->ext
)))
685 ? S_IRUGO
|S_IWUGO
: S_IRWXUGO
)
686 & ~MSDOS_SB(sb
)->options
.fs_umask
) | S_IFREG
;
687 if (MSDOS_SB(sb
)->cvf_format
)
688 inode
->i_op
= (MSDOS_SB(sb
)->cvf_format
->flags
& CVF_USE_READPAGE
)
689 ? &fat_file_inode_operations_readpage
690 : &fat_file_inode_operations_1024
;
692 inode
->i_op
= (sb
->s_blocksize
== 1024 || sb
->s_blocksize
== 2048)
693 ? &fat_file_inode_operations_1024
694 : &fat_file_inode_operations
;
695 MSDOS_I(inode
)->i_start
= CF_LE_W(raw_entry
->start
);
696 if (MSDOS_SB(sb
)->fat_bits
== 32) {
697 MSDOS_I(inode
)->i_start
|=
698 (CF_LE_W(raw_entry
->starthi
) << 16);
700 MSDOS_I(inode
)->i_logstart
= MSDOS_I(inode
)->i_start
;
702 inode
->i_size
= CF_LE_L(raw_entry
->size
);
704 if(raw_entry
->attr
& ATTR_SYS
)
705 if (MSDOS_SB(sb
)->options
.sys_immutable
)
706 inode
->i_flags
|= S_IMMUTABLE
;
707 MSDOS_I(inode
)->i_binary
= is_binary(MSDOS_SB(sb
)->options
.conversion
,
709 MSDOS_I(inode
)->i_attrs
= raw_entry
->attr
& ATTR_UNUSED
;
710 /* this is as close to the truth as we can get ... */
711 inode
->i_blksize
= MSDOS_SB(sb
)->cluster_size
*SECTOR_SIZE
;
712 inode
->i_blocks
= (inode
->i_size
+inode
->i_blksize
-1)/
713 inode
->i_blksize
*MSDOS_SB(sb
)->cluster_size
;
714 inode
->i_mtime
= inode
->i_atime
=
715 date_dos2unix(CF_LE_W(raw_entry
->time
),CF_LE_W(raw_entry
->date
));
717 MSDOS_SB(sb
)->options
.isvfat
718 ? date_dos2unix(CF_LE_W(raw_entry
->ctime
),CF_LE_W(raw_entry
->cdate
))
720 MSDOS_I(inode
)->i_ctime_ms
= raw_entry
->ctime_ms
;
725 void fat_write_inode(struct inode
*inode
)
727 struct super_block
*sb
= inode
->i_sb
;
728 struct buffer_head
*bh
;
729 struct msdos_dir_entry
*raw_entry
;
731 if (inode
->i_ino
== MSDOS_ROOT_INO
|| !inode
->i_nlink
) return;
732 if (!(bh
= fat_bread(sb
, inode
->i_ino
>> MSDOS_DPB_BITS
))) {
733 printk("dev = %s, ino = %ld\n",
734 kdevname(inode
->i_dev
), inode
->i_ino
);
735 fat_fs_panic(sb
, "msdos_write_inode: unable to read i-node block");
738 raw_entry
= &((struct msdos_dir_entry
*) (bh
->b_data
))
739 [inode
->i_ino
& (MSDOS_DPB
-1)];
740 if (S_ISDIR(inode
->i_mode
)) {
741 raw_entry
->attr
= ATTR_DIR
;
745 raw_entry
->attr
= ATTR_NONE
;
746 raw_entry
->size
= CT_LE_L(inode
->i_size
);
748 raw_entry
->attr
|= MSDOS_MKATTR(inode
->i_mode
) |
749 MSDOS_I(inode
)->i_attrs
;
750 raw_entry
->start
= CT_LE_W(MSDOS_I(inode
)->i_logstart
);
751 raw_entry
->starthi
= CT_LE_W(MSDOS_I(inode
)->i_logstart
>> 16);
752 fat_date_unix2dos(inode
->i_mtime
,&raw_entry
->time
,&raw_entry
->date
);
753 raw_entry
->time
= CT_LE_W(raw_entry
->time
);
754 raw_entry
->date
= CT_LE_W(raw_entry
->date
);
755 if (MSDOS_SB(sb
)->options
.isvfat
) {
756 fat_date_unix2dos(inode
->i_ctime
,&raw_entry
->ctime
,&raw_entry
->cdate
);
757 raw_entry
->ctime_ms
= MSDOS_I(inode
)->i_ctime_ms
;
758 raw_entry
->ctime
= CT_LE_W(raw_entry
->ctime
);
759 raw_entry
->cdate
= CT_LE_W(raw_entry
->cdate
);
761 fat_mark_buffer_dirty(sb
, bh
, 1);
766 int fat_notify_change(struct dentry
* dentry
, struct iattr
* attr
)
768 struct super_block
*sb
= dentry
->d_sb
;
769 struct inode
*inode
= dentry
->d_inode
;
772 error
= inode_change_ok(inode
, attr
);
774 return MSDOS_SB(sb
)->options
.quiet
? 0 : error
;
776 if (((attr
->ia_valid
& ATTR_UID
) &&
777 (attr
->ia_uid
!= MSDOS_SB(sb
)->options
.fs_uid
)) ||
778 ((attr
->ia_valid
& ATTR_GID
) &&
779 (attr
->ia_gid
!= MSDOS_SB(sb
)->options
.fs_gid
)) ||
780 ((attr
->ia_valid
& ATTR_MODE
) &&
781 (attr
->ia_mode
& ~MSDOS_VALID_MODE
)))
785 return MSDOS_SB(sb
)->options
.quiet
? 0 : error
;
787 inode_setattr(inode
, attr
);
789 if (IS_NOEXEC(inode
) && !S_ISDIR(inode
->i_mode
))
790 inode
->i_mode
&= S_IFMT
| S_IRUGO
| S_IWUGO
;
792 inode
->i_mode
|= S_IXUGO
;
794 inode
->i_mode
= ((inode
->i_mode
& S_IFMT
) | ((((inode
->i_mode
& S_IRWXU
795 & ~MSDOS_SB(sb
)->options
.fs_umask
) | S_IRUSR
) >> 6)*S_IXUGO
)) &
796 ~MSDOS_SB(sb
)->options
.fs_umask
;
802 int init_module(void)
804 return init_fat_fs();
808 void cleanup_module(void)
810 /* Nothing to be done, really! */