~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/fat/misc.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/fs/fat/misc.c
  3  *
  4  *  Written 1992,1993 by Werner Almesberger
  5  */
  6 
  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>
 14 
 15 #include "msbuffer.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 
 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 
 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 
 78 
 79 /* File creation lock. This is system-wide to avoid deadlocks in rename. */
 80 /* (rename might deadlock before detecting cross-FS moves.) */
 81 
 82 static DECLARE_MUTEX(creation_lock);
 83 
 84 void fat_lock_creation(void)
 85 {
 86         down(&creation_lock);
 87 }
 88 
 89 
 90 void fat_unlock_creation(void)
 91 {
 92         up(&creation_lock);
 93 }
 94 
 95 
 96 void lock_fat(struct super_block *sb)
 97 {
 98         down(&(MSDOS_SB(sb)->fat_lock));
 99 }
100 
101 
102 void unlock_fat(struct super_block *sb)
103 {
104         up(&(MSDOS_SB(sb)->fat_lock));
105 }
106 
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)
110 {
111         int offset;
112         struct buffer_head *bh;
113         struct fat_boot_fsinfo *fsinfo;
114 
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));
118         if (bh == NULL) {
119                 printk("FAT bread failed in fat_clusters_flush\n");
120                 return;
121         }
122         fsinfo = (struct fat_boot_fsinfo *)
123                 &bh->b_data[offset & (SECTOR_SIZE-1)];
124 
125         /* Sanity check */
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);
128                 fat_brelse(sb, bh);
129                 return;
130         }
131         fsinfo->free_clusters = CF_LE_L(MSDOS_SB(sb)->free_clusters);
132         fat_mark_buffer_dirty(sb, bh);
133         fat_brelse(sb, bh);
134 }
135 
136 /*
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.
139  */
140 
141 /* not a directory */
142 
143 int fat_add_cluster(struct inode *inode)
144 {
145         struct super_block *sb = inode->i_sb;
146         int count,nr,limit,last,curr,file_cluster;
147         int res = -ENOSPC;
148         int cluster_size = MSDOS_SB(sb)->cluster_size;
149 
150         if (!MSDOS_SB(sb)->free_clusters) return res;
151         lock_fat(sb);
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;
157         }
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;
161                 unlock_fat(sb);
162                 return res;
163         }
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);
169         unlock_fat(sb);
170         last = 0;
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).
173            
174            Here file_cluster will be the number of the last cluster of the
175            file (before we add nr).
176            
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
179            update the cache.
180         */
181         file_cluster = 0;
182         if ((curr = MSDOS_I(inode)->i_start) != 0) {
183                 fat_cache_lookup(inode,INT_MAX,&last,&curr);
184                 file_cluster = last;
185                 while (curr && curr != -1){
186                         file_cluster++;
187                         if (!(curr = fat_access(sb, last = curr,-1))) {
188                                 fat_fs_panic(sb,"File without EOF");
189                                 return res;
190                         }
191                 }
192         }
193         if (last) fat_access(sb,last,nr);
194         else {
195                 MSDOS_I(inode)->i_start = nr;
196                 MSDOS_I(inode)->i_logstart = nr;
197                 mark_inode_dirty(inode);
198         }
199         fat_cache_add(inode,file_cluster,nr);
200         inode->i_blocks += cluster_size;
201         return 0;
202 }
203 
204 struct buffer_head *fat_extend_dir(struct inode *inode)
205 {
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;
210 
211         if (MSDOS_SB(sb)->fat_bits != 32) {
212                 if (inode->i_ino == MSDOS_ROOT_INO) return res;
213         }
214         if (!MSDOS_SB(sb)->free_clusters) return res;
215         lock_fat(sb);
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;
221         }
222         PRINTK (("cnt = %d --",count));
223 #ifdef DEBUG
224 printk("free cluster: %d\n",nr);
225 #endif
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;
229                 unlock_fat(sb);
230                 return res;
231         }
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);
237         unlock_fat(sb);
238 #ifdef DEBUG
239 printk("set to %x\n",fat_access(sb,nr,-1));
240 #endif
241         last = 0;
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).
244            
245            Here file_cluster will be the number of the last cluster of the
246            file (before we add nr).
247            
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
250            update the cache.
251         */
252         file_cluster = 0;
253         if ((curr = MSDOS_I(inode)->i_start) != 0) {
254                 fat_cache_lookup(inode,INT_MAX,&last,&curr);
255                 file_cluster = last;
256                 while (curr && curr != -1){
257                         PRINTK (("."));
258                         file_cluster++;
259                         if (!(curr = fat_access(sb,
260                             last = curr,-1))) {
261                                 fat_fs_panic(sb,"File without EOF");
262                                 return res;
263                         }
264                 }
265                 PRINTK ((" --  "));
266         }
267 #ifdef DEBUG
268 printk("last = %d\n",last);
269 #endif
270         if (last) fat_access(sb,last,nr);
271         else {
272                 MSDOS_I(inode)->i_start = nr;
273                 MSDOS_I(inode)->i_logstart = nr;
274                 mark_inode_dirty(inode);
275         }
276 #ifdef DEBUG
277 if (last) printk("next set to %d\n",fat_access(sb,last,-1));
278 #endif
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);
284         else
285         for ( ; sector < last_sector; sector++) {
286                 #ifdef DEBUG
287                         printk("zeroing sector %d\n",sector);
288                 #endif
289                 if (!(bh = fat_getblk(sb, sector)))
290                         printk("getblk failed\n");
291                 else {
292                         memset(bh->b_data,0,SECTOR_SIZE);
293                         fat_set_uptodate(sb, bh, 1);
294                         fat_mark_buffer_dirty(sb, bh);
295                         if (!res)
296                                 res=bh;
297                         else
298                                 fat_brelse(sb, bh);
299                 }
300         }
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);
304         }else{
305                 fat_cache_add(inode,file_cluster,nr);
306         }
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) &
311                     ~(SECTOR_SIZE-1);
312         }
313         inode->i_size += SECTOR_SIZE*cluster_size;
314         MSDOS_I(inode)->mmu_private += SECTOR_SIZE*cluster_size;
315         mark_inode_dirty(inode);
316         return res;
317 }
318 
319 /* Linear day numbers of the respective 1sts in non-leap years. */
320 
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 */
323 
324 
325 extern struct timezone sys_tz;
326 
327 
328 /* Convert a MS-DOS time/date pair to a UNIX date (seconds since 1 1 70). */
329 
330 int date_dos2unix(unsigned short time,unsigned short date)
331 {
332         int month,year,secs;
333 
334         month = ((date >> 5) & 15)-1;
335         year = date >> 9;
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         return secs;
342 }
343 
344 
345 /* Convert linear UNIX date to a MS-DOS time/date pair. */
346 
347 void fat_date_unix2dos(int unix_date,unsigned short *time,
348     unsigned short *date)
349 {
350         int day,year,nl_day,month;
351 
352         unix_date -= sys_tz.tz_minuteswest*60;
353         if (sys_tz.tz_dsttime) unix_date += 3600;
354 
355         *time = (unix_date % 60)/2+(((unix_date/60) % 60) << 5)+
356             (((unix_date/3600) % 24) << 11);
357         day = unix_date/86400-3652;
358         year = day/365;
359         if ((year+3)/4+365*year > day) year--;
360         day -= (year+3)/4+365*year;
361         if (day == 59 && !(year & 3)) {
362                 nl_day = day;
363                 month = 2;
364         }
365         else {
366                 nl_day = (year & 3) || day <= 59 ? day : day-1;
367                 for (month = 0; month < 12; month++)
368                         if (day_n[month] > nl_day) break;
369         }
370         *date = nl_day-day_n[month-1]+1+(month << 5)+(year << 9);
371 }
372 
373 
374 /* Returns the inode number of the directory entry at offset pos. If bh is
375    non-NULL, it is brelse'd before. Pos is incremented. The buffer header is
376    returned in bh.
377    AV. Most often we do it item-by-item. Makes sense to optimize.
378    AV. OK, there we go: if both bh and de are non-NULL we assume that we just
379    AV. want the next entry (took one explicit de=NULL in vfat/namei.c).
380    AV. It's done in fat_get_entry() (inlined), here the slow case lives.
381    AV. Additionally, when we return -1 (i.e. reached the end of directory)
382    AV. we make bh NULL. 
383  */
384 
385 int fat__get_entry(struct inode *dir, loff_t *pos,struct buffer_head **bh,
386     struct msdos_dir_entry **de, int *ino)
387 {
388         struct super_block *sb = dir->i_sb;
389         int sector, offset;
390 
391         while (1) {
392                 offset = *pos;
393                 PRINTK (("get_entry offset %d\n",offset));
394                 if (*bh)
395                         fat_brelse(sb, *bh);
396                 *bh = NULL;
397                 if ((sector = fat_bmap(dir,offset >> SECTOR_BITS)) == -1)
398                         return -1;
399                 PRINTK (("get_entry sector %d %p\n",sector,*bh));
400                 PRINTK (("get_entry sector apres brelse\n"));
401                 if (!sector)
402                         return -1; /* beyond EOF */
403                 *pos += sizeof(struct msdos_dir_entry);
404                 if (!(*bh = fat_bread(sb, sector))) {
405                         printk("Directory sread (sector 0x%x) failed\n",sector);
406                         continue;
407                 }
408                 PRINTK (("get_entry apres sread\n"));
409                 *de = (struct msdos_dir_entry *) ((*bh)->b_data+(offset &
410                     (SECTOR_SIZE-1)));
411                 *ino = (sector << MSDOS_DPS_BITS)+((offset & (SECTOR_SIZE-1)) >>
412                     MSDOS_DIR_BITS);
413                 return 0;
414         }
415 }
416 
417 
418 /*
419  * Now an ugly part: this set of directory scan routines works on clusters
420  * rather than on inodes and sectors. They are necessary to locate the '..'
421  * directory "inode". raw_scan_sector operates in four modes:
422  *
423  * name     number   ino      action
424  * -------- -------- -------- -------------------------------------------------
425  * non-NULL -        X        Find an entry with that name
426  * NULL     non-NULL non-NULL Find an entry whose data starts at *number
427  * NULL     non-NULL NULL     Count subdirectories in *number. (*)
428  * NULL     NULL     non-NULL Find an empty entry
429  *
430  * (*) The return code should be ignored. It DOES NOT indicate success or
431  *     failure. *number has to be initialized to zero.
432  *
433  * - = not used, X = a value is returned unless NULL
434  *
435  * If res_bh is non-NULL, the buffer is not deallocated but returned to the
436  * caller on success. res_de is set accordingly.
437  *
438  * If cont is non-zero, raw_found continues with the entry after the one
439  * res_bh/res_de point to.
440  */
441 
442 
443 #define RSS_NAME /* search for name */ \
444     done = !strncmp(data[entry].name,name,MSDOS_NAME) && \
445      !(data[entry].attr & ATTR_VOLUME);
446 
447 #define RSS_START /* search for start cluster */ \
448     done = !IS_FREE(data[entry].name) \
449       && ( \
450            ( \
451              (MSDOS_SB(sb)->fat_bits != 32) ? 0 : (CF_LE_W(data[entry].starthi) << 16) \
452            ) \
453            | CF_LE_W(data[entry].start) \
454          ) == *number;
455 
456 #define RSS_FREE /* search for free entry */ \
457     { \
458         done = IS_FREE(data[entry].name); \
459     }
460 
461 #define RSS_COUNT /* count subdirectories */ \
462     { \
463         done = 0; \
464         if (!IS_FREE(data[entry].name) && (data[entry].attr & ATTR_DIR)) \
465             (*number)++; \
466     }
467 
468 static int raw_scan_sector(struct super_block *sb,int sector,const char *name,
469     int *number,int *ino,struct buffer_head **res_bh,
470     struct msdos_dir_entry **res_de)
471 {
472         struct buffer_head *bh;
473         struct msdos_dir_entry *data;
474         int entry,start,done;
475 
476         if (!(bh = fat_bread(sb,sector)))
477                 return -EIO;
478         data = (struct msdos_dir_entry *) bh->b_data;
479         for (entry = 0; entry < MSDOS_DPS; entry++) {
480 /* RSS_COUNT:  if (data[entry].name == name) done=true else done=false. */
481                 if (name) {
482                         RSS_NAME
483                 } else {
484                         if (!ino) RSS_COUNT
485                         else {
486                                 if (number) RSS_START
487                                 else RSS_FREE
488                         }
489                 }
490                 if (done) {
491                         if (ino) *ino = sector*MSDOS_DPS+entry;
492                         start = CF_LE_W(data[entry].start);
493                         if (MSDOS_SB(sb)->fat_bits == 32) {
494                                 start |= (CF_LE_W(data[entry].starthi) << 16);
495                         }
496                         if (!res_bh)
497                                 fat_brelse(sb, bh);
498                         else {
499                                 *res_bh = bh;
500                                 *res_de = &data[entry];
501                         }
502                         return start;
503                 }
504         }
505         fat_brelse(sb, bh);
506         return -ENOENT;
507 }
508 
509 
510 /*
511  * raw_scan_root performs raw_scan_sector on the root directory until the
512  * requested entry is found or the end of the directory is reached.
513  */
514 
515 static int raw_scan_root(struct super_block *sb,const char *name,int *number,int *ino,
516     struct buffer_head **res_bh,struct msdos_dir_entry **res_de)
517 {
518         int count,cluster;
519 
520         for (count = 0; count < MSDOS_SB(sb)->dir_entries/MSDOS_DPS; count++) {
521                 if ((cluster = raw_scan_sector(sb,MSDOS_SB(sb)->dir_start+count,
522                     name,number,ino,res_bh,res_de)) >= 0) return cluster;
523         }
524         return -ENOENT;
525 }
526 
527 
528 /*
529  * raw_scan_nonroot performs raw_scan_sector on a non-root directory until the
530  * requested entry is found or the end of the directory is reached.
531  */
532 
533 static int raw_scan_nonroot(struct super_block *sb,int start,const char *name,
534     int *number,int *ino,struct buffer_head **res_bh,struct msdos_dir_entry
535     **res_de)
536 {
537         int count,cluster;
538 
539 #ifdef DEBUG
540         printk("raw_scan_nonroot: start=%d\n",start);
541 #endif
542         do {
543                 for (count = 0; count < MSDOS_SB(sb)->cluster_size; count++) {
544                         if ((cluster = raw_scan_sector(sb,(start-2)*
545                             MSDOS_SB(sb)->cluster_size+MSDOS_SB(sb)->data_start+
546                             count,name,number,ino,res_bh,res_de)) >= 0)
547                                 return cluster;
548                 }
549                 if (!(start = fat_access(sb,start,-1))) {
550                         fat_fs_panic(sb,"FAT error");
551                         break;
552                 }
553 #ifdef DEBUG
554         printk("next start: %d\n",start);
555 #endif
556         }
557         while (start != -1);
558         return -ENOENT;
559 }
560 
561 
562 /*
563  * raw_scan performs raw_scan_sector on any sector.
564  *
565  * NOTE: raw_scan must not be used on a directory that is is the process of
566  *       being created.
567  */
568 
569 static int raw_scan(struct super_block *sb, int start, const char *name,
570     int *number, int *ino, struct buffer_head **res_bh,
571     struct msdos_dir_entry **res_de)
572 {
573         if (start) return raw_scan_nonroot
574                 (sb,start,name,number,ino,res_bh,res_de);
575         else return raw_scan_root
576                 (sb,name,number,ino,res_bh,res_de);
577 }
578 
579 
580 /*
581  * fat_parent_ino returns the inode number of the parent directory of dir.
582  * File creation has to be deferred while fat_parent_ino is running to
583  * prevent renames.
584  *
585  * AV. Bad, bad, bad... We need a mapping that would give us inode by
586  * first cluster. Sheeeeit... OK, we can do it on fat_fill_inode() and
587  * update on fat_add_cluster(). When will we remove it? fat_clear_inode()
588  * and fat_truncate() to zero?
589  */
590 
591 int fat_parent_ino(struct inode *dir,int locked)
592 {
593         static int zero = 0;
594         int error,curr,prev,nr;
595 
596         PRINTK(("fat_parent_ino: Debug 0\n"));
597         if (!S_ISDIR(dir->i_mode)) panic("Non-directory fed to m_p_i");
598         if (dir->i_ino == MSDOS_ROOT_INO) return dir->i_ino;
599         if (!locked) fat_lock_creation(); /* prevent renames */
600         if ((curr = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,MSDOS_DOTDOT,
601             &zero,NULL,NULL,NULL)) < 0) {
602                 if (!locked) fat_unlock_creation();
603                 return curr;
604         }
605         PRINTK(("fat_parent_ino: Debug 1 curr=%d\n", curr));
606         if (!curr) nr = MSDOS_ROOT_INO;
607         else {
608                 PRINTK(("fat_parent_ino: Debug 2\n"));
609                 if ((prev = raw_scan(dir->i_sb,curr,MSDOS_DOTDOT,&zero,NULL,
610                     NULL,NULL)) < 0) {
611                         PRINTK(("fat_parent_ino: Debug 3 prev=%d\n", prev));
612                         if (!locked) fat_unlock_creation();
613                         return prev;
614                 }
615                 PRINTK(("fat_parent_ino: Debug 4 prev=%d\n", prev));
616                 if (prev == 0 && MSDOS_SB(dir->i_sb)->fat_bits == 32) {
617                         prev = MSDOS_SB(dir->i_sb)->root_cluster;
618                 }
619                 if ((error = raw_scan(dir->i_sb,prev,NULL,&curr,&nr,NULL,
620                     NULL)) < 0) {
621                         PRINTK(("fat_parent_ino: Debug 5 error=%d\n", error));
622                         if (!locked) fat_unlock_creation();
623                         return error;
624                 }
625                 PRINTK(("fat_parent_ino: Debug 6 nr=%d\n", nr));
626         }
627         if (!locked) fat_unlock_creation();
628         return nr;
629 }
630 
631 
632 /*
633  * fat_subdirs counts the number of sub-directories of dir. It can be run
634  * on directories being created.
635  */
636 
637 int fat_subdirs(struct inode *dir)
638 {
639         int count;
640 
641         count = 0;
642         if ((dir->i_ino == MSDOS_ROOT_INO) &&
643             (MSDOS_SB(dir->i_sb)->fat_bits != 32)) {
644                 (void) raw_scan_root(dir->i_sb,NULL,&count,NULL,NULL,NULL);
645         } else {
646                 if ((dir->i_ino != MSDOS_ROOT_INO) &&
647                     !MSDOS_I(dir)->i_start) return 0; /* in mkdir */
648                 else (void) raw_scan_nonroot(dir->i_sb,MSDOS_I(dir)->i_start,
649                     NULL,&count,NULL,NULL,NULL);
650         }
651         return count;
652 }
653 
654 
655 /*
656  * Scans a directory for a given file (name points to its formatted name) or
657  * for an empty directory slot (name is NULL). Returns an error code or zero.
658  */
659 
660 int fat_scan(struct inode *dir,const char *name,struct buffer_head **res_bh,
661     struct msdos_dir_entry **res_de,int *ino)
662 {
663         int res;
664 
665         res = raw_scan(dir->i_sb,MSDOS_I(dir)->i_start,
666                        name, NULL, ino, res_bh, res_de);
667         return res<0 ? res : 0;
668 }
669 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.