source: rtems/cpukit/libfs/src/imfs/imfs.h @ 1bdff036

4.115
Last change on this file since 1bdff036 was 1bdff036, checked in by Sebastian Huber <sebastian.huber@…>, on 02/23/12 at 16:57:27

IMFS: Reference counting for nodes

The introduction of reference counting of nodes avoids the removal of
open nodes and potential usage of freed memory.

  • Property mode set to 100644
File size: 13.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_jnode_types_t;
137
138typedef union {
139  IMFS_directory_t   directory;
140  IMFS_device_t      device;
141  IMFS_link_t        hard_link;
142  IMFS_sym_link_t    sym_link;
143  IMFS_memfile_t     file;
144  IMFS_linearfile_t  linearfile;
145  IMFS_fifo_t        fifo;
146} IMFS_types_union;
147
148/*
149 * Major device number for the IMFS. This is not a real device number because
150 * the IMFS is just a file system and does not have a driver.
151 */
152#define IMFS_DEVICE_MAJOR_NUMBER (0xfffe)
153
154/*
155 *  Maximum length of a "basename" of an IMFS file/node.
156 */
157
158#define IMFS_NAME_MAX  32
159
160/*
161 *  The control structure for an IMFS jnode.
162 */
163
164struct IMFS_jnode_tt {
165  rtems_chain_node    Node;                  /* for chaining them together */
166  IMFS_jnode_t       *Parent;                /* Parent node */
167  char                name[IMFS_NAME_MAX+1]; /* "basename" */
168  mode_t              st_mode;               /* File mode */
169  unsigned short      reference_count;
170  nlink_t             st_nlink;              /* Link count */
171  ino_t               st_ino;                /* inode */
172
173  uid_t               st_uid;                /* User ID of owner */
174  gid_t               st_gid;                /* Group ID of owner */
175
176  time_t              stat_atime;            /* Time of last access */
177  time_t              stat_mtime;            /* Time of last modification */
178  time_t              stat_ctime;            /* Time of last status change */
179  IMFS_jnode_types_t  type;                  /* Type of this entry */
180  IMFS_types_union    info;
181};
182
183#define IMFS_update_atime( _jnode )         \
184  do {                                      \
185    struct timeval tv;                      \
186    gettimeofday( &tv, 0 );                 \
187    _jnode->stat_atime  = (time_t) tv.tv_sec; \
188  } while (0)
189
190#define IMFS_update_mtime( _jnode )         \
191  do {                                      \
192    struct timeval tv;                      \
193    gettimeofday( &tv, 0 );                 \
194    _jnode->stat_mtime  = (time_t) tv.tv_sec; \
195  } while (0)
196
197#define IMFS_update_ctime( _jnode )         \
198  do {                                      \
199    struct timeval tv;                      \
200    gettimeofday( &tv, 0 );                 \
201    _jnode->stat_ctime  = (time_t) tv.tv_sec; \
202  } while (0)
203
204#define IMFS_mtime_ctime_update( _jnode )   \
205  do {                                      \
206    struct timeval tv;                      \
207    gettimeofday( &tv, 0 );                 \
208    _jnode->stat_mtime  = (time_t) tv.tv_sec; \
209    _jnode->stat_ctime  = (time_t) tv.tv_sec; \
210  } while (0)
211
212typedef struct {
213  int                                     instance;
214  ino_t                                   ino_count;
215  const rtems_filesystem_file_handlers_r *memfile_handlers;
216  const rtems_filesystem_file_handlers_r *directory_handlers;
217  const rtems_filesystem_file_handlers_r *link_handlers;
218  const rtems_filesystem_file_handlers_r *fifo_handlers;
219} IMFS_fs_info_t;
220
221/*
222 *  Shared Data
223 */
224
225extern const rtems_filesystem_file_handlers_r       IMFS_directory_handlers;
226extern const rtems_filesystem_file_handlers_r       IMFS_device_handlers;
227extern const rtems_filesystem_file_handlers_r       IMFS_link_handlers;
228extern const rtems_filesystem_file_handlers_r       IMFS_memfile_handlers;
229extern const rtems_filesystem_file_handlers_r       IMFS_fifo_handlers;
230extern const rtems_filesystem_operations_table      IMFS_ops;
231extern const rtems_filesystem_operations_table      fifoIMFS_ops;
232extern const rtems_filesystem_limits_and_options_t  IMFS_LIMITS_AND_OPTIONS;
233
234/*
235 *  Routines
236 */
237
238extern int IMFS_initialize(
239   rtems_filesystem_mount_table_entry_t *mt_entry,
240   const void                           *data
241);
242
243extern int fifoIMFS_initialize(
244  rtems_filesystem_mount_table_entry_t  *mt_entry,
245  const void                            *data
246);
247
248extern int miniIMFS_initialize(
249   rtems_filesystem_mount_table_entry_t *mt_entry,
250   const void                           *data
251);
252
253extern int IMFS_initialize_support(
254   rtems_filesystem_mount_table_entry_t       *mt_entry,
255   const rtems_filesystem_operations_table    *op_table,
256   const rtems_filesystem_file_handlers_r     *link_handlers,
257   const rtems_filesystem_file_handlers_r     *fifo_handlers
258);
259
260extern void IMFS_fsunmount(
261   rtems_filesystem_mount_table_entry_t *mt_entry
262);
263
264extern int rtems_tarfs_load(
265   const char *mountpoint,
266   uint8_t *tar_image,
267   size_t tar_size
268);
269
270extern void IMFS_dump( void );
271
272/*
273 * Return the size of the largest file which can be created
274 * using the IMFS memory file type.
275 */
276extern int IMFS_memfile_maximum_size( void );
277
278extern void IMFS_node_destroy( IMFS_jnode_t *node );
279
280extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
281
282extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
283
284extern rtems_filesystem_node_types_t IMFS_node_type(
285  const rtems_filesystem_location_info_t *loc
286);
287
288extern int IMFS_stat(
289  const rtems_filesystem_location_info_t *loc,
290  struct stat *buf
291);
292
293extern void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc );
294
295extern void IMFS_eval_path(
296  rtems_filesystem_eval_path_context_t *ctx
297);
298
299extern int IMFS_link(
300  const rtems_filesystem_location_info_t *parentloc,
301  const rtems_filesystem_location_info_t *targetloc,
302  const char *name,
303  size_t namelen
304);
305
306extern int IMFS_chown(
307  const rtems_filesystem_location_info_t *loc,
308  uid_t owner,
309  gid_t group
310);
311
312extern int IMFS_mknod(
313  const rtems_filesystem_location_info_t *parentloc,
314  const char *name,
315  size_t namelen,
316  mode_t mode,
317  dev_t dev
318);
319
320extern IMFS_jnode_t *IMFS_allocate_node(
321  IMFS_jnode_types_t                type,         /* IN  */
322  const char                       *name,         /* IN  */
323  size_t                            namelen,      /* IN  */
324  mode_t                            mode          /* IN  */
325);
326
327extern IMFS_jnode_t *IMFS_create_root_node(void);
328
329extern IMFS_jnode_t *IMFS_create_node(
330  const rtems_filesystem_location_info_t *pathloc, /* IN  */
331  IMFS_jnode_types_t                      type,    /* IN  */
332  const char                             *name,    /* IN  */
333  size_t                                  namelen, /* IN  */
334  mode_t                                  mode,    /* IN  */
335  const IMFS_types_union                 *info     /* IN  */
336);
337
338extern int IMFS_mount(
339  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
340);
341
342extern int IMFS_unmount(
343  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
344);
345
346extern int IMFS_memfile_remove(
347 IMFS_jnode_t  *the_jnode         /* IN/OUT */
348);
349
350extern int memfile_ftruncate(
351  rtems_libio_t *iop,               /* IN  */
352  off_t          length             /* IN  */
353);
354
355extern int imfs_dir_open(
356  rtems_libio_t *iop,             /* IN  */
357  const char    *pathname,        /* IN  */
358  int            oflag,           /* IN  */
359  mode_t         mode             /* IN  */
360);
361
362extern ssize_t imfs_dir_read(
363  rtems_libio_t *iop,              /* IN  */
364  void          *buffer,           /* IN  */
365  size_t         count             /* IN  */
366);
367
368extern off_t imfs_dir_lseek(
369  rtems_libio_t        *iop,              /* IN  */
370  off_t                 offset,           /* IN  */
371  int                   whence            /* IN  */
372);
373
374extern int memfile_open(
375  rtems_libio_t *iop,             /* IN  */
376  const char    *pathname,        /* IN  */
377  int            oflag,           /* IN  */
378  mode_t         mode             /* IN  */
379);
380
381extern ssize_t memfile_read(
382  rtems_libio_t *iop,             /* IN  */
383  void          *buffer,          /* IN  */
384  size_t         count            /* IN  */
385);
386
387extern ssize_t memfile_write(
388  rtems_libio_t *iop,             /* IN  */
389  const void    *buffer,          /* IN  */
390  size_t         count            /* IN  */
391);
392
393extern int memfile_ioctl(
394  rtems_libio_t *iop,             /* IN  */
395  uint32_t       command,         /* IN  */
396  void          *buffer           /* IN  */
397);
398
399extern off_t memfile_lseek(
400  rtems_libio_t        *iop,        /* IN  */
401  off_t                 offset,     /* IN  */
402  int                   whence      /* IN  */
403);
404
405extern int device_open(
406  rtems_libio_t *iop,            /* IN  */
407  const char    *pathname,       /* IN  */
408  int            oflag,          /* IN  */
409  mode_t         mode            /* IN  */
410);
411
412extern int device_close(
413  rtems_libio_t *iop             /* IN  */
414);
415
416extern ssize_t device_read(
417  rtems_libio_t *iop,            /* IN  */
418  void          *buffer,         /* IN  */
419  size_t         count           /* IN  */
420);
421
422extern ssize_t device_write(
423  rtems_libio_t *iop,               /* IN  */
424  const void    *buffer,            /* IN  */
425  size_t         count              /* IN  */
426);
427
428extern int device_ioctl(
429  rtems_libio_t *iop,               /* IN  */
430  uint32_t       command,           /* IN  */
431  void          *buffer             /* IN  */
432);
433
434extern off_t device_lseek(
435  rtems_libio_t *iop,               /* IN  */
436  off_t          offset,            /* IN  */
437  int            whence             /* IN  */
438);
439
440extern int device_ftruncate(
441  rtems_libio_t *iop,               /* IN  */
442  off_t          length             /* IN  */
443);
444
445extern int IMFS_utime(
446  const rtems_filesystem_location_info_t *loc,
447  time_t actime,
448  time_t modtime
449);
450
451extern int IMFS_fchmod(
452  const rtems_filesystem_location_info_t *loc,
453  mode_t mode
454);
455
456extern int IMFS_symlink(
457  const rtems_filesystem_location_info_t *parentloc,
458  const char *name,
459  size_t namelen,
460  const char *target
461);
462
463extern ssize_t IMFS_readlink(
464  const rtems_filesystem_location_info_t *loc,
465  char *buf,
466  size_t bufsize
467);
468
469extern int IMFS_rename(
470  const rtems_filesystem_location_info_t *oldparentloc,
471  const rtems_filesystem_location_info_t *oldloc,
472  const rtems_filesystem_location_info_t *newparentloc,
473  const char *name,
474  size_t namelen
475);
476
477extern int IMFS_rmnod(
478  const rtems_filesystem_location_info_t *parentloc,
479  const rtems_filesystem_location_info_t *loc
480);
481
482/*
483 *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
484 */
485#ifdef RTEMS_DEBUG
486  #include <assert.h>
487
488  #define IMFS_assert(_x) assert(_x)
489#else
490  #define IMFS_assert(_x)
491#endif
492
493static inline void IMFS_add_to_directory(
494  IMFS_jnode_t *dir,
495  IMFS_jnode_t *node
496)
497{
498  node->Parent = dir;
499  rtems_chain_append_unprotected( &dir->info.directory.Entries, &node->Node );
500}
501
502static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
503{
504  IMFS_assert( node->Parent != NULL );
505  node->Parent = NULL;
506  rtems_chain_extract_unprotected( &node->Node );
507}
508
509#ifdef __cplusplus
510}
511#endif
512
513#endif
514/* end of include file */
Note: See TracBrowser for help on using the repository browser.