- pre5:
[davej-history.git] / fs / fat / inode.c
blobd1e8557f7aa710f2cc5084522798946bda1684b2
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/config.h>
14 #include <linux/version.h>
15 #define __NO_VERSION__
16 #include <linux/module.h>
18 #include <linux/msdos_fs.h>
19 #include <linux/nls.h>
20 #include <linux/kernel.h>
21 #include <linux/sched.h>
22 #include <linux/errno.h>
23 #include <linux/string.h>
24 #include <linux/major.h>
25 #include <linux/blkdev.h>
26 #include <linux/fs.h>
27 #include <linux/stat.h>
28 #include <linux/locks.h>
29 #include <linux/fat_cvf.h>
30 #include <linux/malloc.h>
31 #include <linux/smp_lock.h>
33 #include "msbuffer.h"
35 #include <asm/uaccess.h>
36 #include <asm/unaligned.h>
38 extern struct cvf_format default_cvf, bigblock_cvf;
40 /* #define FAT_PARANOIA 1 */
41 #define DEBUG_LEVEL 0
42 #ifdef FAT_DEBUG
43 # define PRINTK(x) printk x
44 #else
45 # define PRINTK(x)
46 #endif
47 #if (DEBUG_LEVEL >= 1)
48 # define PRINTK1(x) printk x
49 #else
50 # define PRINTK1(x)
51 #endif
54 * New FAT inode stuff. We do the following:
55 * a) i_ino is constant and has nothing with on-disk location.
56 * b) FAT manages its own cache of directory entries.
57 * c) *This* cache is indexed by on-disk location.
58 * d) inode has an associated directory entry, all right, but
59 * it may be unhashed.
60 * e) currently entries are stored within struct inode. That should
61 * change.
62 * f) we deal with races in the following way:
63 * 1. readdir() and lookup() do FAT-dir-cache lookup.
64 * 2. rename() unhashes the F-d-c entry and rehashes it in
65 * a new place.
66 * 3. unlink() and rmdir() unhash F-d-c entry.
67 * 4. fat_write_inode() checks whether the thing is unhashed.
68 * If it is we silently return. If it isn't we do bread(),
69 * check if the location is still valid and retry if it
70 * isn't. Otherwise we do changes.
71 * 5. Spinlock is used to protect hash/unhash/location check/lookup
72 * 6. fat_clear_inode() unhashes the F-d-c entry.
73 * 7. lookup() and readdir() do igrab() if they find a F-d-c entry
74 * and consider negative result as cache miss.
77 #define FAT_HASH_BITS 8
78 #define FAT_HASH_SIZE (1UL << FAT_HASH_BITS)
79 #define FAT_HASH_MASK (FAT_HASH_SIZE-1)
80 static struct list_head fat_inode_hashtable[FAT_HASH_SIZE];
81 spinlock_t fat_inode_lock = SPIN_LOCK_UNLOCKED;
83 void fat_hash_init(void) {
84 int i;
85 for(i=0;i<FAT_HASH_SIZE;i++) {
86 INIT_LIST_HEAD(&fat_inode_hashtable[i]);
90 static inline unsigned long fat_hash(struct super_block *sb, int i_pos)
92 unsigned long tmp = (unsigned long)i_pos | (unsigned long) sb;
93 tmp = tmp + (tmp >> FAT_HASH_BITS) + (tmp >> FAT_HASH_BITS*2);
94 return tmp & FAT_HASH_MASK;
97 void fat_attach(struct inode *inode, int i_pos) {
98 spin_lock(&fat_inode_lock);
99 MSDOS_I(inode)->i_location = i_pos;
100 list_add(&MSDOS_I(inode)->i_fat_hash,
101 fat_inode_hashtable+fat_hash(inode->i_sb, i_pos));
102 spin_unlock(&fat_inode_lock);
105 void fat_detach(struct inode *inode) {
106 spin_lock(&fat_inode_lock);
107 MSDOS_I(inode)->i_location = 0;
108 list_del(&MSDOS_I(inode)->i_fat_hash);
109 INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
110 spin_unlock(&fat_inode_lock);
113 struct inode *fat_iget(struct super_block *sb, int i_pos) {
114 struct list_head *p = fat_inode_hashtable + fat_hash(sb, i_pos);
115 struct list_head *walk;
116 struct msdos_inode_info *i;
117 struct inode *inode = NULL;
118 spin_lock(&fat_inode_lock);
119 for(walk=p->next;walk!=p;walk=walk->next) {
120 i = list_entry(walk, struct msdos_inode_info, i_fat_hash);
121 if (i->i_fat_inode->i_sb != sb)
122 continue;
123 if (i->i_location != i_pos)
124 continue;
125 inode = igrab(i->i_fat_inode);
127 spin_unlock(&fat_inode_lock);
128 return inode;
131 static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de);
133 struct inode *fat_build_inode(struct super_block *sb,
134 struct msdos_dir_entry *de, int ino, int *res)
136 struct inode *inode;
137 *res = 0;
138 inode = fat_iget(sb, ino);
139 if (inode)
140 goto out;
141 inode = get_empty_inode();
142 *res = -ENOMEM;
143 if (!inode)
144 goto out;
145 *res = 0;
146 inode->i_sb = sb;
147 inode->i_dev = sb->s_dev;
148 inode->i_ino = iunique(sb, MSDOS_ROOT_INO);
149 fat_fill_inode(inode, de);
150 fat_attach(inode, ino);
151 insert_inode_hash(inode);
152 out:
153 return inode;
156 void fat_delete_inode(struct inode *inode)
158 lock_kernel();
159 inode->i_size = 0;
160 fat_truncate(inode);
161 unlock_kernel();
162 clear_inode(inode);
165 void fat_clear_inode(struct inode *inode)
167 lock_kernel();
168 spin_lock(&fat_inode_lock);
169 fat_cache_inval_inode(inode);
170 list_del(&MSDOS_I(inode)->i_fat_hash);
171 spin_unlock(&fat_inode_lock);
172 unlock_kernel();
175 void fat_put_super(struct super_block *sb)
177 if (MSDOS_SB(sb)->cvf_format->cvf_version) {
178 dec_cvf_format_use_count_by_version(MSDOS_SB(sb)->cvf_format->cvf_version);
179 MSDOS_SB(sb)->cvf_format->unmount_cvf(sb);
181 if (MSDOS_SB(sb)->fat_bits == 32) {
182 fat_clusters_flush(sb);
184 fat_cache_inval_dev(sb->s_dev);
185 set_blocksize (sb->s_dev,BLOCK_SIZE);
186 if (MSDOS_SB(sb)->nls_disk) {
187 unload_nls(MSDOS_SB(sb)->nls_disk);
188 MSDOS_SB(sb)->nls_disk = NULL;
189 MSDOS_SB(sb)->options.codepage = 0;
191 if (MSDOS_SB(sb)->nls_io) {
192 unload_nls(MSDOS_SB(sb)->nls_io);
193 MSDOS_SB(sb)->nls_io = NULL;
196 * Note: the iocharset option might have been specified
197 * without enabling nls_io, so check for it here.
199 if (MSDOS_SB(sb)->options.iocharset) {
200 kfree(MSDOS_SB(sb)->options.iocharset);
201 MSDOS_SB(sb)->options.iocharset = NULL;
206 static int parse_options(char *options,int *fat, int *blksize, int *debug,
207 struct fat_mount_options *opts,
208 char *cvf_format, char *cvf_options)
210 char *this_char,*value,save,*savep;
211 char *p;
212 int ret = 1, len;
214 opts->name_check = 'n';
215 opts->conversion = 'b';
216 opts->fs_uid = current->uid;
217 opts->fs_gid = current->gid;
218 opts->fs_umask = current->fs->umask;
219 opts->quiet = opts->sys_immutable = opts->dotsOK = opts->showexec = 0;
220 opts->codepage = 0;
221 opts->nocase = 0;
222 opts->utf8 = 0;
223 opts->iocharset = NULL;
224 *debug = *fat = 0;
226 if (!options)
227 goto out;
228 save = 0;
229 savep = NULL;
230 for (this_char = strtok(options,","); this_char;
231 this_char = strtok(NULL,",")) {
232 if ((value = strchr(this_char,'=')) != NULL) {
233 save = *value;
234 savep = value;
235 *value++ = 0;
237 if (!strcmp(this_char,"check") && value) {
238 if (value[0] && !value[1] && strchr("rns",*value))
239 opts->name_check = *value;
240 else if (!strcmp(value,"relaxed"))
241 opts->name_check = 'r';
242 else if (!strcmp(value,"normal"))
243 opts->name_check = 'n';
244 else if (!strcmp(value,"strict"))
245 opts->name_check = 's';
246 else ret = 0;
248 else if (!strcmp(this_char,"conv") && value) {
249 if (value[0] && !value[1] && strchr("bta",*value))
250 opts->conversion = *value;
251 else if (!strcmp(value,"binary"))
252 opts->conversion = 'b';
253 else if (!strcmp(value,"text"))
254 opts->conversion = 't';
255 else if (!strcmp(value,"auto"))
256 opts->conversion = 'a';
257 else ret = 0;
259 else if (!strcmp(this_char,"dots")) {
260 opts->dotsOK = 1;
262 else if (!strcmp(this_char,"nocase")) {
263 opts->nocase = 1;
265 else if (!strcmp(this_char,"nodots")) {
266 opts->dotsOK = 0;
268 else if (!strcmp(this_char,"showexec")) {
269 opts->showexec = 1;
271 else if (!strcmp(this_char,"dotsOK") && value) {
272 if (!strcmp(value,"yes")) opts->dotsOK = 1;
273 else if (!strcmp(value,"no")) opts->dotsOK = 0;
274 else ret = 0;
276 else if (!strcmp(this_char,"uid")) {
277 if (!value || !*value) ret = 0;
278 else {
279 opts->fs_uid = simple_strtoul(value,&value,0);
280 if (*value) ret = 0;
283 else if (!strcmp(this_char,"gid")) {
284 if (!value || !*value) ret= 0;
285 else {
286 opts->fs_gid = simple_strtoul(value,&value,0);
287 if (*value) ret = 0;
290 else if (!strcmp(this_char,"umask")) {
291 if (!value || !*value) ret = 0;
292 else {
293 opts->fs_umask = simple_strtoul(value,&value,8);
294 if (*value) ret = 0;
297 else if (!strcmp(this_char,"debug")) {
298 if (value) ret = 0;
299 else *debug = 1;
301 else if (!strcmp(this_char,"fat")) {
302 if (!value || !*value) ret = 0;
303 else {
304 *fat = simple_strtoul(value,&value,0);
305 if (*value || (*fat != 12 && *fat != 16 &&
306 *fat != 32))
307 ret = 0;
310 else if (!strcmp(this_char,"quiet")) {
311 if (value) ret = 0;
312 else opts->quiet = 1;
314 else if (!strcmp(this_char,"blocksize")) {
315 if (!value || !*value) ret = 0;
316 else {
317 *blksize = simple_strtoul(value,&value,0);
318 if (*value || (*blksize != 512 &&
319 *blksize != 1024 && *blksize != 2048))
320 ret = 0;
323 else if (!strcmp(this_char,"sys_immutable")) {
324 if (value) ret = 0;
325 else opts->sys_immutable = 1;
327 else if (!strcmp(this_char,"codepage") && value) {
328 opts->codepage = simple_strtoul(value,&value,0);
329 if (*value) ret = 0;
330 else printk ("MSDOS FS: Using codepage %d\n",
331 opts->codepage);
333 else if (!strcmp(this_char,"iocharset") && value) {
334 p = value;
335 while (*value && *value != ',') value++;
336 len = value - p;
337 if (len) {
338 char * buffer = kmalloc(len+1, GFP_KERNEL);
339 if (buffer) {
340 opts->iocharset = buffer;
341 memcpy(buffer, p, len);
342 buffer[len] = 0;
343 printk("MSDOS FS: IO charset %s\n",
344 buffer);
345 } else
346 ret = 0;
349 else if (!strcmp(this_char,"cvf_format")) {
350 if (!value)
351 return 0;
352 strncpy(cvf_format,value,20);
354 else if (!strcmp(this_char,"cvf_options")) {
355 if (!value)
356 return 0;
357 strncpy(cvf_options,value,100);
360 if (this_char != options) *(this_char-1) = ',';
361 if (value) *savep = save;
362 if (ret == 0)
363 break;
365 out:
366 return ret;
369 static void fat_read_root(struct inode *inode)
371 struct super_block *sb = inode->i_sb;
372 struct msdos_sb_info *sbi = MSDOS_SB(sb);
373 int nr;
375 INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
376 MSDOS_I(inode)->i_location = 0;
377 MSDOS_I(inode)->i_fat_inode = inode;
378 inode->i_uid = sbi->options.fs_uid;
379 inode->i_gid = sbi->options.fs_gid;
380 inode->i_version = ++event;
381 inode->i_mode = (S_IRWXUGO & ~sbi->options.fs_umask) | S_IFDIR;
382 inode->i_op = sbi->dir_ops;
383 inode->i_fop = &fat_dir_operations;
384 if (sbi->fat_bits == 32) {
385 MSDOS_I(inode)->i_start = sbi->root_cluster;
386 if ((nr = MSDOS_I(inode)->i_start) != 0) {
387 while (nr != -1) {
388 inode->i_size += SECTOR_SIZE*sbi->cluster_size;
389 if (!(nr = fat_access(sb,nr,-1))) {
390 printk("Directory %ld: bad FAT\n",
391 inode->i_ino);
392 break;
396 } else {
397 MSDOS_I(inode)->i_start = 0;
398 inode->i_size = sbi->dir_entries*
399 sizeof(struct msdos_dir_entry);
401 inode->i_blksize = sbi->cluster_size* SECTOR_SIZE;
402 inode->i_blocks =
403 ((inode->i_size+inode->i_blksize-1)>>sbi->cluster_bits) *
404 sbi->cluster_size;
405 MSDOS_I(inode)->i_logstart = 0;
406 MSDOS_I(inode)->mmu_private = inode->i_size;
408 MSDOS_I(inode)->i_attrs = 0;
409 inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
410 MSDOS_I(inode)->i_ctime_ms = 0;
411 inode->i_nlink = fat_subdirs(inode)+2;
414 static struct super_operations fat_sops = {
415 write_inode: fat_write_inode,
416 delete_inode: fat_delete_inode,
417 put_super: fat_put_super,
418 statfs: fat_statfs,
419 clear_inode: fat_clear_inode,
423 * Read the super block of an MS-DOS FS.
425 * Note that this may be called from vfat_read_super
426 * with some fields already initialized.
428 struct super_block *
429 fat_read_super(struct super_block *sb, void *data, int silent,
430 struct inode_operations *fs_dir_inode_ops)
432 struct inode *root_inode;
433 struct buffer_head *bh;
434 struct fat_boot_sector *b;
435 struct msdos_sb_info *sbi = MSDOS_SB(sb);
436 char *p;
437 int data_sectors,logical_sector_size,sector_mult,fat_clusters=0;
438 int debug,error,fat,cp;
439 int blksize = 512;
440 int fat32;
441 struct fat_mount_options opts;
442 char buf[50];
443 int i;
444 char cvf_format[21];
445 char cvf_options[101];
447 cvf_format[0] = '\0';
448 cvf_options[0] = '\0';
449 sbi->cvf_format = NULL;
450 sbi->private_data = NULL;
452 sbi->dir_ops = fs_dir_inode_ops;
453 sb->s_op = &fat_sops;
454 if (hardsect_size[MAJOR(sb->s_dev)] != NULL){
455 blksize = hardsect_size[MAJOR(sb->s_dev)][MINOR(sb->s_dev)];
456 if (blksize != 512){
457 printk ("MSDOS: Hardware sector size is %d\n",blksize);
462 opts.isvfat = sbi->options.isvfat;
463 if (!parse_options((char *) data, &fat, &blksize, &debug, &opts,
464 cvf_format, cvf_options)
465 || (blksize != 512 && blksize != 1024 && blksize != 2048))
466 goto out_fail;
467 /* N.B. we should parse directly into the sb structure */
468 memcpy(&(sbi->options), &opts, sizeof(struct fat_mount_options));
470 fat_cache_init();
471 if( blksize > 1024 )
473 /* Force the superblock to a larger size here. */
474 sb->s_blocksize = blksize;
475 set_blocksize(sb->s_dev, blksize);
477 else
479 /* The first read is always 1024 bytes */
480 sb->s_blocksize = 1024;
481 set_blocksize(sb->s_dev, 1024);
483 bh = bread(sb->s_dev, 0, sb->s_blocksize);
484 if (bh == NULL || !buffer_uptodate(bh)) {
485 brelse (bh);
486 goto out_no_bread;
490 * The DOS3 partition size limit is *not* 32M as many people think.
491 * Instead, it is 64K sectors (with the usual sector size being
492 * 512 bytes, leading to a 32M limit).
494 * DOS 3 partition managers got around this problem by faking a
495 * larger sector size, ie treating multiple physical sectors as
496 * a single logical sector.
498 * We can accommodate this scheme by adjusting our cluster size,
499 * fat_start, and data_start by an appropriate value.
501 * (by Drew Eckhardt)
504 #define ROUND_TO_MULTIPLE(n,m) ((n) && (m) ? (n)+(m)-1-((n)-1)%(m) : 0)
505 /* don't divide by zero */
507 b = (struct fat_boot_sector *) bh->b_data;
508 logical_sector_size =
509 CF_LE_W(get_unaligned((unsigned short *) &b->sector_size));
510 sector_mult = logical_sector_size >> SECTOR_BITS;
511 sbi->cluster_size = b->cluster_size*sector_mult;
512 if (!sbi->cluster_size || (sbi->cluster_size & (sbi->cluster_size-1))) {
513 printk("fatfs: bogus cluster size\n");
514 brelse(bh);
515 goto out_invalid;
517 for (sbi->cluster_bits=0;
518 1<<sbi->cluster_bits<sbi->cluster_size;
519 sbi->cluster_bits++)
521 sbi->cluster_bits += SECTOR_BITS;
522 sbi->fats = b->fats;
523 sbi->fat_start = CF_LE_W(b->reserved)*sector_mult;
524 if (!b->fat_length && b->fat32_length) {
525 struct fat_boot_fsinfo *fsinfo;
527 /* Must be FAT32 */
528 fat32 = 1;
529 sbi->fat_length= CF_LE_L(b->fat32_length)*sector_mult;
530 sbi->root_cluster = CF_LE_L(b->root_cluster);
532 /* MC - if info_sector is 0, don't multiply by 0 */
533 if(CF_LE_W(b->info_sector) == 0) {
534 sbi->fsinfo_offset =
535 logical_sector_size + 0x1e0;
536 } else {
537 sbi->fsinfo_offset =
538 (CF_LE_W(b->info_sector) * logical_sector_size)
539 + 0x1e0;
541 if (sbi->fsinfo_offset + sizeof(struct fat_boot_fsinfo) > sb->s_blocksize) {
542 printk("fat_read_super: Bad fsinfo_offset\n");
543 brelse(bh);
544 goto out_invalid;
546 fsinfo = (struct fat_boot_fsinfo *)
547 &bh->b_data[sbi->fsinfo_offset];
548 if (CF_LE_L(fsinfo->signature) != 0x61417272) {
549 printk("fat_read_super: Did not find valid FSINFO "
550 "signature. Found 0x%x\n",
551 CF_LE_L(fsinfo->signature));
552 } else {
553 sbi->free_clusters = CF_LE_L(fsinfo->free_clusters);
555 } else {
556 fat32 = 0;
557 sbi->fat_length = CF_LE_W(b->fat_length)*sector_mult;
558 sbi->root_cluster = 0;
559 sbi->free_clusters = -1; /* Don't know yet */
561 sbi->dir_start= CF_LE_W(b->reserved)*sector_mult+
562 b->fats*sbi->fat_length;
563 sbi->dir_entries =
564 CF_LE_W(get_unaligned((unsigned short *) &b->dir_entries));
565 sbi->data_start = sbi->dir_start+ROUND_TO_MULTIPLE((
566 sbi->dir_entries << MSDOS_DIR_BITS) >> SECTOR_BITS,
567 sector_mult);
568 data_sectors = CF_LE_W(get_unaligned((unsigned short *) &b->sectors));
569 if (!data_sectors) {
570 data_sectors = CF_LE_L(b->total_sect);
572 data_sectors = data_sectors * sector_mult - sbi->data_start;
573 error = !b->cluster_size || !sector_mult;
574 if (!error) {
575 sbi->clusters = b->cluster_size ? data_sectors/
576 b->cluster_size/sector_mult : 0;
577 sbi->fat_bits = fat32 ? 32 :
578 (fat ? fat :
579 (sbi->clusters > MSDOS_FAT12 ? 16 : 12));
580 fat_clusters = sbi->fat_length*SECTOR_SIZE*8/
581 sbi->fat_bits;
582 error = !sbi->fats || (sbi->dir_entries &
583 (MSDOS_DPS-1)) || sbi->clusters+2 > fat_clusters+
584 MSDOS_MAX_EXTRA || (logical_sector_size & (SECTOR_SIZE-1))
585 || !b->secs_track || !b->heads;
587 brelse(bh);
588 set_blocksize(sb->s_dev, blksize);
590 This must be done after the brelse because the bh is a dummy
591 allocated by fat_bread (see buffer.c)
593 sb->s_blocksize = blksize; /* Using this small block size solves */
594 /* the misfit with buffer cache and cluster */
595 /* because clusters (DOS) are often aligned */
596 /* on odd sectors. */
597 sb->s_blocksize_bits = blksize == 512 ? 9 : (blksize == 1024 ? 10 : 11);
598 if (!strcmp(cvf_format,"none"))
599 i = -1;
600 else
601 i = detect_cvf(sb,cvf_format);
602 if (i >= 0)
603 error = cvf_formats[i]->mount_cvf(sb,cvf_options);
604 else if (sb->s_blocksize == 512)
605 sbi->cvf_format = &default_cvf;
606 else
607 sbi->cvf_format = &bigblock_cvf;
608 if (error || debug) {
609 /* The MSDOS_CAN_BMAP is obsolete, but left just to remember */
610 printk("[MS-DOS FS Rel. 12,FAT %d,check=%c,conv=%c,"
611 "uid=%d,gid=%d,umask=%03o%s]\n",
612 sbi->fat_bits,opts.name_check,
613 opts.conversion,opts.fs_uid,opts.fs_gid,opts.fs_umask,
614 MSDOS_CAN_BMAP(sbi) ? ",bmap" : "");
615 printk("[me=0x%x,cs=%d,#f=%d,fs=%d,fl=%ld,ds=%ld,de=%d,data=%ld,"
616 "se=%d,ts=%ld,ls=%d,rc=%ld,fc=%u]\n",
617 b->media,sbi->cluster_size,
618 sbi->fats,sbi->fat_start,
619 sbi->fat_length,
620 sbi->dir_start,sbi->dir_entries,
621 sbi->data_start,
622 CF_LE_W(*(unsigned short *) &b->sectors),
623 (unsigned long)b->total_sect,logical_sector_size,
624 sbi->root_cluster,sbi->free_clusters);
625 printk ("Transaction block size = %d\n",blksize);
627 if (i<0) if (sbi->clusters+2 > fat_clusters)
628 sbi->clusters = fat_clusters-2;
629 if (error)
630 goto out_invalid;
632 sb->s_magic = MSDOS_SUPER_MAGIC;
633 /* set up enough so that it can read an inode */
634 init_waitqueue_head(&sbi->fat_wait);
635 init_MUTEX(&sbi->fat_lock);
636 sbi->prev_free = 0;
638 cp = opts.codepage ? opts.codepage : 437;
639 sprintf(buf, "cp%d", cp);
640 sbi->nls_disk = load_nls(buf);
641 if (! sbi->nls_disk) {
642 /* Fail only if explicit charset specified */
643 if (opts.codepage != 0)
644 goto out_fail;
645 sbi->options.codepage = 0; /* already 0?? */
646 sbi->nls_disk = load_nls_default();
649 sbi->nls_io = NULL;
650 if (sbi->options.isvfat && !opts.utf8) {
651 p = opts.iocharset ? opts.iocharset : CONFIG_NLS_DEFAULT;
652 sbi->nls_io = load_nls(p);
653 if (! sbi->nls_io)
654 /* Fail only if explicit charset specified */
655 if (opts.iocharset)
656 goto out_unload_nls;
658 if (! sbi->nls_io)
659 sbi->nls_io = load_nls_default();
661 root_inode=get_empty_inode();
662 if (!root_inode)
663 goto out_unload_nls;
664 root_inode->i_sb = sb;
665 root_inode->i_dev = sb->s_dev;
666 root_inode->i_ino = MSDOS_ROOT_INO;
667 fat_read_root(root_inode);
668 insert_inode_hash(root_inode);
669 sb->s_root = d_alloc_root(root_inode);
670 if (!sb->s_root)
671 goto out_no_root;
672 if(i>=0) {
673 sbi->cvf_format = cvf_formats[i];
674 ++cvf_format_use_count[i];
676 return sb;
678 out_no_root:
679 printk("get root inode failed\n");
680 iput(root_inode);
681 unload_nls(sbi->nls_io);
682 out_unload_nls:
683 unload_nls(sbi->nls_disk);
684 goto out_fail;
685 out_invalid:
686 if (!silent)
687 printk("VFS: Can't find a valid MSDOS filesystem on dev %s.\n",
688 kdevname(sb->s_dev));
689 goto out_fail;
690 out_no_bread:
691 printk("FAT bread failed\n");
692 out_fail:
693 if (opts.iocharset) {
694 printk("VFS: freeing iocharset=%s\n", opts.iocharset);
695 kfree(opts.iocharset);
697 if(sbi->private_data)
698 kfree(sbi->private_data);
699 sbi->private_data=NULL;
701 return NULL;
704 int fat_statfs(struct super_block *sb,struct statfs *buf)
706 int free,nr;
708 if (MSDOS_SB(sb)->cvf_format &&
709 MSDOS_SB(sb)->cvf_format->cvf_statfs)
710 return MSDOS_SB(sb)->cvf_format->cvf_statfs(sb,buf,
711 sizeof(struct statfs));
713 lock_fat(sb);
714 if (MSDOS_SB(sb)->free_clusters != -1)
715 free = MSDOS_SB(sb)->free_clusters;
716 else {
717 free = 0;
718 for (nr = 2; nr < MSDOS_SB(sb)->clusters+2; nr++)
719 if (!fat_access(sb,nr,-1)) free++;
720 MSDOS_SB(sb)->free_clusters = free;
722 unlock_fat(sb);
723 buf->f_type = sb->s_magic;
724 buf->f_bsize = MSDOS_SB(sb)->cluster_size*SECTOR_SIZE;
725 buf->f_blocks = MSDOS_SB(sb)->clusters;
726 buf->f_bfree = free;
727 buf->f_bavail = free;
728 buf->f_namelen = MSDOS_SB(sb)->options.isvfat ? 260 : 12;
729 return 0;
732 static int is_exec(char *extension)
734 char *exe_extensions = "EXECOMBAT", *walk;
736 for (walk = exe_extensions; *walk; walk += 3)
737 if (!strncmp(extension, walk, 3))
738 return 1;
739 return 0;
742 static int fat_writepage(struct file *file, struct page *page)
744 return block_write_full_page(page,fat_get_block);
746 static int fat_readpage(struct file *file, struct page *page)
748 return block_read_full_page(page,fat_get_block);
750 static int fat_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
752 return cont_prepare_write(page,from,to,fat_get_block,
753 &MSDOS_I((struct inode*)page->mapping->host)->mmu_private);
755 static int _fat_bmap(struct address_space *mapping, long block)
757 return generic_block_bmap(mapping,block,fat_get_block);
759 static struct address_space_operations fat_aops = {
760 readpage: fat_readpage,
761 writepage: fat_writepage,
762 sync_page: block_sync_page,
763 prepare_write: fat_prepare_write,
764 commit_write: generic_commit_write,
765 bmap: _fat_bmap
768 /* doesn't deal with root inode */
769 static void fat_fill_inode(struct inode *inode, struct msdos_dir_entry *de)
771 struct super_block *sb = inode->i_sb;
772 struct msdos_sb_info *sbi = MSDOS_SB(sb);
773 int nr;
775 INIT_LIST_HEAD(&MSDOS_I(inode)->i_fat_hash);
776 MSDOS_I(inode)->i_location = 0;
777 MSDOS_I(inode)->i_fat_inode = inode;
778 inode->i_uid = sbi->options.fs_uid;
779 inode->i_gid = sbi->options.fs_gid;
780 inode->i_version = ++event;
781 if ((de->attr & ATTR_DIR) && !IS_FREE(de->name)) {
782 inode->i_mode = MSDOS_MKMODE(de->attr,S_IRWXUGO &
783 ~sbi->options.fs_umask) | S_IFDIR;
784 inode->i_op = sbi->dir_ops;
785 inode->i_fop = &fat_dir_operations;
787 MSDOS_I(inode)->i_start = CF_LE_W(de->start);
788 if (sbi->fat_bits == 32) {
789 MSDOS_I(inode)->i_start |=
790 (CF_LE_W(de->starthi) << 16);
792 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
793 inode->i_nlink = fat_subdirs(inode);
794 /* includes .., compensating for "self" */
795 #ifdef DEBUG
796 if (!inode->i_nlink) {
797 printk("directory %d: i_nlink == 0\n",inode->i_ino);
798 inode->i_nlink = 1;
800 #endif
801 inode->i_size = 0;
802 if ((nr = MSDOS_I(inode)->i_start) != 0)
803 while (nr != -1) {
804 inode->i_size += SECTOR_SIZE*sbi->cluster_size;
805 if (!(nr = fat_access(sb,nr,-1))) {
806 printk("Directory %ld: bad FAT\n",
807 inode->i_ino);
808 break;
811 MSDOS_I(inode)->mmu_private = inode->i_size;
812 } else { /* not a directory */
813 inode->i_mode = MSDOS_MKMODE(de->attr,
814 ((IS_NOEXEC(inode) ||
815 (sbi->options.showexec &&
816 !is_exec(de->ext)))
817 ? S_IRUGO|S_IWUGO : S_IRWXUGO)
818 & ~sbi->options.fs_umask) | S_IFREG;
819 MSDOS_I(inode)->i_start = CF_LE_W(de->start);
820 if (sbi->fat_bits == 32) {
821 MSDOS_I(inode)->i_start |=
822 (CF_LE_W(de->starthi) << 16);
824 MSDOS_I(inode)->i_logstart = MSDOS_I(inode)->i_start;
825 inode->i_nlink = 1;
826 inode->i_size = CF_LE_L(de->size);
827 inode->i_op = &fat_file_inode_operations;
828 inode->i_fop = &fat_file_operations;
829 inode->i_mapping->a_ops = &fat_aops;
830 MSDOS_I(inode)->mmu_private = inode->i_size;
832 if(de->attr & ATTR_SYS)
833 if (sbi->options.sys_immutable)
834 inode->i_flags |= S_IMMUTABLE;
835 MSDOS_I(inode)->i_attrs = de->attr & ATTR_UNUSED;
836 /* this is as close to the truth as we can get ... */
837 inode->i_blksize = sbi->cluster_size*SECTOR_SIZE;
838 inode->i_blocks =
839 ((inode->i_size+inode->i_blksize-1)>>sbi->cluster_bits) *
840 sbi->cluster_size;
841 inode->i_mtime = inode->i_atime =
842 date_dos2unix(CF_LE_W(de->time),CF_LE_W(de->date));
843 inode->i_ctime =
844 MSDOS_SB(sb)->options.isvfat
845 ? date_dos2unix(CF_LE_W(de->ctime),CF_LE_W(de->cdate))
846 : inode->i_mtime;
847 MSDOS_I(inode)->i_ctime_ms = de->ctime_ms;
850 void fat_write_inode(struct inode *inode, int wait)
852 struct super_block *sb = inode->i_sb;
853 struct buffer_head *bh;
854 struct msdos_dir_entry *raw_entry;
855 int i_pos;
857 retry:
858 i_pos = MSDOS_I(inode)->i_location;
859 if (inode->i_ino == MSDOS_ROOT_INO || !i_pos) {
860 return;
862 lock_kernel();
863 if (!(bh = fat_bread(sb, i_pos >> MSDOS_DPB_BITS))) {
864 printk("dev = %s, ino = %d\n", kdevname(inode->i_dev), i_pos);
865 fat_fs_panic(sb, "msdos_write_inode: unable to read i-node block");
866 unlock_kernel();
867 return;
869 spin_lock(&fat_inode_lock);
870 if (i_pos != MSDOS_I(inode)->i_location) {
871 spin_unlock(&fat_inode_lock);
872 fat_brelse(sb, bh);
873 unlock_kernel();
874 goto retry;
877 raw_entry = &((struct msdos_dir_entry *) (bh->b_data))
878 [i_pos & (MSDOS_DPB-1)];
879 if (S_ISDIR(inode->i_mode)) {
880 raw_entry->attr = ATTR_DIR;
881 raw_entry->size = 0;
883 else {
884 raw_entry->attr = ATTR_NONE;
885 raw_entry->size = CT_LE_L(inode->i_size);
887 raw_entry->attr |= MSDOS_MKATTR(inode->i_mode) |
888 MSDOS_I(inode)->i_attrs;
889 raw_entry->start = CT_LE_W(MSDOS_I(inode)->i_logstart);
890 raw_entry->starthi = CT_LE_W(MSDOS_I(inode)->i_logstart >> 16);
891 fat_date_unix2dos(inode->i_mtime,&raw_entry->time,&raw_entry->date);
892 raw_entry->time = CT_LE_W(raw_entry->time);
893 raw_entry->date = CT_LE_W(raw_entry->date);
894 if (MSDOS_SB(sb)->options.isvfat) {
895 fat_date_unix2dos(inode->i_ctime,&raw_entry->ctime,&raw_entry->cdate);
896 raw_entry->ctime_ms = MSDOS_I(inode)->i_ctime_ms;
897 raw_entry->ctime = CT_LE_W(raw_entry->ctime);
898 raw_entry->cdate = CT_LE_W(raw_entry->cdate);
900 spin_unlock(&fat_inode_lock);
901 fat_mark_buffer_dirty(sb, bh);
902 fat_brelse(sb, bh);
903 unlock_kernel();
907 int fat_notify_change(struct dentry * dentry, struct iattr * attr)
909 struct super_block *sb = dentry->d_sb;
910 struct inode *inode = dentry->d_inode;
911 int error;
913 error = inode_change_ok(inode, attr);
914 if (error)
915 return MSDOS_SB(sb)->options.quiet ? 0 : error;
917 if (((attr->ia_valid & ATTR_UID) &&
918 (attr->ia_uid != MSDOS_SB(sb)->options.fs_uid)) ||
919 ((attr->ia_valid & ATTR_GID) &&
920 (attr->ia_gid != MSDOS_SB(sb)->options.fs_gid)) ||
921 ((attr->ia_valid & ATTR_MODE) &&
922 (attr->ia_mode & ~MSDOS_VALID_MODE)))
923 error = -EPERM;
925 if (error)
926 return MSDOS_SB(sb)->options.quiet ? 0 : error;
928 inode_setattr(inode, attr);
930 if (IS_NOEXEC(inode) && !S_ISDIR(inode->i_mode))
931 inode->i_mode &= S_IFMT | S_IRUGO | S_IWUGO;
932 else
933 inode->i_mode |= S_IXUGO;
935 inode->i_mode = ((inode->i_mode & S_IFMT) | ((((inode->i_mode & S_IRWXU
936 & ~MSDOS_SB(sb)->options.fs_umask) | S_IRUSR) >> 6)*S_IXUGO)) &
937 ~MSDOS_SB(sb)->options.fs_umask;
938 return 0;