1 /*
   2  * This file and its contents are supplied under the terms of the
   3  * Common Development and Distribution License ("CDDL"), version 1.0.
   4  * You may only use this file in accordance with the terms of version
   5  * 1.0 of the CDDL.
   6  *
   7  * A full copy of the text of the CDDL should have accompanied this
   8  * source.  A copy of the CDDL is also available via the Internet at
   9  * http://www.illumos.org/license/CDDL.
  10  */
  11 
  12 /*
  13  * Copyright 2013 Damian Bogel.  All rights reserved.
  14  */
  15 
  16 /*
  17  * This file includes all the necessary declarations for fsh.c, vfs.c
  18  * and vnode.c.
  19  */
  20 
  21 #ifndef _FSH_IMPL_H
  22 #define _FSH_IMPL_H
  23 
  24 #include <sys/atomic.h>
  25 #include <sys/fsh.h>
  26 #include <sys/pathname.h>
  27 #include <sys/types.h>
  28 #include <sys/vfs.h>
  29 #include <sys/vnode.h>
  30 
  31 #ifdef __cplusplus
  32 extern "C" {
  33 #endif
  34 
  35 #define FSH_VFS_MOUNT           0
  36 #define FSH_VFS_UNMOUNT         1
  37 #define FSH_VFS_ROOT            2
  38 #define FSH_VFS_STATFS          3
  39 #define FSH_VFS_VGET            4
  40 
  41 #define FSH_VOP_OPEN            5
  42 #define FSH_VOP_CLOSE           6
  43 #define FSH_VOP_READ            7
  44 #define FSH_VOP_WRITE           8
  45 
  46 #define FSH_SUPPORTED_OPS_COUNT 9
  47 
  48 /*
  49  * TODO:
  50  * - change all defined lists to the ones used in illumos kernel
  51  * - add comments
  52  */
  53 
  54 typedef union fsh_fn {
  55         FSH_OPS;
  56 } fsh_fn_t;
  57 
  58 /*
  59  * fsh_int_t is the internal fsh_t structure. Instead of using a big
  60  * structure containing hooks for all the operations, fsh_int_t contains
  61  * a pointer (in union fsh_fn_t) to one function. Thanks to this approach,
  62  * we don't have to manipulate such big structures. Instead, we keep
  63  * a fsh_int_t list for every operation.
  64  */
  65 typedef struct fsh_int {
  66         fsh_fn_t        fshi_fn;
  67         void            *fshi_arg;
  68 } fsh_int_t;
  69 
  70 
  71 struct fsh_node {
  72         fsh_int_t       fshn_hooki;
  73         struct fsh_node *fshn_next;
  74 };
  75 /* typedef struct fsh_node fsh_node_t; in fsh.h */
  76 
  77 /*
  78  * fshl_lock is read-locked by every call to a fsh_vop/vfsop() for
  79  * entire execution. This way, we guarantee that a list of hooks is unchanged
  80  * during one fop_foo()/fsop_foo() execution.
  81  */
  82 typedef struct fsh_list {
  83         krwlock_t       fshl_lock;
  84         fsh_node_t      *fshl_head;
  85 } fsh_list_t;
  86 
  87 /*
  88  * fshfsr_enabled informs whether FSH is enabled for this vfs_t.
  89  * There are no locks involved. This field should be change only via
  90  * atomic operations.
  91  */
  92 typedef struct fsh_fsrecord {
  93         volatile uint_t fshfsr_enabled;
  94         fsh_list_t      fshfsr_opv[FSH_SUPPORTED_OPS_COUNT];
  95 } fsh_fsrecord_t;
  96 
  97 
  98 typedef struct fsh_callback_node {
  99         fsh_callback_t                  fshcn_callback;
 100         struct fsh_callback_node        *fshcn_next;
 101 } fsh_callback_node_t;
 102 
 103 typedef struct fsh_callback_list {
 104         krwlock_t               fshcl_lock;
 105         fsh_callback_node_t     *fshcl_head;
 106 } fsh_callback_list_t;
 107 
 108 /* API for vnode.c and vfs.c only */
 109 /* vnode.c */
 110 extern int fsh_open(vnode_t **vpp, int mode, cred_t *cr, caller_context_t *ct);
 111 extern int fsh_close(vnode_t *vp, int flag, int count, offset_t offset,
 112                 cred_t *cr, caller_context_t *ct);
 113 extern int fsh_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
 114                 caller_context_t *ct);
 115 extern int fsh_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
 116                 caller_context_t *ct);
 117 
 118 /* vfs.c */
 119 extern void fsh_init(void);
 120 
 121 extern int fsh_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap,
 122                 cred_t *cr);
 123 extern int fsh_unmount(vfs_t *vfsp, int flag, cred_t *cr);
 124 extern int fsh_root(vfs_t *vfsp, vnode_t **vpp);
 125 extern int fsh_statfs(vfs_t *vfsp, statvfs64_t *sp);
 126 extern int fsh_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp);
 127 
 128 extern void fsh_exec_mount_callbacks(vfs_t *vfsp);
 129 extern void fsh_exec_free_callbacks(vfs_t *vfsp);
 130 
 131 extern void fsh_fsrec_destroy(struct fsh_fsrecord *volatile fsrecp);
 132 
 133 #ifdef __cplusplus
 134 }
 135 #endif
 136 
 137 #endif /* _FSH_IMPL_H */