4 * Written 1992,1993 by Werner Almesberger
5 * 22/11/2000 - Fixed fat_date_unix2dos for dates earlier than 01/01/1980
6 * and date_dos2unix for date==0 by Igor Zhbanov(bsg@uniyar.ac.ru)
10 #include <linux/msdos_fs.h>
11 #include <linux/sched.h>
12 #include <linux/kernel.h>
13 #include <linux/errno.h>
14 #include <linux/string.h>
15 #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 "
78 void lock_fat(struct super_block *sb)
80 down(&(MSDOS_SB(sb)->fat_lock));
83 void unlock_fat(struct super_block *sb)
85 up(&(MSDOS_SB(sb)->fat_lock));
88 /* Flushes the number of free clusters on FAT32 */
89 /* XXX: Need to write one per FSINFO block. Currently only writes 1 */
90 void fat_clusters_flush(struct super_block *sb)
92 struct buffer_head *bh;
93 struct fat_boot_fsinfo *fsinfo;
95 bh = fat_bread(sb, MSDOS_SB(sb)->fsinfo_sector);
97 printk("FAT bread failed in fat_clusters_flush\n");
101 fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
103 if (!IS_FSINFO(fsinfo)) {
104 printk("FAT: Did not find valid FSINFO signature.\n"
105 "Found signature1 0x%x signature2 0x%x sector=%ld.\n",
106 CF_LE_L(fsinfo->signature1), CF_LE_L(fsinfo->signature2),
107 MSDOS_SB(sb)->fsinfo_sector);
110 fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
111 fat_mark_buffer_dirty(sb, bh);
116 * fat_add_cluster tries to allocate a new cluster and adds it to the
117 * file represented by inode.
119 int fat_add_cluster(struct inode *inode)
121 struct super_block *sb = inode->i_sb;
122 int count, nr, limit, last, curr, file_cluster;
123 int cluster_size = MSDOS_SB(sb)->cluster_size;
128 if (MSDOS_SB(sb)->free_clusters == 0) {
132 limit = MSDOS_SB(sb)->clusters;
133 nr = limit; /* to keep GCC happy */
134 for (count = 0; count < limit; count++) {
135 nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2;
136 if (fat_access(sb, nr, -1) == 0)
139 if (count >= limit) {
140 MSDOS_SB(sb)->free_clusters = 0;
145 MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit;
146 fat_access(sb, nr, EOF_FAT(sb));
147 if (MSDOS_SB(sb)->free_clusters != -1)
148 MSDOS_SB(sb)->free_clusters--;
149 if (MSDOS_SB(sb)->fat_bits == 32)
150 fat_clusters_flush(sb);
154 /* We must locate the last cluster of the file to add this
155 new one (nr) to the end of the link list (the FAT).
157 Here file_cluster will be the number of the last cluster of the
158 file (before we add nr).
160 last is the corresponding cluster number on the disk. We will
161 use last to plug the nr cluster. We will use file_cluster to
164 last = file_cluster = 0;
165 if ((curr = MSDOS_I(inode)->i_start) != 0) {
166 fat_cache_lookup(inode, INT_MAX, &last, &curr);
168 while (curr && curr != -1){
170 if (!(curr = fat_access(sb, last = curr,-1))) {
171 fat_fs_panic(sb, "File without EOF");
177 fat_access(sb, last, nr);
178 fat_cache_add(inode, file_cluster, nr);
180 MSDOS_I(inode)->i_start = nr;
181 MSDOS_I(inode)->i_logstart = nr;
182 mark_inode_dirty(inode);
185 != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
186 printk ("file_cluster badly computed!!! %d <> %ld\n",
188 inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
189 fat_cache_inval_inode(inode);
191 inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;
196 struct buffer_head *fat_extend_dir(struct inode *inode)
198 struct super_block *sb = inode->i_sb;
199 int nr, sector, last_sector;
200 struct buffer_head *bh, *res = NULL;
201 int cluster_size = MSDOS_SB(sb)->cluster_size;
203 if (MSDOS_SB(sb)->fat_bits != 32) {
204 if (inode->i_ino == MSDOS_ROOT_INO)
208 nr = fat_add_cluster(inode);
212 sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size;
213 last_sector = sector + cluster_size;
214 if (MSDOS_SB(sb)->cvf_format && MSDOS_SB(sb)->cvf_format->zero_out_cluster)
215 MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode, nr);
217 for ( ; sector < last_sector; sector++) {
219 printk("zeroing sector %d\n", sector);
221 if (!(bh = fat_getblk(sb, sector)))
222 printk("getblk failed\n");
224 memset(bh->b_data, 0, sb->s_blocksize);
225 fat_set_uptodate(sb, bh, 1);
226 fat_mark_buffer_dirty(sb, bh);
234 if (inode->i_size & (sb->s_blocksize - 1)) {
235 fat_fs_panic(sb, "Odd directory size");
236 inode->i_size = (inode->i_size + sb->s_blocksize)
237 & ~(sb->s_blocksize - 1);
239 inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits;
240 MSDOS_I(inode)->mmu_private += 1 << MSDOS_SB(sb)->cluster_bits;
241 mark_inode_dirty(inode);
246 /* Linear day numbers of the respective 1sts in non-leap years. */
248 static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
249 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
252 extern struct timezone sys_tz;
255 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
257 int date_dos2unix(unsigned short time,unsigned short date)
261 /* first subtract and mask after that... Otherwise, if
262 date == 0, bad things happen */
263 month = ((date >> 5) - 1) & 15;
265 secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
266 ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
267 month < 2 ? 1 : 0)+3653);
268 /* days since 1.1.70 plus 80's leap day */
269 secs += sys_tz.tz_minuteswest*60;
274 /* Convert linear UNIX date to a MS-DOS time/date pair. */
276 void fat_date_unix2dos(int unix_date,unsigned short *time,
277 unsigned short *date)
279 int day,year,nl_day,month;
281 unix_date -= sys_tz.tz_minuteswest*60;
283 /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
284 if (unix_date < 315532800)
285 unix_date = 315532800;
287 *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
288 (((unix_date/3600) % 24) << 11);
289 day = unix_date/86400-3652;
291 if ((year+3)/4+365*year > day) year--;
292 day -= (year+3)/4+365*year;
293 if (day == 59 && !(year & 3)) {
298 nl_day = (year & 3) || day <= 59 ? day : day-1;
299 for (month = 0; month < 12; month++)
300 if (day_n[month] > nl_day) break;
302 *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
306 /* Returns the inode number of the directory entry at offset pos. If bh is
307 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
309 AV. Most often we do it item-by-item. Makes sense to optimize.
310 AV. OK, there we go: if both bh and de are non-NULL we assume that we just
311 AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
312 AV. It's done in fat_get_entry() (inlined), here the slow case lives.
313 AV. Additionally, when we return -1 (i.e. reached the end of directory)
317 int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
318 struct msdos_dir_entry **de, int *ino)
320 struct super_block *sb = dir->i_sb;
321 struct msdos_sb_info *sbi = MSDOS_SB(sb);
326 PRINTK (("get_entry offset %d\n",offset));
330 if ((sector = fat_bmap(dir,offset >> sb->s_blocksize_bits)) == -1)
332 PRINTK (("get_entry sector %d %p\n",sector,*bh));
333 PRINTK (("get_entry sector apres brelse\n"));
335 return -1; /* beyond EOF */
336 *pos += sizeof(struct msdos_dir_entry);
337 if (!(*bh = fat_bread(sb, sector))) {
338 printk("Directory sread (sector 0x%x) failed\n",sector);
341 PRINTK (("get_entry apres sread\n"));
343 offset &= sb->s_blocksize - 1;
344 *de = (struct msdos_dir_entry *) ((*bh)->b_data + offset);
345 *ino = (sector << sbi->dir_per_block_bits) + (offset >> MSDOS_DIR_BITS);
353 * Now an ugly part: this set of directory scan routines works on clusters
354 * rather than on inodes and sectors. They are necessary to locate the '..'
355 * directory "inode". raw_scan_sector operates in four modes:
357 * name number ino action
358 * -------- -------- -------- -------------------------------------------------
359 * non-NULL - X Find an entry with that name
360 * NULL non-NULL non-NULL Find an entry whose data starts at *number
361 * NULL non-NULL NULL Count subdirectories in *number. (*)
362 * NULL NULL non-NULL Find an empty entry
364 * (*) The return code should be ignored. It DOES NOT indicate success or
365 * failure. *number has to be initialized to zero.
367 * - = not used, X = a value is returned unless NULL
369 * If res_bh is non-NULL, the buffer is not deallocated but returned to the
370 * caller on success. res_de is set accordingly.
372 * If cont is non-zero, raw_found continues with the entry after the one
373 * res_bh/res_de point to.
377 #define RSS_NAME /* search for name */ \
378 done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
379 !(data[entry].attr & ATTR_VOLUME);
381 #define RSS_START /* search for start cluster */ \
382 done = !IS_FREE(data[entry].name) \
385 (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
387 | CF_LE_W(data[entry].start) \
390 #define RSS_FREE /* search for free entry */ \
392 done = IS_FREE(data[entry].name); \
395 #define RSS_COUNT /* count subdirectories */ \
398 if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
402 static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
403 int *number,int *ino,struct buffer_head **res_bh,
404 struct msdos_dir_entry **res_de)
406 struct buffer_head *bh;
407 struct msdos_dir_entry *data;
408 int entry,start,done;
410 if (!(bh = fat_bread(sb,sector)))
412 data = (struct msdos_dir_entry *) bh->b_data;
413 for (entry = 0; entry < MSDOS_SB(sb)->dir_per_block; entry++) {
414 /* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
420 if (number) RSS_START
426 *ino = sector * MSDOS_SB(sb)->dir_per_block + entry;
427 start = CF_LE_W(data[entry].start);
428 if (MSDOS_SB(sb)->fat_bits == 32) {
429 start |= (CF_LE_W(data[entry].starthi) << 16);
435 *res_de = &data[entry];
446 * raw_scan_root performs raw_scan_sector on the root directory until the
447 * requested entry is found or the end of the directory is reached.
450 static int raw_scan_root(struct super_block *sb,const char *name,int *number,int *ino,
451 struct buffer_head **res_bh,struct msdos_dir_entry **res_de)
456 count < MSDOS_SB(sb)->dir_entries / MSDOS_SB(sb)->dir_per_block;
458 if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count,
459 name,number,ino,res_bh,res_de)) >= 0)
467 * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
468 * requested entry is found or the end of the directory is reached.
471 static int raw_scan_nonroot(struct super_block *sb,int start,const char *name,
472 int *number,int *ino,struct buffer_head **res_bh,struct msdos_dir_entry
478 printk("raw_scan_nonroot: start=%d\n",start);
481 for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) {
482 if ((cluster = raw_scan_sector(sb,(start-2)*
483 MSDOS_SB(sb)->cluster_size+MSDOS_SB(sb)->data_start+
484 count,name,number,ino,res_bh,res_de)) >= 0)
487 if (!(start = fat_access(sb,start,-1))) {
488 fat_fs_panic(sb,"FAT error");
492 printk("next start: %d\n",start);
501 * raw_scan performs raw_scan_sector on any sector.
503 * NOTE: raw_scan must not be used on a directory that is is the process of
507 static int raw_scan(struct super_block *sb, int start, const char *name,
508 int *number, int *ino, struct buffer_head **res_bh,
509 struct msdos_dir_entry **res_de)
512 return raw_scan_nonroot(sb,start,name,number,ino,res_bh,res_de);
514 return raw_scan_root(sb,name,number,ino,res_bh,res_de);
518 * fat_subdirs counts the number of sub-directories of dir. It can be run
519 * on directories being created.
521 int fat_subdirs(struct inode *dir)
526 if ((dir->i_ino == MSDOS_ROOT_INO) &&
527 (MSDOS_SB(dir->i_sb)->fat_bits != 32)) {
528 (void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL);
530 if ((dir->i_ino != MSDOS_ROOT_INO) &&
531 !MSDOS_I(dir)->i_start) return 0; /* in mkdir */
532 else (void) raw_scan_nonroot(dir->i_sb,MSDOS_I(dir)->i_start,
533 NULL,&count,NULL,NULL,NULL);
540 * Scans a directory for a given file (name points to its formatted name) or
541 * for an empty directory slot (name is NULL). Returns an error code or zero.
544 int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh,
545 struct msdos_dir_entry **res_de,int *ino)
549 res = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,
550 name, NULL, ino, res_bh, res_de);
551 return res<0 ? res : 0;