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

4.115
Last change on this file since c735cd5 was 8dbbea6b, checked in by Joel Sherrill <joel.sherrill@…>, on 11/27/14 at 15:29:16

msdos_file.c: Reverse return codes per Gedare

  • Property mode set to 100644
File size: 6.9 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_file_set_file_size(fat_fd, (uint32_t) 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_file_set_file_size(fat_fd, 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    if ( rc != 0 )
248      rtems_set_errno_and_return_minus_one(EIO);
249
250    return RC_OK;
251}
Note: See TracBrowser for help on using the repository browser.