1 /*- 2 * Copyright (c) 2017-2020 Juniper Networks, Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 * 25 */ 26 27 /* This file has prototypes specific to the p9fs file system */ 28 29 #ifndef FS_P9FS_P9FS_H 30 #define FS_P9FS_P9FS_H 31 32 struct p9fs_session; 33 34 /* QID: Unique identification for the file being accessed */ 35 struct p9fs_qid { 36 uint8_t qid_mode; /* file mode specifiying file type */ 37 uint32_t qid_version; /* version of the file */ 38 uint64_t qid_path; /* unique integer among all files in hierarchy */ 39 }; 40 41 /* 42 * The in memory representation of the on disk inode. Save the current 43 * fields to write it back later. 44 */ 45 struct p9fs_inode { 46 /* Make it simple first, Add more fields later */ 47 uint64_t i_size; /* size of the inode */ 48 uint16_t i_type; /* type of inode */ 49 uint32_t i_dev; /* type of device */ 50 uint32_t i_mode; /* mode of the inode */ 51 uint32_t i_atime; /* time of last access */ 52 uint32_t i_mtime; /* time of last modification */ 53 uint32_t i_ctime; /* time of last status change */ 54 uint32_t i_atime_nsec; /* times of last access in nanoseconds resolution */ 55 uint32_t i_mtime_nsec; /* time of last modification in nanoseconds resolution */ 56 uint32_t i_ctime_nsec; /* time of last status change in nanoseconds resolution */ 57 uint64_t i_length; 58 char *i_name; /* inode name */ 59 char *i_uid; /* inode user id */ 60 char *i_gid; /* inode group id */ 61 char *i_muid; 62 char *i_extension; /* 9p2000.u extensions */ 63 uid_t n_uid; /* 9p2000.u extensions */ 64 gid_t n_gid; /* 9p2000.u extensions */ 65 uid_t n_muid; /* 9p2000.u extensions */ 66 /* bookkeeping info on the client. */ 67 uint16_t i_links_count; /*number of references to the inode*/ 68 uint64_t i_qid_path; /* using inode number for reference. */ 69 uint64_t i_flags; 70 uint64_t blksize; /* block size for file system */ 71 uint64_t blocks; /* number of 512B blocks allocated */ 72 uint64_t gen; /* reserved for future use */ 73 uint64_t data_version; /* reserved for future use */ 74 75 }; 76 77 #define P9FS_VFID_MTX(_sc) (&(_sc)->vfid_mtx) 78 #define P9FS_VFID_LOCK(_sc) mtx_lock(P9FS_VFID_MTX(_sc)) 79 #define P9FS_VFID_UNLOCK(_sc) mtx_unlock(P9FS_VFID_MTX(_sc)) 80 #define P9FS_VFID_LOCK_INIT(_sc) mtx_init(P9FS_VFID_MTX(_sc), \ 81 "VFID List lock", NULL, MTX_DEF) 82 #define P9FS_VFID_LOCK_DESTROY(_sc) mtx_destroy(P9FS_VFID_MTX(_sc)) 83 84 #define P9FS_VOFID_MTX(_sc) (&(_sc)->vofid_mtx) 85 #define P9FS_VOFID_LOCK(_sc) mtx_lock(P9FS_VOFID_MTX(_sc)) 86 #define P9FS_VOFID_UNLOCK(_sc) mtx_unlock(P9FS_VOFID_MTX(_sc)) 87 #define P9FS_VOFID_LOCK_INIT(_sc) mtx_init(P9FS_VOFID_MTX(_sc), \ 88 "VOFID List lock", NULL, MTX_DEF) 89 #define P9FS_VOFID_LOCK_DESTROY(_sc) mtx_destroy(P9FS_VOFID_MTX(_sc)) 90 91 #define VFID 0x01 92 #define VOFID 0x02 93 94 /* A Plan9 node. */ 95 struct p9fs_node { 96 STAILQ_HEAD( ,p9_fid) vfid_list; /* vfid related to uid */ 97 struct mtx vfid_mtx; /* mutex for vfid list */ 98 STAILQ_HEAD( ,p9_fid) vofid_list; /* vofid related to uid */ 99 struct mtx vofid_mtx; /* mutex for vofid list */ 100 struct p9fs_node *parent; /* pointer to parent p9fs node */ 101 struct p9fs_qid vqid; /* the server qid, will be from the host */ 102 struct vnode *v_node; /* vnode for this fs_node. */ 103 struct p9fs_inode inode; /* in memory representation of ondisk information*/ 104 struct p9fs_session *p9fs_ses; /* Session_ptr for this node */ 105 STAILQ_ENTRY(p9fs_node) p9fs_node_next; 106 uint64_t flags; 107 }; 108 109 #define P9FS_VTON(vp) ((struct p9fs_node *)(vp)->v_data) 110 #define P9FS_NTOV(node) ((node)->v_node) 111 #define VFSTOP9(mp) ((struct p9fs_mount *)(mp)->mnt_data) 112 #define QEMU_DIRENTRY_SZ 25 113 #define P9FS_NODE_MODIFIED 0x1 /* indicating file change */ 114 #define P9FS_ROOT 0x2 /* indicating root p9fs node */ 115 #define P9FS_NODE_DELETED 0x4 /* indicating file or directory delete */ 116 #define P9FS_NODE_IN_SESSION 0x8 /* p9fs_node is in the session - virt_node_list */ 117 #define IS_ROOT(node) (node->flags & P9FS_ROOT) 118 119 #define P9FS_SET_LINKS(inode) do { \ 120 (inode)->i_links_count = 1; \ 121 } while (0) \ 122 123 #define P9FS_INCR_LINKS(inode) do { \ 124 (inode)->i_links_count++; \ 125 } while (0) \ 126 127 #define P9FS_DECR_LINKS(inode) do { \ 128 (inode)->i_links_count--; \ 129 } while (0) \ 130 131 #define P9FS_CLR_LINKS(inode) do { \ 132 (inode)->i_links_count = 0; \ 133 } while (0) \ 134 135 #define P9FS_MTX(_sc) (&(_sc)->p9fs_mtx) 136 #define P9FS_LOCK(_sc) mtx_lock(P9FS_MTX(_sc)) 137 #define P9FS_UNLOCK(_sc) mtx_unlock(P9FS_MTX(_sc)) 138 #define P9FS_LOCK_INIT(_sc) mtx_init(P9FS_MTX(_sc), \ 139 "P9FS session chain lock", NULL, MTX_DEF) 140 #define P9FS_LOCK_DESTROY(_sc) mtx_destroy(P9FS_MTX(_sc)) 141 142 /* Session structure for the FS */ 143 struct p9fs_session { 144 unsigned char flags; /* these flags for the session */ 145 struct mount *p9fs_mount; /* mount point */ 146 struct p9fs_node rnp; /* root p9fs node for this session */ 147 uid_t uid; /* the uid that has access */ 148 const char *uname; /* user name to mount as */ 149 const char *aname; /* name of remote file tree being mounted */ 150 struct p9_client *clnt; /* 9p client */ 151 struct mtx p9fs_mtx; /* mutex used for guarding the chain.*/ 152 STAILQ_HEAD( ,p9fs_node) virt_node_list; /* list of p9fs nodes in this session*/ 153 struct p9_fid *mnt_fid; /* to save nobody 's fid for unmounting as root user */ 154 }; 155 156 struct p9fs_mount { 157 struct p9fs_session p9fs_session; /* per instance session information */ 158 struct mount *p9fs_mountp; /* mount point */ 159 int mount_tag_len; /* length of the mount tag */ 160 char *mount_tag; /* mount tag used */ 161 }; 162 163 /* All session flags based on 9p versions */ 164 enum virt_session_flags { 165 P9FS_PROTO_2000U = 0x01, 166 P9FS_PROTO_2000L = 0x02, 167 }; 168 169 /* Session access flags */ 170 #define P9_ACCESS_ANY 0x04 /* single attach for all users */ 171 #define P9_ACCESS_SINGLE 0x08 /* access to only the user who mounts */ 172 #define P9_ACCESS_USER 0x10 /* new attach established for every user */ 173 #define P9_ACCESS_MASK (P9_ACCESS_ANY|P9_ACCESS_SINGLE|P9_ACCESS_USER) 174 175 u_quad_t p9fs_round_filesize_to_bytes(uint64_t filesize, uint64_t bsize); 176 u_quad_t p9fs_pow2_filesize_to_bytes(uint64_t filesize, uint64_t bsize); 177 178 /* These are all the P9FS specific vops */ 179 int p9fs_stat_vnode_l(void); 180 int p9fs_stat_vnode_dotl(struct p9_stat_dotl *st, struct vnode *vp); 181 int p9fs_reload_stats_dotl(struct vnode *vp, struct ucred *cred); 182 int p9fs_proto_dotl(struct p9fs_session *vses); 183 struct p9_fid *p9fs_init_session(struct mount *mp, int *error); 184 void p9fs_close_session(struct mount *mp); 185 void p9fs_prepare_to_close(struct mount *mp); 186 void p9fs_complete_close(struct mount *mp); 187 int p9fs_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp); 188 int p9fs_vget_common(struct mount *mp, struct p9fs_node *np, int flags, 189 struct p9fs_node *parent, struct p9_fid *fid, struct vnode **vpp, 190 char *name); 191 int p9fs_node_cmp(struct vnode *vp, void *arg); 192 void p9fs_destroy_node(struct p9fs_node **npp); 193 void p9fs_dispose_node(struct p9fs_node **npp); 194 void p9fs_cleanup(struct p9fs_node *vp); 195 void p9fs_fid_remove_all(struct p9fs_node *np, int leave_ofids); 196 void p9fs_fid_remove(struct p9fs_node *np, struct p9_fid *vfid, 197 int fid_type); 198 void p9fs_fid_add(struct p9fs_node *np, struct p9_fid *fid, 199 int fid_type); 200 struct p9_fid *p9fs_get_fid(struct p9_client *clnt, 201 struct p9fs_node *np, struct ucred *cred, int fid_type, int mode, int *error); 202 203 #endif /* FS_P9FS_P9FS_H */ 204