Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:16

0001 /**
0002  * @file
0003  *
0004  * @ingroup DOSFS
0005  *
0006  * @brief MSDOS File Handlers Implementation
0007  */
0008 
0009 /*
0010  *  Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
0011  *  Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
0012  *
0013  *  The license and distribution terms for this file may be
0014  *  found in the file LICENSE in this distribution or at
0015  *  http://www.rtems.org/license/LICENSE.
0016  */
0017 #ifdef HAVE_CONFIG_H
0018 #include "config.h"
0019 #endif
0020 
0021 #include <stdlib.h>
0022 #include <errno.h>
0023 
0024 #include <rtems.h>
0025 #include <rtems/libio.h>
0026 #include <rtems/libio_.h>
0027 
0028 #include "fat.h"
0029 #include "fat_fat_operations.h"
0030 #include "fat_file.h"
0031 
0032 #include "msdos.h"
0033 
0034 /* msdos_file_read --
0035  *     This routine read from file pointed to by file control block into
0036  *     the specified data buffer provided by user
0037  *
0038  * PARAMETERS:
0039  *     iop    - file control block
0040  *     buffer - buffer  provided by user
0041  *     count  - the number of bytes to read
0042  *
0043  * RETURNS:
0044  *     the number of bytes read on success, or -1 if error occurred (errno set
0045  *     appropriately)
0046  */
0047 ssize_t
0048 msdos_file_read(rtems_libio_t *iop, void *buffer, size_t count)
0049 {
0050     ssize_t            ret = 0;
0051     msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
0052     fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
0053 
0054     msdos_fs_lock(fs_info);
0055 
0056     ret = fat_file_read(&fs_info->fat, fat_fd, iop->offset, count,
0057                         buffer);
0058     if (ret > 0)
0059         iop->offset += ret;
0060 
0061     msdos_fs_unlock(fs_info);
0062     return ret;
0063 }
0064 
0065 /* msdos_file_write --
0066  *     This routine writes the specified data buffer into the file pointed to
0067  *     by file control block.
0068  *
0069  * PARAMETERS:
0070  *     iop    - file control block
0071  *     buffer - data to write
0072  *     count  - count of bytes to write
0073  *
0074  * RETURNS:
0075  *     the number of bytes written on success, or -1 if error occurred
0076  *     and errno set appropriately
0077  */
0078 ssize_t
0079 msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
0080 {
0081     ssize_t            ret = 0;
0082     msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
0083     fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
0084 
0085     msdos_fs_lock(fs_info);
0086 
0087     if (rtems_libio_iop_is_append(iop))
0088         iop->offset = fat_fd->fat_file_size;
0089 
0090     ret = fat_file_write(&fs_info->fat, fat_fd, iop->offset, count,
0091                          buffer);
0092     if (ret < 0)
0093     {
0094         msdos_fs_unlock(fs_info);
0095         return -1;
0096     }
0097 
0098     /*
0099      * update file size in both fat-file descriptor and file control block if
0100      * file was extended
0101      */
0102     iop->offset += ret;
0103     if (iop->offset > fat_fd->fat_file_size)
0104         fat_file_set_file_size(fat_fd, (uint32_t) iop->offset);
0105 
0106     if (ret > 0)
0107         fat_file_set_ctime_mtime(fat_fd, time(NULL));
0108 
0109     msdos_fs_unlock(fs_info);
0110     return ret;
0111 }
0112 
0113 /* msdos_file_stat --
0114  *
0115  * PARAMETERS:
0116  *     loc - node description
0117  *     buf - stat buffer provided by user
0118  *
0119  * RETURNS:
0120  *     RC_OK on success, or -1 if error occurred (errno set appropriately)
0121  */
0122 int
0123 msdos_file_stat(
0124     const rtems_filesystem_location_info_t *loc,
0125     struct stat *buf
0126 )
0127 {
0128     msdos_fs_info_t   *fs_info = loc->mt_entry->fs_info;
0129     fat_file_fd_t     *fat_fd = loc->node_access;
0130     uint32_t           cl_mask = fs_info->fat.vol.bpc - 1;
0131 
0132     msdos_fs_lock(fs_info);
0133 
0134     buf->st_dev = fs_info->fat.vol.dev;
0135     buf->st_ino = fat_fd->ino;
0136     buf->st_mode  = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
0137     buf->st_rdev = 0ll;
0138     buf->st_size = fat_fd->fat_file_size;
0139     buf->st_blocks = ((fat_fd->fat_file_size + cl_mask) & ~cl_mask)
0140       >> FAT_SECTOR512_BITS;
0141     buf->st_blksize = fs_info->fat.vol.bpc;
0142     buf->st_atime = fat_fd->mtime;
0143     buf->st_ctime = fat_fd->ctime;
0144     buf->st_mtime = fat_fd->mtime;
0145 
0146     msdos_fs_unlock(fs_info);
0147     return RC_OK;
0148 }
0149 
0150 /* msdos_file_ftruncate --
0151  *     Truncate the file.
0152  *
0153  * PARAMETERS:
0154  *     iop    - file control block
0155  *     length - new length
0156  *
0157  * RETURNS:
0158  *     RC_OK on success, or -1 if error occurred (errno set appropriately).
0159  */
0160 int
0161 msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
0162 {
0163     int                rc = RC_OK;
0164     msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
0165     fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
0166     uint32_t old_length;
0167 
0168     msdos_fs_lock(fs_info);
0169 
0170     old_length = fat_fd->fat_file_size;
0171     if (length < old_length) {
0172         rc = fat_file_truncate(&fs_info->fat, fat_fd, length);
0173     } else {
0174         uint32_t new_length;
0175 
0176         rc = fat_file_extend(&fs_info->fat,
0177                              fat_fd,
0178                              true,
0179                              length,
0180                              &new_length);
0181         if (rc == RC_OK && length != new_length) {
0182             (void) fat_file_truncate(&fs_info->fat, fat_fd, old_length);
0183             errno = ENOSPC;
0184             rc = -1;
0185         }
0186     }
0187 
0188     if (rc == RC_OK)
0189     {
0190         fat_file_set_file_size(fat_fd, length);
0191         fat_file_set_ctime_mtime(fat_fd, time(NULL));
0192     }
0193 
0194     msdos_fs_unlock(fs_info);
0195 
0196     return rc;
0197 }
0198 
0199 /* msdos_file_sync --
0200  *     Synchronize file - synchronize file data and if file is not removed
0201  *     synchronize file metadata.
0202  *
0203  * PARAMETERS:
0204  *     iop - file control block
0205  *
0206  * RETURNS:
0207  *     RC_OK on success, or -1 if error occurred (errno set appropriately)
0208  */
0209 int
0210 msdos_file_sync(rtems_libio_t *iop)
0211 {
0212     int                rc = RC_OK;
0213     msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
0214     fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
0215 
0216     msdos_fs_lock(fs_info);
0217 
0218     rc = fat_file_update(&fs_info->fat, fat_fd);
0219     if (rc != RC_OK)
0220     {
0221         msdos_fs_unlock(fs_info);
0222         return rc;
0223     }
0224 
0225     rc = fat_sync(&fs_info->fat);
0226     if (rc != RC_OK)
0227     {
0228         msdos_fs_unlock(fs_info);
0229         return rc;
0230     }
0231 
0232     msdos_fs_unlock(fs_info);
0233 
0234     return RC_OK;
0235 }