1 #ifndef QEMU_9P_H 2 #define QEMU_9P_H 3 4 #include <dirent.h> 5 #include <utime.h> 6 #include <sys/resource.h> 7 #include "fsdev/file-op-9p.h" 8 #include "fsdev/9p-iov-marshal.h" 9 #include "qemu/thread.h" 10 #include "qemu/coroutine.h" 11 #include "qemu/qht.h" 12 13 enum { 14 P9_TLERROR = 6, 15 P9_RLERROR, 16 P9_TSTATFS = 8, 17 P9_RSTATFS, 18 P9_TLOPEN = 12, 19 P9_RLOPEN, 20 P9_TLCREATE = 14, 21 P9_RLCREATE, 22 P9_TSYMLINK = 16, 23 P9_RSYMLINK, 24 P9_TMKNOD = 18, 25 P9_RMKNOD, 26 P9_TRENAME = 20, 27 P9_RRENAME, 28 P9_TREADLINK = 22, 29 P9_RREADLINK, 30 P9_TGETATTR = 24, 31 P9_RGETATTR, 32 P9_TSETATTR = 26, 33 P9_RSETATTR, 34 P9_TXATTRWALK = 30, 35 P9_RXATTRWALK, 36 P9_TXATTRCREATE = 32, 37 P9_RXATTRCREATE, 38 P9_TREADDIR = 40, 39 P9_RREADDIR, 40 P9_TFSYNC = 50, 41 P9_RFSYNC, 42 P9_TLOCK = 52, 43 P9_RLOCK, 44 P9_TGETLOCK = 54, 45 P9_RGETLOCK, 46 P9_TLINK = 70, 47 P9_RLINK, 48 P9_TMKDIR = 72, 49 P9_RMKDIR, 50 P9_TRENAMEAT = 74, 51 P9_RRENAMEAT, 52 P9_TUNLINKAT = 76, 53 P9_RUNLINKAT, 54 P9_TVERSION = 100, 55 P9_RVERSION, 56 P9_TAUTH = 102, 57 P9_RAUTH, 58 P9_TATTACH = 104, 59 P9_RATTACH, 60 P9_TERROR = 106, 61 P9_RERROR, 62 P9_TFLUSH = 108, 63 P9_RFLUSH, 64 P9_TWALK = 110, 65 P9_RWALK, 66 P9_TOPEN = 112, 67 P9_ROPEN, 68 P9_TCREATE = 114, 69 P9_RCREATE, 70 P9_TREAD = 116, 71 P9_RREAD, 72 P9_TWRITE = 118, 73 P9_RWRITE, 74 P9_TCLUNK = 120, 75 P9_RCLUNK, 76 P9_TREMOVE = 122, 77 P9_RREMOVE, 78 P9_TSTAT = 124, 79 P9_RSTAT, 80 P9_TWSTAT = 126, 81 P9_RWSTAT, 82 }; 83 84 85 /* qid.types */ 86 enum { 87 P9_QTDIR = 0x80, 88 P9_QTAPPEND = 0x40, 89 P9_QTEXCL = 0x20, 90 P9_QTMOUNT = 0x10, 91 P9_QTAUTH = 0x08, 92 P9_QTTMP = 0x04, 93 P9_QTSYMLINK = 0x02, 94 P9_QTLINK = 0x01, 95 P9_QTFILE = 0x00, 96 }; 97 98 typedef enum P9ProtoVersion { 99 V9FS_PROTO_2000U = 0x01, 100 V9FS_PROTO_2000L = 0x02, 101 } P9ProtoVersion; 102 103 #define P9_NOTAG UINT16_MAX 104 #define P9_NOFID UINT32_MAX 105 #define P9_MAXWELEM 16 106 107 #define FID_REFERENCED 0x1 108 #define FID_NON_RECLAIMABLE 0x2 109 static inline char *rpath(FsContext *ctx, const char *path) 110 { 111 return g_strdup_printf("%s/%s", ctx->fs_root, path); 112 } 113 114 /* 115 * ample room for Twrite/Rread header 116 * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4] 117 */ 118 #define P9_IOHDRSZ 24 119 120 typedef struct V9fsPDU V9fsPDU; 121 typedef struct V9fsState V9fsState; 122 typedef struct V9fsTransport V9fsTransport; 123 124 typedef struct { 125 uint32_t size_le; 126 uint8_t id; 127 uint16_t tag_le; 128 } QEMU_PACKED P9MsgHeader; 129 /* According to the specification, 9p messages start with a 7-byte header. 130 * Since most of the code uses this header size in literal form, we must be 131 * sure this is indeed the case. 132 */ 133 QEMU_BUILD_BUG_ON(sizeof(P9MsgHeader) != 7); 134 135 struct V9fsPDU 136 { 137 uint32_t size; 138 uint16_t tag; 139 uint8_t id; 140 uint8_t cancelled; 141 CoQueue complete; 142 V9fsState *s; 143 QLIST_ENTRY(V9fsPDU) next; 144 uint32_t idx; 145 }; 146 147 148 /* FIXME 149 * 1) change user needs to set groups and stuff 150 */ 151 152 #define MAX_REQ 128 153 #define MAX_TAG_LEN 32 154 155 #define BUG_ON(cond) assert(!(cond)) 156 157 typedef struct V9fsFidState V9fsFidState; 158 159 enum { 160 P9_FID_NONE = 0, 161 P9_FID_FILE, 162 P9_FID_DIR, 163 P9_FID_XATTR, 164 }; 165 166 typedef struct V9fsConf 167 { 168 /* tag name for the device */ 169 char *tag; 170 char *fsdev_id; 171 } V9fsConf; 172 173 /* 9p2000.L xattr flags (matches Linux values) */ 174 #define P9_XATTR_CREATE 1 175 #define P9_XATTR_REPLACE 2 176 177 typedef struct V9fsXattr 178 { 179 uint64_t copied_len; 180 uint64_t len; 181 void *value; 182 V9fsString name; 183 int flags; 184 bool xattrwalk_fid; 185 } V9fsXattr; 186 187 typedef struct V9fsDir { 188 DIR *stream; 189 QemuMutex readdir_mutex; 190 } V9fsDir; 191 192 static inline void v9fs_readdir_lock(V9fsDir *dir) 193 { 194 qemu_mutex_lock(&dir->readdir_mutex); 195 } 196 197 static inline void v9fs_readdir_unlock(V9fsDir *dir) 198 { 199 qemu_mutex_unlock(&dir->readdir_mutex); 200 } 201 202 static inline void v9fs_readdir_init(V9fsDir *dir) 203 { 204 qemu_mutex_init(&dir->readdir_mutex); 205 } 206 207 /* 208 * Filled by fs driver on open and other 209 * calls. 210 */ 211 union V9fsFidOpenState { 212 int fd; 213 V9fsDir dir; 214 V9fsXattr xattr; 215 /* 216 * private pointer for fs drivers, that 217 * have its own internal representation of 218 * open files. 219 */ 220 void *private; 221 }; 222 223 struct V9fsFidState 224 { 225 int fid_type; 226 int32_t fid; 227 V9fsPath path; 228 V9fsFidOpenState fs; 229 V9fsFidOpenState fs_reclaim; 230 int flags; 231 int open_flags; 232 uid_t uid; 233 int ref; 234 int clunked; 235 V9fsFidState *next; 236 V9fsFidState *rclm_lst; 237 }; 238 239 typedef enum AffixType_t { 240 AffixType_Prefix, 241 AffixType_Suffix, /* A.k.a. postfix. */ 242 } AffixType_t; 243 244 /** 245 * @brief Unique affix of variable length. 246 * 247 * An affix is (currently) either a suffix or a prefix, which is either 248 * going to be prepended (prefix) or appended (suffix) with some other 249 * number for the goal to generate unique numbers. Accordingly the 250 * suffixes (or prefixes) we generate @b must all have the mathematical 251 * property of being suffix-free (or prefix-free in case of prefixes) 252 * so that no matter what number we concatenate the affix with, that we 253 * always reliably get unique numbers as result after concatenation. 254 */ 255 typedef struct VariLenAffix { 256 AffixType_t type; /* Whether this affix is a suffix or a prefix. */ 257 uint64_t value; /* Actual numerical value of this affix. */ 258 /* 259 * Lenght of the affix, that is how many (of the lowest) bits of @c value 260 * must be used for appending/prepending this affix to its final resulting, 261 * unique number. 262 */ 263 int bits; 264 } VariLenAffix; 265 266 /* See qid_inode_prefix_hash_bits(). */ 267 typedef struct { 268 dev_t dev; /* FS device on host. */ 269 /* 270 * How many (high) bits of the original inode number shall be used for 271 * hashing. 272 */ 273 int prefix_bits; 274 } QpdEntry; 275 276 /* QID path prefix entry, see stat_to_qid */ 277 typedef struct { 278 dev_t dev; 279 uint16_t ino_prefix; 280 uint32_t qp_affix_index; 281 VariLenAffix qp_affix; 282 } QppEntry; 283 284 /* QID path full entry, as above */ 285 typedef struct { 286 dev_t dev; 287 ino_t ino; 288 uint64_t path; 289 } QpfEntry; 290 291 struct V9fsState 292 { 293 QLIST_HEAD(, V9fsPDU) free_list; 294 QLIST_HEAD(, V9fsPDU) active_list; 295 V9fsFidState *fid_list; 296 FileOperations *ops; 297 FsContext ctx; 298 char *tag; 299 P9ProtoVersion proto_version; 300 int32_t msize; 301 V9fsPDU pdus[MAX_REQ]; 302 const V9fsTransport *transport; 303 /* 304 * lock ensuring atomic path update 305 * on rename. 306 */ 307 CoRwlock rename_lock; 308 int32_t root_fid; 309 Error *migration_blocker; 310 V9fsConf fsconf; 311 V9fsQID root_qid; 312 dev_t dev_id; 313 struct qht qpd_table; 314 struct qht qpp_table; 315 struct qht qpf_table; 316 uint64_t qp_ndevices; /* Amount of entries in qpd_table. */ 317 uint16_t qp_affix_next; 318 uint64_t qp_fullpath_next; 319 }; 320 321 /* 9p2000.L open flags */ 322 #define P9_DOTL_RDONLY 00000000 323 #define P9_DOTL_WRONLY 00000001 324 #define P9_DOTL_RDWR 00000002 325 #define P9_DOTL_NOACCESS 00000003 326 #define P9_DOTL_CREATE 00000100 327 #define P9_DOTL_EXCL 00000200 328 #define P9_DOTL_NOCTTY 00000400 329 #define P9_DOTL_TRUNC 00001000 330 #define P9_DOTL_APPEND 00002000 331 #define P9_DOTL_NONBLOCK 00004000 332 #define P9_DOTL_DSYNC 00010000 333 #define P9_DOTL_FASYNC 00020000 334 #define P9_DOTL_DIRECT 00040000 335 #define P9_DOTL_LARGEFILE 00100000 336 #define P9_DOTL_DIRECTORY 00200000 337 #define P9_DOTL_NOFOLLOW 00400000 338 #define P9_DOTL_NOATIME 01000000 339 #define P9_DOTL_CLOEXEC 02000000 340 #define P9_DOTL_SYNC 04000000 341 342 /* 9p2000.L at flags */ 343 #define P9_DOTL_AT_REMOVEDIR 0x200 344 345 /* 9P2000.L lock type */ 346 #define P9_LOCK_TYPE_RDLCK 0 347 #define P9_LOCK_TYPE_WRLCK 1 348 #define P9_LOCK_TYPE_UNLCK 2 349 350 #define P9_LOCK_SUCCESS 0 351 #define P9_LOCK_BLOCKED 1 352 #define P9_LOCK_ERROR 2 353 #define P9_LOCK_GRACE 3 354 355 #define P9_LOCK_FLAGS_BLOCK 1 356 #define P9_LOCK_FLAGS_RECLAIM 2 357 358 typedef struct V9fsFlock 359 { 360 uint8_t type; 361 uint32_t flags; 362 uint64_t start; /* absolute offset */ 363 uint64_t length; 364 uint32_t proc_id; 365 V9fsString client_id; 366 } V9fsFlock; 367 368 typedef struct V9fsGetlock 369 { 370 uint8_t type; 371 uint64_t start; /* absolute offset */ 372 uint64_t length; 373 uint32_t proc_id; 374 V9fsString client_id; 375 } V9fsGetlock; 376 377 extern int open_fd_hw; 378 extern int total_open_fd; 379 380 static inline void v9fs_path_write_lock(V9fsState *s) 381 { 382 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 383 qemu_co_rwlock_wrlock(&s->rename_lock); 384 } 385 } 386 387 static inline void v9fs_path_read_lock(V9fsState *s) 388 { 389 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 390 qemu_co_rwlock_rdlock(&s->rename_lock); 391 } 392 } 393 394 static inline void v9fs_path_unlock(V9fsState *s) 395 { 396 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 397 qemu_co_rwlock_unlock(&s->rename_lock); 398 } 399 } 400 401 static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu) 402 { 403 return pdu->cancelled; 404 } 405 406 void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu); 407 void v9fs_path_init(V9fsPath *path); 408 void v9fs_path_free(V9fsPath *path); 409 void v9fs_path_sprintf(V9fsPath *path, const char *fmt, ...); 410 void v9fs_path_copy(V9fsPath *dst, const V9fsPath *src); 411 int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath, 412 const char *name, V9fsPath *path); 413 int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t, 414 Error **errp); 415 void v9fs_device_unrealize_common(V9fsState *s, Error **errp); 416 417 V9fsPDU *pdu_alloc(V9fsState *s); 418 void pdu_free(V9fsPDU *pdu); 419 void pdu_submit(V9fsPDU *pdu, P9MsgHeader *hdr); 420 void v9fs_reset(V9fsState *s); 421 422 struct V9fsTransport { 423 ssize_t (*pdu_vmarshal)(V9fsPDU *pdu, size_t offset, const char *fmt, 424 va_list ap); 425 ssize_t (*pdu_vunmarshal)(V9fsPDU *pdu, size_t offset, const char *fmt, 426 va_list ap); 427 void (*init_in_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov, 428 unsigned int *pniov, size_t size); 429 void (*init_out_iov_from_pdu)(V9fsPDU *pdu, struct iovec **piov, 430 unsigned int *pniov, size_t size); 431 void (*push_and_notify)(V9fsPDU *pdu); 432 }; 433 434 #endif 435