1 #ifndef _QEMU_9P_H 2 #define _QEMU_9P_H 3 4 #include <sys/types.h> 5 #include <dirent.h> 6 #include <sys/time.h> 7 #include <utime.h> 8 #include <sys/resource.h> 9 #include <glib.h> 10 #include "standard-headers/linux/virtio_9p.h" 11 #include "hw/virtio/virtio.h" 12 #include "fsdev/file-op-9p.h" 13 #include "fsdev/9p-iov-marshal.h" 14 #include "qemu/thread.h" 15 #include "qemu/coroutine.h" 16 17 enum { 18 P9_TLERROR = 6, 19 P9_RLERROR, 20 P9_TSTATFS = 8, 21 P9_RSTATFS, 22 P9_TLOPEN = 12, 23 P9_RLOPEN, 24 P9_TLCREATE = 14, 25 P9_RLCREATE, 26 P9_TSYMLINK = 16, 27 P9_RSYMLINK, 28 P9_TMKNOD = 18, 29 P9_RMKNOD, 30 P9_TRENAME = 20, 31 P9_RRENAME, 32 P9_TREADLINK = 22, 33 P9_RREADLINK, 34 P9_TGETATTR = 24, 35 P9_RGETATTR, 36 P9_TSETATTR = 26, 37 P9_RSETATTR, 38 P9_TXATTRWALK = 30, 39 P9_RXATTRWALK, 40 P9_TXATTRCREATE = 32, 41 P9_RXATTRCREATE, 42 P9_TREADDIR = 40, 43 P9_RREADDIR, 44 P9_TFSYNC = 50, 45 P9_RFSYNC, 46 P9_TLOCK = 52, 47 P9_RLOCK, 48 P9_TGETLOCK = 54, 49 P9_RGETLOCK, 50 P9_TLINK = 70, 51 P9_RLINK, 52 P9_TMKDIR = 72, 53 P9_RMKDIR, 54 P9_TRENAMEAT = 74, 55 P9_RRENAMEAT, 56 P9_TUNLINKAT = 76, 57 P9_RUNLINKAT, 58 P9_TVERSION = 100, 59 P9_RVERSION, 60 P9_TAUTH = 102, 61 P9_RAUTH, 62 P9_TATTACH = 104, 63 P9_RATTACH, 64 P9_TERROR = 106, 65 P9_RERROR, 66 P9_TFLUSH = 108, 67 P9_RFLUSH, 68 P9_TWALK = 110, 69 P9_RWALK, 70 P9_TOPEN = 112, 71 P9_ROPEN, 72 P9_TCREATE = 114, 73 P9_RCREATE, 74 P9_TREAD = 116, 75 P9_RREAD, 76 P9_TWRITE = 118, 77 P9_RWRITE, 78 P9_TCLUNK = 120, 79 P9_RCLUNK, 80 P9_TREMOVE = 122, 81 P9_RREMOVE, 82 P9_TSTAT = 124, 83 P9_RSTAT, 84 P9_TWSTAT = 126, 85 P9_RWSTAT, 86 }; 87 88 89 /* qid.types */ 90 enum { 91 P9_QTDIR = 0x80, 92 P9_QTAPPEND = 0x40, 93 P9_QTEXCL = 0x20, 94 P9_QTMOUNT = 0x10, 95 P9_QTAUTH = 0x08, 96 P9_QTTMP = 0x04, 97 P9_QTSYMLINK = 0x02, 98 P9_QTLINK = 0x01, 99 P9_QTFILE = 0x00, 100 }; 101 102 enum p9_proto_version { 103 V9FS_PROTO_2000U = 0x01, 104 V9FS_PROTO_2000L = 0x02, 105 }; 106 107 #define P9_NOTAG (u16)(~0) 108 #define P9_NOFID (u32)(~0) 109 #define P9_MAXWELEM 16 110 111 #define FID_REFERENCED 0x1 112 #define FID_NON_RECLAIMABLE 0x2 113 static inline char *rpath(FsContext *ctx, const char *path) 114 { 115 return g_strdup_printf("%s/%s", ctx->fs_root, path); 116 } 117 118 /* 119 * ample room for Twrite/Rread header 120 * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4] 121 */ 122 #define P9_IOHDRSZ 24 123 124 typedef struct V9fsPDU V9fsPDU; 125 struct V9fsState; 126 127 struct V9fsPDU 128 { 129 uint32_t size; 130 uint16_t tag; 131 uint8_t id; 132 uint8_t cancelled; 133 CoQueue complete; 134 struct V9fsState *s; 135 QLIST_ENTRY(V9fsPDU) next; 136 uint32_t idx; 137 }; 138 139 140 /* FIXME 141 * 1) change user needs to set groups and stuff 142 */ 143 144 #define MAX_REQ 128 145 #define MAX_TAG_LEN 32 146 147 #define BUG_ON(cond) assert(!(cond)) 148 149 typedef struct V9fsFidState V9fsFidState; 150 151 enum { 152 P9_FID_NONE = 0, 153 P9_FID_FILE, 154 P9_FID_DIR, 155 P9_FID_XATTR, 156 }; 157 158 typedef struct V9fsConf 159 { 160 /* tag name for the device */ 161 char *tag; 162 char *fsdev_id; 163 } V9fsConf; 164 165 typedef struct V9fsXattr 166 { 167 int64_t copied_len; 168 int64_t len; 169 void *value; 170 V9fsString name; 171 int flags; 172 } V9fsXattr; 173 174 /* 175 * Filled by fs driver on open and other 176 * calls. 177 */ 178 union V9fsFidOpenState { 179 int fd; 180 DIR *dir; 181 V9fsXattr xattr; 182 /* 183 * private pointer for fs drivers, that 184 * have its own internal representation of 185 * open files. 186 */ 187 void *private; 188 }; 189 190 struct V9fsFidState 191 { 192 int fid_type; 193 int32_t fid; 194 V9fsPath path; 195 V9fsFidOpenState fs; 196 V9fsFidOpenState fs_reclaim; 197 int flags; 198 int open_flags; 199 uid_t uid; 200 int ref; 201 int clunked; 202 V9fsFidState *next; 203 V9fsFidState *rclm_lst; 204 }; 205 206 typedef struct V9fsState 207 { 208 QLIST_HEAD(, V9fsPDU) free_list; 209 QLIST_HEAD(, V9fsPDU) active_list; 210 V9fsFidState *fid_list; 211 FileOperations *ops; 212 FsContext ctx; 213 char *tag; 214 enum p9_proto_version proto_version; 215 int32_t msize; 216 /* 217 * lock ensuring atomic path update 218 * on rename. 219 */ 220 CoRwlock rename_lock; 221 int32_t root_fid; 222 Error *migration_blocker; 223 V9fsConf fsconf; 224 } V9fsState; 225 226 /* 9p2000.L open flags */ 227 #define P9_DOTL_RDONLY 00000000 228 #define P9_DOTL_WRONLY 00000001 229 #define P9_DOTL_RDWR 00000002 230 #define P9_DOTL_NOACCESS 00000003 231 #define P9_DOTL_CREATE 00000100 232 #define P9_DOTL_EXCL 00000200 233 #define P9_DOTL_NOCTTY 00000400 234 #define P9_DOTL_TRUNC 00001000 235 #define P9_DOTL_APPEND 00002000 236 #define P9_DOTL_NONBLOCK 00004000 237 #define P9_DOTL_DSYNC 00010000 238 #define P9_DOTL_FASYNC 00020000 239 #define P9_DOTL_DIRECT 00040000 240 #define P9_DOTL_LARGEFILE 00100000 241 #define P9_DOTL_DIRECTORY 00200000 242 #define P9_DOTL_NOFOLLOW 00400000 243 #define P9_DOTL_NOATIME 01000000 244 #define P9_DOTL_CLOEXEC 02000000 245 #define P9_DOTL_SYNC 04000000 246 247 /* 9p2000.L at flags */ 248 #define P9_DOTL_AT_REMOVEDIR 0x200 249 250 /* 9P2000.L lock type */ 251 #define P9_LOCK_TYPE_RDLCK 0 252 #define P9_LOCK_TYPE_WRLCK 1 253 #define P9_LOCK_TYPE_UNLCK 2 254 255 #define P9_LOCK_SUCCESS 0 256 #define P9_LOCK_BLOCKED 1 257 #define P9_LOCK_ERROR 2 258 #define P9_LOCK_GRACE 3 259 260 #define P9_LOCK_FLAGS_BLOCK 1 261 #define P9_LOCK_FLAGS_RECLAIM 2 262 263 typedef struct V9fsFlock 264 { 265 uint8_t type; 266 uint32_t flags; 267 uint64_t start; /* absolute offset */ 268 uint64_t length; 269 uint32_t proc_id; 270 V9fsString client_id; 271 } V9fsFlock; 272 273 typedef struct V9fsGetlock 274 { 275 uint8_t type; 276 uint64_t start; /* absolute offset */ 277 uint64_t length; 278 uint32_t proc_id; 279 V9fsString client_id; 280 } V9fsGetlock; 281 282 extern int open_fd_hw; 283 extern int total_open_fd; 284 285 static inline void v9fs_path_write_lock(V9fsState *s) 286 { 287 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 288 qemu_co_rwlock_wrlock(&s->rename_lock); 289 } 290 } 291 292 static inline void v9fs_path_read_lock(V9fsState *s) 293 { 294 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 295 qemu_co_rwlock_rdlock(&s->rename_lock); 296 } 297 } 298 299 static inline void v9fs_path_unlock(V9fsState *s) 300 { 301 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 302 qemu_co_rwlock_unlock(&s->rename_lock); 303 } 304 } 305 306 static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu) 307 { 308 return pdu->cancelled; 309 } 310 311 extern void v9fs_reclaim_fd(V9fsPDU *pdu); 312 extern void v9fs_path_init(V9fsPath *path); 313 extern void v9fs_path_free(V9fsPath *path); 314 extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs); 315 extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath, 316 const char *name, V9fsPath *path); 317 extern int v9fs_device_realize_common(V9fsState *s, Error **errp); 318 extern void v9fs_device_unrealize_common(V9fsState *s, Error **errp); 319 320 ssize_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...); 321 ssize_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...); 322 V9fsPDU *pdu_alloc(V9fsState *s); 323 void pdu_free(V9fsPDU *pdu); 324 void pdu_submit(V9fsPDU *pdu); 325 326 #endif 327