1 #ifndef _QEMU_VIRTIO_9P_H 2 #define _QEMU_VIRTIO_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 "hw/virtio.h" 10 #include "fsdev/file-op-9p.h" 11 #include "qemu-thread.h" 12 #include "qemu-coroutine.h" 13 14 /* The feature bitmap for virtio 9P */ 15 /* The mount point is specified in a config variable */ 16 #define VIRTIO_9P_MOUNT_TAG 0 17 18 enum { 19 P9_TLERROR = 6, 20 P9_RLERROR, 21 P9_TSTATFS = 8, 22 P9_RSTATFS, 23 P9_TLOPEN = 12, 24 P9_RLOPEN, 25 P9_TLCREATE = 14, 26 P9_RLCREATE, 27 P9_TSYMLINK = 16, 28 P9_RSYMLINK, 29 P9_TMKNOD = 18, 30 P9_RMKNOD, 31 P9_TRENAME = 20, 32 P9_RRENAME, 33 P9_TREADLINK = 22, 34 P9_RREADLINK, 35 P9_TGETATTR = 24, 36 P9_RGETATTR, 37 P9_TSETATTR = 26, 38 P9_RSETATTR, 39 P9_TXATTRWALK = 30, 40 P9_RXATTRWALK, 41 P9_TXATTRCREATE = 32, 42 P9_RXATTRCREATE, 43 P9_TREADDIR = 40, 44 P9_RREADDIR, 45 P9_TFSYNC = 50, 46 P9_RFSYNC, 47 P9_TLOCK = 52, 48 P9_RLOCK, 49 P9_TGETLOCK = 54, 50 P9_RGETLOCK, 51 P9_TLINK = 70, 52 P9_RLINK, 53 P9_TMKDIR = 72, 54 P9_RMKDIR, 55 P9_TRENAMEAT = 74, 56 P9_RRENAMEAT, 57 P9_TUNLINKAT = 76, 58 P9_RUNLINKAT, 59 P9_TVERSION = 100, 60 P9_RVERSION, 61 P9_TAUTH = 102, 62 P9_RAUTH, 63 P9_TATTACH = 104, 64 P9_RATTACH, 65 P9_TERROR = 106, 66 P9_RERROR, 67 P9_TFLUSH = 108, 68 P9_RFLUSH, 69 P9_TWALK = 110, 70 P9_RWALK, 71 P9_TOPEN = 112, 72 P9_ROPEN, 73 P9_TCREATE = 114, 74 P9_RCREATE, 75 P9_TREAD = 116, 76 P9_RREAD, 77 P9_TWRITE = 118, 78 P9_RWRITE, 79 P9_TCLUNK = 120, 80 P9_RCLUNK, 81 P9_TREMOVE = 122, 82 P9_RREMOVE, 83 P9_TSTAT = 124, 84 P9_RSTAT, 85 P9_TWSTAT = 126, 86 P9_RWSTAT, 87 }; 88 89 90 /* qid.types */ 91 enum { 92 P9_QTDIR = 0x80, 93 P9_QTAPPEND = 0x40, 94 P9_QTEXCL = 0x20, 95 P9_QTMOUNT = 0x10, 96 P9_QTAUTH = 0x08, 97 P9_QTTMP = 0x04, 98 P9_QTSYMLINK = 0x02, 99 P9_QTLINK = 0x01, 100 P9_QTFILE = 0x00, 101 }; 102 103 enum p9_proto_version { 104 V9FS_PROTO_2000U = 0x01, 105 V9FS_PROTO_2000L = 0x02, 106 }; 107 108 #define P9_NOTAG (u16)(~0) 109 #define P9_NOFID (u32)(~0) 110 #define P9_MAXWELEM 16 111 112 #define FID_REFERENCED 0x1 113 #define FID_NON_RECLAIMABLE 0x2 114 static inline const char *rpath(FsContext *ctx, const char *path, char *buffer) 115 { 116 snprintf(buffer, PATH_MAX, "%s/%s", ctx->fs_root, path); 117 return buffer; 118 } 119 120 /* 121 * ample room for Twrite/Rread header 122 * size[4] Tread/Twrite tag[2] fid[4] offset[8] count[4] 123 */ 124 #define P9_IOHDRSZ 24 125 126 typedef struct V9fsPDU V9fsPDU; 127 struct V9fsState; 128 129 struct V9fsPDU 130 { 131 uint32_t size; 132 uint16_t tag; 133 uint8_t id; 134 uint8_t cancelled; 135 CoQueue complete; 136 VirtQueueElement elem; 137 struct V9fsState *s; 138 QLIST_ENTRY(V9fsPDU) next; 139 }; 140 141 142 /* FIXME 143 * 1) change user needs to set groups and stuff 144 */ 145 146 /* from Linux's linux/virtio_9p.h */ 147 148 /* The ID for virtio console */ 149 #define VIRTIO_ID_9P 9 150 #define MAX_REQ 128 151 #define MAX_TAG_LEN 32 152 153 #define BUG_ON(cond) assert(!(cond)) 154 155 typedef struct V9fsFidState V9fsFidState; 156 157 typedef struct V9fsString 158 { 159 int16_t size; 160 char *data; 161 } V9fsString; 162 163 typedef struct V9fsQID 164 { 165 int8_t type; 166 int32_t version; 167 int64_t path; 168 } V9fsQID; 169 170 typedef struct V9fsStat 171 { 172 int16_t size; 173 int16_t type; 174 int32_t dev; 175 V9fsQID qid; 176 int32_t mode; 177 int32_t atime; 178 int32_t mtime; 179 int64_t length; 180 V9fsString name; 181 V9fsString uid; 182 V9fsString gid; 183 V9fsString muid; 184 /* 9p2000.u */ 185 V9fsString extension; 186 int32_t n_uid; 187 int32_t n_gid; 188 int32_t n_muid; 189 } V9fsStat; 190 191 enum { 192 P9_FID_NONE = 0, 193 P9_FID_FILE, 194 P9_FID_DIR, 195 P9_FID_XATTR, 196 }; 197 198 typedef struct V9fsXattr 199 { 200 int64_t copied_len; 201 int64_t len; 202 void *value; 203 V9fsString name; 204 int flags; 205 } V9fsXattr; 206 207 /* 208 * Filled by fs driver on open and other 209 * calls. 210 */ 211 union V9fsFidOpenState { 212 int fd; 213 DIR *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 struct V9fsState 240 { 241 VirtIODevice vdev; 242 VirtQueue *vq; 243 V9fsPDU pdus[MAX_REQ]; 244 QLIST_HEAD(, V9fsPDU) free_list; 245 QLIST_HEAD(, V9fsPDU) active_list; 246 V9fsFidState *fid_list; 247 FileOperations *ops; 248 FsContext ctx; 249 char *tag; 250 size_t config_size; 251 enum p9_proto_version proto_version; 252 int32_t msize; 253 /* 254 * lock ensuring atomic path update 255 * on rename. 256 */ 257 CoRwlock rename_lock; 258 int32_t root_fid; 259 Error *migration_blocker; 260 } V9fsState; 261 262 typedef struct V9fsStatState { 263 V9fsPDU *pdu; 264 size_t offset; 265 V9fsStat v9stat; 266 V9fsFidState *fidp; 267 struct stat stbuf; 268 } V9fsStatState; 269 270 typedef struct V9fsStatDotl { 271 uint64_t st_result_mask; 272 V9fsQID qid; 273 uint32_t st_mode; 274 uint32_t st_uid; 275 uint32_t st_gid; 276 uint64_t st_nlink; 277 uint64_t st_rdev; 278 uint64_t st_size; 279 uint64_t st_blksize; 280 uint64_t st_blocks; 281 uint64_t st_atime_sec; 282 uint64_t st_atime_nsec; 283 uint64_t st_mtime_sec; 284 uint64_t st_mtime_nsec; 285 uint64_t st_ctime_sec; 286 uint64_t st_ctime_nsec; 287 uint64_t st_btime_sec; 288 uint64_t st_btime_nsec; 289 uint64_t st_gen; 290 uint64_t st_data_version; 291 } V9fsStatDotl; 292 293 typedef struct V9fsOpenState { 294 V9fsPDU *pdu; 295 size_t offset; 296 int32_t mode; 297 V9fsFidState *fidp; 298 V9fsQID qid; 299 struct stat stbuf; 300 int iounit; 301 } V9fsOpenState; 302 303 typedef struct V9fsReadState { 304 V9fsPDU *pdu; 305 size_t offset; 306 int32_t count; 307 int32_t total; 308 int64_t off; 309 V9fsFidState *fidp; 310 struct iovec iov[128]; /* FIXME: bad, bad, bad */ 311 struct iovec *sg; 312 off_t dir_pos; 313 struct dirent *dent; 314 struct stat stbuf; 315 V9fsString name; 316 V9fsStat v9stat; 317 int32_t len; 318 int32_t cnt; 319 int32_t max_count; 320 } V9fsReadState; 321 322 typedef struct V9fsWriteState { 323 V9fsPDU *pdu; 324 size_t offset; 325 int32_t len; 326 int32_t count; 327 int32_t total; 328 int64_t off; 329 V9fsFidState *fidp; 330 struct iovec iov[128]; /* FIXME: bad, bad, bad */ 331 struct iovec *sg; 332 int cnt; 333 } V9fsWriteState; 334 335 typedef struct V9fsIattr 336 { 337 int32_t valid; 338 int32_t mode; 339 int32_t uid; 340 int32_t gid; 341 int64_t size; 342 int64_t atime_sec; 343 int64_t atime_nsec; 344 int64_t mtime_sec; 345 int64_t mtime_nsec; 346 } V9fsIattr; 347 348 struct virtio_9p_config 349 { 350 /* number of characters in tag */ 351 uint16_t tag_len; 352 /* Variable size tag name */ 353 uint8_t tag[0]; 354 } QEMU_PACKED; 355 356 typedef struct V9fsMkState { 357 V9fsPDU *pdu; 358 size_t offset; 359 V9fsQID qid; 360 struct stat stbuf; 361 V9fsString name; 362 V9fsString fullname; 363 } V9fsMkState; 364 365 /* 9p2000.L open flags */ 366 #define P9_DOTL_RDONLY 00000000 367 #define P9_DOTL_WRONLY 00000001 368 #define P9_DOTL_RDWR 00000002 369 #define P9_DOTL_NOACCESS 00000003 370 #define P9_DOTL_CREATE 00000100 371 #define P9_DOTL_EXCL 00000200 372 #define P9_DOTL_NOCTTY 00000400 373 #define P9_DOTL_TRUNC 00001000 374 #define P9_DOTL_APPEND 00002000 375 #define P9_DOTL_NONBLOCK 00004000 376 #define P9_DOTL_DSYNC 00010000 377 #define P9_DOTL_FASYNC 00020000 378 #define P9_DOTL_DIRECT 00040000 379 #define P9_DOTL_LARGEFILE 00100000 380 #define P9_DOTL_DIRECTORY 00200000 381 #define P9_DOTL_NOFOLLOW 00400000 382 #define P9_DOTL_NOATIME 01000000 383 #define P9_DOTL_CLOEXEC 02000000 384 #define P9_DOTL_SYNC 04000000 385 386 /* 9p2000.L at flags */ 387 #define P9_DOTL_AT_REMOVEDIR 0x200 388 389 /* 9P2000.L lock type */ 390 #define P9_LOCK_TYPE_RDLCK 0 391 #define P9_LOCK_TYPE_WRLCK 1 392 #define P9_LOCK_TYPE_UNLCK 2 393 394 #define P9_LOCK_SUCCESS 0 395 #define P9_LOCK_BLOCKED 1 396 #define P9_LOCK_ERROR 2 397 #define P9_LOCK_GRACE 3 398 399 #define P9_LOCK_FLAGS_BLOCK 1 400 #define P9_LOCK_FLAGS_RECLAIM 2 401 402 typedef struct V9fsFlock 403 { 404 uint8_t type; 405 uint32_t flags; 406 uint64_t start; /* absolute offset */ 407 uint64_t length; 408 uint32_t proc_id; 409 V9fsString client_id; 410 } V9fsFlock; 411 412 typedef struct V9fsGetlock 413 { 414 uint8_t type; 415 uint64_t start; /* absolute offset */ 416 uint64_t length; 417 uint32_t proc_id; 418 V9fsString client_id; 419 } V9fsGetlock; 420 421 extern int open_fd_hw; 422 extern int total_open_fd; 423 424 size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count, 425 size_t offset, size_t size, int pack); 426 427 static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count, 428 size_t offset, size_t size) 429 { 430 return pdu_packunpack(dst, sg, sg_count, offset, size, 0); 431 } 432 433 static inline void v9fs_path_write_lock(V9fsState *s) 434 { 435 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 436 qemu_co_rwlock_wrlock(&s->rename_lock); 437 } 438 } 439 440 static inline void v9fs_path_read_lock(V9fsState *s) 441 { 442 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 443 qemu_co_rwlock_rdlock(&s->rename_lock); 444 } 445 } 446 447 static inline void v9fs_path_unlock(V9fsState *s) 448 { 449 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 450 qemu_co_rwlock_unlock(&s->rename_lock); 451 } 452 } 453 454 static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu) 455 { 456 return pdu->cancelled; 457 } 458 459 extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq); 460 extern void virtio_9p_set_fd_limit(void); 461 extern void v9fs_reclaim_fd(V9fsPDU *pdu); 462 extern void v9fs_string_init(V9fsString *str); 463 extern void v9fs_string_free(V9fsString *str); 464 extern void v9fs_string_null(V9fsString *str); 465 extern void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...); 466 extern void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs); 467 extern void v9fs_path_init(V9fsPath *path); 468 extern void v9fs_path_free(V9fsPath *path); 469 extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs); 470 extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath, 471 const char *name, V9fsPath *path); 472 #endif 473