summaryrefslogtreecommitdiffstats
path: root/cpukit/libfs/src/rfs/rtems-rfs-file.h
blob: ecadb359bc87198982957d3e4f4b1bf10223b912 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
/*
 *  COPYRIGHT (c) 2010 Chris Johns <chrisj@rtems.org>
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */
/**
 * @file
 *
 * @ingroup rtems-rfs
 *
 * RTEMS File System File Support
 *
 * This file provides the support functions.
 */

#if !defined (_RTEMS_RFS_FILE_H_)
#define _RTEMS_RFS_FILE_H_

#include <rtems/libio_.h>

#include <rtems/rfs/rtems-rfs-block.h>
#include <rtems/rfs/rtems-rfs-data.h>
#include <rtems/rfs/rtems-rfs-file-system.h>
#include <rtems/rfs/rtems-rfs-inode.h>

/**
 * File data that is shared by various file handles accessing the same file. We
 * hold various inode values common to the file that can change frequently so
 * the inode is not thrashed yet we meet the requirements of the POSIX
 * standard. The stat call needs to check the shared file data.
 */
typedef struct _rtems_rfs_file_shared
{
  /**
   * The shared parts are maintained as a list.
   */
  rtems_chain_node link;

  /**
   * Reference count the users of this data.
   */
  int references;

  /**
   * The inode for the file.
   */
  rtems_rfs_inode_handle inode;

  /**
   * The block map for the file. The handle holds the file's position not the
   * map.
   */
  rtems_rfs_block_map map;

  /**
   * The size of the file as taken from the inode. The map's size and
   * this size should be the same.
   */
  rtems_rfs_block_size size;

  /**
   * The access time. The last time the file was read.
   */
  rtems_rfs_time atime;

  /**
   * The modified time. The last time the file was written too.
   */
  rtems_rfs_time mtime;

  /**
   * The change time. The last time the inode was written too.
   */
  rtems_rfs_time ctime;

  /**
   * Hold a pointer to the file system data so users can take the handle and
   * use it without the needing to hold the file system data pointer.
   */
  rtems_rfs_file_system* fs;

} rtems_rfs_file_shared;

/**
 * Get the atime.
 *
 * @param shared The shared file data.
 * @return rtems_rfs_time The atime.
 */
static inline rtems_rfs_time
rtems_rfs_file_shared_get_atime (rtems_rfs_file_shared* shared)
{
  return shared->atime;
}

/**
 * Get the mtime.
 *
 * @param shared The shared file data.
 * @return rtems_rfs_time The mtime.
 */
static inline rtems_rfs_time
rtems_rfs_file_shared_get_mtime (rtems_rfs_file_shared* shared)
{
  return shared->mtime;
}

/**
 * Get the ctime.
 *
 * @param shared The shared file data.
 * @return rtems_rfs_time The ctime.
 */
static inline rtems_rfs_time
rtems_rfs_file_shared_get_ctime (rtems_rfs_file_shared* shared)
{
  return shared->ctime;
}

/**
 * Get the block count.
 *
 * @param shared The shared file data.
 * @return uint32_t The block count.
 */
static inline uint32_t
rtems_rfs_file_shared_get_block_count (rtems_rfs_file_shared* shared)
{
  return shared->size.count;
}

/**
 * Get the block offset.
 *
 * @param shared The shared file data.
 * @return uint16_t The block offset.
 */
static inline uint16_t
rtems_rfs_file_shared_get_block_offset (rtems_rfs_file_shared* shared)
{
  return shared->size.offset;
}

/**
 * Calculate the size of data.
 *
 * @param fs The file system data.
 * @oaram shared The shared file data.
 * @return rtems_rfs_pos The data size in bytes.
 */
static inline rtems_rfs_pos
rtems_rfs_file_shared_get_size (rtems_rfs_file_system* fs,
                                rtems_rfs_file_shared* shared)
{
  return rtems_rfs_block_get_size (fs, &shared->size);
}

/**
 * File flags.
 */
#define RTEMS_RFS_FILE_NO_ATIME_UPDATE  (1 << 0) /**< Do not update the atime
                                                  * field in the inode if
                                                  * set. */
#define RTEMS_RFS_FILE_NO_MTIME_UPDATE  (1 << 1) /**< Do not update the mtime
                                                  * field in the inode if
                                                  * set. */
#define RTEMS_RFS_FILE_NO_LENGTH_UPDATE (1 << 2) /**< Do not update the position
                                                  * field in the inode if
                                                  * set. */

/**
 * File data used to managed an open file.
 */
typedef struct _rtems_rfs_file_handle
{
  /**
   * Special flags that can be controlled by the fctrl call.
   */
  int flags;

  /**
   * The buffer of data at the file's position.
   */
  rtems_rfs_buffer_handle buffer;

  /**
   * The block position of this file handle.
   */
  rtems_rfs_block_pos bpos;

  /**
   * Pointer to the shared file data.
   */
  rtems_rfs_file_shared* shared;

} rtems_rfs_file_handle;

/**
 * Access the data in the buffer.
 */
#define rtems_rfs_file_data(_f) \
  (rtems_rfs_buffer_data (&(_f)->buffer) + (_f)->bpos.boff)

/**
 * Return the file system data pointer given a file handle.
 */
#define rtems_rfs_file_fs(_f) ((_f)->shared->fs)

