1 /*
2  *  linux/fs/fat/misc.c
3  *
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)
7  */
8 
9 #include <linux/fs.h>
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>
16 
17 #if 0
18 #  define PRINTK(x)	printk x
19 #else
20 #  define PRINTK(x)
21 #endif
22 #define Printk(x)	printk x
23 
24 /* Well-known binary file extensions - of course there are many more */
25 
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 */
33   "TEX";				/* TeX */
34 
35 
36 /*
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.
39  */
40 
fat_fs_panic(struct super_block * s,const char * msg)41 void fat_fs_panic(struct super_block *s,const char *msg)
42 {
43 	int not_ro;
44 
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);
48 	if (not_ro)
49 		printk("  File system has been set read-only\n");
50 }
51 
52 
53 /*
54  * fat_is_binary selects optional text conversion based on the conversion mode
55  * and the extension part of the file name.
56  */
57 
fat_is_binary(char conversion,char * extension)58 int fat_is_binary(char conversion,char *extension)
59 {
60 	char *walk;
61 
62 	switch (conversion) {
63 		case 'b':
64 			return 1;
65 		case 't':
66 			return 0;
67 		case 'a':
68 			for (walk = ascii_extensions; *walk; walk += 3)
69 				if (!strncmp(extension,walk,3)) return 0;
70 			return 1;	/* default binary conversion */
71 		default:
72 			printk("Invalid conversion mode - defaulting to "
73 			    "binary.\n");
74 			return 1;
75 	}
76 }
77 
lock_fat(struct super_block * sb)78 void lock_fat(struct super_block *sb)
79 {
80 	down(&(MSDOS_SB(sb)->fat_lock));
81 }
82 
unlock_fat(struct super_block * sb)83 void unlock_fat(struct super_block *sb)
84 {
85 	up(&(MSDOS_SB(sb)->fat_lock));
86 }
87 
88 /* Flushes the number of free clusters on FAT32 */
89 /* XXX: Need to write one per FSINFO block.  Currently only writes 1 */
fat_clusters_flush(struct super_block * sb)90 void fat_clusters_flush(struct super_block *sb)
91 {
92 	struct buffer_head *bh;
93 	struct fat_boot_fsinfo *fsinfo;
94 
95 	bh = fat_bread(sb, MSDOS_SB(sb)->fsinfo_sector);
96 	if (bh == NULL) {
97 		printk("FAT bread failed in fat_clusters_flush\n");
98 		return;
99 	}
100 
101 	fsinfo = (struct fat_boot_fsinfo *)bh->b_data;
102 	/* Sanity check */
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);
108 		return;
109 	}
110 	fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
111 	fsinfo->next_cluster = CF_LE_L(MSDOS_SB(sb)->prev_free);
112 	fat_mark_buffer_dirty(sb, bh);
113 	fat_brelse(sb, bh);
114 }
115 
116 /*
117  * fat_add_cluster tries to allocate a new cluster and adds it to the
118  * file represented by inode.
119  */
fat_add_cluster(struct inode * inode)120 int fat_add_cluster(struct inode *inode)
121 {
122 	struct super_block *sb = inode->i_sb;
123 	int count, nr, limit, last, curr, file_cluster;
124 	int cluster_size = MSDOS_SB(sb)->cluster_size;
125 	int res = -ENOSPC;
126 
127 	lock_fat(sb);
128 
129 	if (MSDOS_SB(sb)->free_clusters == 0) {
130 		unlock_fat(sb);
131 		return res;
132 	}
133 	limit = MSDOS_SB(sb)->clusters;
134 	nr = limit; /* to keep GCC happy */
135 	for (count = 0; count < limit; count++) {
136 		nr = ((count + MSDOS_SB(sb)->prev_free) % limit) + 2;
137 		if (fat_access(sb, nr, -1) == 0)
138 			break;
139 	}
140 	if (count >= limit) {
141 		MSDOS_SB(sb)->free_clusters = 0;
142 		unlock_fat(sb);
143 		return res;
144 	}
145 
146 	MSDOS_SB(sb)->prev_free = (count + MSDOS_SB(sb)->prev_free + 1) % limit;
147 	fat_access(sb, nr, EOF_FAT(sb));
148 	if (MSDOS_SB(sb)->free_clusters != -1)
149 		MSDOS_SB(sb)->free_clusters--;
150 	if (MSDOS_SB(sb)->fat_bits == 32)
151 		fat_clusters_flush(sb);
152 
153 	unlock_fat(sb);
154 
155 	/* We must locate the last cluster of the file to add this
156 	   new one (nr) to the end of the link list (the FAT).
157 
158 	   Here file_cluster will be the number of the last cluster of the
159 	   file (before we add nr).
160 
161 	   last is the corresponding cluster number on the disk. We will
162 	   use last to plug the nr cluster. We will use file_cluster to
163 	   update the cache.
164 	*/
165 	last = file_cluster = 0;
166 	if ((curr = MSDOS_I(inode)->i_start) != 0) {
167 		fat_cache_lookup(inode, INT_MAX, &last, &curr);
168 		file_cluster = last;
169 		while (curr && curr != -1){
170 			file_cluster++;
171 			if (!(curr = fat_access(sb, last = curr,-1))) {
172 				fat_fs_panic(sb, "File without EOF");
173 				return res;
174 			}
175 		}
176 	}
177 	if (last) {
178 		fat_access(sb, last, nr);
179 		fat_cache_add(inode, file_cluster, nr);
180 	} else {
181 		MSDOS_I(inode)->i_start = nr;
182 		MSDOS_I(inode)->i_logstart = nr;
183 		mark_inode_dirty(inode);
184 	}
185 	if (file_cluster
186 	    != inode->i_blocks / cluster_size / (sb->s_blocksize / 512)) {
187 		printk ("file_cluster badly computed!!! %d <> %ld\n",
188 			file_cluster,
189 			inode->i_blocks / cluster_size / (sb->s_blocksize / 512));
190 		fat_cache_inval_inode(inode);
191 	}
192 	inode->i_blocks += (1 << MSDOS_SB(sb)->cluster_bits) / 512;
193 
194 	return nr;
195 }
196 
fat_extend_dir(struct inode * inode)197 struct buffer_head *fat_extend_dir(struct inode *inode)
198 {
199 	struct super_block *sb = inode->i_sb;
200 	int nr, sector, last_sector;
201 	struct buffer_head *bh, *res = NULL;
202 	int cluster_size = MSDOS_SB(sb)->cluster_size;
203 
204 	if (MSDOS_SB(sb)->fat_bits != 32) {
205 		if (inode->i_ino == MSDOS_ROOT_INO)
206 			return res;
207 	}
208 
209 	nr = fat_add_cluster(inode);
210 	if (nr < 0)
211 		return res;
212 
213 	sector = MSDOS_SB(sb)->data_start + (nr - 2) * cluster_size;
214 	last_sector = sector + cluster_size;
215 	if (MSDOS_SB(sb)->cvf_format && MSDOS_SB(sb)->cvf_format->zero_out_cluster)
216 		MSDOS_SB(sb)->cvf_format->zero_out_cluster(inode, nr);
217 	else {
218 		for ( ; sector < last_sector; sector++) {
219 #ifdef DEBUG
220 			printk("zeroing sector %d\n", sector);
221 #endif
222 			if (!(bh = fat_getblk(sb, sector)))
223 				printk("getblk failed\n");
224 			else {
225 				memset(bh->b_data, 0, sb->s_blocksize);
226 				fat_set_uptodate(sb, bh, 1);
227 				fat_mark_buffer_dirty(sb, bh);
228 				if (!res)
229 					res = bh;
230 				else
231 					fat_brelse(sb, bh);
232 			}
233 		}
234 	}
235 	if (inode->i_size & (sb->s_blocksize - 1)) {
236 		fat_fs_panic(sb, "Odd directory size");
237 		inode->i_size = (inode->i_size + sb->s_blocksize)
238 			& ~(sb->s_blocksize - 1);
239 	}
240 	inode->i_size += 1 << MSDOS_SB(sb)->cluster_bits;
241 	MSDOS_I(inode)->mmu_private += 1 << MSDOS_SB(sb)->cluster_bits;
242 	mark_inode_dirty(inode);
243 
244 	return res;
245 }
246 
247 /* Linear day numbers of the respective 1sts in non-leap years. */
248 
249 static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
250 		  /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
251 
252 
253 extern struct timezone sys_tz;
254 
255 
256 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
257 
date_dos2unix(unsigned short time,unsigned short date)258 int date_dos2unix(unsigned short time,unsigned short date)
259 {
260 	int month,year,secs;
261 
262 	/* first subtract and mask after that... Otherwise, if
263 	   date == 0, bad things happen */
264 	month = ((date >> 5) - 1) & 15;
265 	year = date >> 9;
266 	secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
267 	    ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
268 	    month < 2 ? 1 : 0)+3653);
269 			/* days since 1.1.70 plus 80's leap day */
270 	secs += sys_tz.tz_minuteswest*60;
271 	return secs;
272 }
273 
274 
275 /* Convert linear UNIX date to a MS-DOS time/date pair. */
276 
fat_date_unix2dos(int unix_date,unsigned short * time,unsigned short * date)277 void fat_date_unix2dos(int unix_date,unsigned short *time,
278     unsigned short *date)
279 {
280 	int day,year,nl_day,month;
281 
282 	unix_date -= sys_tz.tz_minuteswest*60;
283 
284 	/* Jan 1 GMT 00:00:00 1980. But what about another time zone? */
285 	if (unix_date < 315532800)
286 		unix_date = 315532800;
287 
288 	*time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
289 	    (((unix_date/3600) % 24) << 11);
290 	day = unix_date/86400-3652;
291 	year = day/365;
292 	if ((year+3)/4+365*year > day) year--;
293 	day -= (year+3)/4+365*year;
294 	if (day == 59 && !(year & 3)) {
295 		nl_day = day;
296 		month = 2;
297 	}
298 	else {
299 		nl_day = (year & 3) || day <= 59 ? day : day-1;
300 		for (month = 0; month < 12; month++)
301 			if (day_n[month] > nl_day) break;
302 	}
303 	*date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
304 }
305 
306 
307 /* Returns the inode number of the directory entry at offset pos. If bh is
308    non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
309    returned in bh.
310    AV. Most often we do it item-by-item. Makes sense to optimize.
311    AV. OK, there we go: if both bh and de are non-NULL we assume that we just
312    AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
313    AV. It's done in fat_get_entry() (inlined), here the slow case lives.
314    AV. Additionally, when we return -1 (i.e. reached the end of directory)
315    AV. we make bh NULL.
316  */
317 
fat__get_entry(struct inode * dir,loff_t * pos,struct buffer_head ** bh,struct msdos_dir_entry ** de,loff_t * i_pos)318 int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
319 		   struct msdos_dir_entry **de, loff_t *i_pos)
320 {
321 	struct super_block *sb = dir->i_sb;
322 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
323 	int sector;
324 	loff_t offset;
325 
326 	while (1) {
327 		offset = *pos;
328 		PRINTK (("get_entry offset %d\n",offset));
329 		if (*bh)
330 			fat_brelse(sb, *bh);
331 		*bh = NULL;
332 		if ((sector = fat_bmap(dir,offset >> sb->s_blocksize_bits)) == -1)
333 			return -1;
334 		PRINTK (("get_entry sector %d %p\n",sector,*bh));
335 		PRINTK (("get_entry sector apres brelse\n"));
336 		if (!sector)
337 			return -1; /* beyond EOF */
338 		*pos += sizeof(struct msdos_dir_entry);
339 		if (!(*bh = fat_bread(sb, sector))) {
340 			printk("Directory sread (sector 0x%x) failed\n",sector);
341 			continue;
342 		}
343 		PRINTK (("get_entry apres sread\n"));
344 
345 		offset &= sb->s_blocksize - 1;
346 		*de = (struct msdos_dir_entry *) ((*bh)->b_data + offset);
347 		*i_pos = ((loff_t)sector << sbi->dir_per_block_bits) + (offset >> MSDOS_DIR_BITS);
348 
349 		return 0;
350 	}
351 }
352 
353 
354 /*
355  * Now an ugly part: this set of directory scan routines works on clusters
356  * rather than on inodes and sectors. They are necessary to locate the '..'
357  * directory "inode". raw_scan_sector operates in four modes:
358  *
359  * name     number   ino      action
360  * -------- -------- -------- -------------------------------------------------
361  * non-NULL -        X        Find an entry with that name
362  * NULL     non-NULL non-NULL Find an entry whose data starts at *number
363  * NULL     non-NULL NULL     Count subdirectories in *number. (*)
364  * NULL     NULL     non-NULL Find an empty entry
365  *
366  * (*) The return code should be ignored. It DOES NOT indicate success or
367  *     failure. *number has to be initialized to zero.
368  *
369  * - = not used, X = a value is returned unless NULL
370  *
371  * If res_bh is non-NULL, the buffer is not deallocated but returned to the
372  * caller on success. res_de is set accordingly.
373  *
374  * If cont is non-zero, raw_found continues with the entry after the one
375  * res_bh/res_de point to.
376  */
377 
378 
379 #define RSS_NAME /* search for name */ \
380     done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
381      !(data[entry].attr & ATTR_VOLUME);
382 
383 #define RSS_START /* search for start cluster */ \
384     done = !IS_FREE(data[entry].name) \
385       && ( \
386            ( \
387              (sbi->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
388            ) \
389            | CF_LE_W(data[entry].start) \
390          ) == *number;
391 
392 #define RSS_FREE /* search for free entry */ \
393     { \
394 	done = IS_FREE(data[entry].name); \
395     }
396 
397 #define RSS_COUNT /* count subdirectories */ \
398     { \
399 	done = 0; \
400 	if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
401 	    (*number)++; \
402     }
403 
raw_scan_sector(struct super_block * sb,int sector,const char * name,int * number,loff_t * i_pos,struct buffer_head ** res_bh,struct msdos_dir_entry ** res_de)404 static int raw_scan_sector(struct super_block *sb, int sector,
405 			   const char *name, int *number, loff_t *i_pos,
406 			   struct buffer_head **res_bh,
407 			   struct msdos_dir_entry **res_de)
408 {
409 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
410 	struct buffer_head *bh;
411 	struct msdos_dir_entry *data;
412 	int entry,start,done;
413 
414 	if (!(bh = fat_bread(sb, sector)))
415 		return -EIO;
416 	data = (struct msdos_dir_entry *) bh->b_data;
417 	for (entry = 0; entry < sbi->dir_per_block; entry++) {
418 /* RSS_COUNT:  if (data[entry].name == name) done=true else done=false. */
419 		if (name) {
420 			RSS_NAME
421 		} else {
422 			if (!i_pos) RSS_COUNT
423 			else {
424 				if (number) RSS_START
425 				else RSS_FREE
426 			}
427 		}
428 		if (done) {
429 			if (i_pos) {
430 				*i_pos = ((loff_t)sector << sbi->dir_per_block_bits) + entry;
431 			}
432 			start = CF_LE_W(data[entry].start);
433 			if (sbi->fat_bits == 32)
434 				start |= (CF_LE_W(data[entry].starthi) << 16);
435 
436 			if (!res_bh)
437 				fat_brelse(sb, bh);
438 			else {
439 				*res_bh = bh;
440 				*res_de = &data[entry];
441 			}
442 			return start;
443 		}
444 	}
445 	fat_brelse(sb, bh);
446 	return -ENOENT;
447 }
448 
449 
450 /*
451  * raw_scan_root performs raw_scan_sector on the root directory until the
452  * requested entry is found or the end of the directory is reached.
453  */
454 
raw_scan_root(struct super_block * sb,const char * name,int * number,loff_t * i_pos,struct buffer_head ** res_bh,struct msdos_dir_entry ** res_de)455 static int raw_scan_root(struct super_block *sb, const char *name,
456 			 int *number, loff_t *i_pos,
457 			 struct buffer_head **res_bh,
458 			 struct msdos_dir_entry **res_de)
459 {
460 	int count,cluster;
461 
462 	for (count = 0;
463 	     count < MSDOS_SB(sb)->dir_entries / MSDOS_SB(sb)->dir_per_block;
464 	     count++) {
465 		cluster = raw_scan_sector(sb, MSDOS_SB(sb)->dir_start + count,
466 					  name, number, i_pos, res_bh, res_de);
467 		if (cluster >= 0)
468 			return cluster;
469 	}
470 	return -ENOENT;
471 }
472 
473 
474 /*
475  * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
476  * requested entry is found or the end of the directory is reached.
477  */
478 
raw_scan_nonroot(struct super_block * sb,int start,const char * name,int * number,loff_t * i_pos,struct buffer_head ** res_bh,struct msdos_dir_entry ** res_de)479 static int raw_scan_nonroot(struct super_block *sb, int start, const char *name,
480 			    int *number, loff_t *i_pos,
481 			    struct buffer_head **res_bh,
482 			    struct msdos_dir_entry **res_de)
483 {
484 	struct msdos_sb_info *sbi = MSDOS_SB(sb);
485 	int count, cluster, sector;
486 
487 #ifdef DEBUG
488 	printk("raw_scan_nonroot: start=%d\n",start);
489 #endif
490 	do {
491 		for (count = 0; count < sbi->cluster_size; count++) {
492 			sector = (start - 2) * sbi->cluster_size
493 				+ count + sbi->data_start;
494 			cluster = raw_scan_sector(sb, sector, name, number,
495 						  i_pos, res_bh, res_de);
496 			if (cluster >= 0)
497 				return cluster;
498 		}
499 		if (!(start = fat_access(sb,start,-1))) {
500 			fat_fs_panic(sb,"FAT error");
501 			break;
502 		}
503 #ifdef DEBUG
504 	printk("next start: %d\n",start);
505 #endif
506 	}
507 	while (start != -1);
508 	return -ENOENT;
509 }
510 
511 
512 /*
513  * raw_scan performs raw_scan_sector on any sector.
514  *
515  * NOTE: raw_scan must not be used on a directory that is is the process of
516  *       being created.
517  */
518 
raw_scan(struct super_block * sb,int start,const char * name,loff_t * i_pos,struct buffer_head ** res_bh,struct msdos_dir_entry ** res_de)519 static int raw_scan(struct super_block *sb, int start, const char *name,
520 		    loff_t *i_pos, struct buffer_head **res_bh,
521 		    struct msdos_dir_entry **res_de)
522 {
523 	if (start)
524 		return raw_scan_nonroot(sb,start,name,NULL,i_pos,res_bh,res_de);
525 	else
526 		return raw_scan_root(sb,name,NULL,i_pos,res_bh,res_de);
527 }
528 
529 /*
530  * fat_subdirs counts the number of sub-directories of dir. It can be run
531  * on directories being created.
532  */
fat_subdirs(struct inode * dir)533 int fat_subdirs(struct inode *dir)
534 {
535 	struct msdos_sb_info *sbi = MSDOS_SB(dir->i_sb);
536 	int number;
537 
538 	number = 0;
539 	if ((dir->i_ino == MSDOS_ROOT_INO) && (sbi->fat_bits != 32))
540 		raw_scan_root(dir->i_sb, NULL, &number, NULL, NULL, NULL);
541 	else {
542 		if ((dir->i_ino != MSDOS_ROOT_INO) && !MSDOS_I(dir)->i_start)
543 			return 0; /* in mkdir */
544 		else {
545 			raw_scan_nonroot(dir->i_sb, MSDOS_I(dir)->i_start,
546 					 NULL, &number, NULL, NULL, NULL);
547 		}
548 	}
549 	return number;
550 }
551 
552 
553 /*
554  * Scans a directory for a given file (name points to its formatted name) or
555  * for an empty directory slot (name is NULL). Returns an error code or zero.
556  */
557 
fat_scan(struct inode * dir,const char * name,struct buffer_head ** res_bh,struct msdos_dir_entry ** res_de,loff_t * i_pos)558 int fat_scan(struct inode *dir, const char *name, struct buffer_head **res_bh,
559 	     struct msdos_dir_entry **res_de, loff_t *i_pos)
560 {
561 	int res;
562 
563 	res = raw_scan(dir->i_sb, MSDOS_I(dir)->i_start, name, i_pos,
564 		       res_bh, res_de);
565 	return (res < 0) ? res : 0;
566 }
567