source: rtems/cpukit/libfs/src/imfs/imfs.h @ 699ac7c

4.115
Last change on this file since 699ac7c was 699ac7c, checked in by Sebastian Huber <sebastian.huber@…>, on 02/24/12 at 16:08:06

IMFS: Add and use node control

Add and use structure IMFS_node_control with support functions. This
helps to make high level functions independent of the node type and
reduces the number of branches in the code.

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