source: rtems/cpukit/libfs/src/dosfs/msdos_file.c @ a7eaaae8

4.115
Last change on this file since a7eaaae8 was a7eaaae8, checked in by Sebastian Huber <sebastian.huber@…>, on 10/20/14 at 07:33:34

dosfs: Support ctime and mtime

Implement ctime and mtime updates according to POSIX. The ctime is
mapped to the FAT create time and date. The mtime is mapped to the FAT
last modified time and date. For the atime use the mtime for
simplicity.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/**
2 * @file
3 *
4 * @brief MSDOS File Handlers Implementation
5 * @ingroup libfs
6 */
7
8/*
9 *  Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
10 *  Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.org/license/LICENSE.
15 */
16#if HAVE_CONFIG_H
17#include "config.h"
18#endif
19
20#include <stdlib.h>
21#include <errno.h>
22
23#include <rtems.h>
24#include <rtems/libio.h>
25#include <rtems/libio_.h>
26
27#include "fat.h"
28#include "fat_fat_operations.h"
29#include "fat_file.h"
30
31#include "msdos.h"
32
33/* msdos_file_read --
34 *     This routine read from file pointed to by file control block into
35 *     the specified data buffer provided by user
36 *
37 * PARAMETERS:
38 *     iop    - file control block
39 *     buffer - buffer  provided by user
40 *     count  - the number of bytes to read
41 *
42 * RETURNS:
43 *     the number of bytes read on success, or -1 if error occured (errno set
44 *     appropriately)
45 */
46ssize_t
47msdos_file_read(rtems_libio_t *iop, void *buffer, size_t count)
48{
49    ssize_t            ret = 0;
50    rtems_status_code  sc = RTEMS_SUCCESSFUL;
51    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
52    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
53
54    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
55                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
56    if (sc != RTEMS_SUCCESSFUL)
57        rtems_set_errno_and_return_minus_one(EIO);
58
59    ret = fat_file_read(&fs_info->fat, fat_fd, iop->offset, count,
60                        buffer);
61    if (ret > 0)
62        iop->offset += ret;
63
64    rtems_semaphore_release(fs_info->vol_sema);
65    return ret;
66}
67
68/* msdos_file_write --
69 *     This routine writes the specified data buffer into the file pointed to
70 *     by file control block.
71 *
72 * PARAMETERS:
73 *     iop    - file control block
74 *     buffer - data to write
75 *     count  - count of bytes to write
76 *
77 * RETURNS:
78 *     the number of bytes written on success, or -1 if error occured
79 *     and errno set appropriately
80 */
81ssize_t
82msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
83{
84    ssize_t            ret = 0;
85    rtems_status_code  sc = RTEMS_SUCCESSFUL;
86    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
87    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
88
89    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
90                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
91    if (sc != RTEMS_SUCCESSFUL)
92        rtems_set_errno_and_return_minus_one(EIO);
93
94    if ((iop->flags & LIBIO_FLAGS_APPEND) != 0)
95        iop->offset = fat_fd->fat_file_size;
96
97    ret = fat_file_write(&fs_info->fat, fat_fd, iop->offset, count,
98                         buffer);
99    if (ret < 0)
100    {
101        rtems_semaphore_release(fs_info->vol_sema);
102        return -1;
103    }
104
105    /*
106     * update file size in both fat-file descriptor and file control block if
107     * file was extended
108     */
109    iop->offset += ret;
110    if (iop->offset > fat_fd->fat_file_size)
111        fat_fd->fat_file_size = iop->offset;
112
113    if (ret > 0)
114        fat_file_set_ctime_mtime(fat_fd, time(NULL));
115
116    rtems_semaphore_release(fs_info->vol_sema);
117    return ret;
118}
119
120/* msdos_file_stat --
121 *
122 * PARAMETERS:
123 *     loc - node description
124 *     buf - stat buffer provided by user
125 *
126 * RETURNS:
127 *     RC_OK on success, or -1 if error occured (errno set appropriately)
128 */
129int
130msdos_file_stat(
131    const rtems_filesystem_location_info_t *loc,
132    struct stat *buf
133)
134{
135    rtems_status_code  sc = RTEMS_SUCCESSFUL;
136    msdos_fs_info_t   *fs_info = loc->mt_entry->fs_info;
137    fat_file_fd_t     *fat_fd = loc->node_access;
138    uint32_t           cl_mask = fs_info->fat.vol.bpc - 1;
139
140    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
141                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
142    if (sc != RTEMS_SUCCESSFUL)
143        rtems_set_errno_and_return_minus_one(EIO);
144
145    buf->st_dev = rtems_disk_get_device_identifier(fs_info->fat.vol.dd);
146    buf->st_ino = fat_fd->ino;
147    buf->st_mode  = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
148    buf->st_rdev = 0ll;
149    buf->st_size = fat_fd->fat_file_size;
150    buf->st_blocks = ((fat_fd->fat_file_size + cl_mask) & ~cl_mask)
151      >> FAT_SECTOR512_BITS;
152    buf->st_blksize = fs_info->fat.vol.bpc;
153    buf->st_atime = fat_fd->mtime;
154    buf->st_ctime = fat_fd->ctime;
155    buf->st_mtime = fat_fd->mtime;
156
157    rtems_semaphore_release(fs_info->vol_sema);
158    return RC_OK;
159}
160
161/* msdos_file_ftruncate --
162 *     Truncate the file.
163 *
164 * PARAMETERS:
165 *     iop    - file control block
166 *     length - new length
167 *
168 * RETURNS:
169 *     RC_OK on success, or -1 if error occured (errno set appropriately).
170 */
171int
172msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
173{
174    int                rc = RC_OK;
175    rtems_status_code  sc = RTEMS_SUCCESSFUL;
176    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
177    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
178    uint32_t old_length;
179
180    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
181                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
182    if (sc != RTEMS_SUCCESSFUL)
183        rtems_set_errno_and_return_minus_one(EIO);
184
185    old_length = fat_fd->fat_file_size;
186    if (length < old_length) {
187        rc = fat_file_truncate(&fs_info->fat, fat_fd, length);
188    } else {
189        uint32_t new_length;
190
191        rc = fat_file_extend(&fs_info->fat,
192                             fat_fd,
193                             true,
194                             length,
195                             &new_length);
196        if (rc == RC_OK && length != new_length) {
197            fat_file_truncate(&fs_info->fat, fat_fd, old_length);
198            errno = ENOSPC;
199            rc = -1;
200        }
201    }
202
203    if (rc == RC_OK)
204    {
205        fat_fd->fat_file_size = length;
206        fat_file_set_ctime_mtime(fat_fd, time(NULL));
207    }
208
209    rtems_semaphore_release(fs_info->vol_sema);
210
211    return rc;
212}
213
214/* msdos_file_sync --
215 *     Synchronize file - synchronize file data and if file is not removed
216 *     synchronize file metadata.
217 *
218 * PARAMETERS:
219 *     iop - file control block
220 *
221 * RETURNS:
222 *     RC_OK on success, or -1 if error occured (errno set appropriately)
223 */
224int
225msdos_file_sync(rtems_libio_t *iop)
226{
227    int                rc = RC_OK;
228    rtems_status_code  sc = RTEMS_SUCCESSFUL;
229    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
230    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
231
232    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
233                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
234    if (sc != RTEMS_SUCCESSFUL)
235        rtems_set_errno_and_return_minus_one(EIO);
236
237    rc = fat_file_update(&fs_info->fat, fat_fd);
238    if (rc != RC_OK)
239    {
240        rtems_semaphore_release(fs_info->vol_sema);
241        return rc;
242    }
243
244    rc = fat_sync(&fs_info->fat);
245
246    rtems_semaphore_release(fs_info->vol_sema);
247    return RC_OK;
248}
Note: See TracBrowser for help on using the repository browser.