source: rtems/cpukit/libfs/src/dosfs/fat.c @ 01c5b9d7

Last change on this file since 01c5b9d7 was 01c5b9d7, checked in by Joel Sherrill <joel.sherrill@…>, on Mar 25, 2003 at 5:01:56 PM

2003-03-25 Thomas Doerfler <Thomas.Doerfler@…>

PR 367/filesystem

  • src/dosfs/Makefile.am, src/dosfs/fat.c, src/dosfs/fat.h, src/dosfs/fat_fat_operations.c, src/dosfs/fat_file.c, src/dosfs/msdos.h, src/dosfs/msdos_dir.c: Some bugs were still present in the DOSFS implementation:
    • FAT12 did not work properly on Big-Endian machines
    • Some synchronization and error handling problems were present
    • Some legal codings for EOC were not recognized
  • Property mode set to 100644
File size: 19.7 KB
Line 
1/*
2 * fat.c
3 *
4 * Low-level operations on a volume with FAT filesystem
5 *
6 * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
7 * Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
8 *
9 * @(#) $Id$
10 */
11
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <unistd.h>
16#include <errno.h>
17#include <stdlib.h>
18#include <assert.h>
19
20#include <rtems/libio_.h>
21
22#include "fat.h"
23#include "fat_fat_operations.h"
24
25/* _fat_block_read --
26 *     This function reads 'count' bytes from device filesystem is mounted on,
27 *     starts at 'start+offset' position where 'start' computed in sectors
28 *     and 'offset' is offset inside sector (reading may cross sectors
29 *     boundary; in this case assumed we want to read sequential sector(s))
30 *
31 * PARAMETERS:
32 *     mt_entry - mount table entry
33 *     start    - sector num to start read from
34 *     offset   - offset inside sector 'start'
35 *     count    - count of bytes to read
36 *     buff     - buffer provided by user
37 *
38 * RETURNS:
39 *     bytes read on success, or -1 if error occured
40 *     and errno set appropriately
41 */
42ssize_t
43_fat_block_read(
44    rtems_filesystem_mount_table_entry_t *mt_entry, 
45    unsigned32                            start, 
46    unsigned32                            offset,
47    unsigned32                            count, 
48    void                                 *buff
49    )
50{
51    int                     rc = RC_OK;
52    register fat_fs_info_t *fs_info = mt_entry->fs_info;
53    ssize_t                 cmpltd = 0;
54    unsigned32              blk = start;
55    unsigned32              ofs = offset;
56    bdbuf_buffer           *block = NULL;
57    unsigned32              c = 0;
58 
59    while (count > 0)
60    {
61        rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
62        if (rc != RC_OK)
63            return rc;
64   
65        c = MIN(count, (fs_info->vol.bps - ofs));
66        memcpy((buff + cmpltd), (block->buffer + ofs), c);
67
68        count -= c;
69        cmpltd += c;
70        blk++;
71        ofs = 0;
72    }
73    return cmpltd;
74}
75
76/* _fat_block_write --
77 *     This function write 'count' bytes to device filesystem is mounted on,
78 *     starts at 'start+offset' position where 'start' computed in sectors
79 *     and 'offset' is offset inside sector (writing may cross sectors
80 *     boundary; in this case assumed we want to write sequential sector(s))
81 *
82 * PARAMETERS:
83 *     mt_entry - mount table entry
84 *     start    - sector num to start read from
85 *     offset   - offset inside sector 'start'
86 *     count    - count of bytes to write
87 *     buff     - buffer provided by user
88 *
89 * RETURNS:
90 *     bytes written on success, or -1 if error occured
91 *     and errno set appropriately
92 */
93ssize_t
94_fat_block_write(
95    rtems_filesystem_mount_table_entry_t *mt_entry, 
96    unsigned32                            start, 
97    unsigned32                            offset,
98    unsigned32                            count, 
99    const void                           *buff)
100{
101    int            rc = RC_OK;
102    fat_fs_info_t *fs_info = mt_entry->fs_info;
103    ssize_t        cmpltd = 0;
104    unsigned32     blk  = start;
105    unsigned32     ofs = offset;
106    bdbuf_buffer  *block = NULL;
107    unsigned32     c = 0;
108 
109    while(count > 0)
110    {
111        c = MIN(count, (fs_info->vol.bps - ofs));
112
113        if (c == fs_info->vol.bps)
114            rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_GET, &block);
115        else
116            rc = fat_buf_access(fs_info, blk, FAT_OP_TYPE_READ, &block);
117        if (rc != RC_OK)
118            return rc;
119   
120        memcpy((block->buffer + ofs), (buff + cmpltd), c);
121
122        fat_buf_mark_modified(fs_info);
123
124        count -= c;
125        cmpltd +=c;
126        blk++;
127        ofs = 0;
128    }
129    return cmpltd;
130}
131
132
133
134
135/* fat_cluster_read --
136 *     wrapper for reading a whole cluster at once
137 *
138 * PARAMETERS:
139 *     mt_entry - mount table entry
140 *     cln      - number of cluster to read
141 *     buff     - buffer provided by user
142 *
143 * RETURNS:
144 *     bytes read on success, or -1 if error occured
145 *     and errno set appropriately
146 */
147ssize_t 
148fat_cluster_read(
149    rtems_filesystem_mount_table_entry_t *mt_entry,
150    unsigned32                            cln,
151    void                                 *buff
152    )
153{
154    fat_fs_info_t *fs_info = mt_entry->fs_info;
155    unsigned32     fsec = 0; 
156 
157    fsec = fat_cluster_num_to_sector_num(mt_entry, cln); 
158
159    return _fat_block_read(mt_entry, fsec, 0, 
160                           fs_info->vol.spc << fs_info->vol.sec_log2, buff); 
161}                 
162
163/* fat_cluster_write --
164 *     wrapper for writting a whole cluster at once
165 *
166 * PARAMETERS:
167 *     mt_entry - mount table entry
168 *     cln      - number of cluster to write
169 *     buff     - buffer provided by user
170 *
171 * RETURNS:
172 *     bytes written on success, or -1 if error occured
173 *     and errno set appropriately
174 */
175ssize_t 
176fat_cluster_write(
177    rtems_filesystem_mount_table_entry_t *mt_entry,
178    unsigned32                            cln,
179    const void                           *buff
180    )
181{
182    fat_fs_info_t *fs_info = mt_entry->fs_info;
183    unsigned32     fsec = 0;
184 
185    fsec = fat_cluster_num_to_sector_num(mt_entry, cln); 
186 
187    return _fat_block_write(mt_entry, fsec, 0,
188                          fs_info->vol.spc << fs_info->vol.sec_log2, buff); 
189}                 
190
191/* fat_init_volume_info --
192 *     Get inforamtion about volume on which filesystem is mounted on
193 *
194 * PARAMETERS:
195 *     mt_entry - mount table entry
196 *
197 * RETURNS:
198 *     RC_OK on success, or -1 if error occured
199 *     and errno set appropriately
200 */
201int
202fat_init_volume_info(rtems_filesystem_mount_table_entry_t *mt_entry)
203{
204    int                 rc = RC_OK;
205    fat_fs_info_t      *fs_info = mt_entry->fs_info;     
206    register fat_vol_t *vol = &fs_info->vol;
207    unsigned32          data_secs = 0;
208    char                boot_rec[FAT_MAX_BPB_SIZE];
209    char                fs_info_sector[FAT_USEFUL_INFO_SIZE];
210    ssize_t             ret = 0;
211    int                 fd;
212    struct stat         stat_buf;
213    int                 i = 0;
214
215    rc = stat(mt_entry->dev, &stat_buf);
216    if (rc == -1)
217        return rc;
218
219    /* rtmes feature: no block devices, all are character devices */   
220    if (!S_ISCHR(stat_buf.st_mode))
221        set_errno_and_return_minus_one(ENOTBLK);   
222
223    /* check that  device is registred as block device and lock it */
224    vol->dd = rtems_disk_lookup(stat_buf.st_dev);
225    if (vol->dd == NULL) 
226        set_errno_and_return_minus_one(ENOTBLK);
227       
228    vol->dev = stat_buf.st_dev;
229
230    fd = open(mt_entry->dev, O_RDONLY);
231    if (fd == -1)
232    {
233        rtems_disk_release(vol->dd);
234        return -1;
235    }   
236 
237    ret = read(fd, (void *)boot_rec, FAT_MAX_BPB_SIZE);
238    if ( ret != FAT_MAX_BPB_SIZE )
239    {
240        close(fd);
241        rtems_disk_release(vol->dd);
242        set_errno_and_return_minus_one( EIO );
243    }
244    close(fd);
245
246    vol->bps = FAT_BR_BYTES_PER_SECTOR(boot_rec);
247 
248    if ( (vol->bps != 512)  && 
249         (vol->bps != 1024) && 
250         (vol->bps != 2048) &&
251         (vol->bps != 4096))
252    {     
253        rtems_disk_release(vol->dd);
254        set_errno_and_return_minus_one( EINVAL );
255    }   
256
257    for (vol->sec_mul = 0, i = (vol->bps >> FAT_SECTOR512_BITS); (i & 1) == 0; 
258         i >>= 1, vol->sec_mul++);
259    for (vol->sec_log2 = 0, i = vol->bps; (i & 1) == 0; 
260         i >>= 1, vol->sec_log2++);
261
262    vol->spc = FAT_BR_SECTORS_PER_CLUSTER(boot_rec);
263    /*
264     * "sectors per cluster" of zero is invalid
265     * (and would hang the following loop)
266     */
267    if (vol->spc == 0)
268    {
269        rtems_disk_release(vol->dd);
270        set_errno_and_return_minus_one(EINVAL);
271    }   
272
273    for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0; 
274         i >>= 1, vol->spc_log2++);
275 
276    /*
277     * According to M$ White Paper "bytes per cluster" value
278     * greater than 32K is invalid
279     */
280    if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT)
281    {
282        rtems_disk_release(vol->dd);
283        set_errno_and_return_minus_one(EINVAL);
284    }   
285
286    for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0; 
287         i >>= 1, vol->bpc_log2++);
288
289    vol->fats = FAT_BR_FAT_NUM(boot_rec);
290    vol->fat_loc = FAT_BR_RESERVED_SECTORS_NUM(boot_rec);
291
292    vol->rdir_entrs = FAT_BR_FILES_PER_ROOT_DIR(boot_rec);
293   
294    /* calculate the count of sectors occupied by the root directory */
295    vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) /
296                     vol->bps;
297
298    vol->rdir_size = vol->rdir_secs << vol->sec_log2;
299
300    if ( (FAT_BR_SECTORS_PER_FAT(boot_rec)) != 0)
301        vol->fat_length = FAT_BR_SECTORS_PER_FAT(boot_rec);
302    else
303        vol->fat_length = FAT_BR_SECTORS_PER_FAT32(boot_rec);
304 
305    vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length + 
306                     vol->rdir_secs;
307
308    /* for  FAT12/16 root dir starts at(sector) */
309    vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length;
310 
311    if ( (FAT_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0)
312        vol->tot_secs = FAT_BR_TOTAL_SECTORS_NUM16(boot_rec);
313    else
314        vol->tot_secs = FAT_BR_TOTAL_SECTORS_NUM32(boot_rec);
315 
316    data_secs = vol->tot_secs - vol->data_fsec;
317 
318    vol->data_cls = data_secs / vol->spc;
319
320    /* determine FAT type at least */
321    if ( vol->data_cls < FAT_FAT12_MAX_CLN)
322    {
323        vol->type = FAT_FAT12;
324        vol->mask = FAT_FAT12_MASK;
325        vol->eoc_val = FAT_FAT12_EOC;
326    }
327    else 
328    {
329        if ( vol->data_cls < FAT_FAT16_MAX_CLN)
330        {
331            vol->type = FAT_FAT16;
332            vol->mask = FAT_FAT16_MASK;
333            vol->eoc_val = FAT_FAT16_EOC;
334        }
335        else
336        {
337            vol->type = FAT_FAT32;
338            vol->mask = FAT_FAT32_MASK;
339            vol->eoc_val = FAT_FAT32_EOC;
340        }
341    }
342 
343    if (vol->type == FAT_FAT32)
344    {
345        vol->rdir_cl = FAT_BR_FAT32_ROOT_CLUSTER(boot_rec);
346     
347        vol->mirror = FAT_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR;
348        if (vol->mirror)
349            vol->afat = FAT_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_FAT_NUM;
350        else
351            vol->afat = 0; 
352
353        vol->info_sec = FAT_BR_FAT32_FS_INFO_SECTOR(boot_rec);
354        if( vol->info_sec == 0 )
355        { 
356            rtems_disk_release(vol->dd);
357            set_errno_and_return_minus_one( EINVAL );
358        }   
359        else 
360        {
361            ret = _fat_block_read(mt_entry, vol->info_sec , 0, 
362                                  FAT_FSI_LEADSIG_SIZE, fs_info_sector);
363            if ( ret < 0 )
364            {
365                rtems_disk_release(vol->dd);
366                return -1;
367            }   
368     
369            if (FAT_FSINFO_LEAD_SIGNATURE(fs_info_sector) != 
370                FAT_FSINFO_LEAD_SIGNATURE_VALUE)
371            {   
372                rtems_disk_release(vol->dd);
373                set_errno_and_return_minus_one( EINVAL );
374            }   
375            else
376            {
377                ret = _fat_block_read(mt_entry, vol->info_sec , FAT_FSI_INFO, 
378                                      FAT_USEFUL_INFO_SIZE, fs_info_sector);
379                if ( ret < 0 )
380                {
381                    rtems_disk_release(vol->dd);
382                    return -1;
383                }   
384                   
385                vol->free_cls = FAT_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector);
386                vol->next_cl = FAT_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector);
387                rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF, 
388                                                    0xFFFFFFFF);
389                if ( rc != RC_OK )
390                {
391                    rtems_disk_release(vol->dd); 
392                    return rc; 
393                }   
394            }
395        }
396    }
397    else
398    {
399        vol->rdir_cl = 0;
400        vol->mirror = 0;
401        vol->afat = 0;
402        vol->free_cls = 0xFFFFFFFF;
403        vol->next_cl = 0xFFFFFFFF;
404    }
405    vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat;
406
407    /* set up collection of fat-files fd */
408    fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
409    if ( fs_info->vhash == NULL ) 
410    {
411        rtems_disk_release(vol->dd);
412        set_errno_and_return_minus_one( ENOMEM );
413    }   
414
415    for (i = 0; i < FAT_HASH_SIZE; i++)
416        _Chain_Initialize_empty(fs_info->vhash + i);
417
418    fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
419    if ( fs_info->rhash == NULL ) 
420    {
421        rtems_disk_release(vol->dd);
422        free(fs_info->vhash);
423        set_errno_and_return_minus_one( ENOMEM );
424    }
425    for (i = 0; i < FAT_HASH_SIZE; i++)
426        _Chain_Initialize_empty(fs_info->rhash + i);
427 
428    fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE;
429    fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4;
430    fs_info->index = 0;
431    fs_info->uino = (char *)calloc(fs_info->uino_pool_size, sizeof(char));
432    if ( fs_info->uino == NULL )
433    {
434        rtems_disk_release(vol->dd);
435        free(fs_info->vhash);
436        free(fs_info->rhash);
437        set_errno_and_return_minus_one( ENOMEM );
438    }
439    fs_info->sec_buf = (char *)calloc(vol->bps, sizeof(char));
440    if (fs_info->sec_buf == NULL)
441    {
442        rtems_disk_release(vol->dd);
443        free(fs_info->vhash);
444        free(fs_info->rhash);
445        free(fs_info->uino);
446        set_errno_and_return_minus_one( ENOMEM );
447    }
448   
449    return RC_OK; 
450}
451
452/* fat_shutdown_drive --
453 *     Free all allocated resources and synchronize all necessary data
454 *
455 * PARAMETERS:
456 *     mt_entry - mount table entry
457 *
458 * RETURNS:
459 *     RC_OK on success, or -1 if error occured
460 *     and errno set appropriately
461 */
462int
463fat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry)
464{
465    int            rc = RC_OK;
466    fat_fs_info_t *fs_info = mt_entry->fs_info;
467    int            i = 0;
468
469    if (fs_info->vol.type & FAT_FAT32)
470    {
471        rc = fat_fat32_update_fsinfo_sector(mt_entry, fs_info->vol.free_cls,
472                                            fs_info->vol.next_cl);
473        if ( rc != RC_OK )
474            rc = -1;
475    } 
476
477    fat_buf_release(fs_info);
478   
479    if (rtems_bdbuf_syncdev(fs_info->vol.dev) != RTEMS_SUCCESSFUL)
480        rc = -1;
481
482    for (i = 0; i < FAT_HASH_SIZE; i++)
483    {
484        Chain_Node    *node = NULL;
485        Chain_Control *the_chain = fs_info->vhash + i;
486   
487        while ( (node = _Chain_Get(the_chain)) != NULL )
488            free(node);
489    }   
490
491    for (i = 0; i < FAT_HASH_SIZE; i++)
492    {
493        Chain_Node    *node = NULL;
494        Chain_Control *the_chain = fs_info->rhash + i;
495
496        while ( (node = _Chain_Get(the_chain)) != NULL )
497            free(node);
498    }   
499
500    free(fs_info->vhash);
501    free(fs_info->rhash); 
502
503    free(fs_info->uino);
504    free(fs_info->sec_buf);
505    rtems_disk_release(fs_info->vol.dd);
506
507    if (rc)
508        errno = EIO;
509    return rc;
510}
511
512/* fat_init_clusters_chain --
513 *     Zeroing contents of all clusters in the chain
514 *
515 * PARAMETERS:
516 *     mt_entry          - mount table entry
517 *     start_cluster_num - num of first cluster in the chain
518 *
519 * RETURNS:
520 *     RC_OK on success, or -1 if error occured
521 *     and errno set appropriately
522 */
523int
524fat_init_clusters_chain(
525    rtems_filesystem_mount_table_entry_t *mt_entry,
526    unsigned32                            start_cln
527    )
528{
529    int                     rc = RC_OK;
530    ssize_t                 ret = 0;
531    register fat_fs_info_t *fs_info = mt_entry->fs_info;
532    unsigned32              cur_cln = start_cln;
533    char                   *buf;
534 
535    buf = calloc(fs_info->vol.bpc, sizeof(char));
536    if ( buf == NULL )
537        set_errno_and_return_minus_one( EIO );
538
539    while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
540    {
541        ret = fat_cluster_write(mt_entry, cur_cln, buf);
542        if ( ret == -1 )
543        {
544            free(buf);
545            return -1;
546        }
547
548        rc  = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
549        if ( rc != RC_OK )
550        {
551            free(buf);
552            return rc;
553        }
554       
555    }
556    free(buf);
557    return rc;
558}                       
559 
560#define FAT_UNIQ_INO_BASE 0x0FFFFF00
561
562#define FAT_UNIQ_INO_IS_BUSY(index, arr) \
563  (((arr)[((index)>>3)]>>((index) & (8-1))) & 0x01)
564
565#define FAT_SET_UNIQ_INO_BUSY(index, arr) \
566  ((arr)[((index)>>3)] |= (0x01<<((index) & (8-1))))
567
568#define FAT_SET_UNIQ_INO_FREE(index, arr) \
569  ((arr)[((index)>>3)] &= (~(0x01<<((index) & (8-1)))))
570
571/* fat_get_unique_ino --
572 *     Allocate unique ino from unique ino pool
573 *
574 * PARAMETERS:
575 *     mt_entry - mount table entry
576 *
577 * RETURNS:
578 *     unique inode number on success, or 0 if there is no free unique inode
579 *     number in the pool
580 *
581 * ATTENTION:
582 *     0 means FAILED !!!
583 *     
584 */
585unsigned32
586fat_get_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry)
587{
588    register fat_fs_info_t *fs_info = mt_entry->fs_info;
589    unsigned32              j = 0;
590    rtems_boolean           resrc_unsuff = FALSE;
591
592    while (!resrc_unsuff)
593    { 
594        for (j = 0; j < fs_info->uino_pool_size; j++)
595        {
596            if (!FAT_UNIQ_INO_IS_BUSY(fs_info->index, fs_info->uino))
597            {
598                FAT_SET_UNIQ_INO_BUSY(fs_info->index, fs_info->uino);
599                return (fs_info->uino_base + fs_info->index);           
600            }
601            fs_info->index++;
602            if (fs_info->index >= fs_info->uino_pool_size)
603                fs_info->index = 0;
604        }
605
606        if ((fs_info->uino_pool_size << 1) < (0x0FFFFFFF - fs_info->uino_base))
607        {
608            fs_info->uino_pool_size <<= 1;
609            fs_info->uino = realloc(fs_info->uino, fs_info->uino_pool_size);
610            if (fs_info->uino != NULL)
611                fs_info->index = fs_info->uino_pool_size;
612            else   
613                resrc_unsuff = TRUE;
614        }
615        else
616            resrc_unsuff = TRUE;
617    }   
618    return 0;
619}
620
621/* fat_free_unique_ino --
622 *     Return unique ino to unique ino pool
623 *
624 * PARAMETERS:
625 *     mt_entry - mount table entry
626 *     ino      - inode number to free
627 *
628 * RETURNS:
629 *     None
630 */
631void
632fat_free_unique_ino(
633    rtems_filesystem_mount_table_entry_t *mt_entry,
634    unsigned32                            ino
635    )
636{
637    fat_fs_info_t *fs_info = mt_entry->fs_info;
638   
639    FAT_SET_UNIQ_INO_FREE((ino - fs_info->uino_base), fs_info->uino);
640}
641
642/* fat_ino_is_unique --
643 *     Test whether ino is from unique ino pool
644 *
645 * PARAMETERS:
646 *     mt_entry - mount table entry
647 *     ino   - ino to be tested
648 *
649 * RETURNS:
650 *     TRUE if ino is allocated from unique ino pool, FALSE otherwise
651 */
652inline rtems_boolean
653fat_ino_is_unique(
654    rtems_filesystem_mount_table_entry_t *mt_entry,
655    unsigned32                            ino
656    )
657{
658    fat_fs_info_t *fs_info = mt_entry->fs_info;
659   
660    return (ino >= fs_info->uino_base);
661}
662
663/* fat_fat32_update_fsinfo_sector --
664 *     Synchronize fsinfo sector for FAT32 volumes
665 *
666 * PARAMETERS:
667 *     mt_entry   - mount table entry
668 *     free_count - count of free clusters
669 *     next_free  - the next free cluster num
670 *
671 * RETURNS:
672 *     RC_OK on success, or -1 if error occured (errno set appropriately)
673 */
674int
675fat_fat32_update_fsinfo_sector(
676    rtems_filesystem_mount_table_entry_t *mt_entry,
677    unsigned32                            free_count,
678    unsigned32                            next_free
679    )
680{
681    ssize_t                 ret1 = 0, ret2 = 0;
682    register fat_fs_info_t *fs_info = mt_entry->fs_info;
683    unsigned32              le_free_count = 0;
684    unsigned32              le_next_free = 0;
685
686    le_free_count = CT_LE_L(free_count);
687    le_next_free = CT_LE_L(next_free);
688
689    ret1 = _fat_block_write(mt_entry,
690                            fs_info->vol.info_sec,
691                            FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET,
692                            4,
693                            (char *)(&le_free_count));
694
695    ret2 = _fat_block_write(mt_entry,
696                            fs_info->vol.info_sec,
697                            FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET,
698                            4,
699                            (char *)(&le_next_free));
700
701    if ( (ret1 < 0) || (ret2 < 0) )
702        return -1;
703
704    return RC_OK;
705}
706
Note: See TracBrowser for help on using the repository browser.