source: rtems/cpukit/include/rtems/imfs.h @ 0161b93d

5
Last change on this file since 0161b93d was 0161b93d, checked in by Sebastian Huber <sebastian.huber@…>, on 03/03/20 at 18:23:53

imfs: Replace devfs with an IMFS specialization

Add a simplified path evaluation function IMFS_eval_path_devfs() for a
device only IMFS configuration.

The code size can be further reduced by the application if it disables
the support for legacy IO drivers via:

#define CONFIGURE_IMFS_DISABLE_MKNOD
#define CONFIGURE_IMFS_DISABLE_MKNOD_DEVICE

Obsolete CONFIGURE_MAXIMUM_DEVICES. Remove BSP_MAXIMUM_DEVICES.

Update #3894.
Update #3898.

  • Property mode set to 100644
File size: 27.1 KB
Line 
1/**
2 * @file
3 *
4 * @brief 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.org/license/LICENSE.
14 */
15
16#ifndef _RTEMS_IMFS_H
17#define _RTEMS_IMFS_H
18
19#include <sys/time.h>
20#include <limits.h>
21
22#include <rtems/libio_.h>
23#include <rtems/pipe.h>
24#include <rtems/score/timecounter.h>
25
26/**
27 * @brief In-Memory File System Support.
28 *
29 * @defgroup IMFS In-Memory File System Support
30 *
31 * @ingroup FileSystemTypesAndMount
32 */
33/**@{*/
34
35#ifdef __cplusplus
36extern "C" {
37#endif
38
39/*
40 *  Data types
41 */
42
43struct IMFS_jnode_tt;
44typedef struct IMFS_jnode_tt IMFS_jnode_t;
45
46/**
47 *  IMFS "memfile" information
48 *
49 *  The data structure for the in-memory "memfiles" is based on classic UNIX.
50 *
51 *  block_ptr is a pointer to a block of IMFS_MEMFILE_BYTES_PER_BLOCK in
52 *  length which could be data or a table of pointers to blocks.
53 *
54 *  Setting IMFS_MEMFILE_BYTES_PER_BLOCK to different values has a significant
55 *  impact on the maximum file size supported as well as the amount of
56 *  memory wasted due to internal file fragmentation.  The following
57 *  is a list of maximum file sizes based on various settings
58 *
59 *  @code
60 *    max_filesize with blocks of   16 is         1,328
61 *    max_filesize with blocks of   32 is        18,656
62 *    max_filesize with blocks of   64 is       279,488
63 *    max_filesize with blocks of  128 is     4,329,344
64 *    max_filesize with blocks of  256 is    68,173,568
65 *    max_filesize with blocks of  512 is 1,082,195,456
66 *  @endcode
67 */
68#define IMFS_MEMFILE_DEFAULT_BYTES_PER_BLOCK     128
69  extern const int imfs_memfile_bytes_per_block;
70
71#define IMFS_MEMFILE_BYTES_PER_BLOCK imfs_memfile_bytes_per_block
72#define IMFS_MEMFILE_BLOCK_SLOTS \
73  (IMFS_MEMFILE_BYTES_PER_BLOCK / sizeof(void *))
74
75typedef uint8_t *block_p;
76typedef block_p *block_ptr;
77
78/*
79 *  Important block numbers for "memfiles"
80 */
81#define FIRST_INDIRECT           (0)
82#define LAST_INDIRECT            (IMFS_MEMFILE_BLOCK_SLOTS - 1)
83
84#define FIRST_DOUBLY_INDIRECT    (LAST_INDIRECT + 1)
85#define LAST_DOUBLY_INDIRECT     \
86   (LAST_INDIRECT + \
87     (IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
88
89#define FIRST_TRIPLY_INDIRECT    (LAST_DOUBLY_INDIRECT + 1)
90#define LAST_TRIPLY_INDIRECT \
91   (LAST_DOUBLY_INDIRECT +\
92     (IMFS_MEMFILE_BLOCK_SLOTS * \
93        IMFS_MEMFILE_BLOCK_SLOTS * IMFS_MEMFILE_BLOCK_SLOTS))
94
95#define IMFS_MEMFILE_MAXIMUM_SIZE \
96  (LAST_TRIPLY_INDIRECT * IMFS_MEMFILE_BYTES_PER_BLOCK)
97
98/** @} */
99
100/**
101 * @addtogroup IMFSGenericNodes
102 */
103/**@{*/
104
105/**
106 * @brief Initializes an IMFS node.
107 *
108 * @param[in] node The IMFS node.
109 * @param[in] arg The user provided argument pointer.  It may contain node
110 *   specific initialization information.
111 *
112 * @retval node Successful operation.
113 * @retval NULL An error occurred.  The @c errno indicates the error.  This
114 * will abort the make operation.
115 *
116 * @see IMFS_node_control, IMFS_node_initialize_default(), and
117 * IMFS_node_initialize_generic().
118 */
119typedef IMFS_jnode_t *(*IMFS_node_control_initialize)(
120  IMFS_jnode_t *node,
121  void *arg
122);
123
124/**
125 * @brief Returns the node and does nothing else.
126 *
127 * @param[in] node The IMFS node.
128 * @param[in] arg The user provided argument pointer.  It is not used.
129 *
130 * @retval node Returns always the node passed as parameter.
131 *
132 * @see IMFS_node_control.
133 */
134IMFS_jnode_t *IMFS_node_initialize_default(
135  IMFS_jnode_t *node,
136  void *arg
137);
138
139IMFS_jnode_t *IMFS_node_initialize_directory(
140  IMFS_jnode_t *node,
141  void *arg
142);
143
144/**
145 * @brief Returns the node and sets the generic node context.
146 *
147 * @param[in] node The IMFS node.
148 * @param[in] arg The user provided argument pointer.  It must contain the
149 *   generic context.
150 *
151 * @retval node Returns always the node passed as parameter.
152 *
153 * @see IMFS_node_control.
154 */
155IMFS_jnode_t *IMFS_node_initialize_generic(
156  IMFS_jnode_t *node,
157  void *arg
158);
159
160/**
161 * @brief Prepares the removal of an IMFS node from its parent directory.
162 *
163 * @param[in] node The IMFS node.
164 *
165 * @retval node Successful operation.
166 * @retval NULL An error occurred.  The @c errno indicates the error.  This
167 * will abort the removal operation.
168 *
169 * @see IMFS_node_control and IMFS_node_remove_default().
170 */
171typedef IMFS_jnode_t *(*IMFS_node_control_remove)(
172  IMFS_jnode_t *node
173);
174
175/**
176 * @brief Returns the node and does nothing else.
177 *
178 * @param[in] node The IMFS node.
179 *
180 * @retval node Returns always the node passed as parameter.
181 *
182 * @see IMFS_node_control.
183 */
184IMFS_jnode_t *IMFS_node_remove_default(
185  IMFS_jnode_t *node
186);
187
188IMFS_jnode_t *IMFS_node_remove_directory( IMFS_jnode_t *node );
189
190/**
191 * @brief Destroys an IMFS node.
192 *
193 * @param[in] node The IMFS node.
194 *
195 * @see IMFS_node_control and IMFS_node_destroy_default().
196 */
197typedef void (*IMFS_node_control_destroy)( IMFS_jnode_t *node );
198
199/**
200 * @brief Frees the node.
201 *
202 * @param[in] node The IMFS node.
203 *
204 * @see IMFS_node_control.
205 */
206void IMFS_node_destroy_default( IMFS_jnode_t *node );
207
208/**
209 * @brief Does nothing.
210 *
211 * @param node The IMFS node.
212 *
213 * @see IMFS_node_control.
214 */
215void IMFS_do_nothing_destroy( IMFS_jnode_t *node );
216
217/**
218 * @brief IMFS node control.
219 */
220typedef struct {
221  const rtems_filesystem_file_handlers_r *handlers;
222  IMFS_node_control_initialize node_initialize;
223  IMFS_node_control_remove node_remove;
224  IMFS_node_control_destroy node_destroy;
225} IMFS_node_control;
226
227typedef struct {
228  IMFS_node_control node_control;
229  size_t node_size;
230} IMFS_mknod_control;
231
232/** @} */
233
234/**
235 * @addtogroup IMFS
236 */
237/**@{*/
238
239/*
240 *  Maximum length of a "basename" of an IMFS file/node.
241 */
242
243#define IMFS_NAME_MAX _POSIX_NAME_MAX
244
245/*
246
247 *  The control structure for an IMFS jnode.
248 */
249
250struct IMFS_jnode_tt {
251  rtems_chain_node    Node;                  /* for chaining them together */
252  IMFS_jnode_t       *Parent;                /* Parent node */
253  const char         *name;                  /* "basename" (not \0 terminated) */
254  uint16_t            namelen;               /* Length of "basename" */
255  mode_t              st_mode;               /* File mode */
256  unsigned short      reference_count;
257  nlink_t             st_nlink;              /* Link count */
258
259  uid_t               st_uid;                /* User ID of owner */
260  gid_t               st_gid;                /* Group ID of owner */
261
262  time_t              stat_atime;            /* Time of last access */
263  time_t              stat_mtime;            /* Time of last modification */
264  time_t              stat_ctime;            /* Time of last status change */
265  const IMFS_node_control *control;
266};
267
268typedef struct {
269  IMFS_jnode_t                          Node;
270  rtems_chain_control                   Entries;
271  rtems_filesystem_mount_table_entry_t *mt_fs;
272} IMFS_directory_t;
273
274typedef struct {
275  IMFS_jnode_t              Node;
276  rtems_device_major_number major;
277  rtems_device_minor_number minor;
278} IMFS_device_t;
279
280typedef struct {
281  IMFS_jnode_t  Node;
282  IMFS_jnode_t *link_node;
283} IMFS_link_t;
284
285typedef struct {
286  IMFS_jnode_t  Node;
287  char         *name;
288} IMFS_sym_link_t;
289
290typedef struct {
291  IMFS_jnode_t Node;
292  size_t       size;             /* size of file in bytes */
293} IMFS_filebase_t;
294
295typedef struct {
296  IMFS_filebase_t File;
297  block_ptr       indirect;         /* array of 128 data blocks pointers */
298  block_ptr       doubly_indirect;  /* 128 indirect blocks */
299  block_ptr       triply_indirect;  /* 128 doubly indirect blocks */
300} IMFS_memfile_t;
301
302typedef struct {
303  IMFS_filebase_t File;
304  block_p         direct;           /* pointer to file image */
305} IMFS_linearfile_t;
306
307/* Support copy on write for linear files */
308typedef union {
309  IMFS_jnode_t      Node;
310  IMFS_filebase_t   File;
311  IMFS_memfile_t    Memfile;
312  IMFS_linearfile_t Linearfile;
313} IMFS_file_t;
314
315typedef struct {
316  IMFS_jnode_t    Node;
317  pipe_control_t *pipe;
318} IMFS_fifo_t;
319
320typedef struct {
321  IMFS_jnode_t  Node;
322  void         *context;
323} IMFS_generic_t;
324
325typedef struct {
326  const void *data;
327  size_t      size;
328} IMFS_linearfile_context;
329
330static inline IMFS_jnode_t *IMFS_iop_to_node( const rtems_libio_t *iop )
331{
332  return (IMFS_jnode_t *) iop->pathinfo.node_access;
333}
334
335static inline IMFS_directory_t *IMFS_iop_to_directory(
336  const rtems_libio_t *iop
337)
338{
339  return (IMFS_directory_t *) iop->pathinfo.node_access;
340}
341
342static inline IMFS_device_t *IMFS_iop_to_device( const rtems_libio_t *iop )
343{
344  return (IMFS_device_t *) iop->pathinfo.node_access;
345}
346
347static inline IMFS_file_t *IMFS_iop_to_file( const rtems_libio_t *iop )
348{
349  return (IMFS_file_t *) iop->pathinfo.node_access;
350}
351
352static inline IMFS_memfile_t *IMFS_iop_to_memfile( const rtems_libio_t *iop )
353{
354  return (IMFS_memfile_t *) iop->pathinfo.node_access;
355}
356
357static inline time_t _IMFS_get_time( void )
358{
359  struct bintime now;
360
361  /* Use most efficient way to get the time in seconds (CLOCK_REALTIME) */
362  _Timecounter_Getbintime( &now );
363
364  return now.sec;
365}
366
367static inline void IMFS_update_atime( IMFS_jnode_t *jnode )
368{
369  jnode->stat_atime = _IMFS_get_time();
370}
371
372static inline void IMFS_update_mtime( IMFS_jnode_t *jnode )
373{
374  jnode->stat_mtime = _IMFS_get_time();
375}
376
377static inline void IMFS_update_ctime( IMFS_jnode_t *jnode )
378{
379  jnode->stat_ctime = _IMFS_get_time();
380}
381
382static inline void IMFS_mtime_ctime_update( IMFS_jnode_t *jnode )
383{
384  time_t now;
385
386  now = _IMFS_get_time();
387
388  jnode->stat_mtime = now;
389  jnode->stat_ctime = now;
390}
391
392typedef struct {
393  const IMFS_mknod_control *directory;
394  const IMFS_mknod_control *device;
395  const IMFS_mknod_control *file;
396  const IMFS_mknod_control *fifo;
397} IMFS_mknod_controls;
398
399typedef struct {
400  IMFS_directory_t Root_directory;
401  const IMFS_mknod_controls *mknod_controls;
402} IMFS_fs_info_t;
403
404typedef struct {
405  IMFS_fs_info_t *fs_info;
406  const rtems_filesystem_operations_table *ops;
407  const IMFS_mknod_controls *mknod_controls;
408} IMFS_mount_data;
409
410/*
411 *  Shared Data
412 */
413
414extern const IMFS_mknod_control IMFS_mknod_control_dir_default;
415extern const IMFS_mknod_control IMFS_mknod_control_dir_minimal;
416extern const IMFS_mknod_control IMFS_mknod_control_device;
417extern const IMFS_mknod_control IMFS_mknod_control_memfile;
418extern const IMFS_node_control IMFS_node_control_linfile;
419extern const IMFS_mknod_control IMFS_mknod_control_fifo;
420extern const IMFS_mknod_control IMFS_mknod_control_enosys;
421
422extern const rtems_filesystem_limits_and_options_t  IMFS_LIMITS_AND_OPTIONS;
423
424/*
425 *  Routines
426 */
427
428extern int IMFS_initialize(
429   rtems_filesystem_mount_table_entry_t *mt_entry,
430   const void                           *data
431);
432
433extern int IMFS_initialize_support(
434  rtems_filesystem_mount_table_entry_t *mt_entry,
435  const void                           *data
436);
437
438/**
439 * @brief Unmount this instance of IMFS.
440 */
441extern void IMFS_fsunmount(
442   rtems_filesystem_mount_table_entry_t *mt_entry
443);
444
445/**
446 * @brief RTEMS load tarfs.
447 *
448 * This file implements the "mount" procedure for tar-based IMFS
449 * extensions.  The TAR is not actually mounted under the IMFS.
450 * Directories from the TAR file are created as usual in the IMFS.
451 * File entries are created as IMFS_LINEAR_FILE nodes with their nods
452 * pointing to addresses in the TAR image.
453 *
454 * Here we create the mountpoint directory and load the tarfs at
455 * that node.  Once the IMFS has been mounted, we work through the
456 * tar image and perform as follows:
457 *  - For directories, simply call mkdir().  The IMFS creates nodes as
458 *    needed.
459 *  - For files, we make our own calls to IMFS eval_for_make and
460 *    create_node.
461 *
462 * TAR file format:
463 *
464 * @code
465 *   Offset   Length                 Contents
466 *     0    100  bytes  File name ('\0' terminated, 99 maxmum length)
467 *   100      8  bytes  File mode (in octal ascii)
468 *   108      8  bytes  User ID (in octal ascii)
469 *   116      8  bytes  Group ID (in octal ascii)
470 *   124     12  bytes  File size (s) (in octal ascii)
471 *   136     12  bytes  Modify time (in octal ascii)
472 *   148      8  bytes  Header checksum (in octal ascii)
473 *   156      1  bytes  Link flag
474 *   157    100  bytes  Linkname ('\0' terminated, 99 maxmum length)
475 *   257      8  bytes  Magic PAX ("ustar\0" + 2 bytes padding)
476 *   257      8  bytes  Magic GNU tar ("ustar  \0")
477 *   265     32  bytes  User name ('\0' terminated, 31 maxmum length)
478 *   297     32  bytes  Group name ('\0' terminated, 31 maxmum length)
479 *   329      8  bytes  Major device ID (in octal ascii)
480 *   337      8  bytes  Minor device ID (in octal ascii)
481 *   345    167  bytes  Padding
482 *   512   (s+p) bytes  File contents (s+p) := (((s) + 511) & ~511),
483 *                      round up to 512 bytes
484 * @endcode
485 *
486 *  Checksum:
487 *  @code
488 *    int   i, sum;
489 *    char *header = tar_header_pointer;
490 *
491 *    sum = 0;
492 *    for (i = 0; i < 512; i++)
493 *        sum += 0xFF & header[i];
494 * @endcode
495 */
496extern int rtems_tarfs_load(
497   const char *mountpoint,
498   uint8_t *tar_image,
499   size_t tar_size
500);
501
502/**
503 * @brief Destroy an IMFS node.
504 */
505extern void IMFS_node_destroy( IMFS_jnode_t *node );
506
507/**
508 * @brief Clone an IMFS node.
509 */
510extern int IMFS_node_clone( rtems_filesystem_location_info_t *loc );
511
512/**
513 * @brief Free an IMFS node.
514 */
515extern void IMFS_node_free( const rtems_filesystem_location_info_t *loc );
516
517/**
518 * @brief Perform a status processing for the IMFS.
519 *
520 * This routine provides a stat for the IMFS file system.
521 */
522extern int IMFS_stat(
523  const rtems_filesystem_location_info_t *loc,
524  struct stat *buf
525);
526
527extern int IMFS_stat_file(
528  const rtems_filesystem_location_info_t *loc,
529  struct stat *buf
530);
531
532/**
533 * @brief IMFS evaluation node support.
534 */
535extern void IMFS_eval_path(
536  rtems_filesystem_eval_path_context_t *ctx
537);
538
539/**
540 * @brief IMFS device filesystem evaluation node support.
541 */
542extern void IMFS_eval_path_devfs(
543  rtems_filesystem_eval_path_context_t *ctx
544);
545
546/**
547 * @brief Create a new IMFS link node.
548 *
549 * The following rouine creates a new link node under parent with the
550 * name given in name.  The link node is set to point to the node at
551 * to_loc.
552 */
553extern int IMFS_link(
554  const rtems_filesystem_location_info_t *parentloc,
555  const rtems_filesystem_location_info_t *targetloc,
556  const char *name,
557  size_t namelen
558);
559
560/**
561 * @brief Change the owner of IMFS.
562 *
563 * This routine is the implementation of the chown() system
564 * call for the IMFS.
565 */
566extern int IMFS_chown(
567  const rtems_filesystem_location_info_t *loc,
568  uid_t owner,
569  gid_t group
570);
571
572/**
573 * @brief Create an IMFS node.
574 *
575 * Routine to create a node in the IMFS file system.
576 */
577extern int IMFS_mknod(
578  const rtems_filesystem_location_info_t *parentloc,
579  const char *name,
580  size_t namelen,
581  mode_t mode,
582  dev_t dev
583);
584
585extern IMFS_jnode_t *IMFS_initialize_node(
586  IMFS_jnode_t *node,
587  const IMFS_node_control *node_control,
588  const char *name,
589  size_t namelen,
590  mode_t mode,
591  void *arg
592);
593
594/**
595 * @brief Create an IMFS node.
596 *
597 * Create an IMFS filesystem node of an arbitrary type that is NOT
598 * the root directory node.
599 */
600extern IMFS_jnode_t *IMFS_create_node(
601  const rtems_filesystem_location_info_t *parentloc,
602  const IMFS_node_control *node_control,
603  size_t node_size,
604  const char *name,
605  size_t namelen,
606  mode_t mode,
607  void *arg
608);
609
610static inline bool IMFS_is_imfs_instance(
611  const rtems_filesystem_location_info_t *loc
612)
613{
614  return loc->mt_entry->ops->clonenod_h == IMFS_node_clone;
615}
616
617/**
618 * @brief Initializer for an IMFS node control.
619 *
620 * @param handlers The file system node handlers.
621 * @param init The node initialization method.
622 * @param destroy The node destruction method.
623 */
624#define IMFS_NODE_CONTROL_INITIALIZER( handlers, init, destroy ) \
625  { \
626    ( handlers ), \
627    ( init ), \
628    IMFS_node_remove_default, \
629    ( destroy ) \
630  }
631
632/**
633 * @brief Initializer for an IMFS node.
634 *
635 * Initialize the node control with IMFS_NODE_CONTROL_INITIALIZER().
636 *
637 * @param node_control The node control of the IMFS node.
638 * @param name The name of the IMFS node.
639 * @param namelen The length of the name of the IMFS node.
640 * @param mode The mode of the IMFS node.
641 *
642 * @see IMFS_node_preinitialize().
643 */
644#define IMFS_NODE_INITIALIZER( node_control, name, namelen, mode ) \
645  { \
646    { NULL, NULL }, \
647    NULL, \
648    ( name ), \
649    ( namelen ), \
650    ( mode ), \
651    0, \
652    0, \
653    0, \
654    0, \
655    0, \
656    0, \
657    0, \
658    ( node_control ) \
659  }
660
661/**
662 * @brief Preinitializes an IMFS node.
663 *
664 * Initialize the node control with IMFS_NODE_CONTROL_INITIALIZER().
665 *
666 * @param node The IMFS node to preinitialize.
667 * @param node_control The node control of the IMFS node.
668 * @param name The name of the IMFS node.
669 * @param namelen The length of the name of the IMFS node.
670 * @param mode The mode of the IMFS node.
671 *
672 * @see IMFS_NODE_INITIALIZER().
673 */
674static inline void IMFS_node_preinitialize(
675  IMFS_jnode_t            *node,
676  const IMFS_node_control *node_control,
677  const char              *name,
678  size_t                   namelen,
679  mode_t                   mode
680)
681{
682  node->control = node_control;
683  node->name = name;
684  node->namelen = namelen;
685  node->st_mode = mode;
686}
687
688/**
689 * @brief Adds an IMFS node.
690 *
691 * Initialize the node with IMFS_NODE_INITIALIZER(), IMFS_node_preinitialize(),
692 * IMFS_GENERIC_NODE_INITIALIZER(), or IMFS_generic_node_preinitialize().
693 *
694 * @param path The path of parent directories for the IMFS node to add.
695 * @param node The IMFS node to add.
696 * @param arg The argument passed to the node initialization method.
697 *
698 * @retval 0 Successful operation.
699 * @retval -1 An error occurred.  The @c errno indicates the error.
700 */
701int IMFS_add_node( const char *path, IMFS_jnode_t *node, void *arg );
702
703extern int IMFS_make_node(
704  const char              *path,
705  mode_t                   mode,
706  const IMFS_node_control *node_control,
707  size_t                   node_size,
708  void                    *context
709);
710
711/**
712 * @brief Makes a linear IMFS file.
713 *
714 * @param path The path to the new linear IMFS file.
715 * @param mode The file mode permissions.  S_IFREG is set by the function.
716 * @param data The begin of linear file data area.
717 * @param size The size of the linear file data area in bytes.
718 *
719 * @retval 0 Successful operation.
720 * @retval -1 An error occurred.  The @c errno indicates the error.
721 */
722extern int IMFS_make_linearfile(
723  const char *path,
724  mode_t      mode,
725  const void *data,
726  size_t      size
727);
728
729/** @} */
730
731/**
732 * @defgroup IMFSGenericNodes IMFS Generic Nodes
733 *
734 * @ingroup LibIO
735 *
736 * @brief Generic nodes are an alternative to standard drivers in RTEMS.
737 *
738 * The handlers of a generic node are called with less overhead compared to the
739 * standard driver operations.  The usage of file system node handlers enable
740 * more features like support for fsync() and fdatasync().  The generic nodes
741 * use the reference counting of the IMFS.  This provides automatic node
742 * destruction when the last reference vanishes.
743 *
744 * @{
745 */
746
747/* Provided for backward compatibility */
748#define IMFS_GENERIC_INITIALIZER( handlers, init, destroy ) \
749  IMFS_NODE_CONTROL_INITIALIZER( handlers, init, destroy )
750
751/**
752 * @brief Initializer for a generic node control.
753 *
754 * @param handlers The file system node handlers.
755 * @param init The node initialization method.
756 * @param destroy The node destruction method.
757 */
758#define IMFS_GENERIC_CONTROL_INITIALIZER( handlers, init, destroy ) \
759  IMFS_NODE_CONTROL_INITIALIZER( handlers, init, destroy )
760
761/**
762 * @brief Initializer for a generic node.
763 *
764 * Initialize the node control with IMFS_GENERIC_CONTROL_INITIALIZER().
765 *
766 * @param node_control The node control of the IMFS generic node.
767 * @param name The name of the IMFS generic node.
768 * @param namelen The length of the name of the IMFS generic node.
769 * @param mode The mode of the IMFS generic node.
770 */
771#define IMFS_GENERIC_NODE_INITIALIZER( node_control, name, namelen, mode ) \
772  { IMFS_NODE_INITIALIZER( node_control, name, namelen, mode ), NULL }
773
774/**
775 * @brief Preinitializes a generic IMFS node.
776 *
777 * Initialize the node control with IMFS_GENERIC_CONTROL_INITIALIZER().
778 *
779 * @param node The generic IMFS node to preinitialize.
780 * @param node_control The node control of the generic IMFS node.
781 * @param name The name of the generic IMFS node.
782 * @param namelen The length of the name of the generic IMFS node.
783 * @param mode The mode of the generic IMFS node.
784 *
785 * @see IMFS_GENERIC_NODE_INITIALIZER().
786 */
787static inline void IMFS_generic_node_preinitialize(
788  IMFS_generic_t          *node,
789  const IMFS_node_control *node_control,
790  const char              *name,
791  size_t                   namelen,
792  mode_t                   mode
793)
794{
795  IMFS_node_preinitialize( &node->Node, node_control, name, namelen, mode );
796}
797
798/**
799 * @brief Makes a generic IMFS node.
800 *
801 * @param[in] path The path to the new generic IMFS node.
802 * @param[in] mode The node mode.
803 * @param[in] node_control The node control.
804 * @param[in] context The node control handler context.
805 *
806 * @retval 0 Successful operation.
807 * @retval -1 An error occurred.  The @c errno indicates the error.
808 *
809 * @code
810 * #include <sys/stat.h>
811 * #include <assert.h>
812 * #include <fcntl.h>
813 *
814 * #include <rtems/imfs.h>
815 *
816 * static const rtems_filesystem_file_handlers_r some_node_handlers = {
817 *   ...
818 * };
819 *
820 * static IMFS_jnode_t *some_node_init(IMFS_jnode_t *node, void *arg)
821 * {
822 *   void *context;
823 *
824 *   node = IMFS_node_initialize_generic(node, arg);
825 *   context = IMFS_generic_get_context_by_node(node);
826 *
827 *   return node;
828 * }
829 *
830 * static void some_node_destroy(IMFS_jnode_t *node)
831 * {
832 *   void *context = IMFS_generic_get_context_by_node(node);
833 *
834 *   IMFS_node_destroy_default(node);
835 * }
836 *
837 * static const IMFS_node_control
838 * some_node_control = IMFS_GENERIC_CONTROL_INITIALIZER(
839 *   &some_node_handlers,
840 *   some_node_init,
841 *   some_node_destroy
842 * );
843 *
844 * void example(void *some_node_context)
845 * {
846 *   int rv;
847 *
848 *   rv = IMFS_make_generic_node(
849 *     "/path/to/some/generic/node",
850 *     S_IFCHR | S_IRWXU | S_IRWXG | S_IRWXO,
851 *     &some_node_control,
852 *     some_node_context
853 *   );
854 *   assert(rv == 0);
855 * }
856 * @endcode
857 */
858extern int IMFS_make_generic_node(
859  const char *path,
860  mode_t mode,
861  const IMFS_node_control *node_control,
862  void *context
863);
864
865/** @} */
866
867/**
868 * @addtogroup IMFS
869 */
870/**@{*/
871
872/**
873 * @brief Mount an IMFS.
874 */
875extern int IMFS_mount(
876  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
877);
878
879/**
880 * @brief Unmount an IMFS.
881 */
882extern int IMFS_unmount(
883  rtems_filesystem_mount_table_entry_t *mt_entry  /* IN */
884);
885
886/**
887 * @name IMFS Memory File Handlers
888 *
889 * This section contains the set of handlers used to process operations on
890 * IMFS memory file nodes.  The memory files are created in memory using
891 * malloc'ed memory.  Thus any data stored in one of these files is lost
892 * at system shutdown unless special arrangements to copy the data to
893 * some type of non-volailte storage are made by the application.
894 */
895/**@{*/
896
897extern ssize_t IMFS_memfile_write(
898  IMFS_memfile_t      *memfile,
899  off_t                start,
900  const unsigned char *source,
901  unsigned int         length
902);
903
904/** @} */
905
906/**
907 * @name IMFS Device Node Handlers
908 *
909 * This section contains the set of handlers used to map operations on
910 * IMFS device nodes onto calls to the RTEMS Classic API IO Manager.
911 */
912/**@{*/
913
914extern int device_open(
915  rtems_libio_t *iop,            /* IN  */
916  const char    *pathname,       /* IN  */
917  int            oflag,          /* IN  */
918  mode_t         mode            /* IN  */
919);
920
921extern int device_close(
922  rtems_libio_t *iop             /* IN  */
923);
924
925extern ssize_t device_read(
926  rtems_libio_t *iop,            /* IN  */
927  void          *buffer,         /* IN  */
928  size_t         count           /* IN  */
929);
930
931extern ssize_t device_write(
932  rtems_libio_t *iop,               /* IN  */
933  const void    *buffer,            /* IN  */
934  size_t         count              /* IN  */
935);
936
937extern int device_ioctl(
938  rtems_libio_t   *iop,
939  ioctl_command_t  command,
940  void            *buffer
941);
942
943extern int device_ftruncate(
944  rtems_libio_t *iop,               /* IN  */
945  off_t          length             /* IN  */
946);
947
948/** @} */
949
950/**
951 * @brief Set IMFS file access and modification times.
952 *
953 *
954 * This routine is the implementation of the utime() system
955 * call for the IMFS.
956 */
957extern int IMFS_utime(
958  const rtems_filesystem_location_info_t *loc,
959  time_t actime,
960  time_t modtime
961);
962
963/**
964 * @brief Change the IMFS file mode.
965 */
966extern int IMFS_fchmod(
967  const rtems_filesystem_location_info_t *loc,
968  mode_t mode
969);
970
971/**
972 * @brief Create a new IMFS symbolic link node.
973 *
974 * The following rouine creates a new symbolic link node under parent
975 * with the name given in name.  The node is set to point to the node at
976 * to_loc.
977 */
978extern int IMFS_symlink(
979  const rtems_filesystem_location_info_t *parentloc,
980  const char *name,
981  size_t namelen,
982  const char *target
983);
984
985/**
986 * @brief Put IMFS symbolic link into buffer.
987 *
988 * The following rouine puts the symbolic links destination name into
989 * buff.
990 *
991 */
992extern ssize_t IMFS_readlink(
993  const rtems_filesystem_location_info_t *loc,
994  char *buf,
995  size_t bufsize
996);
997
998/**
999 * @brief Rename the IMFS.
1000 *
1001 * The following rouine creates a new link node under parent with the
1002 * name given in name and removes the old.
1003 */
1004extern int IMFS_rename(
1005  const rtems_filesystem_location_info_t *oldparentloc,
1006  const rtems_filesystem_location_info_t *oldloc,
1007  const rtems_filesystem_location_info_t *newparentloc,
1008  const char *name,
1009  size_t namelen
1010);
1011/**
1012 * @brief IMFS node removal handler.
1013 *
1014 * This file contains the handler used to remove a node when a file type
1015 * does not require special actions.
1016 */
1017extern int IMFS_rmnod(
1018  const rtems_filesystem_location_info_t *parentloc,
1019  const rtems_filesystem_location_info_t *loc
1020);
1021
1022/*
1023 *  Turn on IMFS assertions when RTEMS_DEBUG is defined.
1024 */
1025#ifdef RTEMS_DEBUG
1026  #include <assert.h>
1027
1028  #define IMFS_assert(_x) assert(_x)
1029#else
1030  #define IMFS_assert(_x)
1031#endif
1032
1033static inline void IMFS_Set_handlers( rtems_filesystem_location_info_t *loc )
1034{
1035  IMFS_jnode_t *node = (IMFS_jnode_t *) loc->node_access;
1036
1037  loc->handlers = node->control->handlers;
1038}
1039
1040static inline void IMFS_add_to_directory(
1041  IMFS_jnode_t *dir_node,
1042  IMFS_jnode_t *entry_node
1043)
1044{
1045  IMFS_directory_t *dir = (IMFS_directory_t *) dir_node;
1046
1047  entry_node->Parent = dir_node;
1048  rtems_chain_append_unprotected( &dir->Entries, &entry_node->Node );
1049}
1050
1051static inline void IMFS_remove_from_directory( IMFS_jnode_t *node )
1052{
1053  IMFS_assert( node->Parent != NULL );
1054  node->Parent = NULL;
1055  rtems_chain_extract_unprotected( &node->Node );
1056}
1057
1058static inline bool IMFS_is_directory( const IMFS_jnode_t *node )
1059{
1060  return S_ISDIR( node->st_mode );
1061}
1062
1063#define IMFS_STAT_FMT_HARD_LINK 0
1064
1065static inline bool IMFS_is_hard_link( mode_t mode )
1066{
1067  return ( mode & S_IFMT ) == IMFS_STAT_FMT_HARD_LINK;
1068}
1069
1070static inline ino_t IMFS_node_to_ino( const IMFS_jnode_t *node )
1071{
1072  return (ino_t) ((uintptr_t) node);
1073}
1074
1075/** @} */
1076
1077/**
1078 * @addtogroup IMFSGenericNodes
1079 */
1080/**@{*/
1081
1082static inline void *IMFS_generic_get_context_by_node(
1083  const IMFS_jnode_t *node
1084)
1085{
1086  const IMFS_generic_t *generic = (const IMFS_generic_t *) node;
1087
1088  return generic->context;
1089}
1090
1091static inline void *IMFS_generic_get_context_by_location(
1092  const rtems_filesystem_location_info_t *loc
1093)
1094{
1095  return loc->node_access_2;
1096}
1097
1098static inline void *IMFS_generic_get_context_by_iop(
1099  const rtems_libio_t *iop
1100)
1101{
1102  return IMFS_generic_get_context_by_location( &iop->pathinfo );
1103}
1104
1105static inline dev_t IMFS_generic_get_device_identifier_by_node(
1106  const IMFS_jnode_t *node
1107)
1108{
1109  return rtems_filesystem_make_dev_t_from_pointer( node );
1110}
1111
1112#ifdef __cplusplus
1113}
1114#endif
1115/** @} */
1116#endif
1117/* end of include file */
Note: See TracBrowser for help on using the repository browser.