source: rtems/cpukit/libfs/src/dosfs/fat.c @ 7c007cf

4.104.114.95
Last change on this file since 7c007cf was bf95ccb5, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on 05/27/08 at 10:34:15

Added const qualifier to various pointers and data tables to

reduce size of data area.
IMFS: Fixed creation of symbolic links to avoid a compiler warning.
DOSFS: Use LibBlock? instead of read() to read the boot record.

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