fsync() for FAT file system

Thomas Doerfler Thomas.Doerfler at embedded-brains.de
Fri May 4 14:51:41 UTC 2012


Sebastian,

if I get this code right, it actually parses each buffer of the _volume_
and ensures it is synced, so this is FAR from optimal ;-)

Syncing the device will defintivly be an improvement. For large files,
this will not be worse than syncing the file-specific buffers.

Another area: For really "syncing" the file, would it make sense to also
ensure that the file/directory information is updated as far as possible
to make sure the FS contains as much information as possible to read
back the file (in case of a device or power loss)?

wkr,

Thomas.



Am 04.05.2012 16:25, schrieb Sebastian Huber:
> Hi,
> 
> currently the fsync() handler for FAT file systems looks like this:
> 
> /* fat_file_datasync --
>  *     Synchronize fat-file -  flush all buffered data to the media.
>  *
>  * PARAMETERS:
>  *     mt_entry - mount table entry
>  *     fat_fd   - fat-file descriptor
>  *
>  * RETURNS:
>  *     RC_OK on success, or -1 if error occured and errno set appropriately
>  */
> int
> fat_file_datasync(
>     rtems_filesystem_mount_table_entry_t *mt_entry,
>     fat_file_fd_t                        *fat_fd
>     )
> {
>     int                 rc = RC_OK;
>     rtems_status_code   sc = RTEMS_SUCCESSFUL;
>     fat_fs_info_t      *fs_info = mt_entry->fs_info;
>     uint32_t            cur_cln = fat_fd->cln;
>     rtems_bdbuf_buffer *block = NULL;
>     uint32_t            sec = 0;
>     uint32_t            i = 0;
> 
>     if (fat_fd->fat_file_size == 0)
>         return RC_OK;
> 
>     /*
>      * we can use only one bdbuf :( and we also know that cache is useless
>      * for sync operation, so don't use it
>      */
>     rc = fat_buf_release(fs_info);
>     if (rc != RC_OK)
>         return rc;
> 
>     /* for each cluster of the file ... */
>     while ((cur_cln & fs_info->vol.mask) < fs_info->vol.eoc_val)
>     {
>         sec = fat_cluster_num_to_sector_num(mt_entry, cur_cln);
>         /* for each sector in cluster ... */
>         for ( i = 0; i < fs_info->vol.spc; i++ )
>         {
>             /* ... sync it */
>             sc = rtems_bdbuf_read(fs_info->vol.dd, (sec + i), &block);
>             if (sc != RTEMS_SUCCESSFUL)
>                 rtems_set_errno_and_return_minus_one( EIO );
> 
>             sc = rtems_bdbuf_sync(block);
>             if ( sc != RTEMS_SUCCESSFUL )
>                 rtems_set_errno_and_return_minus_one( EIO );
>         }
> 
>         rc = fat_get_fat_cluster(mt_entry, cur_cln, &cur_cln);
>         if ( rc != RC_OK )
>             return rc;
>     }
>     return rc;
> }
> 
> This function will read every cluster of the file into the cache and
> then synchronize it step-by-step.  For unmodified buffers this is a
> non-operation. For modified buffers this will wake-up the swapout task
> which performs then a single buffer write operation.  This is usually
> quite inefficient.  Firstly we do single buffer writes and secondly we
> may perform a lot of unnecessary read operations.
> 
> I think we should replace this synchronization procedure with a simple
> rtems_bdbuf_sync_dev(fs_info->vol.dev).  This has the side-effect that
> also buffers not related to the file are synchronized, but I think this
> is acceptable.
> 
> What do you think?
> 


-- 
--------------------------------------------
Embedded Brains GmbH
Thomas Doerfler           Obere Lagerstr. 30
D-82178 Puchheim          Germany
email: Thomas.Doerfler at embedded-brains.de
Phone: +49-89-18908079-2
Fax:   +49-89-18908079-9



More information about the devel mailing list