Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
5e4eaa79
Q
qemu
项目概览
openeuler
/
qemu
通知
10
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
Q
qemu
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
5e4eaa79
编写于
5月 18, 2011
作者:
A
Aneesh Kumar K.V
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
hw/9pfs: Update v9fs_readdir to use coroutines
Signed-off-by:
N
Aneesh Kumar K.V
<
aneesh.kumar@linux.vnet.ibm.com
>
上级
dcb9dbe3
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
72 addition
and
101 deletion
+72
-101
hw/9pfs/virtio-9p.c
hw/9pfs/virtio-9p.c
+72
-101
未找到文件。
hw/9pfs/virtio-9p.c
浏览文件 @
5e4eaa79
...
...
@@ -112,11 +112,6 @@ static off_t v9fs_do_telldir(V9fsState *s, DIR *dir)
return
s
->
ops
->
telldir
(
&
s
->
ctx
,
dir
);
}
static
struct
dirent
*
v9fs_do_readdir
(
V9fsState
*
s
,
DIR
*
dir
)
{
return
s
->
ops
->
readdir
(
&
s
->
ctx
,
dir
);
}
static
void
v9fs_do_seekdir
(
V9fsState
*
s
,
DIR
*
dir
,
off_t
off
)
{
return
s
->
ops
->
seekdir
(
&
s
->
ctx
,
dir
,
off
);
...
...
@@ -1966,7 +1961,7 @@ static void v9fs_read_post_dir_lstat(V9fsState *s, V9fsReadState *vs,
v9fs_stat_free
(
&
vs
->
v9stat
);
v9fs_string_free
(
&
vs
->
name
);
vs
->
dir_pos
=
vs
->
dent
->
d_off
;
v
s
->
dent
=
v9fs_do_readdir
(
s
,
vs
->
fidp
->
fs
.
dir
);
v
9fs_co_readdir
(
s
,
vs
->
fidp
,
&
vs
->
dent
);
v9fs_read_post_readdir
(
s
,
vs
,
err
);
return
;
out:
...
...
@@ -1998,7 +1993,7 @@ static void v9fs_read_post_readdir(V9fsState *s, V9fsReadState *vs, ssize_t err)
static
void
v9fs_read_post_telldir
(
V9fsState
*
s
,
V9fsReadState
*
vs
,
ssize_t
err
)
{
v
s
->
dent
=
v9fs_do_readdir
(
s
,
vs
->
fidp
->
fs
.
dir
);
v
9fs_co_readdir
(
s
,
vs
->
fidp
,
&
vs
->
dent
);
v9fs_read_post_readdir
(
s
,
vs
,
err
);
return
;
}
...
...
@@ -2127,126 +2122,102 @@ out:
qemu_free
(
vs
);
}
typedef
struct
V9fsReadDirState
{
V9fsPDU
*
pdu
;
V9fsFidState
*
fidp
;
V9fsQID
qid
;
off_t
saved_dir_pos
;
struct
dirent
*
dent
;
int32_t
count
;
int32_t
max_count
;
size_t
offset
;
int64_t
initial_offset
;
V9fsString
name
;
}
V9fsReadDirState
;
static
void
v9fs_readdir_post_seekdir
(
V9fsState
*
s
,
V9fsReadDirState
*
vs
)
static
size_t
v9fs_readdir_data_size
(
V9fsString
*
name
)
{
vs
->
offset
+=
pdu_marshal
(
vs
->
pdu
,
vs
->
offset
,
"d"
,
vs
->
count
);
vs
->
offset
+=
vs
->
count
;
complete_pdu
(
s
,
vs
->
pdu
,
vs
->
offset
);
qemu_free
(
vs
);
return
;
/*
* Size of each dirent on the wire: size of qid (13) + size of offset (8)
* size of type (1) + size of name.size (2) + strlen(name.data)
*/
return
24
+
v9fs_string_size
(
name
)
;
}
/* Size of each dirent on the wire: size of qid (13) + size of offset (8)
* size of type (1) + size of name.size (2) + strlen(name.data)
*/
#define V9_READDIR_DATA_SZ (24 + strlen(vs->name.data))
static
void
v9fs_readdir_post_readdir
(
V9fsState
*
s
,
V9fsReadDirState
*
vs
)
static
int
v9fs_do_readdir
(
V9fsState
*
s
,
V9fsPDU
*
pdu
,
V9fsFidState
*
fidp
,
int32_t
max_count
)
{
int
len
;
size_t
size
;
V9fsQID
qid
;
V9fsString
name
;
int
len
,
err
=
0
;
int32_t
count
=
0
;
off_t
saved_dir_pos
;
struct
dirent
*
dent
;
if
(
vs
->
dent
)
{
v9fs_string_init
(
&
vs
->
name
);
v9fs_string_sprintf
(
&
vs
->
name
,
"%s"
,
vs
->
dent
->
d_name
);
if
((
vs
->
count
+
V9_READDIR_DATA_SZ
)
>
vs
->
max_count
)
{
/* save the directory position */
saved_dir_pos
=
v9fs_co_telldir
(
s
,
fidp
);
if
(
saved_dir_pos
<
0
)
{
return
saved_dir_pos
;
}
while
(
1
)
{
err
=
v9fs_co_readdir
(
s
,
fidp
,
&
dent
);
if
(
err
||
!
dent
)
{
break
;
}
v9fs_string_init
(
&
name
);
v9fs_string_sprintf
(
&
name
,
"%s"
,
dent
->
d_name
);
if
((
count
+
v9fs_readdir_data_size
(
&
name
))
>
max_count
)
{
/* Ran out of buffer. Set dir back to old position and return */
v9fs_
do_seekdir
(
s
,
vs
->
fidp
->
fs
.
dir
,
vs
->
saved_dir_pos
);
v9fs_
readdir_post_seekdir
(
s
,
vs
);
return
;
v9fs_
co_seekdir
(
s
,
fidp
,
saved_dir_pos
);
v9fs_
string_free
(
&
name
);
return
count
;
}
/
* Fill up just the path field of qid because the client uses
/*
* Fill up just the path field of qid because the client uses
* only that. To fill the entire qid structure we will have
* to stat each dirent found, which is expensive
*/
size
=
MIN
(
sizeof
(
vs
->
dent
->
d_ino
),
sizeof
(
vs
->
qid
.
path
));
memcpy
(
&
vs
->
qid
.
path
,
&
vs
->
dent
->
d_ino
,
size
);
size
=
MIN
(
sizeof
(
dent
->
d_ino
),
sizeof
(
qid
.
path
));
memcpy
(
&
qid
.
path
,
&
dent
->
d_ino
,
size
);
/* Fill the other fields with dummy values */
vs
->
qid
.
type
=
0
;
vs
->
qid
.
version
=
0
;
len
=
pdu_marshal
(
vs
->
pdu
,
vs
->
offset
+
4
+
vs
->
count
,
"Qqbs"
,
&
vs
->
qid
,
vs
->
dent
->
d_off
,
vs
->
dent
->
d_type
,
&
vs
->
name
);
vs
->
count
+=
len
;
v9fs_string_free
(
&
vs
->
name
);
vs
->
saved_dir_pos
=
vs
->
dent
->
d_off
;
vs
->
dent
=
v9fs_do_readdir
(
s
,
vs
->
fidp
->
fs
.
dir
);
v9fs_readdir_post_readdir
(
s
,
vs
);
return
;
}
vs
->
offset
+=
pdu_marshal
(
vs
->
pdu
,
vs
->
offset
,
"d"
,
vs
->
count
);
vs
->
offset
+=
vs
->
count
;
complete_pdu
(
s
,
vs
->
pdu
,
vs
->
offset
);
qemu_free
(
vs
);
return
;
}
static
void
v9fs_readdir_post_telldir
(
V9fsState
*
s
,
V9fsReadDirState
*
vs
)
{
vs
->
dent
=
v9fs_do_readdir
(
s
,
vs
->
fidp
->
fs
.
dir
);
v9fs_readdir_post_readdir
(
s
,
vs
);
return
;
}
qid
.
type
=
0
;
qid
.
version
=
0
;
static
void
v9fs_readdir_post_setdir
(
V9fsState
*
s
,
V9fsReadDirState
*
vs
)
{
vs
->
saved_dir_pos
=
v9fs_do_telldir
(
s
,
vs
->
fidp
->
fs
.
dir
);
v9fs_readdir_post_telldir
(
s
,
vs
);
return
;
/* 11 = 7 + 4 (7 = start offset, 4 = space for storing count) */
len
=
pdu_marshal
(
pdu
,
11
+
count
,
"Qqbs"
,
&
qid
,
dent
->
d_off
,
dent
->
d_type
,
&
name
);
count
+=
len
;
v9fs_string_free
(
&
name
);
saved_dir_pos
=
dent
->
d_off
;
}
if
(
err
<
0
)
{
return
err
;
}
return
count
;
}
static
void
v9fs_readdir
(
void
*
opaque
)
{
V9fsPDU
*
pdu
=
opaque
;
V9fsState
*
s
=
pdu
->
s
;
int32_t
fid
;
V9fs
ReadDirState
*
vs
;
ssize_t
err
=
0
;
V9fs
FidState
*
fidp
;
ssize_t
retval
=
0
;
size_t
offset
=
7
;
int64_t
initial_offset
;
int32_t
count
,
max_count
;
V9fsPDU
*
pdu
=
opaque
;
V9fsState
*
s
=
pdu
->
s
;
vs
=
qemu_malloc
(
sizeof
(
*
vs
));
vs
->
pdu
=
pdu
;
vs
->
offset
=
7
;
vs
->
count
=
0
;
pdu_unmarshal
(
vs
->
pdu
,
offset
,
"dqd"
,
&
fid
,
&
vs
->
initial_offset
,
&
vs
->
max_count
);
pdu_unmarshal
(
pdu
,
offset
,
"dqd"
,
&
fid
,
&
initial_offset
,
&
max_count
);
vs
->
fidp
=
lookup_fid
(
s
,
fid
);
if
(
vs
->
fidp
==
NULL
||
!
(
vs
->
fidp
->
fs
.
dir
)
)
{
err
=
-
EINVAL
;
fidp
=
lookup_fid
(
s
,
fid
);
if
(
fidp
==
NULL
||
!
fidp
->
fs
.
dir
)
{
retval
=
-
EINVAL
;
goto
out
;
}
if
(
vs
->
initial_offset
==
0
)
{
v9fs_do_rewinddir
(
s
,
vs
->
fidp
->
fs
.
dir
);
if
(
initial_offset
==
0
)
{
v9fs_co_rewinddir
(
s
,
fidp
);
}
else
{
v9fs_
do_seekdir
(
s
,
vs
->
fidp
->
fs
.
dir
,
vs
->
initial_offset
);
v9fs_
co_seekdir
(
s
,
fidp
,
initial_offset
);
}
v9fs_readdir_post_setdir
(
s
,
vs
);
return
;
count
=
v9fs_do_readdir
(
s
,
pdu
,
fidp
,
max_count
);
if
(
count
<
0
)
{
retval
=
count
;
goto
out
;
}
retval
=
offset
;
retval
+=
pdu_marshal
(
pdu
,
offset
,
"d"
,
count
);
retval
+=
count
;
out:
complete_pdu
(
s
,
pdu
,
err
);
qemu_free
(
vs
);
complete_pdu
(
s
,
pdu
,
retval
);
}
static
void
v9fs_write_post_pwritev
(
V9fsState
*
s
,
V9fsWriteState
*
vs
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录