source: rtems/cpukit/libfs/src/imfs/imfs.h @ e4d35d8

4.115
Last change on this file since e4d35d8 was e4d35d8, checked in by Sebastian Huber <sebastian.huber@…>, on 02/05/15 at 15:43:58

IMFS: Split linfile and memfile modules

Make several functions static.

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