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

4.104.114.84.95
Last change on this file since 7192476f was 7192476f, checked in by Ralf Corsepius <ralf.corsepius@…>, on 12/08/06 at 07:18:27

Use size_t instead of uint32_t for read/write count-args.

  • Property mode set to 100644
File size: 13.4 KB
RevLine 
[f36a7bfc]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
[cf0539b1]9 *  http://www.rtems.com/license/LICENSE.
[f36a7bfc]10 *
11 *  @(#) $Id$
12 */
13#if HAVE_CONFIG_H
14#include "config.h"
15#endif
16
17#include <stdlib.h>
18#include <assert.h>
19#include <errno.h>
20
21#include <rtems.h>
22#include <rtems/libio.h>
23#include <rtems/libio_.h>
24
25#include "fat.h"
26#include "fat_fat_operations.h"
27#include "fat_file.h"
28
29#include "msdos.h"
30
31/* msdos_file_open --
32 *     Open fat-file which correspondes to the file
33 *
34 * PARAMETERS:
35 *     iop        - file control block
36 *     pathname   - name
37 *     flag       - flags
38 *     mode       - mode
39 *
40 * RETURNS:
41 *     RC_OK, if file opened successfully, or -1 if error occured
42 *     and errno set appropriately
43 */
[a5305f6b]44int
[f91bbe64]45msdos_file_open(rtems_libio_t *iop, const char *pathname, uint32_t   flag,
46                uint32_t   mode)
[f36a7bfc]47{
[a5305f6b]48    int                rc = RC_OK;
[f36a7bfc]49    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]50    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[f36a7bfc]51    fat_file_fd_t     *fat_fd = iop->file_info;
52
53    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
54                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
55    if (sc != RTEMS_SUCCESSFUL)
56        set_errno_and_return_minus_one(EIO);
57
58    rc = fat_file_reopen(fat_fd);
59    if (rc != RC_OK)
60    {
61        rtems_semaphore_release(fs_info->vol_sema);
[a5305f6b]62        return rc;
[f36a7bfc]63    }
64
65    if (iop->flags & LIBIO_FLAGS_APPEND)
66        iop->offset = fat_fd->fat_file_size;
[a5305f6b]67
[f36a7bfc]68    iop->size = fat_fd->fat_file_size;
[a5305f6b]69
[f36a7bfc]70    rtems_semaphore_release(fs_info->vol_sema);
71    return RC_OK;
72}
73
74/* msdos_file_close --
[a5305f6b]75 *     Close fat-file which correspondes to the file. If fat-file descriptor
76 *     which correspondes to the file is not marked "removed", synchronize
[f36a7bfc]77 *     size, first cluster number, write time and date fields of the file.
78 *
79 * PARAMETERS:
80 *     iop - file control block
81 *
82 * RETURNS:
[a5305f6b]83 *     RC_OK, if file closed successfully, or -1 if error occured (errno set
[f36a7bfc]84 *     appropriately)
85 */
[a5305f6b]86int
[f36a7bfc]87msdos_file_close(rtems_libio_t *iop)
88{
[a5305f6b]89    int                rc = RC_OK;
[f36a7bfc]90    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]91    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[f36a7bfc]92    fat_file_fd_t     *fat_fd = iop->file_info;
93
[a5305f6b]94    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
[f36a7bfc]95                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
96    if (sc != RTEMS_SUCCESSFUL)
97        set_errno_and_return_minus_one(EIO);
[a5305f6b]98
99    /*
100     * if fat-file descriptor is not marked as "removed", synchronize
[f36a7bfc]101     * size, first cluster number, write time and date fields of the file
102     */
103    if (!FAT_FILE_IS_REMOVED(fat_fd))
[a5305f6b]104    {
[f36a7bfc]105        rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd);
106        if (rc != RC_OK)
107        {
108            rtems_semaphore_release(fs_info->vol_sema);
109            return rc;
110        }
111
112        rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd);
113        if (rc != RC_OK)
[a5305f6b]114        {
[f36a7bfc]115            rtems_semaphore_release(fs_info->vol_sema);
116            return rc;
[a5305f6b]117        }
[f36a7bfc]118
119        rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd);
120        if (rc != RC_OK)
121        {
122            rtems_semaphore_release(fs_info->vol_sema);
123            return rc;
[a5305f6b]124        }
[f36a7bfc]125    }
[a5305f6b]126
[f36a7bfc]127    rc = fat_file_close(iop->pathinfo.mt_entry, fat_fd);
128
129    rtems_semaphore_release(fs_info->vol_sema);
130    return rc;
131}
132
133/* msdos_file_read --
134 *     This routine read from file pointed to by file control block into
135 *     the specified data buffer provided by user
136 *
137 * PARAMETERS:
138 *     iop    - file control block
139 *     buffer - buffer  provided by user
140 *     count  - the number of bytes to read
141 *
142 * RETURNS:
[a5305f6b]143 *     the number of bytes read on success, or -1 if error occured (errno set
[f36a7bfc]144 *     appropriately)
145 */
[a5305f6b]146ssize_t
[7192476f]147msdos_file_read(rtems_libio_t *iop, void *buffer, size_t count)
[f36a7bfc]148{
[c788f380]149    ssize_t            ret = 0;
[f36a7bfc]150    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]151    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[f36a7bfc]152    fat_file_fd_t     *fat_fd = iop->file_info;
153
154    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
155                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
156    if (sc != RTEMS_SUCCESSFUL)
157        set_errno_and_return_minus_one(EIO);
158
[a5305f6b]159    ret = fat_file_read(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
[f36a7bfc]160                        buffer);
161
162    rtems_semaphore_release(fs_info->vol_sema);
163    return ret;
164}
165
166/* msdos_file_write --
[a5305f6b]167 *     This routine writes the specified data buffer into the file pointed to
[f36a7bfc]168 *     by file control block.
169 *
170 * PARAMETERS:
171 *     iop    - file control block
172 *     buffer - data to write
173 *     count  - count of bytes to write
174 *
175 * RETURNS:
176 *     the number of bytes written on success, or -1 if error occured
177 *     and errno set appropriately
178 */
[a5305f6b]179ssize_t
[7192476f]180msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
[f36a7bfc]181{
[a5305f6b]182    ssize_t            ret = 0;
[f36a7bfc]183    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]184    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[f36a7bfc]185    fat_file_fd_t     *fat_fd = iop->file_info;
186
187    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
188                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
189    if (sc != RTEMS_SUCCESSFUL)
190        set_errno_and_return_minus_one(EIO);
191
[a5305f6b]192    ret = fat_file_write(iop->pathinfo.mt_entry, fat_fd, iop->offset, count,
[f36a7bfc]193                         buffer);
194    if (ret < 0)
195    {
[a5305f6b]196        rtems_semaphore_release(fs_info->vol_sema);
[f36a7bfc]197        return -1;
198    }
199
[a5305f6b]200    /*
201     * update file size in both fat-file descriptor and file control block if
[f36a7bfc]202     * file was extended
203     */
204    if (iop->offset + ret > fat_fd->fat_file_size)
205        fat_fd->fat_file_size = iop->offset + ret;
206
207    iop->size = fat_fd->fat_file_size;
208
209    rtems_semaphore_release(fs_info->vol_sema);
210    return ret;
211}
212
213/* msdos_file_lseek --
[a5305f6b]214 *     Process lseek call to the file: extend file if lseek is up to the end
[f36a7bfc]215 *     of the file.
216 *
217 * PARAMETERS:
218 *     iop    - file control block
219 *     offset - new offset
220 *     whence - predefine directive
221 *
222 * RETURNS:
[a5305f6b]223 *     new offset on success, or -1 if error occured (errno set
[f36a7bfc]224 *     appropriately).
225 */
[a5305f6b]226int
[f36a7bfc]227msdos_file_lseek(rtems_libio_t *iop, off_t offset, int whence)
228{
229    int                rc = RC_OK;
230    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]231    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[f36a7bfc]232    fat_file_fd_t     *fat_fd = iop->file_info;
[f91bbe64]233    uint32_t           real_size = 0;
[f36a7bfc]234
235    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
236                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
237    if (sc != RTEMS_SUCCESSFUL)
238        set_errno_and_return_minus_one(EIO);
239
[a5305f6b]240    rc = fat_file_extend(iop->pathinfo.mt_entry, fat_fd, iop->offset,
[f36a7bfc]241                         &real_size);
242    if (rc != RC_OK)
243    {
244        rtems_semaphore_release(fs_info->vol_sema);
245        return rc;
246    }
247
248    if (real_size > fat_fd->fat_file_size)
249        fat_fd->fat_file_size = iop->offset = real_size;
[a5305f6b]250
[f36a7bfc]251    iop->size = fat_fd->fat_file_size;
252
253    rtems_semaphore_release(fs_info->vol_sema);
254    return iop->offset;
255}
256
257/* msdos_file_stat --
258 *
259 * PARAMETERS:
260 *     loc - node description
261 *     buf - stat buffer provided by user
262 *
263 * RETURNS:
264 *     RC_OK on success, or -1 if error occured (errno set appropriately)
265 */
[a5305f6b]266int
[f36a7bfc]267msdos_file_stat(
268    rtems_filesystem_location_info_t *loc,
269    struct stat                      *buf
270    )
271{
272    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]273    msdos_fs_info_t   *fs_info = loc->mt_entry->fs_info;
[f36a7bfc]274    fat_file_fd_t     *fat_fd = loc->node_access;
275
276    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
277                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
278    if (sc != RTEMS_SUCCESSFUL)
279        set_errno_and_return_minus_one(EIO);
[a5305f6b]280
[f36a7bfc]281    buf->st_dev = fs_info->fat.vol.dev;
282    buf->st_ino = fat_fd->ino;
283    buf->st_mode  = S_IFREG;
284    buf->st_rdev = 0ll;
285    buf->st_size = fat_fd->fat_file_size;
286    buf->st_blocks = fat_fd->fat_file_size >> FAT_SECTOR512_BITS;
287    buf->st_blksize = fs_info->fat.vol.bps;
288    buf->st_mtime = fat_fd->mtime;
289
290    rtems_semaphore_release(fs_info->vol_sema);
291    return RC_OK;
292}
293
294/* msdos_file_ftruncate --
295 *     Truncate the file (if new length is greater then current do nothing).
296 *
297 * PARAMETERS:
298 *     iop    - file control block
[a5305f6b]299 *     length - new length
[f36a7bfc]300 *
301 * RETURNS:
302 *     RC_OK on success, or -1 if error occured (errno set appropriately).
303 */
[a5305f6b]304int
[f36a7bfc]305msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
306{
307    int                rc = RC_OK;
308    rtems_status_code  sc = RTEMS_SUCCESSFUL;
[a5305f6b]309    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[f36a7bfc]310    fat_file_fd_t     *fat_fd = iop->file_info;
311
312    if (length >= fat_fd->fat_file_size)
313        return RC_OK;
314
315    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
316                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
317    if (sc != RTEMS_SUCCESSFUL)
318        set_errno_and_return_minus_one(EIO);
[a5305f6b]319
[f36a7bfc]320    rc = fat_file_truncate(iop->pathinfo.mt_entry, fat_fd, length);
321    if (rc != RC_OK)
322    {
323        rtems_semaphore_release(fs_info->vol_sema);
324        return rc;
325    }
326
[a5305f6b]327    /*
328     * fat_file_truncate do nothing if new length >= fat-file size, so update
[f36a7bfc]329     * file size only if length < fat-file size
330     */
331    if (length < fat_fd->fat_file_size)
332        iop->size = fat_fd->fat_file_size = length;
[a5305f6b]333
[f36a7bfc]334    rtems_semaphore_release(fs_info->vol_sema);
335    return RC_OK;
336}
337
338/* msdos_file_sync --
[a5305f6b]339 *     Synchronize file - synchronize file data and if file is not removed
[f36a7bfc]340 *     synchronize file metadata.
341 *
342 * PARAMETERS:
343 *     iop - file control block
344 *
345 * RETURNS:
346 *     RC_OK on success, or -1 if error occured (errno set appropriately)
347 */
348int
349msdos_file_sync(rtems_libio_t *iop)
350{
351    int                rc = RC_OK;
352    rtems_status_code  sc = RTEMS_SUCCESSFUL;
353    fat_file_fd_t     *fat_fd = iop->file_info;
354    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[a5305f6b]355
[f36a7bfc]356    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
357                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
358    if (sc != RTEMS_SUCCESSFUL)
359        set_errno_and_return_minus_one(EIO);
[a5305f6b]360
[f36a7bfc]361    /* synchronize file data */
362    rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
363    if (rc != RC_OK)
364    {
365        rtems_semaphore_release(fs_info->vol_sema);
366        return rc;
367    }
368
[a5305f6b]369    /*
370     * if fat-file descriptor is not marked "removed" - synchronize file
[f36a7bfc]371     * metadata
372     */
373    if (!FAT_FILE_IS_REMOVED(fat_fd))
[a5305f6b]374    {
[f36a7bfc]375        rc = msdos_set_first_cluster_num(iop->pathinfo.mt_entry, fat_fd);
376        if (rc != RC_OK)
377        {
378            rtems_semaphore_release(fs_info->vol_sema);
379            return rc;
380        }
381        rc = msdos_set_file_size(iop->pathinfo.mt_entry, fat_fd);
382        if (rc != RC_OK)
383        {
384            rtems_semaphore_release(fs_info->vol_sema);
385            return rc;
[a5305f6b]386        }
[f36a7bfc]387        rc = msdos_set_dir_wrt_time_and_date(iop->pathinfo.mt_entry, fat_fd);
388        if (rc != RC_OK)
389        {
390            rtems_semaphore_release(fs_info->vol_sema);
391            return rc;
[a5305f6b]392        }
[f36a7bfc]393    }
[a5305f6b]394
[f36a7bfc]395    rtems_semaphore_release(fs_info->vol_sema);
396    return RC_OK;
397}
398
399/* msdos_file_datasync --
400 *     Synchronize file - synchronize only file data (metadata is letf intact).
401 *
402 * PARAMETERS:
403 *     iop - file control block
404 *
405 * RETURNS:
406 *     RC_OK on success, or -1 if error occured (errno set appropriately)
407 */
408int
409msdos_file_datasync(rtems_libio_t *iop)
410{
411    int                rc = RC_OK;
412    rtems_status_code  sc = RTEMS_SUCCESSFUL;
413    fat_file_fd_t     *fat_fd = iop->file_info;
414    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
[a5305f6b]415
[f36a7bfc]416    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
417                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
418    if (sc != RTEMS_SUCCESSFUL)
419        set_errno_and_return_minus_one(EIO);
[a5305f6b]420
[f36a7bfc]421    /* synchronize file data */
422    rc = fat_file_datasync(iop->pathinfo.mt_entry, fat_fd);
[a5305f6b]423
[f36a7bfc]424    rtems_semaphore_release(fs_info->vol_sema);
425    return RC_OK;
426}
427
428
429/* msdos_file_ioctl --
430 *
431 *
432 * PARAMETERS:
433 *     iop    - file control block
434 *     ...
435 *
436 * RETURNS:
437 *
438 */
[a5305f6b]439int
[f91bbe64]440msdos_file_ioctl(rtems_libio_t *iop,uint32_t   command, void *buffer)
[f36a7bfc]441{
442    int rc = RC_OK;
443
444    return rc;
445}
446
447/* msdos_file_rmnod --
[a5305f6b]448 *     Remove node associated with a file - set up first name character to
449 *     predefined value(and write it to the disk), and mark fat-file which
[f36a7bfc]450 *     correspondes to the file as "removed"
451 *
452 * PARAMETERS:
453 *     pathloc - node description
454 *
455 * RETURNS:
456 *     RC_OK on success, or -1 if error occured (errno set appropriately)
457 */
[e197621]458int
[f36a7bfc]459msdos_file_rmnod(rtems_filesystem_location_info_t *pathloc)
460{
[e197621]461    int                rc = RC_OK;
[f36a7bfc]462    rtems_status_code  sc = RTEMS_SUCCESSFUL;
463    msdos_fs_info_t   *fs_info = pathloc->mt_entry->fs_info;
464    fat_file_fd_t     *fat_fd = pathloc->node_access;
465
466    sc = rtems_semaphore_obtain(fs_info->vol_sema, RTEMS_WAIT,
467                                MSDOS_VOLUME_SEMAPHORE_TIMEOUT);
468    if (sc != RTEMS_SUCCESSFUL)
469        set_errno_and_return_minus_one(EIO);
470
471    /* mark file removed */
[a5305f6b]472    rc = msdos_set_first_char4file_name(pathloc->mt_entry, fat_fd->info_cln,
473                                        fat_fd->info_ofs,
[f36a7bfc]474                                        MSDOS_THIS_DIR_ENTRY_EMPTY);
475    if (rc != RC_OK)
476    {
477        rtems_semaphore_release(fs_info->vol_sema);
478        return rc;
479    }
480
[a5305f6b]481    fat_file_mark_removed(pathloc->mt_entry, fat_fd);
[f36a7bfc]482
483    rtems_semaphore_release(fs_info->vol_sema);
484    return RC_OK;
485}
Note: See TracBrowser for help on using the repository browser.