/**
 * Return the file's inode handle pointer given a file handle.
 */
#define rtems_rfs_file_inode(_f) (&(_f)->shared->inode)

/**
 * Return the file's block map pointer given a file handle.
 */
#define rtems_rfs_file_map(_f) (&(_f)->shared->map)

/**
 * Return the file's block position pointer given a file handle.
 */
#define rtems_rfs_file_bpos(_f) (&(_f)->bpos)

/**
 * Return the file's block number given a file handle.
 */
#define rtems_rfs_file_block(_f) ((_f)->bpos.bno)

/**
 * Return the file's block offset given a file handle.
 */
#define rtems_rfs_file_block_offset(_f) ((_f)->bpos.boff)

/**
 * Set the file's block position given a file position (absolute).
 */
#define rtems_rfs_file_set_bpos(_f, _p) \
  rtems_rfs_block_get_bpos (rtems_rfs_file_fs (_f), _p, (&(_f)->bpos))

/**
 * Return the file's buffer handle pointer given a file handle.
 */
#define rtems_rfs_file_buffer(_f) (&(_f)->buffer)

/**
 * Update the access time field of the inode when reading if flagged to do so.
 */
#define rtems_rfs_file_update_atime(_f) \
  (((_f)->flags & RTEMS_RFS_FILE_NO_ATIME_UPDATE) == 0)

/**
 * Update the modified time field of the inode when writing if flagged to do so.
 */
#define rtems_rfs_file_update_mtime(_f) \
  (((_f)->flags & RTEMS_RFS_FILE_NO_MTIME_UPDATE) == 0)

/**
 * Update the length field of the inode.
 */
#define rtems_rfs_file_update_length(_f) \
  (((_f)->flags & RTEMS_RFS_FILE_NO_LENGTH_UPDATE) == 0)

/**
 * Return the shared size varable.
 */
#define rtems_rfs_file_get_size(_f) \
   (&(_f)->shared->size)

/**
 * Return the size of file.
 */
#define rtems_rfs_file_size(_f) \
  rtems_rfs_file_shared_get_size (rtems_rfs_file_fs (_f), (_f)->shared)

/**
 * Return the file block count.
 */
#define rtems_rfs_file_size_count(_f) \
  rtems_rfs_file_shared_get_block_count ((_f)->shared)

/**
 * Return the file block offset.
 */
#define rtems_rfs_file_size_offset(_f) \
  rtems_rfs_file_shared_get_block_offset ((_f)->shared)

/**
 * Open a file handle.
 *
 * @param fs The file system.
 * @param ino The inode number of the file to be opened.
 * @param handle Return the handle pointer in this handle.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_open (rtems_rfs_file_system*  fs,
                         rtems_rfs_ino           ino,
                         int                     oflag,
                         rtems_rfs_file_handle** handle);

/**
 * Close an open file handle.
 *
 * @param fs The file system.
 * @param handle The open file handle.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_close (rtems_rfs_file_system* fs,
                          rtems_rfs_file_handle* handle);

/**
 * Start I/O on a block of a file. This call only requests the block from the
 * media if reading and makes the buffer available to you the via the
 * rtems_rfs_file_data interface after the call. The available amount data is
 * taken from the current file position until the end of the block. The file
 * position is not adujsted until the I/O ends. An I/O request cannot perform
 * I/O past the end of a block so the call returns the amount of data
 * available.
 *
 * @param handle The file handle.
 * @param available The amount of data available for I/O.
 * @param read The I/O operation is a read so the block is read from the media.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_io_start (rtems_rfs_file_handle* handle,
                             size_t*                available,
                             bool                   read);

/**
 * End the I/O. Any buffers held in the file handle and returned to the
 * cache. If inode updating is not disable and the I/O is a read the atime
 * field is updated and if a write I/O the mtime is updated.
 *
 * If the file's position is updated by the size amount.
 *
 * @param handle The file handle.
 * @param size The amount of data read or written.
 * @param read The I/O was a read if true else it was a write.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_io_end (rtems_rfs_file_handle* handle,
                           size_t                 size,
                           bool                   read);

/**
 * Release the I/O resources without any changes. If data has changed in the
 * buffer and the buffer was not already released as modified the data will be
 * lost.
 *
 * @param handle The file handle.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_io_release (rtems_rfs_file_handle* handle);

/**
 * The file to the position returning the old position. The position is
 * abolute.
 *
 * @param handle The file handle.
 * @param pos The position to seek to.
 * @param new_pos The actual position.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_seek (rtems_rfs_file_handle* handle,
                         rtems_rfs_pos          pos,
                         rtems_rfs_pos*         new_pos);

/**
 * Set the size of the file to the new size. This can extend the file to a new
 * size.
 *
 * @param handle The file handle.
 * @param size The new size of the file.
 * @return int The error number (errno). No error if 0.
 */
int rtems_rfs_file_set_size (rtems_rfs_file_handle* handle,
                             rtems_rfs_pos          size);

/**
 * Return the shared file data for an ino.
 *
 * @param fs The file system data.
 * @param ino The inode number to locate the data for.
 * @return rtems_rfs_file_shared* The shared data or NULL is not located.
 */
rtems_rfs_file_shared* rtems_rfs_file_get_shared (rtems_rfs_file_system* fs,
                                                  rtems_rfs_ino          ino);


#endif