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

4.11
Last change on this file since fed66f99 was fce1169, checked in by Sebastian Huber <sebastian.huber@…>, on May 14, 2012 at 2:54:45 PM

dosfs: Remove unused parameter

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