source: rtems/cpukit/include/rtems/imfs.h @ fa44c39

5
Last change on this file since fa44c39 was fa44c39, checked in by Sebastian Huber <sebastian.huber@…>, on 02/29/20 at 15:14:31

imfs: Add IMFS_add_node()

Update #3894.

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