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

4.104.114.84.9
Last change on this file since d32359a7 was d32359a7, checked in by Joel Sherrill <joel.sherrill@…>, on Sep 14, 2002 at 9:01:39 PM

2002-09-14 Joel Sherrill <joel@…>

  • src/dosfs/fat.c, src/imfs/deviceio.c, src/imfs/imfs.h, src/imfs/imfs_directory.c, src/imfs/imfs_fchmod.c, src/imfs/memfile.c: Eliminated warnings. A lot of this focus was on changing read and write entry points to return ssize_t as read(2) and write(2) now do.
  • Property mode set to 100644
File size: 19.5 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    for (vol->spc_log2 = 0, i = vol->spc; (i & 1) == 0; 
264         i >>= 1, vol->spc_log2++);
265 
266    /*
267     * According to M$ White Paper "bytes per cluster" value
268     * greater than 32K is invalid
269     */
270    if ((vol->bpc = vol->bps << vol->spc_log2) > MS_BYTES_PER_CLUSTER_LIMIT)
271    {
272        rtems_disk_release(vol->dd);
273        set_errno_and_return_minus_one(EINVAL);
274    }   
275
276    for (vol->bpc_log2 = 0, i = vol->bpc; (i & 1) == 0; 
277         i >>= 1, vol->bpc_log2++);
278
279    vol->fats = FAT_BR_FAT_NUM(boot_rec);
280    vol->fat_loc = FAT_BR_RESERVED_SECTORS_NUM(boot_rec);
281
282    vol->rdir_entrs = FAT_BR_FILES_PER_ROOT_DIR(boot_rec);
283   
284    /* calculate the count of sectors occupied by the root directory */
285    vol->rdir_secs = ((vol->rdir_entrs * FAT_DIRENTRY_SIZE) + (vol->bps - 1)) /
286                     vol->bps;
287
288    vol->rdir_size = vol->rdir_secs << vol->sec_log2;
289
290    if ( (FAT_BR_SECTORS_PER_FAT(boot_rec)) != 0)
291        vol->fat_length = FAT_BR_SECTORS_PER_FAT(boot_rec);
292    else
293        vol->fat_length = FAT_BR_SECTORS_PER_FAT32(boot_rec);
294 
295    vol->data_fsec = vol->fat_loc + vol->fats * vol->fat_length + 
296                     vol->rdir_secs;
297
298    /* for  FAT12/16 root dir starts at(sector) */
299    vol->rdir_loc = vol->fat_loc + vol->fats * vol->fat_length;
300 
301    if ( (FAT_BR_TOTAL_SECTORS_NUM16(boot_rec)) != 0)
302        vol->tot_secs = FAT_BR_TOTAL_SECTORS_NUM16(boot_rec);
303    else
304        vol->tot_secs = FAT_BR_TOTAL_SECTORS_NUM32(boot_rec);
305 
306    data_secs = vol->tot_secs - vol->data_fsec;
307 
308    vol->data_cls = data_secs / vol->spc;
309
310    /* determine FAT type at least */
311    if ( vol->data_cls < FAT_FAT12_MAX_CLN)
312    {
313        vol->type = FAT_FAT12;
314        vol->mask = FAT_FAT12_MASK;
315        vol->eoc_val = FAT_FAT12_EOC;
316    }
317    else 
318    {
319        if ( vol->data_cls < FAT_FAT16_MAX_CLN)
320        {
321            vol->type = FAT_FAT16;
322            vol->mask = FAT_FAT16_MASK;
323            vol->eoc_val = FAT_FAT16_EOC;
324        }
325        else
326        {
327            vol->type = FAT_FAT32;
328            vol->mask = FAT_FAT32_MASK;
329            vol->eoc_val = FAT_FAT32_EOC;
330        }
331    }
332 
333    if (vol->type == FAT_FAT32)
334    {
335        vol->rdir_cl = FAT_BR_FAT32_ROOT_CLUSTER(boot_rec);
336     
337        vol->mirror = FAT_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_MIRROR;
338        if (vol->mirror)
339            vol->afat = FAT_BR_EXT_FLAGS(boot_rec) & FAT_BR_EXT_FLAGS_FAT_NUM;
340        else
341            vol->afat = 0; 
342
343        vol->info_sec = FAT_BR_FAT32_FS_INFO_SECTOR(boot_rec);
344        if( vol->info_sec == 0 )
345        { 
346            rtems_disk_release(vol->dd);
347            set_errno_and_return_minus_one( EINVAL );
348        }   
349        else 
350        {
351            ret = _fat_block_read(mt_entry, vol->info_sec , 0, 
352                                  FAT_FSI_LEADSIG_SIZE, fs_info_sector);
353            if ( ret < 0 )
354            {
355                rtems_disk_release(vol->dd);
356                return -1;
357            }   
358     
359            if (FAT_FSINFO_LEAD_SIGNATURE(fs_info_sector) != 
360                FAT_FSINFO_LEAD_SIGNATURE_VALUE)
361            {   
362                rtems_disk_release(vol->dd);
363                set_errno_and_return_minus_one( EINVAL );
364            }   
365            else
366            {
367                ret = _fat_block_read(mt_entry, vol->info_sec , FAT_FSI_INFO, 
368                                      FAT_USEFUL_INFO_SIZE, fs_info_sector);
369                if ( ret < 0 )
370                {
371                    rtems_disk_release(vol->dd);
372                    return -1;
373                }   
374                   
375                vol->free_cls = FAT_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector);
376                vol->next_cl = FAT_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector);
377                rc = fat_fat32_update_fsinfo_sector(mt_entry, 0xFFFFFFFF, 
378                                                    0xFFFFFFFF);
379                if ( rc != RC_OK )
380                {
381                    rtems_disk_release(vol->dd); 
382                    return rc; 
383                }   
384            }
385        }
386    }
387    else
388    {
389        vol->rdir_cl = 0;
390        vol->mirror = 0;
391        vol->afat = 0;
392        vol->free_cls = 0xFFFFFFFF;
393        vol->next_cl = 0xFFFFFFFF;
394    }
395    vol->afat_loc = vol->fat_loc + vol->fat_length * vol->afat;
396
397    /* set up collection of fat-files fd */
398    fs_info->vhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
399    if ( fs_info->vhash == NULL ) 
400    {
401        rtems_disk_release(vol->dd);
402        set_errno_and_return_minus_one( ENOMEM );
403    }   
404
405    for (i = 0; i < FAT_HASH_SIZE; i++)
406        _Chain_Initialize_empty(fs_info->vhash + i);
407
408    fs_info->rhash = calloc(FAT_HASH_SIZE, sizeof(Chain_Control));
409    if ( fs_info->rhash == NULL ) 
410    {
411        rtems_disk_release(vol->dd);
412        free(fs_info->vhash);
413        set_errno_and_return_minus_one( ENOMEM );
414    }
415    for (i = 0; i < FAT_HASH_SIZE; i++)
416        _Chain_Initialize_empty(fs_info->rhash + i);
417 
418    fs_info->uino_pool_size = FAT_UINO_POOL_INIT_SIZE;
419    fs_info->uino_base = (vol->tot_secs << vol->sec_mul) << 4;
420    fs_info->index = 0;
421    fs_info->uino = (char *)calloc(fs_info->uino_pool_size, sizeof(char));
422    if ( fs_info->uino == NULL )
423    {
424        rtems_disk_release(vol->dd);
425        free(fs_info->vhash);
426        free(fs_info->rhash);
427        set_errno_and_return_minus_one( ENOMEM );
428    }
429    fs_info->sec_buf = (char *)calloc(vol->bps, sizeof(char));
430    if (fs_info->sec_buf == NULL)
431    {
432        rtems_disk_release(vol->dd);
433        free(fs_info->vhash);
434        free(fs_info->rhash);
435        free(fs_info->uino);
436        set_errno_and_return_minus_one( ENOMEM );
437    }
438   
439    return RC_OK; 
440}
441
442/* fat_shutdown_drive --
443 *     Free all allocated resources and synchronize all necessary data
444 *
445 * PARAMETERS:
446 *     mt_entry - mount table entry
447 *
448 * RETURNS:
449 *     RC_OK on success, or -1 if error occured
450 *     and errno set appropriately
451 */
452int
453fat_shutdown_drive(rtems_filesystem_mount_table_entry_t *mt_entry)
454{
455    int            rc = RC_OK;
456    fat_fs_info_t *fs_info = mt_entry->fs_info;
457    int            i = 0;
458
459    if (fs_info->vol.type & FAT_FAT32)
460    {
461        rc = fat_fat32_update_fsinfo_sector(mt_entry, fs_info->vol.free_cls,
462                                            fs_info->vol.next_cl);
463        if ( rc != RC_OK )
464            rc = -1;
465    } 
466
467    fat_buf_release(fs_info);
468   
469    if (rtems_bdbuf_syncdev(fs_info->vol.dev) != RTEMS_SUCCESSFUL)
470        rc = -1;
471
472    for (i = 0; i < FAT_HASH_SIZE; i++)
473    {
474        Chain_Node    *node = NULL;
475        Chain_Control *the_chain = fs_info->vhash + i;
476   
477        while ( (node = _Chain_Get(the_chain)) != NULL )
478            free(node);
479    }   
480
481    for (i = 0; i < FAT_HASH_SIZE; i++)
482    {
483        Chain_Node    *node = NULL;
484        Chain_Control *the_chain = fs_info->rhash + i;
485
486        while ( (node = _Chain_Get(the_chain)) != NULL )
487            free(node);
488    }   
489
490    free(fs_info->vhash);
491    free(fs_info->rhash); 
492
493    free(fs_info->uino);
494    free(fs_info->sec_buf);
495    rtems_disk_release(fs_info->vol.dd);
496
497    if (rc)
498        errno = EIO;
499    return rc;
500}
501
502/* fat_init_clusters_chain --
503 *     Zeroing contents of all clusters in the chain
504 *
505 * PARAMETERS:
506 *     mt_entry          - mount table entry
507 *     start_cluster_num - num of first cluster in the chain
508 *
509 * RETURNS:
510 *     RC_OK on success, or -1 if error occured
511 *     and errno set appropriately
512 */
513int
514fat_init_clusters_chain(
515    rtems_filesystem_mount_table_entry_t *mt_entry,
516    unsigned32                            start_cln
517    )
518{
519    int                     rc = RC_OK;
520    ssize_t                 ret = 0;
521    register fat_fs_info_t *fs_info = mt_entry->fs_info;
522    unsigned32              cur_cln = start_cln;
523    char                   *buf;
524 
525    buf = calloc(fs_info->vol.bpc, sizeof(char));
526    if ( buf == NULL )
527        set_errno_and_return_minus_one( EIO );
528
529    while ((cur_cln & fs_info->vol.mask) != fs_info->vol.eoc_val)
530    {
531        ret = fat_cluster_write(mt_entry, cur_cln, buf);
532        if ( ret == -1 )
533        {
534            free(buf);
535            return -1;
536        }
537
538        rc  = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
539        if ( rc != RC_OK )
540        {
541            free(buf);
542            return rc;
543        }
544       
545    }
546    free(buf);
547    return rc;
548}                       
549 
550#define FAT_UNIQ_INO_BASE 0x0FFFFF00
551
552#define FAT_UNIQ_INO_IS_BUSY(index, arr) \
553  (((arr)[((index)>>3)]>>((index) & (8-1))) & 0x01)
554
555#define FAT_SET_UNIQ_INO_BUSY(index, arr) \
556  ((arr)[((index)>>3)] |= (0x01<<((index) & (8-1))))
557
558#define FAT_SET_UNIQ_INO_FREE(index, arr) \
559  ((arr)[((index)>>3)] &= (~(0x01<<((index) & (8-1)))))
560
561/* fat_get_unique_ino --
562 *     Allocate unique ino from unique ino pool
563 *
564 * PARAMETERS:
565 *     mt_entry - mount table entry
566 *
567 * RETURNS:
568 *     unique inode number on success, or 0 if there is no free unique inode
569 *     number in the pool
570 *
571 * ATTENTION:
572 *     0 means FAILED !!!
573 *     
574 */
575unsigned32
576fat_get_unique_ino(rtems_filesystem_mount_table_entry_t *mt_entry)
577{
578    register fat_fs_info_t *fs_info = mt_entry->fs_info;
579    unsigned32              j = 0;
580    rtems_boolean           resrc_unsuff = FALSE;
581
582    while (!resrc_unsuff)
583    { 
584        for (j = 0; j < fs_info->uino_pool_size; j++)
585        {
586            if (!FAT_UNIQ_INO_IS_BUSY(fs_info->index, fs_info->uino))
587            {
588                FAT_SET_UNIQ_INO_BUSY(fs_info->index, fs_info->uino);
589                return (fs_info->uino_base + fs_info->index);           
590            }
591            fs_info->index++;
592            if (fs_info->index >= fs_info->uino_pool_size)
593                fs_info->index = 0;
594        }
595
596        if ((fs_info->uino_pool_size << 1) < (0x0FFFFFFF - fs_info->uino_base))
597        {
598            fs_info->uino_pool_size <<= 1;
599            fs_info->uino = realloc(fs_info->uino, fs_info->uino_pool_size);
600            if (fs_info->uino != NULL)
601                fs_info->index = fs_info->uino_pool_size;
602            else   
603                resrc_unsuff = TRUE;
604        }
605        else
606            resrc_unsuff = TRUE;
607    }   
608    return 0;
609}
610
611/* fat_free_unique_ino --
612 *     Return unique ino to unique ino pool
613 *
614 * PARAMETERS:
615 *     mt_entry - mount table entry
616 *     ino      - inode number to free
617 *
618 * RETURNS:
619 *     None
620 */
621void
622fat_free_unique_ino(
623    rtems_filesystem_mount_table_entry_t *mt_entry,
624    unsigned32                            ino
625    )
626{
627    fat_fs_info_t *fs_info = mt_entry->fs_info;
628   
629    FAT_SET_UNIQ_INO_FREE((ino - fs_info->uino_base), fs_info->uino);
630}
631
632/* fat_ino_is_unique --
633 *     Test whether ino is from unique ino pool
634 *
635 * PARAMETERS:
636 *     mt_entry - mount table entry
637 *     ino   - ino to be tested
638 *
639 * RETURNS:
640 *     TRUE if ino is allocated from unique ino pool, FALSE otherwise
641 */
642inline rtems_boolean
643fat_ino_is_unique(
644    rtems_filesystem_mount_table_entry_t *mt_entry,
645    unsigned32                            ino
646    )
647{
648    fat_fs_info_t *fs_info = mt_entry->fs_info;
649   
650    return (ino >= fs_info->uino_base);
651}
652
653/* fat_fat32_update_fsinfo_sector --
654 *     Synchronize fsinfo sector for FAT32 volumes
655 *
656 * PARAMETERS:
657 *     mt_entry   - mount table entry
658 *     free_count - count of free clusters
659 *     next_free  - the next free cluster num
660 *
661 * RETURNS:
662 *     RC_OK on success, or -1 if error occured (errno set appropriately)
663 */
664int
665fat_fat32_update_fsinfo_sector(
666    rtems_filesystem_mount_table_entry_t *mt_entry,
667    unsigned32                            free_count,
668    unsigned32                            next_free
669    )
670{
671    ssize_t                 ret1 = 0, ret2 = 0;
672    register fat_fs_info_t *fs_info = mt_entry->fs_info;
673    unsigned32              le_free_count = 0;
674    unsigned32              le_next_free = 0;
675
676    le_free_count = CT_LE_L(free_count);
677    le_next_free = CT_LE_L(next_free);
678
679    ret1 = _fat_block_write(mt_entry,
680                            fs_info->vol.info_sec,
681                            FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET,
682                            4,
683                            (char *)(&le_free_count));
684
685    ret2 = _fat_block_write(mt_entry,
686                            fs_info->vol.info_sec,
687                            FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET,
688                            4,
689                            (char *)(&le_next_free));
690
691    if ( (ret1 < 0) || (ret2 < 0) )
692        return -1;
693
694    return RC_OK;
695}
696
Note: See TracBrowser for help on using the repository browser.