Changeset 0f0db894 in rtems


Ignore:
Timestamp:
Nov 8, 2012, 2:41:23 PM (7 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, master
Children:
3c1d387
Parents:
8863338
git-author:
Sebastian Huber <sebastian.huber@…> (11/08/12 14:41:23)
git-committer:
Sebastian Huber <sebastian.huber@…> (11/13/12 08:38:03)
Message:

dosfs: Lazy update of FAT32 FS info sector

The FAT32 FS info sector contains hints for the free cluster count and
the next free cluster. The previous code read these values during mount
and replaced them with invalid values. The shutdown operation updated
them with the current values. These values are only hints. Every FAT
implementation must cope with arbitrary values. They are intended to
speed up certain operations.

Now we update the free cluster count and next free culster in the FAT32
FS info sector only during unmount or sync operations and only if the
values have changed. This avoids writes to the FS info sector and
conforms to the behaviour of Linux and Windows.

The application can force an update of these values now with the fsync()
and fdatasync() operations. Applications that only read will perform
not write operations to the FAT32 FS info sector.

The new fat_sync() function performs all non-file specific
synchronizations.

Location:
cpukit/libfs/src/dosfs
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libfs/src/dosfs/fat.c

    r8863338 r0f0db894  
    575575                }
    576576
    577                 vol->free_cls = FAT_GET_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector);
    578                 vol->next_cl = FAT_GET_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector);
    579                 rc = fat_fat32_update_fsinfo_sector(fs_info, FAT_UNDEFINED_VALUE,
    580                                                     FAT_UNDEFINED_VALUE);
    581                 if ( rc != RC_OK )
    582                 {
    583                     _fat_block_release(fs_info);
    584                     close(vol->fd);
    585                     return rc;
    586                 }
     577                vol->free_cls_in_fs_info =
     578                  FAT_GET_FSINFO_FREE_CLUSTER_COUNT(fs_info_sector);
     579                vol->free_cls = vol->free_cls_in_fs_info;
     580                vol->next_cl_in_fs_info =
     581                  FAT_GET_FSINFO_NEXT_FREE_CLUSTER(fs_info_sector);
     582                vol->next_cl = vol->next_cl_in_fs_info;
    587583            }
    588584        }
     
    646642}
    647643
     644/* fat_fat32_update_fsinfo_sector --
     645 *     Synchronize fsinfo sector for FAT32 volumes
     646 *
     647 * PARAMETERS:
     648 *     fs_info    - FS info
     649 *
     650 * RETURNS:
     651 *     RC_OK on success, or -1 if error occured (errno set appropriately)
     652 */
     653static int
     654fat_fat32_update_fsinfo_sector(fat_fs_info_t *fs_info)
     655{
     656    ssize_t ret1 = 0, ret2 = 0;
     657
     658    if (fs_info->vol.type == FAT_FAT32)
     659    {
     660        uint32_t free_count = fs_info->vol.free_cls;
     661        uint32_t next_free = fs_info->vol.next_cl;
     662
     663        if (free_count != fs_info->vol.free_cls_in_fs_info)
     664        {
     665            uint32_t le_free_count = CT_LE_L(free_count);
     666
     667            fs_info->vol.free_cls_in_fs_info = free_count;
     668
     669            ret1 = _fat_block_write(fs_info,
     670                                    fs_info->vol.info_sec,
     671                                    FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET,
     672                                    sizeof(le_free_count),
     673                                    &le_free_count);
     674        }
     675
     676        if (next_free != fs_info->vol.next_cl_in_fs_info)
     677        {
     678            uint32_t le_next_free = CT_LE_L(next_free);
     679
     680            fs_info->vol.next_cl_in_fs_info = next_free;
     681
     682            ret2 = _fat_block_write(fs_info,
     683                                    fs_info->vol.info_sec,
     684                                    FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET,
     685                                    sizeof(le_next_free),
     686                                    &le_next_free);
     687        }
     688    }
     689
     690    if ( (ret1 < 0) || (ret2 < 0) )
     691        return -1;
     692
     693    return RC_OK;
     694}
     695
     696int
     697fat_sync(fat_fs_info_t *fs_info)
     698{
     699    int rc = RC_OK;
     700
     701    rc = fat_fat32_update_fsinfo_sector(fs_info);
     702    if ( rc != RC_OK )
     703        rc = -1;
     704
     705    fat_buf_release(fs_info);
     706
     707    if (rtems_bdbuf_syncdev(fs_info->vol.dd) != RTEMS_SUCCESSFUL)
     708        rc = -1;
     709
     710    return rc;
     711}
     712
    648713/* fat_shutdown_drive --
    649714 *     Free all allocated resources and synchronize all necessary data
     
    662727    int            i = 0;
    663728
    664     if (fs_info->vol.type & FAT_FAT32)
    665     {
    666         rc = fat_fat32_update_fsinfo_sector(fs_info, fs_info->vol.free_cls,
    667                                             fs_info->vol.next_cl);
    668         if ( rc != RC_OK )
    669             rc = -1;
    670     }
    671 
    672     fat_buf_release(fs_info);
    673 
    674     if (rtems_bdbuf_syncdev(fs_info->vol.dd) != RTEMS_SUCCESSFUL)
     729    rc = fat_sync(fs_info);
     730    if ( rc != RC_OK )
    675731        rc = -1;
    676732
     
    850906    return (ino >= fs_info->uino_base);
    851907}
    852 
    853 /* fat_fat32_update_fsinfo_sector --
    854  *     Synchronize fsinfo sector for FAT32 volumes
    855  *
    856  * PARAMETERS:
    857  *     fs_info    - FS info
    858  *     free_count - count of free clusters
    859  *     next_free  - the next free cluster num
    860  *
    861  * RETURNS:
    862  *     RC_OK on success, or -1 if error occured (errno set appropriately)
    863  */
    864 int
    865 fat_fat32_update_fsinfo_sector(
    866     fat_fs_info_t                        *fs_info,
    867     uint32_t                              free_count,
    868     uint32_t                              next_free
    869     )
    870 {
    871     ssize_t                 ret1 = 0, ret2 = 0;
    872     uint32_t                le_free_count = 0;
    873     uint32_t                le_next_free = 0;
    874 
    875     le_free_count = CT_LE_L(free_count);
    876     le_next_free = CT_LE_L(next_free);
    877 
    878     ret1 = _fat_block_write(fs_info,
    879                             fs_info->vol.info_sec,
    880                             FAT_FSINFO_FREE_CLUSTER_COUNT_OFFSET,
    881                             4,
    882                             (char *)(&le_free_count));
    883 
    884     ret2 = _fat_block_write(fs_info,
    885                             fs_info->vol.info_sec,
    886                             FAT_FSINFO_NEXT_FREE_CLUSTER_OFFSET,
    887                             4,
    888                             (char *)(&le_next_free));
    889 
    890     if ( (ret1 < 0) || (ret2 < 0) )
    891         return -1;
    892 
    893     return RC_OK;
    894 }
  • cpukit/libfs/src/dosfs/fat.h

    r8863338 r0f0db894  
    314314    uint16_t           info_sec;       /* FSInfo Sector Structure location */
    315315    uint32_t           free_cls;       /* last known free clusters count */
     316    uint32_t           free_cls_in_fs_info; /* last known free clusters count
     317                                               in FS info sector */
    316318    uint32_t           next_cl;        /* next free cluster number */
     319    uint32_t           next_cl_in_fs_info; /* next free cluster number in FS
     320                                              info sector */
    317321    uint8_t            mirror;         /* mirroring enabla/disable */
    318322    uint32_t           afat_loc;       /* active FAT location */
     
    501505
    502506int
    503 fat_fat32_update_fsinfo_sector(
    504   fat_fs_info_t                        *fs_info,
    505   uint32_t                              free_count,
    506   uint32_t                              next_free
    507   );
     507fat_sync(fat_fs_info_t *fs_info);
    508508
    509509#ifdef __cplusplus
  • cpukit/libfs/src/dosfs/msdos.h

    r8863338 r0f0db894  
    398398);
    399399
    400 int msdos_sync_unprotected(msdos_fs_info_t *fs_info);
    401 
    402400int msdos_sync(rtems_libio_t *iop);
    403401
  • cpukit/libfs/src/dosfs/msdos_file.c

    r8863338 r0f0db894  
    291291    }
    292292
    293     rc = msdos_sync_unprotected(fs_info);
     293    rc = fat_sync(&fs_info->fat);
    294294
    295295    rtems_semaphore_release(fs_info->vol_sema);
  • cpukit/libfs/src/dosfs/msdos_misc.c

    r8863338 r0f0db894  
    16471647
    16481648int
    1649 msdos_sync_unprotected(msdos_fs_info_t *fs_info)
    1650 {
    1651     int rc = fat_buf_release(&fs_info->fat);
    1652     rtems_status_code sc = rtems_bdbuf_syncdev(fs_info->fat.vol.dd);
    1653     if (sc != RTEMS_SUCCESSFUL) {
    1654         errno = EIO;
    1655         rc = -1;
    1656     }
    1657 
    1658     return rc;
    1659 }
    1660 
    1661 int
    16621649msdos_sync(rtems_libio_t *iop)
    16631650{
     
    16711658        rtems_set_errno_and_return_minus_one(EIO);
    16721659
    1673     rc = msdos_sync_unprotected(fs_info);
     1660    rc = fat_sync(&fs_info->fat);
    16741661
    16751662    rtems_semaphore_release(fs_info->vol_sema);
Note: See TracChangeset for help on using the changeset viewer.