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 * is_binary selects optional text conversion based on the conversion mode and
55 * the extension part of the file name.
58 int 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 struct wait_queue
*creation_wait
= NULL
;
83 static int creation_lock
= 0;
86 void fat_lock_creation(void)
88 while (creation_lock
) sleep_on(&creation_wait
);
93 void fat_unlock_creation(void)
96 wake_up(&creation_wait
);
100 void lock_fat(struct super_block
*sb
)
102 while (MSDOS_SB(sb
)->fat_lock
) sleep_on(&MSDOS_SB(sb
)->fat_wait
);
103 MSDOS_SB(sb
)->fat_lock
= 1;
107 void unlock_fat(struct super_block
*sb
)
109 MSDOS_SB(sb
)->fat_lock
= 0;
110 wake_up(&MSDOS_SB(sb
)->fat_wait
);
113 /* Flushes the number of free clusters on FAT32 */
114 /* XXX: Need to write one per FSINFO block. Currently only writes 1 */
115 void fat_clusters_flush(struct super_block
*sb
)
118 struct buffer_head
*bh
;
119 struct fat_boot_fsinfo
*fsinfo
;
121 /* The fat32 boot fs info is at offset 0x3e0 by observation */
122 offset
= MSDOS_SB(sb
)->fsinfo_offset
;
123 bh
= fat_bread(sb
, (offset
>> SECTOR_BITS
));
125 printk("FAT bread failed in fat_clusters_flush\n");
128 fsinfo
= (struct fat_boot_fsinfo
*)
129 &bh
->b_data
[offset
& (SECTOR_SIZE
-1)];
132 if (CF_LE_L(fsinfo
->signature
) != 0x61417272) {
133 printk("fat_clusters_flush: Did not find valid FSINFO signature. Found 0x%x. offset=0x%x\n", CF_LE_L(fsinfo
->signature
), offset
);
137 fsinfo
->free_clusters
= CF_LE_L(MSDOS_SB(sb
)->free_clusters
);
138 fat_mark_buffer_dirty(sb
, bh
, 1);
143 * fat_add_cluster tries to allocate a new cluster and adds it to the file
144 * represented by inode. The cluster is zero-initialized.
147 int fat_add_cluster(struct inode
*inode
)
149 struct super_block
*sb
= inode
->i_sb
;
150 int count
,nr
,limit
,last
,curr
,sector
,last_sector
,file_cluster
;
151 struct buffer_head
*bh
;
152 int cluster_size
= MSDOS_SB(sb
)->cluster_size
;
154 if (MSDOS_SB(sb
)->fat_bits
!= 32) {
155 if (inode
->i_ino
== MSDOS_ROOT_INO
) return -ENOSPC
;
157 if (!MSDOS_SB(sb
)->free_clusters
) return -ENOSPC
;
159 limit
= MSDOS_SB(sb
)->clusters
;
160 nr
= limit
; /* to keep GCC happy */
161 for (count
= 0; count
< limit
; count
++) {
162 nr
= ((count
+MSDOS_SB(sb
)->prev_free
) % limit
)+2;
163 if (fat_access(sb
,nr
,-1) == 0) break;
165 PRINTK (("cnt = %d --",count
));
167 printk("free cluster: %d\n",nr
);
169 MSDOS_SB(sb
)->prev_free
= (count
+MSDOS_SB(sb
)->prev_free
+1) % limit
;
170 if (count
>= limit
) {
171 MSDOS_SB(sb
)->free_clusters
= 0;
175 fat_access(sb
,nr
,EOF_FAT(sb
));
176 if (MSDOS_SB(sb
)->free_clusters
!= -1)
177 MSDOS_SB(sb
)->free_clusters
--;
178 if (MSDOS_SB(sb
)->fat_bits
== 32)
179 fat_clusters_flush(sb
);
182 printk("set to %x\n",fat_access(sb
,nr
,-1));
185 /* We must locate the last cluster of the file to add this
186 new one (nr) to the end of the link list (the FAT).
188 Here file_cluster will be the number of the last cluster of the
189 file (before we add nr).
191 last is the corresponding cluster number on the disk. We will
192 use last to plug the nr cluster. We will use file_cluster to
196 if ((curr
= MSDOS_I(inode
)->i_start
) != 0) {
197 fat_cache_lookup(inode
,INT_MAX
,&last
,&curr
);
199 while (curr
&& curr
!= -1){
202 if (!(curr
= fat_access(sb
,
204 fat_fs_panic(sb
,"File without EOF");
211 printk("last = %d\n",last
);
213 if (last
) fat_access(sb
,last
,nr
);
215 MSDOS_I(inode
)->i_start
= nr
;
216 MSDOS_I(inode
)->i_logstart
= nr
;
217 mark_inode_dirty(inode
);
220 if (last
) printk("next set to %d\n",fat_access(sb
,last
,-1));
222 sector
= MSDOS_SB(sb
)->data_start
+(nr
-2)*cluster_size
;
223 last_sector
= sector
+ cluster_size
;
224 if (MSDOS_SB(sb
)->cvf_format
&&
225 MSDOS_SB(sb
)->cvf_format
->zero_out_cluster
)
226 MSDOS_SB(sb
)->cvf_format
->zero_out_cluster(inode
,nr
);
228 for ( ; sector
< last_sector
; sector
++) {
230 printk("zeroing sector %d\n",sector
);
232 if (!(bh
= fat_getblk(sb
, sector
)))
233 printk("getblk failed\n");
235 memset(bh
->b_data
,0,SECTOR_SIZE
);
236 fat_set_uptodate(sb
, bh
, 1);
237 fat_mark_buffer_dirty(sb
, bh
, 1);
241 if (file_cluster
!= inode
->i_blocks
/cluster_size
){
242 printk ("file_cluster badly computed!!! %d <> %ld\n"
243 ,file_cluster
,inode
->i_blocks
/cluster_size
);
245 fat_cache_add(inode
,file_cluster
,nr
);
247 inode
->i_blocks
+= cluster_size
;
248 if (S_ISDIR(inode
->i_mode
)) {
249 if (inode
->i_size
& (SECTOR_SIZE
-1)) {
250 fat_fs_panic(sb
,"Odd directory size");
251 inode
->i_size
= (inode
->i_size
+SECTOR_SIZE
) &
254 inode
->i_size
+= SECTOR_SIZE
*cluster_size
;
256 printk("size is %d now (%x)\n",inode
->i_size
,inode
);
258 mark_inode_dirty(inode
);
264 /* Linear day numbers of the respective 1sts in non-leap years. */
266 static int day_n
[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
267 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
270 extern struct timezone sys_tz
;
273 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
275 int date_dos2unix(unsigned short time
,unsigned short date
)
279 month
= ((date
>> 5) & 15)-1;
281 secs
= (time
& 31)*2+60*((time
>> 5) & 63)+(time
>> 11)*3600+86400*
282 ((date
& 31)-1+day_n
[month
]+(year
/4)+year
*365-((year
& 3) == 0 &&
283 month
< 2 ? 1 : 0)+3653);
284 /* days since 1.1.70 plus 80's leap day */
285 secs
+= sys_tz
.tz_minuteswest
*60;
286 if (sys_tz
.tz_dsttime
) secs
-= 3600;
291 /* Convert linear UNIX date to a MS-DOS time/date pair. */
293 void fat_date_unix2dos(int unix_date
,unsigned short *time
,
294 unsigned short *date
)
296 int day
,year
,nl_day
,month
;
298 unix_date
-= sys_tz
.tz_minuteswest
*60;
299 if (sys_tz
.tz_dsttime
) unix_date
+= 3600;
301 *time
= (unix_date
% 60)/2+(((unix_date
/60) % 60) << 5)+
302 (((unix_date
/3600) % 24) << 11);
303 day
= unix_date
/86400-3652;
305 if ((year
+3)/4+365*year
> day
) year
--;
306 day
-= (year
+3)/4+365*year
;
307 if (day
== 59 && !(year
& 3)) {
312 nl_day
= (year
& 3) || day
<= 59 ? day
: day
-1;
313 for (month
= 0; month
< 12; month
++)
314 if (day_n
[month
] > nl_day
) break;
316 *date
= nl_day
-day_n
[month
-1]+1+(month
<< 5)+(year
<< 9);
320 /* Returns the inode number of the directory entry at offset pos. If bh is
321 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
324 int fat_get_entry(struct inode
*dir
, loff_t
*pos
,struct buffer_head
**bh
,
325 struct msdos_dir_entry
**de
)
327 struct super_block
*sb
= dir
->i_sb
;
332 PRINTK (("get_entry offset %d\n",offset
));
333 if ((sector
= fat_smap(dir
,offset
>> SECTOR_BITS
)) == -1)
335 PRINTK (("get_entry sector %d %p\n",sector
,*bh
));
337 return -1; /* beyond EOF */
338 *pos
+= sizeof(struct msdos_dir_entry
);
341 PRINTK (("get_entry sector apres brelse\n"));
342 if (!(*bh
= fat_bread(sb
, sector
))) {
343 printk("Directory sread (sector 0x%x) failed\n",sector
);
346 PRINTK (("get_entry apres sread\n"));
347 *de
= (struct msdos_dir_entry
*) ((*bh
)->b_data
+(offset
&
349 return (sector
<< MSDOS_DPS_BITS
)+((offset
& (SECTOR_SIZE
-1)) >>
356 * Now an ugly part: this set of directory scan routines works on clusters
357 * rather than on inodes and sectors. They are necessary to locate the '..'
358 * directory "inode". raw_scan_sector operates in four modes:
360 * name number ino action
361 * -------- -------- -------- -------------------------------------------------
362 * non-NULL - X Find an entry with that name
363 * NULL non-NULL non-NULL Find an entry whose data starts at *number
364 * NULL non-NULL NULL Count subdirectories in *number. (*)
365 * NULL NULL non-NULL Find an empty entry
367 * (*) The return code should be ignored. It DOES NOT indicate success or
368 * failure. *number has to be initialized to zero.
370 * - = not used, X = a value is returned unless NULL
372 * If res_bh is non-NULL, the buffer is not deallocated but returned to the
373 * caller on success. res_de is set accordingly.
375 * If cont is non-zero, raw_found continues with the entry after the one
376 * res_bh/res_de point to.
380 #define RSS_NAME /* search for name */ \
381 done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
382 !(data[entry].attr & ATTR_VOLUME);
384 #define RSS_START /* search for start cluster */ \
385 done = !IS_FREE(data[entry].name) \
388 (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
390 | CF_LE_W(data[entry].start) \
393 #define RSS_FREE /* search for free entry */ \
395 done = IS_FREE(data[entry].name); \
397 inode = iget(sb,sector*MSDOS_DPS+entry); \
399 /* Directory slots of busy deleted files aren't available yet. */ \
400 done = !MSDOS_I(inode)->i_busy; \
406 #define RSS_COUNT /* count subdirectories */ \
409 if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
413 static int raw_scan_sector(struct super_block
*sb
,int sector
,const char *name
,
414 int *number
,int *ino
,struct buffer_head
**res_bh
,
415 struct msdos_dir_entry
**res_de
,char scantype
)
417 struct buffer_head
*bh
;
418 struct msdos_dir_entry
*data
;
420 int entry
,start
,done
;
422 if (!(bh
= fat_bread(sb
,sector
)))
424 data
= (struct msdos_dir_entry
*) bh
->b_data
;
425 for (entry
= 0; entry
< MSDOS_DPS
; entry
++) {
426 /* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
429 if (done
&& scantype
) { /* scantype != SCAN_ANY */
430 done
= (data
[entry
].attr
& ATTR_HIDDEN
)
431 ? (scantype
==SCAN_HID
)
432 : (scantype
==SCAN_NOTHID
);
437 if (number
) RSS_START
442 if (ino
) *ino
= sector
*MSDOS_DPS
+entry
;
443 start
= CF_LE_W(data
[entry
].start
);
444 if (MSDOS_SB(sb
)->fat_bits
== 32) {
445 start
|= (CF_LE_W(data
[entry
].starthi
) << 16);
451 *res_de
= &data
[entry
];
462 * raw_scan_root performs raw_scan_sector on the root directory until the
463 * requested entry is found or the end of the directory is reached.
466 static int raw_scan_root(struct super_block
*sb
,const char *name
,int *number
,int *ino
,
467 struct buffer_head
**res_bh
,struct msdos_dir_entry
**res_de
,char scantype
)
471 for (count
= 0; count
< MSDOS_SB(sb
)->dir_entries
/MSDOS_DPS
; count
++) {
472 if ((cluster
= raw_scan_sector(sb
,MSDOS_SB(sb
)->dir_start
+count
,
473 name
,number
,ino
,res_bh
,res_de
,scantype
)) >= 0) return cluster
;
480 * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
481 * requested entry is found or the end of the directory is reached.
484 static int raw_scan_nonroot(struct super_block
*sb
,int start
,const char *name
,
485 int *number
,int *ino
,struct buffer_head
**res_bh
,struct msdos_dir_entry
486 **res_de
,char scantype
)
491 printk("raw_scan_nonroot: start=%d\n",start
);
494 for (count
= 0; count
< MSDOS_SB(sb
)->cluster_size
; count
++) {
495 if ((cluster
= raw_scan_sector(sb
,(start
-2)*
496 MSDOS_SB(sb
)->cluster_size
+MSDOS_SB(sb
)->data_start
+
497 count
,name
,number
,ino
,res_bh
,res_de
,scantype
)) >= 0)
500 if (!(start
= fat_access(sb
,start
,-1))) {
501 fat_fs_panic(sb
,"FAT error");
505 printk("next start: %d\n",start
);
514 * raw_scan performs raw_scan_sector on any sector.
516 * NOTE: raw_scan must not be used on a directory that is is the process of
520 static int raw_scan(struct super_block
*sb
, int start
, const char *name
,
521 int *number
, int *ino
, struct buffer_head
**res_bh
,
522 struct msdos_dir_entry
**res_de
, char scantype
)
524 if (start
) return raw_scan_nonroot
525 (sb
,start
,name
,number
,ino
,res_bh
,res_de
,scantype
);
526 else return raw_scan_root
527 (sb
,name
,number
,ino
,res_bh
,res_de
,scantype
);
532 * fat_parent_ino returns the inode number of the parent directory of dir.
533 * File creation has to be deferred while fat_parent_ino is running to
537 int fat_parent_ino(struct inode
*dir
,int locked
)
540 int error
,curr
,prev
,nr
;
542 PRINTK(("fat_parent_ino: Debug 0\n"));
543 if (!S_ISDIR(dir
->i_mode
)) panic("Non-directory fed to m_p_i");
544 if (dir
->i_ino
== MSDOS_ROOT_INO
) return dir
->i_ino
;
545 if (!locked
) fat_lock_creation(); /* prevent renames */
546 if ((curr
= raw_scan(dir
->i_sb
,MSDOS_I(dir
)->i_start
,MSDOS_DOTDOT
,
547 &zero
,NULL
,NULL
,NULL
,SCAN_ANY
)) < 0) {
548 if (!locked
) fat_unlock_creation();
551 PRINTK(("fat_parent_ino: Debug 1 curr=%d\n", curr
));
552 if (!curr
) nr
= MSDOS_ROOT_INO
;
554 PRINTK(("fat_parent_ino: Debug 2\n"));
555 if ((prev
= raw_scan(dir
->i_sb
,curr
,MSDOS_DOTDOT
,&zero
,NULL
,
556 NULL
,NULL
,SCAN_ANY
)) < 0) {
557 PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev
));
558 if (!locked
) fat_unlock_creation();
561 PRINTK(("fat_parent_ino: Debug 4 prev=%d\n", prev
));
562 if (prev
== 0 && MSDOS_SB(dir
->i_sb
)->fat_bits
== 32) {
563 prev
= MSDOS_SB(dir
->i_sb
)->root_cluster
;
565 if ((error
= raw_scan(dir
->i_sb
,prev
,NULL
,&curr
,&nr
,NULL
,
566 NULL
,SCAN_ANY
)) < 0) {
567 PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error
));
568 if (!locked
) fat_unlock_creation();
571 PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr
));
573 if (!locked
) fat_unlock_creation();
579 * fat_subdirs counts the number of sub-directories of dir. It can be run
580 * on directories being created.
583 int fat_subdirs(struct inode
*dir
)
588 if ((dir
->i_ino
== MSDOS_ROOT_INO
) &&
589 (MSDOS_SB(dir
->i_sb
)->fat_bits
!= 32)) {
590 (void) raw_scan_root(dir
->i_sb
,NULL
,&count
,NULL
,NULL
,NULL
,SCAN_ANY
);
592 if ((dir
->i_ino
!= MSDOS_ROOT_INO
) &&
593 !MSDOS_I(dir
)->i_start
) return 0; /* in mkdir */
594 else (void) raw_scan_nonroot(dir
->i_sb
,MSDOS_I(dir
)->i_start
,
595 NULL
,&count
,NULL
,NULL
,NULL
,SCAN_ANY
);
602 * Scans a directory for a given file (name points to its formatted name) or
603 * for an empty directory slot (name is NULL). Returns an error code or zero.
606 int fat_scan(struct inode
*dir
,const char *name
,struct buffer_head
**res_bh
,
607 struct msdos_dir_entry
**res_de
,int *ino
, char scantype
)
611 res
= raw_scan(dir
->i_sb
,MSDOS_I(dir
)->i_start
,
612 name
, NULL
, ino
, res_bh
, res_de
, scantype
);
613 return res
<0 ? res
: 0;