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

5
Last change on this file since 0ec9bbc was 3b77417, checked in by Sebastian Huber <sebastian.huber@…>, on 12/13/17 at 15:15:25

dosfs: Use self-contained recursive mutex

Update #2843.

  • Property mode set to 100644
File size: 5.6 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    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
51    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
52
53    msdos_fs_lock(fs_info);
54
55    ret = fat_file_read(&fs_info->fat, fat_fd, iop->offset, count,
56                        buffer);
57    if (ret > 0)
58        iop->offset += ret;
59
60    msdos_fs_unlock(fs_info);
61    return ret;
62}
63
64/* msdos_file_write --
65 *     This routine writes the specified data buffer into the file pointed to
66 *     by file control block.
67 *
68 * PARAMETERS:
69 *     iop    - file control block
70 *     buffer - data to write
71 *     count  - count of bytes to write
72 *
73 * RETURNS:
74 *     the number of bytes written on success, or -1 if error occured
75 *     and errno set appropriately
76 */
77ssize_t
78msdos_file_write(rtems_libio_t *iop,const void *buffer, size_t count)
79{
80    ssize_t            ret = 0;
81    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
82    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
83
84    msdos_fs_lock(fs_info);
85
86    if (rtems_libio_iop_is_append(iop))
87        iop->offset = fat_fd->fat_file_size;
88
89    ret = fat_file_write(&fs_info->fat, fat_fd, iop->offset, count,
90                         buffer);
91    if (ret < 0)
92    {
93        msdos_fs_unlock(fs_info);
94        return -1;
95    }
96
97    /*
98     * update file size in both fat-file descriptor and file control block if
99     * file was extended
100     */
101    iop->offset += ret;
102    if (iop->offset > fat_fd->fat_file_size)
103        fat_file_set_file_size(fat_fd, (uint32_t) iop->offset);
104
105    if (ret > 0)
106        fat_file_set_ctime_mtime(fat_fd, time(NULL));
107
108    msdos_fs_unlock(fs_info);
109    return ret;
110}
111
112/* msdos_file_stat --
113 *
114 * PARAMETERS:
115 *     loc - node description
116 *     buf - stat buffer provided by user
117 *
118 * RETURNS:
119 *     RC_OK on success, or -1 if error occured (errno set appropriately)
120 */
121int
122msdos_file_stat(
123    const rtems_filesystem_location_info_t *loc,
124    struct stat *buf
125)
126{
127    msdos_fs_info_t   *fs_info = loc->mt_entry->fs_info;
128    fat_file_fd_t     *fat_fd = loc->node_access;
129    uint32_t           cl_mask = fs_info->fat.vol.bpc - 1;
130
131    msdos_fs_lock(fs_info);
132
133    buf->st_dev = rtems_disk_get_device_identifier(fs_info->fat.vol.dd);
134    buf->st_ino = fat_fd->ino;
135    buf->st_mode  = S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO;
136    buf->st_rdev = 0ll;
137    buf->st_size = fat_fd->fat_file_size;
138    buf->st_blocks = ((fat_fd->fat_file_size + cl_mask) & ~cl_mask)
139      >> FAT_SECTOR512_BITS;
140    buf->st_blksize = fs_info->fat.vol.bpc;
141    buf->st_atime = fat_fd->mtime;
142    buf->st_ctime = fat_fd->ctime;
143    buf->st_mtime = fat_fd->mtime;
144
145    msdos_fs_unlock(fs_info);
146    return RC_OK;
147}
148
149/* msdos_file_ftruncate --
150 *     Truncate the file.
151 *
152 * PARAMETERS:
153 *     iop    - file control block
154 *     length - new length
155 *
156 * RETURNS:
157 *     RC_OK on success, or -1 if error occured (errno set appropriately).
158 */
159int
160msdos_file_ftruncate(rtems_libio_t *iop, off_t length)
161{
162    int                rc = RC_OK;
163    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
164    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
165    uint32_t old_length;
166
167    msdos_fs_lock(fs_info);
168
169    old_length = fat_fd->fat_file_size;
170    if (length < old_length) {
171        rc = fat_file_truncate(&fs_info->fat, fat_fd, length);
172    } else {
173        uint32_t new_length;
174
175        rc = fat_file_extend(&fs_info->fat,
176                             fat_fd,
177                             true,
178                             length,
179                             &new_length);
180        if (rc == RC_OK && length != new_length) {
181            fat_file_truncate(&fs_info->fat, fat_fd, old_length);
182            errno = ENOSPC;
183            rc = -1;
184        }
185    }
186
187    if (rc == RC_OK)
188    {
189        fat_file_set_file_size(fat_fd, length);
190        fat_file_set_ctime_mtime(fat_fd, time(NULL));
191    }
192
193    msdos_fs_unlock(fs_info);
194
195    return rc;
196}
197
198/* msdos_file_sync --
199 *     Synchronize file - synchronize file data and if file is not removed
200 *     synchronize file metadata.
201 *
202 * PARAMETERS:
203 *     iop - file control block
204 *
205 * RETURNS:
206 *     RC_OK on success, or -1 if error occured (errno set appropriately)
207 */
208int
209msdos_file_sync(rtems_libio_t *iop)
210{
211    int                rc = RC_OK;
212    msdos_fs_info_t   *fs_info = iop->pathinfo.mt_entry->fs_info;
213    fat_file_fd_t     *fat_fd = iop->pathinfo.node_access;
214
215    msdos_fs_lock(fs_info);
216
217    rc = fat_file_update(&fs_info->fat, fat_fd);
218    if (rc != RC_OK)
219    {
220        msdos_fs_unlock(fs_info);
221        return rc;
222    }
223
224    rc = fat_sync(&fs_info->fat);
225
226    msdos_fs_unlock(fs_info);
227
228    return RC_OK;
229}
Note: See TracBrowser for help on using the repository browser.