OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [cpukit/] [libfs/] [src/] [dosfs/] [fat.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.