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 struct V9fsFidState 208 { 209 int fid_type; 210 int32_t fid; 211 V9fsPath path; 212 union { 213 int fd; 214 DIR *dir; 215 V9fsXattr xattr; 216 } fs; 217 union { 218 int fd; 219 DIR *dir; 220 } fs_reclaim; 221 int flags; 222 int open_flags; 223 uid_t uid; 224 int ref; 225 int clunked; 226 V9fsFidState *next; 227 V9fsFidState *rclm_lst; 228 }; 229 230 typedef struct V9fsState 231 { 232 VirtIODevice vdev; 233 VirtQueue *vq; 234 V9fsPDU pdus[MAX_REQ]; 235 QLIST_HEAD(, V9fsPDU) free_list; 236 QLIST_HEAD(, V9fsPDU) active_list; 237 V9fsFidState *fid_list; 238 FileOperations *ops; 239 FsContext ctx; 240 uint16_t tag_len; 241 uint8_t *tag; 242 size_t config_size; 243 enum p9_proto_version proto_version; 244 int32_t msize; 245 /* 246 * lock ensuring atomic path update 247 * on rename. 248 */ 249 CoRwlock rename_lock; 250 } V9fsState; 251 252 typedef struct V9fsStatState { 253 V9fsPDU *pdu; 254 size_t offset; 255 V9fsStat v9stat; 256 V9fsFidState *fidp; 257 struct stat stbuf; 258 } V9fsStatState; 259 260 typedef struct V9fsStatDotl { 261 uint64_t st_result_mask; 262 V9fsQID qid; 263 uint32_t st_mode; 264 uint32_t st_uid; 265 uint32_t st_gid; 266 uint64_t st_nlink; 267 uint64_t st_rdev; 268 uint64_t st_size; 269 uint64_t st_blksize; 270 uint64_t st_blocks; 271 uint64_t st_atime_sec; 272 uint64_t st_atime_nsec; 273 uint64_t st_mtime_sec; 274 uint64_t st_mtime_nsec; 275 uint64_t st_ctime_sec; 276 uint64_t st_ctime_nsec; 277 uint64_t st_btime_sec; 278 uint64_t st_btime_nsec; 279 uint64_t st_gen; 280 uint64_t st_data_version; 281 } V9fsStatDotl; 282 283 typedef struct V9fsOpenState { 284 V9fsPDU *pdu; 285 size_t offset; 286 int32_t mode; 287 V9fsFidState *fidp; 288 V9fsQID qid; 289 struct stat stbuf; 290 int iounit; 291 } V9fsOpenState; 292 293 typedef struct V9fsReadState { 294 V9fsPDU *pdu; 295 size_t offset; 296 int32_t count; 297 int32_t total; 298 int64_t off; 299 V9fsFidState *fidp; 300 struct iovec iov[128]; /* FIXME: bad, bad, bad */ 301 struct iovec *sg; 302 off_t dir_pos; 303 struct dirent *dent; 304 struct stat stbuf; 305 V9fsString name; 306 V9fsStat v9stat; 307 int32_t len; 308 int32_t cnt; 309 int32_t max_count; 310 } V9fsReadState; 311 312 typedef struct V9fsWriteState { 313 V9fsPDU *pdu; 314 size_t offset; 315 int32_t len; 316 int32_t count; 317 int32_t total; 318 int64_t off; 319 V9fsFidState *fidp; 320 struct iovec iov[128]; /* FIXME: bad, bad, bad */ 321 struct iovec *sg; 322 int cnt; 323 } V9fsWriteState; 324 325 typedef struct V9fsIattr 326 { 327 int32_t valid; 328 int32_t mode; 329 int32_t uid; 330 int32_t gid; 331 int64_t size; 332 int64_t atime_sec; 333 int64_t atime_nsec; 334 int64_t mtime_sec; 335 int64_t mtime_nsec; 336 } V9fsIattr; 337 338 struct virtio_9p_config 339 { 340 /* number of characters in tag */ 341 uint16_t tag_len; 342 /* Variable size tag name */ 343 uint8_t tag[0]; 344 } QEMU_PACKED; 345 346 typedef struct V9fsMkState { 347 V9fsPDU *pdu; 348 size_t offset; 349 V9fsQID qid; 350 struct stat stbuf; 351 V9fsString name; 352 V9fsString fullname; 353 } V9fsMkState; 354 355 /* 9p2000.L open flags */ 356 #define P9_DOTL_RDONLY 00000000 357 #define P9_DOTL_WRONLY 00000001 358 #define P9_DOTL_RDWR 00000002 359 #define P9_DOTL_NOACCESS 00000003 360 #define P9_DOTL_CREATE 00000100 361 #define P9_DOTL_EXCL 00000200 362 #define P9_DOTL_NOCTTY 00000400 363 #define P9_DOTL_TRUNC 00001000 364 #define P9_DOTL_APPEND 00002000 365 #define P9_DOTL_NONBLOCK 00004000 366 #define P9_DOTL_DSYNC 00010000 367 #define P9_DOTL_FASYNC 00020000 368 #define P9_DOTL_DIRECT 00040000 369 #define P9_DOTL_LARGEFILE 00100000 370 #define P9_DOTL_DIRECTORY 00200000 371 #define P9_DOTL_NOFOLLOW 00400000 372 #define P9_DOTL_NOATIME 01000000 373 #define P9_DOTL_CLOEXEC 02000000 374 #define P9_DOTL_SYNC 04000000 375 376 /* 9p2000.L at flags */ 377 #define P9_DOTL_AT_REMOVEDIR 0x200 378 379 /* 9P2000.L lock type */ 380 #define P9_LOCK_TYPE_RDLCK 0 381 #define P9_LOCK_TYPE_WRLCK 1 382 #define P9_LOCK_TYPE_UNLCK 2 383 384 #define P9_LOCK_SUCCESS 0 385 #define P9_LOCK_BLOCKED 1 386 #define P9_LOCK_ERROR 2 387 #define P9_LOCK_GRACE 3 388 389 #define P9_LOCK_FLAGS_BLOCK 1 390 #define P9_LOCK_FLAGS_RECLAIM 2 391 392 typedef struct V9fsFlock 393 { 394 uint8_t type; 395 uint32_t flags; 396 uint64_t start; /* absolute offset */ 397 uint64_t length; 398 uint32_t proc_id; 399 V9fsString client_id; 400 } V9fsFlock; 401 402 typedef struct V9fsGetlock 403 { 404 uint8_t type; 405 uint64_t start; /* absolute offset */ 406 uint64_t length; 407 uint32_t proc_id; 408 V9fsString client_id; 409 } V9fsGetlock; 410 411 extern int open_fd_hw; 412 extern int total_open_fd; 413 414 size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count, 415 size_t offset, size_t size, int pack); 416 417 static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count, 418 size_t offset, size_t size) 419 { 420 return pdu_packunpack(dst, sg, sg_count, offset, size, 0); 421 } 422 423 static inline void v9fs_path_write_lock(V9fsState *s) 424 { 425 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 426 qemu_co_rwlock_wrlock(&s->rename_lock); 427 } 428 } 429 430 static inline void v9fs_path_read_lock(V9fsState *s) 431 { 432 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 433 qemu_co_rwlock_rdlock(&s->rename_lock); 434 } 435 } 436 437 static inline void v9fs_path_unlock(V9fsState *s) 438 { 439 if (s->ctx.export_flags & V9FS_PATHNAME_FSCONTEXT) { 440 qemu_co_rwlock_unlock(&s->rename_lock); 441 } 442 } 443 444 static inline uint8_t v9fs_request_cancelled(V9fsPDU *pdu) 445 { 446 return pdu->cancelled; 447 } 448 449 extern void handle_9p_output(VirtIODevice *vdev, VirtQueue *vq); 450 extern void virtio_9p_set_fd_limit(void); 451 extern void v9fs_reclaim_fd(V9fsPDU *pdu); 452 extern void v9fs_string_init(V9fsString *str); 453 extern void v9fs_string_free(V9fsString *str); 454 extern void v9fs_string_null(V9fsString *str); 455 extern void v9fs_string_sprintf(V9fsString *str, const char *fmt, ...); 456 extern void v9fs_string_copy(V9fsString *lhs, V9fsString *rhs); 457 extern void v9fs_path_init(V9fsPath *path); 458 extern void v9fs_path_free(V9fsPath *path); 459 extern void v9fs_path_copy(V9fsPath *lhs, V9fsPath *rhs); 460 extern int v9fs_name_to_path(V9fsState *s, V9fsPath *dirpath, 461 const char *name, V9fsPath *path); 462 #endif 463