Import 2.3.2
[davej-history.git] / fs / fat / misc.c
blob4cd218d589c90c7d69dacf2916e73183fc4f261b
1 /*
2 * linux/fs/fat/misc.c
4 * Written 1992,1993 by Werner Almesberger
5 */
7 #include <linux/fs.h>
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>
15 #include "msbuffer.h"
17 #if 0
18 # define PRINTK(x) printk x
19 #else
20 # define PRINTK(x)
21 #endif
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 */
33 "TEX"; /* TeX */
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)
43 int not_ro;
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");
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)
60 char *walk;
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;
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_WAIT_QUEUE_HEAD(creation_wait);
83 static int creation_lock = 0;
86 void fat_lock_creation(void)
88 while (creation_lock) sleep_on(&creation_wait);
89 creation_lock = 1;
93 void fat_unlock_creation(void)
95 creation_lock = 0;
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)
117 int offset;
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));
124 if (bh == NULL) {
125 printk("FAT bread failed in fat_clusters_flush\n");
126 return;
128 fsinfo = (struct fat_boot_fsinfo *)
129 &bh->b_data[offset & (SECTOR_SIZE-1)];
131 /* Sanity check */
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);
134 fat_brelse(sb, bh);
135 return;
137 fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
138 fat_mark_buffer_dirty(sb, bh, 1);
139 fat_brelse(sb, bh);
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 struct buffer_head *fat_add_cluster1(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, *res=NULL;
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 res;
157 if (!MSDOS_SB(sb)->free_clusters) return res;
158 lock_fat(sb);
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));
166 #ifdef DEBUG
167 printk("free cluster: %d\n",nr);
168 #endif
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;
172 unlock_fat(sb);
173 return res;
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);
180 unlock_fat(sb);
181 #ifdef DEBUG
182 printk("set to %x\n",fat_access(sb,nr,-1));
183 #endif
184 last = 0;
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
193 update the cache.
195 file_cluster = 0;
196 if ((curr = MSDOS_I(inode)->i_start) != 0) {
197 fat_cache_lookup(inode,INT_MAX,&last,&curr);
198 file_cluster = last;
199 while (curr && curr != -1){
200 PRINTK (("."));
201 file_cluster++;
202 if (!(curr = fat_access(sb,
203 last = curr,-1))) {
204 fat_fs_panic(sb,"File without EOF");
205 return res;
208 PRINTK ((" -- "));
210 #ifdef DEBUG
211 printk("last = %d\n",last);
212 #endif
213 if (last) fat_access(sb,last,nr);
214 else {
215 MSDOS_I(inode)->i_start = nr;
216 MSDOS_I(inode)->i_logstart = nr;
217 mark_inode_dirty(inode);
219 #ifdef DEBUG
220 if (last) printk("next set to %d\n",fat_access(sb,last,-1));
221 #endif
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);
227 else
228 for ( ; sector < last_sector; sector++) {
229 #ifdef DEBUG
230 printk("zeroing sector %d\n",sector);
231 #endif
232 if (!(bh = fat_getblk(sb, sector)))
233 printk("getblk failed\n");
234 else {
235 memset(bh->b_data,0,SECTOR_SIZE);
236 fat_set_uptodate(sb, bh, 1);
237 fat_mark_buffer_dirty(sb, bh, 1);
238 if (!res)
239 res=bh;
240 else
241 fat_brelse(sb, bh);
244 if (file_cluster != inode->i_blocks/cluster_size){
245 printk ("file_cluster badly computed!!! %d <> %ld\n"
246 ,file_cluster,inode->i_blocks/cluster_size);
247 }else{
248 fat_cache_add(inode,file_cluster,nr);
250 inode->i_blocks += cluster_size;
251 if (S_ISDIR(inode->i_mode)) {
252 if (inode->i_size & (SECTOR_SIZE-1)) {
253 fat_fs_panic(sb,"Odd directory size");
254 inode->i_size = (inode->i_size+SECTOR_SIZE) &
255 ~(SECTOR_SIZE-1);
257 inode->i_size += SECTOR_SIZE*cluster_size;
258 #ifdef DEBUG
259 printk("size is %d now (%x)\n",inode->i_size,inode);
260 #endif
261 mark_inode_dirty(inode);
263 return res;
266 int fat_add_cluster(struct inode *inode)
268 struct buffer_head *bh = fat_add_cluster1(inode);
269 if (!bh)
270 return -ENOSPC;
271 fat_brelse(inode->i_sb, bh);
272 return 0;
275 /* Linear day numbers of the respective 1sts in non-leap years. */
277 static int day_n[] = { 0,31,59,90,120,151,181,212,243,273,304,334,0,0,0,0 };
278 /* JanFebMarApr May Jun Jul Aug Sep Oct Nov Dec */
281 extern struct timezone sys_tz;
284 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
286 int date_dos2unix(unsigned short time,unsigned short date)
288 int month,year,secs;
290 month = ((date >> 5) & 15)-1;
291 year = date >> 9;
292 secs = (time & 31)*2+60*((time >> 5) & 63)+(time >> 11)*3600+86400*
293 ((date & 31)-1+day_n[month]+(year/4)+year*365-((year & 3) == 0 &&
294 month < 2 ? 1 : 0)+3653);
295 /* days since 1.1.70 plus 80's leap day */
296 secs += sys_tz.tz_minuteswest*60;
297 if (sys_tz.tz_dsttime) secs -= 3600;
298 return secs;
302 /* Convert linear UNIX date to a MS-DOS time/date pair. */
304 void fat_date_unix2dos(int unix_date,unsigned short *time,
305 unsigned short *date)
307 int day,year,nl_day,month;
309 unix_date -= sys_tz.tz_minuteswest*60;
310 if (sys_tz.tz_dsttime) unix_date += 3600;
312 *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
313 (((unix_date/3600) % 24) << 11);
314 day = unix_date/86400-3652;
315 year = day/365;
316 if ((year+3)/4+365*year > day) year--;
317 day -= (year+3)/4+365*year;
318 if (day == 59 && !(year & 3)) {
319 nl_day = day;
320 month = 2;
322 else {
323 nl_day = (year & 3) || day <= 59 ? day : day-1;
324 for (month = 0; month < 12; month++)
325 if (day_n[month] > nl_day) break;
327 *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
331 /* Returns the inode number of the directory entry at offset pos. If bh is
332 non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
333 returned in bh.
334 AV. Most often we do it item-by-item. Makes sense to optimize.
335 AV. OK, there we go: if both bh and de are non-NULL we assume that we just
336 AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
337 AV. It's done in fat_get_entry() (inlined), here the slow case lives.
338 AV. Additionally, when we return -1 (i.e. reached the end of directory)
339 AV. we make bh NULL.
342 int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
343 struct msdos_dir_entry **de, int *ino)
345 struct super_block *sb = dir->i_sb;
346 int sector, offset;
348 while (1) {
349 offset = *pos;
350 PRINTK (("get_entry offset %d\n",offset));
351 if (*bh)
352 fat_brelse(sb, *bh);
353 *bh = NULL;
354 if ((sector = fat_smap(dir,offset >> SECTOR_BITS)) == -1)
355 return -1;
356 PRINTK (("get_entry sector %d %p\n",sector,*bh));
357 PRINTK (("get_entry sector apres brelse\n"));
358 if (!sector)
359 return -1; /* beyond EOF */
360 *pos += sizeof(struct msdos_dir_entry);
361 if (!(*bh = fat_bread(sb, sector))) {
362 printk("Directory sread (sector 0x%x) failed\n",sector);
363 continue;
365 PRINTK (("get_entry apres sread\n"));
366 *de = (struct msdos_dir_entry *) ((*bh)->b_data+(offset &
367 (SECTOR_SIZE-1)));
368 *ino = (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
369 MSDOS_DIR_BITS);
370 return 0;
376 * Now an ugly part: this set of directory scan routines works on clusters
377 * rather than on inodes and sectors. They are necessary to locate the '..'
378 * directory "inode". raw_scan_sector operates in four modes:
380 * name number ino action
381 * -------- -------- -------- -------------------------------------------------
382 * non-NULL - X Find an entry with that name
383 * NULL non-NULL non-NULL Find an entry whose data starts at *number
384 * NULL non-NULL NULL Count subdirectories in *number. (*)
385 * NULL NULL non-NULL Find an empty entry
387 * (*) The return code should be ignored. It DOES NOT indicate success or
388 * failure. *number has to be initialized to zero.
390 * - = not used, X = a value is returned unless NULL
392 * If res_bh is non-NULL, the buffer is not deallocated but returned to the
393 * caller on success. res_de is set accordingly.
395 * If cont is non-zero, raw_found continues with the entry after the one
396 * res_bh/res_de point to.
400 #define RSS_NAME /* search for name */ \
401 done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
402 !(data[entry].attr & ATTR_VOLUME);
404 #define RSS_START /* search for start cluster */ \
405 done = !IS_FREE(data[entry].name) \
406 && ( \
408 (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
410 | CF_LE_W(data[entry].start) \
411 ) == *number;
413 #define RSS_FREE /* search for free entry */ \
415 done = IS_FREE(data[entry].name); \
418 #define RSS_COUNT /* count subdirectories */ \
420 done = 0; \
421 if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
422 (*number)++; \
425 static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
426 int *number,int *ino,struct buffer_head **res_bh,
427 struct msdos_dir_entry **res_de)
429 struct buffer_head *bh;
430 struct msdos_dir_entry *data;
431 int entry,start,done;
433 if (!(bh = fat_bread(sb,sector)))
434 return -EIO;
435 data = (struct msdos_dir_entry *) bh->b_data;
436 for (entry = 0; entry < MSDOS_DPS; entry++) {
437 /* RSS_COUNT: if (data[entry].name == name) done=true else done=false. */
438 if (name) {
439 RSS_NAME
440 } else {
441 if (!ino) RSS_COUNT
442 else {
443 if (number) RSS_START
444 else RSS_FREE
447 if (done) {
448 if (ino) *ino = sector*MSDOS_DPS+entry;
449 start = CF_LE_W(data[entry].start);
450 if (MSDOS_SB(sb)->fat_bits == 32) {
451 start |= (CF_LE_W(data[entry].starthi) << 16);
453 if (!res_bh)
454 fat_brelse(sb, bh);
455 else {
456 *res_bh = bh;
457 *res_de = &data[entry];
459 return start;
462 fat_brelse(sb, bh);
463 return -ENOENT;
468 * raw_scan_root performs raw_scan_sector on the root directory until the
469 * requested entry is found or the end of the directory is reached.
472 static int raw_scan_root(struct super_block *sb,const char *name,int *number,int *ino,
473 struct buffer_head **res_bh,struct msdos_dir_entry **res_de)
475 int count,cluster;
477 for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) {
478 if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count,
479 name,number,ino,res_bh,res_de)) >= 0) return cluster;
481 return -ENOENT;
486 * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
487 * requested entry is found or the end of the directory is reached.
490 static int raw_scan_nonroot(struct super_block *sb,int start,const char *name,
491 int *number,int *ino,struct buffer_head **res_bh,struct msdos_dir_entry
492 **res_de)
494 int count,cluster;
496 #ifdef DEBUG
497 printk("raw_scan_nonroot: start=%d\n",start);
498 #endif
499 do {
500 for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) {
501 if ((cluster = raw_scan_sector(sb,(start-2)*
502 MSDOS_SB(sb)->cluster_size+MSDOS_SB(sb)->data_start+
503 count,name,number,ino,res_bh,res_de)) >= 0)
504 return cluster;
506 if (!(start = fat_access(sb,start,-1))) {
507 fat_fs_panic(sb,"FAT error");
508 break;
510 #ifdef DEBUG
511 printk("next start: %d\n",start);
512 #endif
514 while (start != -1);
515 return -ENOENT;
520 * raw_scan performs raw_scan_sector on any sector.
522 * NOTE: raw_scan must not be used on a directory that is is the process of
523 * being created.
526 static int raw_scan(struct super_block *sb, int start, const char *name,
527 int *number, int *ino, struct buffer_head **res_bh,
528 struct msdos_dir_entry **res_de)
530 if (start) return raw_scan_nonroot
531 (sb,start,name,number,ino,res_bh,res_de);
532 else return raw_scan_root
533 (sb,name,number,ino,res_bh,res_de);
538 * fat_parent_ino returns the inode number of the parent directory of dir.
539 * File creation has to be deferred while fat_parent_ino is running to
540 * prevent renames.
542 * AV. Bad, bad, bad... We need a mapping that would give us inode by
543 * first cluster. Sheeeeit... OK, we can do it on fat_fill_inode() and
544 * update on fat_add_cluster(). When will we remove it? fat_clear_inode()
545 * and fat_truncate() to zero?
548 int fat_parent_ino(struct inode *dir,int locked)
550 static int zero = 0;
551 int error,curr,prev,nr;
553 PRINTK(("fat_parent_ino: Debug 0\n"));
554 if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i");
555 if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino;
556 if (!locked) fat_lock_creation(); /* prevent renames */
557 if ((curr = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,MSDOS_DOTDOT,
558 &zero,NULL,NULL,NULL)) < 0) {
559 if (!locked) fat_unlock_creation();
560 return curr;
562 PRINTK(("fat_parent_ino: Debug 1 curr=%d\n", curr));
563 if (!curr) nr = MSDOS_ROOT_INO;
564 else {
565 PRINTK(("fat_parent_ino: Debug 2\n"));
566 if ((prev = raw_scan(dir->i_sb,curr,MSDOS_DOTDOT,&zero,NULL,
567 NULL,NULL)) < 0) {
568 PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev));
569 if (!locked) fat_unlock_creation();
570 return prev;
572 PRINTK(("fat_parent_ino: Debug 4 prev=%d\n", prev));
573 if (prev == 0 && MSDOS_SB(dir->i_sb)->fat_bits == 32) {
574 prev = MSDOS_SB(dir->i_sb)->root_cluster;
576 if ((error = raw_scan(dir->i_sb,prev,NULL,&curr,&nr,NULL,
577 NULL)) < 0) {
578 PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error));
579 if (!locked) fat_unlock_creation();
580 return error;
582 PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr));
584 if (!locked) fat_unlock_creation();
585 return nr;
590 * fat_subdirs counts the number of sub-directories of dir. It can be run
591 * on directories being created.
594 int fat_subdirs(struct inode *dir)
596 int count;
598 count = 0;
599 if ((dir->i_ino == MSDOS_ROOT_INO) &&
600 (MSDOS_SB(dir->i_sb)->fat_bits != 32)) {
601 (void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL);
602 } else {
603 if ((dir->i_ino != MSDOS_ROOT_INO) &&
604 !MSDOS_I(dir)->i_start) return 0; /* in mkdir */
605 else (void) raw_scan_nonroot(dir->i_sb,MSDOS_I(dir)->i_start,
606 NULL,&count,NULL,NULL,NULL);
608 return count;
613 * Scans a directory for a given file (name points to its formatted name) or
614 * for an empty directory slot (name is NULL). Returns an error code or zero.
617 int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh,
618 struct msdos_dir_entry **res_de,int *ino)
620 int res;
622 res = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,
623 name, NULL, ino, res_bh, res_de);
624 return res<0 ? res : 0;