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/list.h>
  27 #include <sys/pathname.h>
  28 #include <sys/types.h>
  29 #include <sys/vfs.h>
  30 #include <sys/vnode.h>
  31 
  32 #ifdef __cplusplus
  33 extern "C" {
  34 #endif
  35 
  36 #define FSH_VFS_MOUNT           0
  37 #define FSH_VFS_UNMOUNT         1
  38 
  39 #define FSH_VOP_READ            2
  40 #define FSH_VOP_WRITE           3
  41 
  42 #define FSH_SUPPORTED_OPS_COUNT 4
  43 
  44 /*
  45  * TODO:
  46  * - change all defined lists to the ones used in illumos kernel
  47  * - add comments
  48  */
  49 
  50 typedef union fsh_fn {
  51         FSH_OPS;
  52 } fsh_fn_t;
  53 
  54 /*
  55  * fsh_int_t is the internal fsh_t structure. Instead of using a big
  56  * structure containing hooks for all the operations, fsh_int_t contains
  57  * a pointer (in union fsh_fn_t) to one function. Thanks to this approach,
  58  * we don't have to manipulate such big structures. Instead, we keep
  59  * a fsh_int_t list for every operation.
  60  */
  61 struct fsh_int {
  62         fsh_fn_t        fshi_fn;
  63         void            *fshi_arg;
  64         list_node_t     fshi_next;
  65 };
  66 /* typedef struct fsh_int fsh_int_t; in fsh.h */
  67 
  68 /*
  69  * fshl_lock is read-locked by every call to a fsh_vop/vfsop() for
  70  * entire execution. This way, we guarantee that a list of hooks is unchanged
  71  * during one fop_foo()/fsop_foo() execution.
  72  */
  73 typedef struct fsh_list {
  74         krwlock_t       fshl_lock;
  75         list_t          fshl_list;
  76 } fsh_list_t;
  77 
  78 /*
  79  * fshfsr_enabled informs whether FSH is enabled for this vfs_t.
  80  * There are no locks involved. This field should be change only via
  81  * atomic operations.
  82  */
  83 typedef struct fsh_fsrecord {
  84         volatile uint_t fshfsr_enabled;
  85         fsh_list_t      fshfsr_opv[FSH_SUPPORTED_OPS_COUNT];
  86 } fsh_fsrecord_t;
  87 
  88 typedef struct fsh_callback_int {
  89         fsh_callback_t  fshci_callback;
  90         list_node_t     fshci_next;
  91 } fsh_callback_int_t;
  92 
  93 typedef struct fsh_callback_list {
  94         krwlock_t       fshcl_lock;
  95         list_t          fshcl_list;
  96 } fsh_callback_list_t;
  97 
  98 /* API for vnode.c and vfs.c only */
  99 /* vnode.c */
 100 extern int fsh_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
 101                 caller_context_t *ct);
 102 extern int fsh_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
 103                 caller_context_t *ct);
 104 
 105 /* vfs.c */
 106 extern void fsh_init(void);
 107 
 108 extern int fsh_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap,
 109                 cred_t *cr);
 110 extern int fsh_unmount(vfs_t *vfsp, int flag, cred_t *cr);
 111 
 112 extern void fsh_exec_mount_callbacks(vfs_t *vfsp);
 113 extern void fsh_exec_free_callbacks(vfs_t *vfsp);
 114 
 115 extern void fsh_fsrec_destroy(struct fsh_fsrecord *volatile fsrecp);
 116 
 117 #ifdef __cplusplus
 118 }
 119 #endif
 120 
 121 #endif /* _FSH_IMPL_H */