func: static void v9fs_open(void *opaque) int flags ; int32_t fid ; int32_t mode ; size_t offset = 7 ; struct stat stbuf ; V9fsFidState * fidp ; V9fsPDU * pdu = opaque ; V9fsState * s = pdu -> s ; if ( s -> proto_version == V9FS_PROTO_2000L )  err = pdu_unmarshal ( pdu , offset , "dd" , & fid , & mode ); uint8_t modebyte ; err = pdu_unmarshal ( pdu , offset , "db" , & fid , & modebyte ); mode = modebyte; if ( err < 0 )  fidp = get_fid ( pdu , fid ); static V9fsFidState *get_fid(V9fsPDU *pdu, int32_t fid) int err ; V9fsFidState * f ; V9fsState * s = pdu -> s ; for (f = s->fid_list; f; f = f->next) if ( f -> fid == fid )  f -> ref ++; err = v9fs_reopen_fid ( pdu , f ); if ( err < 0 )  return NULL ; return f ; return NULL ; if ( fidp == NULL )  err = - ENOENT; err = v9fs_co_lstat ( pdu , & fidp -> path , & stbuf ); if ( err < 0 )  if ( S_ISDIR ( stbuf . st_mode ) )  err = v9fs_co_opendir ( pdu , fidp ); if ( err < 0 )  err = pdu_marshal ( pdu , offset , "Qd" , & qid , 0 ); if ( err < 0 )  err += offset; if ( s -> proto_version == V9FS_PROTO_2000L )  flags = get_dotl_openflags ( s , mode ); static int get_dotl_openflags(V9fsState *s, int oflags) int flags ; flags = dotl_to_open_flags ( oflags ); static int dotl_to_open_flags(int flags) int i ; int oflags = flags & O_ACCMODE ; struct dotl_openflag_map dotl_oflag_map [ ] P9_DOTL_CREATE , O_CREAT P9_DOTL_EXCL , O_EXCL P9_DOTL_NOCTTY , O_NOCTTY P9_DOTL_TRUNC , O_TRUNC P9_DOTL_APPEND , O_APPEND P9_DOTL_NONBLOCK , O_NONBLOCK P9_DOTL_DSYNC , O_DSYNC P9_DOTL_FASYNC , FASYNC P9_DOTL_DIRECT , O_DIRECT P9_DOTL_LARGEFILE , O_LARGEFILE P9_DOTL_DIRECTORY , O_DIRECTORY P9_DOTL_NOFOLLOW , O_NOFOLLOW P9_DOTL_NOATIME , O_NOATIME P9_DOTL_SYNC , O_SYNC , for (i = 0; i < ARRAY_SIZE(dotl_oflag_map); i++) if ( flags & dotl_oflag_map [ i ] . dotl_flag )  oflags |= dotl_oflag_map [ i ] . open_flag; return oflags ; flags &= ~ ( O_NOCTTY | O_ASYNC | O_CREAT ); flags &= ~O_DIRECT; return flags ; flags = omode_to_uflags ( mode ); static int omode_to_uflags(int8_t mode) int ret = 0 ; switch ( mode & 3 )  ret = O_RDONLY; ret = O_RDWR; ret = O_WRONLY; ret = O_RDONLY; if ( mode & Otrunc )  ret |= O_TRUNC; if ( mode & Oappend )  ret |= O_APPEND; if ( mode & Oexcl )  ret |= O_EXCL; return ret ; if ( is_ro_export ( & s -> ctx ) )  static inline bool is_ro_export(FsContext *ctx) return ctx -> export_flags & V9FS_RDONLY ; if ( mode & O_WRONLY || mode & O_RDWR || mode & O_APPEND || mode & O_TRUNC )  err = - EROFS; err = v9fs_co_open ( pdu , fidp , flags ); if ( err < 0 )  fidp -> fid_type = P9_FID_FILE; fidp -> open_flags = flags; if ( flags & O_EXCL )  fidp -> flags |= FID_NON_RECLAIMABLE; iounit = get_iounit ( pdu , & fidp -> path ); static int32_t get_iounit(V9fsPDU *pdu, V9fsPath *path) struct statfs stbuf ; int32_t iounit = 0 ; V9fsState * s = pdu -> s ; if ( ! v9fs_co_statfs ( pdu , path , & stbuf ) )  iounit = stbuf . f_bsize; iounit *= ( s -> msize - P9_IOHDRSZ ) / stbuf . f_bsize; if ( ! iounit )  iounit = s -> msize - P9_IOHDRSZ; return iounit ; err = pdu_marshal ( pdu , offset , "Qd" , & qid , iounit ); if ( err < 0 )  err += offset; complete_pdu ( s , pdu , err ); static void complete_pdu(V9fsState *s, V9fsPDU *pdu, ssize_t len) if ( len < 0 )  int err = - len ; if ( s -> proto_version != V9FS_PROTO_2000L )  V9fsString str ; str . data = strerror ( err ); str . size = strlen ( str . data ); len += pdu_marshal ( pdu , len , "s" , & str ); len += pdu_marshal ( pdu , len , "d" , err ); pdu_marshal ( pdu , 0 , "dbw" , ( int32_t ) len , id , pdu -> tag ); pdu -> size = len; pdu -> id = id; virtqueue_push ( s -> vq , & pdu -> elem , len ); qemu_co_queue_next ( & pdu -> complete ); free_pdu ( s , pdu ); 