source: rtems/cpukit/libfs/src/imfs/imfs.h @ 30d4124

4.115
Last change on this file since 30d4124 was 30d4124, checked in by Sebastian Huber <sebastian.huber@…>, on 05/07/12 at 14:30:37

Filesystem: PR1398: Fix lseek() mechanic

According to POSIX the lseek() function shall not, by itself, extend the
size of a file.

Remove the size field of rtems_libio_t. A file has only one size but
may have multiple open file descriptors. Thus a file size field in the
file descriptor may lead to inconsistencies.

New default handlers rtems_filesystem_default_lseek_file() and
rtems_filesystem_default_lseek_directory().

  • Property mode set to 100644
File size: 15.5 KB
Line 
1/**
2 * @file rtems/imfs.h
3 *
4 * Header file for the In-Memory File System
5 */
6
7/*
8 *  COPYRIGHT (c) 1989-2011.
9 *  On-Line Applications Research Corporation (OAR).
10 *
11 *  The license and distribution terms for this file may be
12 *  found in the file LICENSE in this distribution or at
13 *  http://www.rtems.com/license/LICENSE.
14 *
15 *  $Id$
16 */
17
18#ifndef _RTEMS_IMFS_H
19#define _RTEMS_IMFS_H
20
21#include <limits.h>
22
23#include <rtems/libio_.h>
24#include <rtems/pipe.h>
25
26#ifdef __cplusplus
27extern "C" {
28#endif
29
30/*
31 *  Data types
32 */
33
34struct IMFS_jnode_tt;
35typedef struct IMFS_jnode_tt IMFS_jnode_t;
36
37typedef struct {
38  rtems_chain_control                    Entries;
39  rtems_filesystem_mount_table_entry_t  *mt_fs;
40}  IMFS_directory_t;
41
42typedef struct {
43  rtems_device_major_number  major;
44  rtems_device_minor_number  minor;
45}  IMFS_device_t;
46
47typedef struct {
48  IMFS_jnode_t  *link_node;
49} IMFS_link_t;
50
51typedef struct {
52  char *name;
53} IMFS_sym_link_t;
54
55typedef struct {
56  pipe_control_t  *pipe;
57} IMFS_fifo_t;
58
59typedef struct {
60  void *context;
61} IMFS_generic_t;
62
63/*
64 *  IMFS "memfile" information
65 *
66 *  The data structure for the in-memory "memfiles" is based on classic UNIX.
67 *
68 *  block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
69 *  length which could be data or a table of pointers to blocks.
70 *
71 *  Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
72 *  impact on the maximum file size supported as well as the amount of
73 *  memory wasted due to internal file fragmentation.  The following
74 *  is a list of maximum file sizes based on various settings
75 *
76 *    max_filesize with blocks of   16 is         1,328
77 *    max_filesize with blocks of   32 is        18,656
78 *    max_filesize with blocks of   64 is       279,488
79 *    max_filesize with blocks of  128 is     4,329,344
80 *    max_filesize with blocks of  256 is    68,173,568
81 *    max_filesize with blocks of  512 is 1,082,195,456
82 */
83
84#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK     128
85  extern int imfs_rq_memfile_bytes_per_block;
86  extern int imfs_memfile_bytes_per_block;
87
88#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
89#define IMFS_MEMFILE_BLOCK_SLOTS \
90  (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
91
92typedef uint8_t *block_p;
93typedef block_p *block_ptr;
94
95typedef struct {
96  off_t         size;             /* size of file in bytes */
97  block_ptr     indirect;         /* array of 128 data blocks pointers */
98  block_ptr     doubly_indirect;  /* 128 indirect blocks */
99  block_ptr     triply_indirect;  /* 128 doubly indirect blocks */
100} IMFS_memfile_t;
101
102typedef struct {
103  off_t         size;             /* size of file in bytes */
104  block_p       direct;           /* pointer to file image */
105} IMFS_linearfile_t;
106
107/*
108 *  Important block numbers for "memfiles"
109 */
110
111#define FIRST_INDIRECT           (0)
112#define LAST_INDIRECT            (IMFS_MEMFILE_BLOCK_SLOTS - 1)
113
114#define FIRST_DOUBLY_INDIRECT    (LAST_INDIRECT + 1)
115#define LAST_DOUBLY_INDIRECT     \
116   (LAST_INDIRECT + \
117     (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
118
119#define FIRST_TRIPLY_INDIRECT    (LAST_DOUBLY_INDIRECT + 1)
120#define LAST_TRIPLY_INDIRECT \
121   (LAST_DOUBLY_INDIRECT +\
122     (IMFS_MEMFILE_BLOCK_SLOTS * \
123        IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
124
125#define IMFS_MEMFILE_MAXIMUM_SIZE \
126  (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
127
128/*
129 *  What types of IMFS file systems entities there can be.
130 */
131
132typedef enum {
133  IMFS_DIRECTORY = RTEMS_FILESYSTEM_DIRECTORY,
134  IMFS_DEVICE = RTEMS_FILESYSTEM_DEVICE,
135  IMFS_HARD_LINK = RTEMS_FILESYSTEM_HARD_LINK,
136  IMFS_SYM_LINK =  RTEMS_FILESYSTEM_SYM_LINK,
137  IMFS_MEMORY_FILE = RTEMS_FILESYSTEM_MEMORY_FILE,
138  IMFS_LINEAR_FILE,
139  IMFS_FIFO,
140  IMFS_GENERIC,
141  IMFS_INVALID_NODE
142} IMFS_jnode_types_t;
143
144/* The IMFS_GENERIC does not count */
145#define IMFS_TYPE_COUNT (IMFS_FIFO + 1)
146
147typedef union {
148  IMFS_directory_t   directory;
149  IMFS_device_t      device;
150  IMFS_link_t        hard_link;
151  IMFS_sym_link_t    sym_link;
152  IMFS_memfile_t     file;
153  IMFS_linearfile_t  linearfile;
154  IMFS_fifo_t        fifo;
155  IMFS_generic_t     generic;
156} IMFS_types_union;
157
158typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
159  IMFS_jnode_t *node,
160  const IMFS_types_union *info
161);
162
163IMFS_jnode_t *IMFS_node_initialize_default(
164  IMFS_jnode_t *node,
165  const IMFS_types_union *info
166);
167
168IMFS_jnode_t *IMFS_node_initialize_generic(
169  IMFS_jnode_t *node,
170  const IMFS_types_union *info
171);
172
173typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
174  IMFS_jnode_t *node,
175  const IMFS_jnode_t *root_node
176);
177
178IMFS_jnode_t *IMFS_node_remove_default(
179  IMFS_jnode_t *node,
180  const IMFS_jnode_t *root_node
181);
182
183typedef IMFS_jnode_t *(*IMFS_node_control_destroy)( IMFS_jnode_t *node );
184
185IMFS_jnode_t *IMFS_node_destroy_default( IMFS_jnode_t *node );
186
187typedef struct {
188  IMFS_jnode_types_t imfs_type;
189  const rtems_filesystem_file_handlers_r *handlers;
190  IMFS_node_control_initialize node_initialize;
191  IMFS_node_control_remove node_remove;
192  IMFS_node_control_destroy node_destroy;
193} IMFS_node_control;
194
195/*
196 * Major device number for the IMFS. This is not a real device number because
197 * the IMFS is just a file system and does not have a driver.
198 */
199#define IMFS_DEVICE_MAJOR_NUMBER (0xfffe)
200
201#define IMFS_GENERIC_DEVICE_MAJOR_NUMBER (0xfffd)
202
203/*
204 *  Maximum length of a "basename" of an IMFS file/node.
205 */
206
207#define IMFS_NAME_MAX  32
208
209/*
210 *  The control structure for an IMFS jnode.
211 */
212
213struct IMFS_jnode_tt {
214  rtems_chain_node    Node;                  /* for chaining them together */
215  IMFS_jnode_t       *Parent;                /* Parent node */
216  char                name[IMFS_NAME_MAX+1]; /* "basename" */
217  mode_t              st_mode;               /* File mode */
218  unsigned short      reference_count;
219  nlink_t             st_nlink;              /* Link count */
220  ino_t               st_ino;                /* inode */
221
222  uid_t               st_uid;                /* User ID of owner */
223  gid_t               st_gid;                /* Group ID of owner */
224
225  time_t              stat_atime;            /* Time of last access */
226  time_t              stat_mtime;            /* Time of last modification */
227  time_t              stat_ctime;            /* Time of last status change */
228  const IMFS_node_control *control;
229  IMFS_types_union    info;
230};
231
232#define IMFS_update_atime( _jnode )         \
233  do {                                      \
234    struct timeval tv;                      \
235    gettimeofday( &tv, 0 );                 \
236    _jnode->stat_atime  = (time_t) tv.tv_sec; \
237  } while (0)
238
239#define IMFS_update_mtime( _jnode )         \
240  do {                                      \
241    struct timeval tv;                      \
242    gettimeofday( &tv, 0 );                 \
243    _jnode->stat_mtime  = (time_t) tv.tv_sec; \
244  } while (0)
245
246#define IMFS_update_ctime( _jnode )         \
247  do {                                      \
248    struct timeval tv;                      \
249    gettimeofday( &tv, 0 );                 \
250    _jnode->stat_ctime  = (time_t) tv.tv_sec; \
251  } while (0)
252
253#define IMFS_mtime_ctime_update( _jnode )   \
254  do {                                      \
255    struct timeval tv;                      \
256    gettimeofday( &tv, 0 );                 \
257    _jnode->stat_mtime  = (time_t) tv.tv_sec; \
258    _jnode->stat_ctime  = (time_t) tv.tv_sec; \
259  } while (0)
260
261typedef struct {
262  int instance;
263  ino_t ino_count;
264  const IMFS_node_control *node_controls [IMFS_TYPE_COUNT];
265} IMFS_fs_info_t;
266
267/*
268 *  Shared Data
269 */
270
271extern const IMFS_node_control IMFS_node_control_directory;
272extern const IMFS_node_control IMFS_node_control_device;
273extern const IMFS_node_control IMFS_node_control_hard_link;
274extern const IMFS_node_control IMFS_node_control_sym_link;
275extern const IMFS_node_control IMFS_node_control_memfile;
276extern const IMFS_node_control IMFS_node_control_linfile;
277extern const IMFS_node_control IMFS_node_control_fifo;
278extern const IMFS_node_control IMFS_node_control_default;
279
280extern const rtems_filesystem_operations_table miniIMFS_ops;
281extern const rtems_filesystem_operations_table IMFS_ops;
282extern const rtems_filesystem_operations_table fifoIMFS_ops;
283
284extern const rtems_filesystem_limits_and_options_t  IMFS_LIMITS_AND_OPTIONS;
285
286/*
287 *  Routines
288 */
289
290extern int IMFS_initialize(
291   rtems_filesystem_mount_table_entry_t *mt_entry,
292   const void                           *data
293);
294
295extern int fifoIMFS_initialize(
296  rtems_filesystem_mount_table_entry_t  *mt_entry,
297  const void                            *data
298);
299
300extern int miniIMFS_initialize(
301   rtems_filesystem_mount_table_entry_t *mt_entry,
302   const void                           *data
303);
304
305extern int IMFS_initialize_support(
306  rtems_filesystem_mount_table_entry_t *mt_entry,
307  const rtems_filesystem_operations_table *op_table,
308  const IMFS_node_control *const node_controls [IMFS_TYPE_COUNT]
309);
310
311extern void IMFS_fsunmount(
312   rtems_filesystem_mount_table_entry_t *mt_entry
313);
314
315extern int rtems_tarfs_load(
316   const char *mountpoint,
317   uint8_t *tar_image,
318   size_t tar_size
319);
320
321extern void IMFS_dump( void );
322
323/*
324 * Return the size of the largest file which can be created
325 * using the IMFS memory file type.
326 */
327extern int IMFS_memfile_maximum_size( void );
328
329extern void IMFS_node_destroy( IMFS_jnode_t *node );
330
331extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
332
333extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
334
335extern rtems_filesystem_node_types_t IMFS_node_type(
336  const rtems_filesystem_location_info_t *loc
337);
338
339extern int IMFS_stat(
340  const rtems_filesystem_location_info_t *loc,
341  struct stat *buf
342);
343
344extern void IMFS_eval_path(
345  rtems_filesystem_eval_path_context_t *ctx
346);
347
348extern int IMFS_link(
349  const rtems_filesystem_location_info_t *parentloc,
350  const rtems_filesystem_location_info_t *targetloc,
351  const char *name,
352  size_t namelen
353);
354
355extern int IMFS_chown(
356  const rtems_filesystem_location_info_t *loc,
357  uid_t owner,
358  gid_t group
359);
360
361extern int IMFS_mknod(
362  const rtems_filesystem_location_info_t *parentloc,
363  const char *name,
364  size_t namelen,
365  mode_t mode,
366  dev_t dev
367);
368
369extern IMFS_jnode_t *IMFS_allocate_node(
370  IMFS_fs_info_t *fs_info,
371  const IMFS_node_control *node_control,
372  const char *name,
373  size_t namelen,
374  mode_t mode,
375  const IMFS_types_union *info
376);
377
378extern IMFS_jnode_t *IMFS_create_node_with_control(
379  const rtems_filesystem_location_info_t *parentloc,
380  const IMFS_node_control *node_control,
381  const char *name,
382  size_t namelen,
383  mode_t mode,
384  const IMFS_types_union *info
385);
386
387extern bool IMFS_is_imfs_instance(
388  const rtems_filesystem_location_info_t *loc
389);
390
391extern int IMFS_make_generic_node(
392  const char *path,
393  mode_t mode,
394  const IMFS_node_control *node_control,
395  void *context
396);
397
398extern int IMFS_mount(
399  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
400);
401
402extern int IMFS_unmount(
403  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
404);
405
406extern IMFS_jnode_t *IMFS_memfile_remove(
407 IMFS_jnode_t  *the_jnode         /* IN/OUT */
408);
409
410extern int memfile_ftruncate(
411  rtems_libio_t *iop,               /* IN  */
412  off_t          length             /* IN  */
413);
414
415extern ssize_t imfs_dir_read(
416  rtems_libio_t *iop,              /* IN  */
417  void          *buffer,           /* IN  */
418  size_t         count             /* IN  */
419);
420
421extern int memfile_open(
422  rtems_libio_t *iop,             /* IN  */
423  const char    *pathname,        /* IN  */
424  int            oflag,           /* IN  */
425  mode_t         mode             /* IN  */
426);
427
428extern ssize_t memfile_read(
429  rtems_libio_t *iop,             /* IN  */
430  void          *buffer,          /* IN  */
431  size_t         count            /* IN  */
432);
433
434extern ssize_t memfile_write(
435  rtems_libio_t *iop,             /* IN  */
436  const void    *buffer,          /* IN  */
437  size_t         count            /* IN  */
438);
439
440extern int memfile_ioctl(
441  rtems_libio_t *iop,             /* IN  */
442  uint32_t       command,         /* IN  */
443  void          *buffer           /* IN  */
444);
445
446extern int device_open(
447  rtems_libio_t *iop,            /* IN  */
448  const char    *pathname,       /* IN  */
449  int            oflag,          /* IN  */
450  mode_t         mode            /* IN  */
451);
452
453extern int device_close(
454  rtems_libio_t *iop             /* IN  */
455);
456
457extern ssize_t device_read(
458  rtems_libio_t *iop,            /* IN  */
459  void          *buffer,         /* IN  */
460  size_t         count           /* IN  */
461);
462
463extern ssize_t device_write(
464  rtems_libio_t *iop,               /* IN  */
465  const void    *buffer,            /* IN  */
466  size_t         count              /* IN  */
467);
468
469extern int device_ioctl(
470  rtems_libio_t *iop,               /* IN  */
471  uint32_t       command,           /* IN  */
472  void          *buffer             /* IN  */
473);
474
475extern int device_ftruncate(
476  rtems_libio_t *iop,               /* IN  */
477  off_t          length             /* IN  */
478);
479
480extern int IMFS_utime(
481  const rtems_filesystem_location_info_t *loc,
482  time_t actime,
483  time_t modtime
484);
485
486extern int IMFS_fchmod(
487  const rtems_filesystem_location_info_t *loc,
488  mode_t mode
489);
490
491extern int IMFS_symlink(
492  const rtems_filesystem_location_info_t *parentloc,
493  const char *name,
494  size_t namelen,
495  const char *target
496);
497
498extern ssize_t IMFS_readlink(
499  const rtems_filesystem_location_info_t *loc,
500  char *buf,
501  size_t bufsize
502);
503
504extern int IMFS_rename(
505  const rtems_filesystem_location_info_t *oldparentloc,
506  const rtems_filesystem_location_info_t *oldloc,
507  const rtems_filesystem_location_info_t *newparentloc,
508  const char *name,
509  size_t namelen
510);
511
512extern int IMFS_rmnod(
513  const rtems_filesystem_location_info_t *parentloc,
514  const rtems_filesystem_location_info_t *loc
515);
516
517/*
518 *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
519 */
520#ifdef RTEMS_DEBUG
521  #include <assert.h>
522
523  #define IMFS_assert(_x) assert(_x)
524#else
525  #define IMFS_assert(_x)
526#endif
527
528static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
529{
530  IMFS_jnode_t *node = (IMFS_jnode_t *) loc->node_access;
531
532  loc->handlers = node->control->handlers;
533}
534
535static inline void IMFS_add_to_directory(
536  IMFS_jnode_t *dir,
537  IMFS_jnode_t *node
538)
539{
540  node->Parent = dir;
541  rtems_chain_append_unprotected( &dir->info.directory.Entries, &node->Node );
542}
543
544static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
545{
546  IMFS_assert( node->Parent != NULL );
547  node->Parent = NULL;
548  rtems_chain_extract_unprotected( &node->Node );
549}
550
551static inline IMFS_jnode_types_t IMFS_type( const IMFS_jnode_t *node )
552{
553  return node->control->imfs_type;
554}
555
556static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
557{
558  return node->control->imfs_type == IMFS_DIRECTORY;
559}
560
561static inline IMFS_jnode_t *IMFS_create_node(
562  const rtems_filesystem_location_info_t *parentloc,
563  IMFS_jnode_types_t type,
564  const char *name,
565  size_t namelen,
566  mode_t mode,
567  const IMFS_types_union *info
568)
569{
570  const IMFS_fs_info_t *fs_info =
571    (const IMFS_fs_info_t *) parentloc->mt_entry->fs_info;
572
573  return IMFS_create_node_with_control(
574    parentloc,
575    fs_info->node_controls [type],
576    name,
577    namelen,
578    mode,
579    info
580  );
581}
582
583static inline void *IMFS_generic_get_context_by_node(
584  const IMFS_jnode_t *node
585)
586{
587  return node->info.generic.context;
588}
589
590static inline void *IMFS_generic_get_context_by_location(
591  const rtems_filesystem_location_info_t *loc
592)
593{
594  const IMFS_jnode_t *node = (const IMFS_jnode_t *) loc->node_access;
595
596  return IMFS_generic_get_context_by_node( node );
597}
598
599static inline void *IMFS_generic_get_context_by_iop(
600  const rtems_libio_t *iop
601)
602{
603  return IMFS_generic_get_context_by_location( &iop->pathinfo );
604}
605
606static inline dev_t IMFS_generic_get_device_identifier_by_node(
607  const IMFS_jnode_t *node
608)
609{
610  return rtems_filesystem_make_dev_t(
611    IMFS_GENERIC_DEVICE_MAJOR_NUMBER,
612    node->st_ino
613  );
614}
615
616#ifdef __cplusplus
617}
618#endif
619
620#endif
621/* end of include file */
Note: See TracBrowser for help on using the repository browser.