4 * Written 1992,1993 by Werner Almesberger
8 #include <linux/msdos_fs.h>
9 #include <linux/sched.h>
10 #include <linux/kernel.h>
11 #include <linux/errno.h>
12 #include <linux/string.h>
13 #include <linux/stat.h>
18 # define PRINTK(x) printk x
22 #define Printk(x) printk x
24 /* Well-known binary file extensions - of course there are many more */
26 static char ascii_extensions
[] =
27 "TXT" "ME " "HTM" "1ST" "LOG" " " /* text files */
28 "C " "H " "CPP" "LIS" "PAS" "FOR" /* programming languages */
29 "F " "MAK" "INC" "BAS" /* programming languages */
30 "BAT" "SH " /* program code :) */
31 "INI" /* config files */
32 "PBM" "PGM" "DXF" /* graphics */
37 * fat_fs_panic reports a severe file system problem and sets the file system
38 * read-only. The file system can be made writable again by remounting it.
41 void fat_fs_panic(struct super_block
*s
,const char *msg
)
45 not_ro
= !(s
->s_flags
& MS_RDONLY
);
46 if (not_ro
) s
->s_flags
|= MS_RDONLY
;
47 printk("Filesystem panic (dev %s).\n %s\n", kdevname(s
->s_dev
), msg
);
49 printk(" File system has been set read-only\n");
54 * fat_is_binary selects optional text conversion based on the conversion mode
55 * and the extension part of the file name.
58 int fat_is_binary(char conversion
,char *extension
)
68 for (walk
= ascii_extensions
; *walk
; walk
+= 3)
69 if (!strncmp(extension
,walk
,3)) return 0;
70 return 1; /* default binary conversion */
72 printk("Invalid conversion mode - defaulting to "
79 /* File creation lock. This is system-wide to avoid deadlocks in rename. */
80 /* (rename might deadlock before detecting cross-FS moves.) */
82 static DECLARE_MUTEX(creation_lock
);
84 void fat_lock_creation(void)
90 void fat_unlock_creation(void)
96 void lock_fat(struct super_block
*sb
)
98 down(&(MSDOS_SB(sb
)->fat_lock
));
102 void unlock_fat(struct super_block
*sb
)
104 up(&(MSDOS_SB(sb
)->fat_lock
));
107 /* Flushes the number of free clusters on FAT32 */
108 /* XXX: Need to write one per FSINFO block. Currently only writes 1 */
109 void fat_clusters_flush(struct super_block
*sb
)
112 struct buffer_head
*bh
;
113 struct fat_boot_fsinfo
*fsinfo
;
115 /* The fat32 boot fs info is at offset 0x3e0 by observation */
116 offset
= MSDOS_SB(sb
)->fsinfo_offset
;
117 bh
= fat_bread(sb
, (offset
>> SECTOR_BITS
));
119 printk("FAT bread failed in fat_clusters_flush\n");
122 fsinfo
= (struct fat_boot_fsinfo
*)
123 &bh
->b_data
[offset
& (SECTOR_SIZE
-1)];
126 if (CF_LE_L(fsinfo
->signature
) != 0x61417272) {
127 printk("fat_clusters_flush: Did not find valid FSINFO signature. Found 0x%x. offset=0x%x\n", CF_LE_L(fsinfo
->signature
), offset
);
131 fsinfo
->free_clusters
= CF_LE_L(MSDOS_SB(sb
)->free_clusters
);
132 fat_mark_buffer_dirty(sb
, bh
, 1);
137 * fat_add_cluster tries to allocate a new cluster and adds it to the file
138 * represented by inode. The cluster is zero-initialized.
141 /* not a directory */
143 int fat_add_cluster(struct inode
*inode
)
145 struct super_block
*sb
= inode
->i_sb
;
146 int count
,nr
,limit
,last
,curr
,file_cluster
;
148 int cluster_size
= MSDOS_SB(sb
)->cluster_size
;
150 if (!MSDOS_SB(sb
)->free_clusters
) return res
;
152 limit
= MSDOS_SB(sb
)->clusters
;
153 nr
= limit
; /* to keep GCC happy */
154 for (count
= 0; count
< limit
; count
++) {
155 nr
= ((count
+MSDOS_SB(sb
)->prev_free
) % limit
)+2;
156 if (fat_access(sb
,nr
,-1) == 0) break;
158 MSDOS_SB(sb
)->prev_free
= (count
+MSDOS_SB(sb
)->prev_free
+1) % limit
;
159 if (count
>= limit
) {
160 MSDOS_SB(sb
)->free_clusters
= 0;
164 fat_access(sb
,nr
,EOF_FAT(sb
));
165 if (MSDOS_SB(sb
)->free_clusters
!= -1)
166 MSDOS_SB(sb
)->free_clusters
--;
167 if (MSDOS_SB(sb
)->fat_bits
== 32)
168 fat_clusters_flush(sb
);
171 /* We must locate the last cluster of the file to add this
172 new one (nr) to the end of the link list (the FAT).
174 Here file_cluster will be the number of the last cluster of the
175 file (before we add nr).
177 last is the corresponding cluster number on the disk. We will
178 use last to plug the nr cluster. We will use file_cluster to
182 if ((curr
= MSDOS_I(inode
)->i_start
) != 0) {
183 fat_cache_lookup(inode
,INT_MAX
,&last
,&curr
);
185 while (curr
&& curr
!= -1){
187 if (!(curr
= fat_access(sb
, last
= curr
,-1))) {
188 fat_fs_panic(sb
,"File without EOF");
193 if (last
) fat_access(sb
,last
,nr
);
195 MSDOS_I(inode
)->i_start
= nr
;
196 MSDOS_I(inode
)->i_logstart
= nr
;
197 mark_inode_dirty(inode
);
199 fat_cache_add(inode
,file_cluster
,nr
);
200 inode
->i_blocks
+= cluster_size
;
204 struct buffer_head
*fat_extend_dir(struct inode
*inode
)
206 struct super_block
*sb
= inode
->i_sb
;
207 int count
,nr
,limit
,last
,curr
,sector
,last_sector
,file_cluster
;
208 struct buffer_head
*bh
, *res
=NULL
;
209 int cluster_size
= MSDOS_SB(sb
)->cluster_size
;
211 if (MSDOS_SB(sb
)->fat_bits
!= 32) {
212 if (inode
->i_ino
== MSDOS_ROOT_INO
) return res
;
214 if (!MSDOS_SB(sb
)->free_clusters
) return res
;
216 limit
= MSDOS_SB(sb
)->clusters
;
217 nr
= limit
; /* to keep GCC happy */
218 for (count
= 0; count
< limit
; count
++) {
219 nr
= ((count
+MSDOS_SB(sb
)->prev_free
) % limit
)+2;
220 if (fat_access(sb
,nr
,-1) == 0) break;
222 PRINTK (("cnt = %d --",count
));
224 printk("free cluster: %d\n",nr
);
226 MSDOS_SB(sb
)->prev_free
= (count
+MSDOS_SB(sb
)->prev_free
+1) % limit
;
227 if (count
>= limit
) {
228 MSDOS_SB(sb
)->free_clusters
= 0;
232 fat_access(sb
,nr
,EOF_FAT(sb
));
233 if (MSDOS_SB(sb
)->free_clusters
!= -1)
234 MSDOS_SB(sb
)->free_clusters
--;
235 if (MSDOS_SB(sb
)->fat_bits
== 32)
236 fat_clusters_flush(sb
);
239 printk("set to %x\n",fat_access(sb
,nr
,-1));
242 /* We must locate the last cluster of the file to add this
243 new one (nr) to the end of the link list (the FAT).
245 Here file_cluster will be the number of the last cluster of the
246 file (before we add nr).
248 last is the corresponding cluster number on the disk. We will
249 use last to plug the nr cluster. We will use file_cluster to
253 if ((curr
= MSDOS_I(inode
)->i_start
) != 0) {
254 fat_cache_lookup(inode
,INT_MAX
,&last
,&curr
);
256 while (curr
&& curr
!= -1){
259 if (!(curr
= fat_access(sb
,
261 fat_fs_panic(sb
,"File without EOF");
268 printk("last = %d\n",last
);
270 if (last
) fat_access(sb
,last
,nr
);
272 MSDOS_I(inode
)->i_start
= nr
;
273 MSDOS_I(inode
)->i_logstart
= nr
;
274 mark_inode_dirty(inode
);
277 if (last
) printk("next set to %d\n",fat_access(sb
,last
,-1));
279 sector
= MSDOS_SB(sb
)->data_start
+(nr
-2)*cluster_size
;
280 last_sector
= sector
+ cluster_size
;
281 if (MSDOS_SB(sb
)->cvf_format
&&
282 MSDOS_SB(sb
)->cvf_format
->zero_out_cluster
)
283 MSDOS_SB(sb
)->cvf_format
->zero_out_cluster(inode
,nr
);
285 for ( ; sector
< last_sector
; sector
++) {
287 printk("zeroing sector %d\n",sector
);
289 if (!(bh
= fat_getblk(sb
, sector
)))
290 printk("getblk failed\n");
292 memset(bh
->b_data
,0,SECTOR_SIZE
);
293 fat_set_uptodate(sb
, bh
, 1);
294 fat_mark_buffer_dirty(sb
, bh
, 1);
301 if (file_cluster
!= inode
->i_blocks
/cluster_size
){
302 printk ("file_cluster badly computed!!! %d <> %ld\n"
303 ,file_cluster
,inode
->i_blocks
/cluster_size
);
305 fat_cache_add(inode
,file_cluster
,nr
);
307 inode
->i_blocks
+= cluster_size
;
308 if (inode
->i_size
& (SECTOR_SIZE
-1)) {
309 fat_fs_panic(sb
,"Odd directory size");
310 inode
->i_size
= (inode
->i_size
+SECTOR_SIZE
) &
313 inode
->i_size
+= SECTOR_SIZE
*cluster_size
;
314 MSDOS_I(inode
)->i_realsize
+= SECTOR_SIZE
*cluster_size
;
315 mark_inode_dirty(inode
);
319 /* Linear day numbers of the respective 1sts in non-leap years. */
321 static int day_n
[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
322 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
325 extern struct timezone sys_tz
;
328 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
330 int date_dos2unix(unsigned short time
,unsigned short date
)
334 month
= ((date
>> 5) & 15)-1;
336 secs
= (time
& 31)*2+60*((time
>> 5) & 63)+(time
>> 11)*3600+86400*
337 ((date
& 31)-1+day_n
[month
]+(year
/4)+year
*365-((year
& 3) == 0 &&
338 month
< 2 ? 1 : 0)+3653);
339 /* days since 1.1.70 plus 80's leap day */
340 secs
+= sys_tz
.tz_minuteswest
*60;
341 if (sys_tz
.tz_dsttime
) secs
-= 3600;
346 /* Convert linear UNIX date to a MS-DOS time/date pair. */
348 void fat_date_unix2dos(int unix_date
,unsigned short *time
,
349 unsigned short *date
)
351 int day
,year
,nl_day
,month
;
353 unix_date
-= sys_tz
.tz_minuteswest
*60;
354 if (sys_tz
.tz_dsttime
) unix_date
+= 3600;
356 *time
= (unix_date
% 60)/2+(((unix_date
/60) % 60) << 5)+
357 (((unix_date
/3600) % 24) << 11);
358 day
= unix_date
/86400-3652;
360 if ((year
+3)/4+365*year
> day
) year
--;
361 day
-= (year
+3)/4+365*year
;
362 if (day
== 59 && !(year
& 3)) {
367 nl_day
= (year
& 3) || day
<= 59 ? day
: day
-1;
368 for (month
= 0; month
< 12; month
++)
369 if (day_n
[month
] > nl_day
) break;
371 *date
= nl_day
-day_n
[month
-1]+1+(month
<< 5)+(year
<< 9);
375 /* Returns the inode number of the directory entry at offset pos. If bh is
376 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
378 AV. Most often we do it item-by-item. Makes sense to optimize.
379 AV. OK, there we go: if both bh and de are non-NULL we assume that we just
380 AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
381 AV. It's done in fat_get_entry() (inlined), here the slow case lives.
382 AV. Additionally, when we return -1 (i.e. reached the end of directory)
386 int fat__get_entry(struct inode
*dir
, loff_t
*pos
,struct buffer_head
**bh
,
387 struct msdos_dir_entry
**de
, int *ino
)
389 struct super_block
*sb
= dir
->i_sb
;
394 PRINTK (("get_entry offset %d\n",offset
));
398 if ((sector
= fat_bmap(dir
,offset
>> SECTOR_BITS
)) == -1)
400 PRINTK (("get_entry sector %d %p\n",sector
,*bh
));
401 PRINTK (("get_entry sector apres brelse\n"));
403 return -1; /* beyond EOF */
404 *pos
+= sizeof(struct msdos_dir_entry
);
405 if (!(*bh
= fat_bread(sb
, sector
))) {
406 printk("Directory sread (sector 0x%x) failed\n",sector
);
409 PRINTK (("get_entry apres sread\n"));
410 *de
= (struct msdos_dir_entry
*) ((*bh
)->b_data
+(offset
&
412 *ino
= (sector
<< MSDOS_DPS_BITS
)+((offset
& (SECTOR_SIZE
-1)) >>
420 * Now an ugly part: this set of directory scan routines works on clusters
421 * rather than on inodes and sectors. They are necessary to locate the '..'
422 * directory "inode". raw_scan_sector operates in four modes:
424 * name number ino action
425 * -------- -------- -------- -------------------------------------------------
426 * non-NULL - X Find an entry with that name
427 * NULL non-NULL non-NULL Find an entry whose data starts at *number
428 * NULL non-NULL NULL Count subdirectories in *number. (*)
429 * NULL NULL non-NULL Find an empty entry
431 * (*) The return code should be ignored. It DOES NOT indicate success or
432 * failure. *number has to be initialized to zero.
434 * - = not used, X = a value is returned unless NULL
436 * If res_bh is non-NULL, the buffer is not deallocated but returned to the
437 * caller on success. res_de is set accordingly.
439 * If cont is non-zero, raw_found continues with the entry after the one
440 * res_bh/res_de point to.
444 #define RSS_NAME /* search for name */ \
445 done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
446 !(data[entry].attr & ATTR_VOLUME);
448 #define RSS_START /* search for start cluster */ \
449 done = !IS_FREE(data[entry].name) \
452 (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
454 | CF_LE_W(data[entry].start) \
457 #define RSS_FREE /* search for free entry */ \
459 done = IS_FREE(data[entry].name); \
462 #define RSS_COUNT /* count subdirectories */ \
465 if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
469 static int raw_scan_sector(struct super_block
*sb
,int sector
,const char *name
,
470 int *number
,int *ino
,struct buffer_head
**res_bh
,
471 struct msdos_dir_entry
**res_de
)
473 struct buffer_head
*bh
;
474 struct msdos_dir_entry
*data
;
475 int entry
,start
,done
;
477 if (!(bh
= fat_bread(sb
,sector
)))
479 data
= (struct msdos_dir_entry
*) bh
->b_data
;
480 for (entry
= 0; entry
< MSDOS_DPS
; entry
++) {
481 /* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
487 if (number
) RSS_START
492 if (ino
) *ino
= sector
*MSDOS_DPS
+entry
;
493 start
= CF_LE_W(data
[entry
].start
);
494 if (MSDOS_SB(sb
)->fat_bits
== 32) {
495 start
|= (CF_LE_W(data
[entry
].starthi
) << 16);
501 *res_de
= &data
[entry
];
512 * raw_scan_root performs raw_scan_sector on the root directory until the
513 * requested entry is found or the end of the directory is reached.
516 static int raw_scan_root(struct super_block
*sb
,const char *name
,int *number
,int *ino
,
517 struct buffer_head
**res_bh
,struct msdos_dir_entry
**res_de
)
521 for (count
= 0; count
< MSDOS_SB(sb
)->dir_entries
/MSDOS_DPS
; count
++) {
522 if ((cluster
= raw_scan_sector(sb
,MSDOS_SB(sb
)->dir_start
+count
,
523 name
,number
,ino
,res_bh
,res_de
)) >= 0) return cluster
;
530 * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
531 * requested entry is found or the end of the directory is reached.
534 static int raw_scan_nonroot(struct super_block
*sb
,int start
,const char *name
,
535 int *number
,int *ino
,struct buffer_head
**res_bh
,struct msdos_dir_entry
541 printk("raw_scan_nonroot: start=%d\n",start
);
544 for (count
= 0; count
< MSDOS_SB(sb
)->cluster_size
; count
++) {
545 if ((cluster
= raw_scan_sector(sb
,(start
-2)*
546 MSDOS_SB(sb
)->cluster_size
+MSDOS_SB(sb
)->data_start
+
547 count
,name
,number
,ino
,res_bh
,res_de
)) >= 0)
550 if (!(start
= fat_access(sb
,start
,-1))) {
551 fat_fs_panic(sb
,"FAT error");
555 printk("next start: %d\n",start
);
564 * raw_scan performs raw_scan_sector on any sector.
566 * NOTE: raw_scan must not be used on a directory that is is the process of
570 static int raw_scan(struct super_block
*sb
, int start
, const char *name
,
571 int *number
, int *ino
, struct buffer_head
**res_bh
,
572 struct msdos_dir_entry
**res_de
)
574 if (start
) return raw_scan_nonroot
575 (sb
,start
,name
,number
,ino
,res_bh
,res_de
);
576 else return raw_scan_root
577 (sb
,name
,number
,ino
,res_bh
,res_de
);
582 * fat_parent_ino returns the inode number of the parent directory of dir.
583 * File creation has to be deferred while fat_parent_ino is running to
586 * AV. Bad, bad, bad... We need a mapping that would give us inode by
587 * first cluster. Sheeeeit... OK, we can do it on fat_fill_inode() and
588 * update on fat_add_cluster(). When will we remove it? fat_clear_inode()
589 * and fat_truncate() to zero?
592 int fat_parent_ino(struct inode
*dir
,int locked
)
595 int error
,curr
,prev
,nr
;
597 PRINTK(("fat_parent_ino: Debug 0\n"));
598 if (!S_ISDIR(dir
->i_mode
)) panic("Non-directory fed to m_p_i");
599 if (dir
->i_ino
== MSDOS_ROOT_INO
) return dir
->i_ino
;
600 if (!locked
) fat_lock_creation(); /* prevent renames */
601 if ((curr
= raw_scan(dir
->i_sb
,MSDOS_I(dir
)->i_start
,MSDOS_DOTDOT
,
602 &zero
,NULL
,NULL
,NULL
)) < 0) {
603 if (!locked
) fat_unlock_creation();
606 PRINTK(("fat_parent_ino: Debug 1 curr=%d\n", curr
));
607 if (!curr
) nr
= MSDOS_ROOT_INO
;
609 PRINTK(("fat_parent_ino: Debug 2\n"));
610 if ((prev
= raw_scan(dir
->i_sb
,curr
,MSDOS_DOTDOT
,&zero
,NULL
,
612 PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev
));
613 if (!locked
) fat_unlock_creation();
616 PRINTK(("fat_parent_ino: Debug 4 prev=%d\n", prev
));
617 if (prev
== 0 && MSDOS_SB(dir
->i_sb
)->fat_bits
== 32) {
618 prev
= MSDOS_SB(dir
->i_sb
)->root_cluster
;
620 if ((error
= raw_scan(dir
->i_sb
,prev
,NULL
,&curr
,&nr
,NULL
,
622 PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error
));
623 if (!locked
) fat_unlock_creation();
626 PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr
));
628 if (!locked
) fat_unlock_creation();
634 * fat_subdirs counts the number of sub-directories of dir. It can be run
635 * on directories being created.
638 int fat_subdirs(struct inode
*dir
)
643 if ((dir
->i_ino
== MSDOS_ROOT_INO
) &&
644 (MSDOS_SB(dir
->i_sb
)->fat_bits
!= 32)) {
645 (void) raw_scan_root(dir
->i_sb
,NULL
,&count
,NULL
,NULL
,NULL
);
647 if ((dir
->i_ino
!= MSDOS_ROOT_INO
) &&
648 !MSDOS_I(dir
)->i_start
) return 0; /* in mkdir */
649 else (void) raw_scan_nonroot(dir
->i_sb
,MSDOS_I(dir
)->i_start
,
650 NULL
,&count
,NULL
,NULL
,NULL
);
657 * Scans a directory for a given file (name points to its formatted name) or
658 * for an empty directory slot (name is NULL). Returns an error code or zero.
661 int fat_scan(struct inode
*dir
,const char *name
,struct buffer_head
**res_bh
,
662 struct msdos_dir_entry
**res_de
,int *ino
)
666 res
= raw_scan(dir
->i_sb
,MSDOS_I(dir
)->i_start
,
667 name
, NULL
, ino
, res_bh
, res_de
);
668 return res
<0 ? res
: 0;