func: static void v9fs_read(void *opaque) int32_t fid ; uint64_t off ; int32_t count = 0 ; size_t offset = 7 ; uint32_t max_count ; V9fsFidState * fidp ; V9fsPDU * pdu = opaque ; V9fsState * s = pdu -> s ; err = pdu_unmarshal ( pdu , offset , "dqd" , & fid , & off , & max_count ); 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 = - EINVAL; if ( fidp -> fid_type == P9_FID_DIR )  count = v9fs_do_readdir_with_stat ( pdu , fidp , max_count ); static int v9fs_do_readdir_with_stat(V9fsPDU V9fsFidState *fidp, uint32_t max_count) V9fsStat v9stat ; int len , err = 0 ; int32_t count = 0 ; off_t saved_dir_pos ; struct dirent * dent , * result ; saved_dir_pos = v9fs_co_telldir ( pdu , fidp ); if ( saved_dir_pos < 0 )  return saved_dir_pos ; dent = g_malloc ( sizeof ( struct dirent ) ); while ( 1 )  err = v9fs_co_readdir_r ( pdu , fidp , dent , & result ); if ( err || ! result )  err = v9fs_co_name_to_path ( pdu , & fidp -> path , dent -> d_name , & path ); if ( err < 0 )  err = v9fs_co_lstat ( pdu , & path , & stbuf ); if ( err < 0 )  err = stat_to_v9stat ( pdu , & path , & stbuf , & v9stat ); static int stat_to_v9stat(V9fsPDU *pdu, V9fsPath const struct stat V9fsStat *v9stat) int err ; memset ( v9stat , 0 , sizeof ( * v9stat ) ); v9stat -> mode = stat_to_v9mode ( stbuf ); static uint32_t stat_to_v9mode(const struct stat *stbuf) uint32_t mode ; mode = stbuf -> st_mode & 0777; if ( S_ISDIR ( stbuf -> st_mode ) )  mode |= P9_STAT_MODE_DIR; if ( S_ISLNK ( stbuf -> st_mode ) )  mode |= P9_STAT_MODE_SYMLINK; if ( S_ISSOCK ( stbuf -> st_mode ) )  mode |= P9_STAT_MODE_SOCKET; if ( S_ISFIFO ( stbuf -> st_mode ) )  mode |= P9_STAT_MODE_NAMED_PIPE; if ( S_ISBLK ( stbuf -> st_mode ) || S_ISCHR ( stbuf -> st_mode ) )  mode |= P9_STAT_MODE_DEVICE; if ( stbuf -> st_mode & S_ISUID )  mode |= P9_STAT_MODE_SETUID; if ( stbuf -> st_mode & S_ISGID )  mode |= P9_STAT_MODE_SETGID; if ( stbuf -> st_mode & S_ISVTX )  mode |= P9_STAT_MODE_SETVTX; return mode ; v9stat -> atime = stbuf -> st_atime; v9stat -> mtime = stbuf -> st_mtime; v9stat -> length = stbuf -> st_size; v9stat -> n_uid = stbuf -> st_uid; v9stat -> n_gid = stbuf -> st_gid; v9stat -> n_muid = 0; if ( v9stat -> mode & P9_STAT_MODE_SYMLINK )  err = v9fs_co_readlink ( pdu , name , & v9stat -> extension ); if ( err < 0 )  return err ; return 0 ; if ( err < 0 )  len = pdu_marshal ( pdu , 11 + count , "S" , & v9stat ); if ( ( len != ( v9stat . size + 2 ) ) || ( ( count + len ) > max_count ) )  return count ; count += len; if ( err < 0 )  return err ; return count ; if ( count < 0 )  err = count; err = pdu_marshal ( pdu , offset , "d" , count ); if ( err < 0 )  err += offset + count; if ( fidp -> fid_type == P9_FID_FILE )  QEMUIOVector qiov ; int32_t len ; len = v9fs_co_preadv ( pdu , fidp , qiov . iov , qiov . niov , off ); if ( len >= 0 )  off += len; count += len; while ( len == - EINTR && ! pdu -> cancelled )  if ( len < 0 )  err = len; while ( count < max_count && len > 0 )  err = pdu_marshal ( pdu , offset , "d" , count ); if ( err < 0 )  err += offset + count; if ( fidp -> fid_type == P9_FID_XATTR )  err = v9fs_xattr_read ( s , pdu , fidp , off , max_count ); static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState uint64_t off, uint32_t max_count) ssize_t err ; size_t offset = 7 ; int read_count ; int64_t xattr_len ; xattr_len = fidp -> fs . xattr . len; read_count = xattr_len - off; if ( read_count > max_count )  read_count = max_count; if ( read_count < 0 )  read_count = 0; err = pdu_marshal ( pdu , offset , "d" , read_count ); if ( err < 0 )  return err ; offset += err; err = v9fs_pack ( pdu -> elem . in_sg , pdu -> elem . in_num , offset , ( ( char * ) fidp -> fs . xattr . value ) + off , read_count ); if ( err < 0 )  return err ; offset += err; return offset ; err = - EINVAL; 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 ); 