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 <glib.h> 8 #include "fsdev/file-op-9p.h" 9 #include "fsdev/9p-iov-marshal.h" 10 #include "qemu/thread.h" 11 #include "qemu/coroutine.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 enum p9_proto_version { 99 V9FS_PROTO_2000U = 0x01, 100 V9FS_PROTO_2000L = 0x02, 101 }; 102 103 #define P9_NOTAG (u16)(~0) 104 #define P9_NOFID (u32)(~0) 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 struct V9fsState; 122 123 struct V9fsPDU 124 { 125 uint32_t size; 126 uint16_t tag; 127 uint8_t id; 128 uint8_t cancelled; 129 CoQueue complete; 130 struct V9fsState *s; 131 QLIST_ENTRY(V9fsPDU) next; 132 uint32_t idx; 133 }; 134 135 136 /* FIXME 137 * 1) change user needs to set groups and stuff 138 */ 139 140 #define MAX_REQ 128 141 #define MAX_TAG_LEN 32 142 143 #define BUG_ON(cond) assert(!(cond)) 144 145 typedef struct V9fsFidState V9fsFidState; 146 147 enum { 148 P9_FID_NONE = 0, 149 P9_FID_FILE, 150 P9_FID_DIR, 151 P9_FID_XATTR, 152 }; 153 154 typedef struct V9fsConf 155 { 156 /* tag name for the device */ 157 char *tag; 158 char *fsdev_id; 159 } V9fsConf; 160 161 typedef struct V9fsXattr 162 { 163 int64_t copied_len; 164 int64_t len; 165 void *value; 166 V9fsString name; 167 int flags; 168 } V9fsXattr; 169 170 typedef struct V9fsDir { 171 DIR *stream; 172 } V9fsDir; 173 174 /* 175 * Filled by fs driver on open and other 176 * calls. 177 */ 178 union V9fsFidOpenState { 179 int fd; 180 V9fsDir 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