Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
d439b79d
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,发现更多精彩内容 >>
提交
d439b79d
编写于
10月 31, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'aneesh/for-upstream-7' into staging
上级
96b3d73f
2583e443
变更
21
显示空白变更内容
内联
并排
Showing
21 changed file
with
973 addition
and
161 deletion
+973
-161
Makefile.objs
Makefile.objs
+1
-0
configure
configure
+1
-1
fsdev/file-op-9p.h
fsdev/file-op-9p.h
+22
-14
fsdev/qemu-fsdev.c
fsdev/qemu-fsdev.c
+7
-1
fsdev/qemu-fsdev.h
fsdev/qemu-fsdev.h
+1
-0
hw/9pfs/codir.c
hw/9pfs/codir.c
+8
-8
hw/9pfs/cofile.c
hw/9pfs/cofile.c
+17
-20
hw/9pfs/virtio-9p-coth.h
hw/9pfs/virtio-9p-coth.h
+3
-3
hw/9pfs/virtio-9p-handle.c
hw/9pfs/virtio-9p-handle.c
+55
-41
hw/9pfs/virtio-9p-local.c
hw/9pfs/virtio-9p-local.c
+64
-49
hw/9pfs/virtio-9p-synth.c
hw/9pfs/virtio-9p-synth.c
+571
-0
hw/9pfs/virtio-9p-synth.h
hw/9pfs/virtio-9p-synth.h
+50
-0
hw/9pfs/virtio-9p.c
hw/9pfs/virtio-9p.c
+56
-6
hw/9pfs/virtio-9p.h
hw/9pfs/virtio-9p.h
+18
-9
qemu-config.c
qemu-config.c
+7
-0
qemu-option.c
qemu-option.c
+35
-4
qemu-option.h
qemu-option.h
+2
-1
qemu-options.hx
qemu-options.hx
+19
-4
qemu-queue.h
qemu-queue.h
+13
-0
qemu-thread.h
qemu-thread.h
+3
-0
vl.c
vl.c
+20
-0
未找到文件。
Makefile.objs
浏览文件 @
d439b79d
...
...
@@ -310,6 +310,7 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
9pfs-nested-$(CONFIG_VIRTFS)
+=
virtio-9p-xattr-user.o virtio-9p-posix-acl.o
9pfs-nested-$(CONFIG_VIRTFS)
+=
virtio-9p-coth.o cofs.o codir.o cofile.o
9pfs-nested-$(CONFIG_VIRTFS)
+=
coxattr.o virtio-9p-handle.o
9pfs-nested-$(CONFIG_VIRTFS)
+=
virtio-9p-synth.o
hw-obj-$(CONFIG_REALLY_VIRTFS)
+=
$(
addprefix
9pfs/,
$
(
9pfs-nested-y
))
$(addprefix 9pfs/, $(9pfs-nested-y))
:
QEMU_CFLAGS+=$(GLIB_CFLAGS)
...
...
configure
浏览文件 @
d439b79d
...
...
@@ -2562,7 +2562,7 @@ fi
open_by_hande_at
=
no
cat
>
$TMPC
<<
EOF
#include <fcntl.h>
int main(void) { struct file_handle
*fh; open_by_handle_at(0,
fh, 0); }
int main(void) { struct file_handle
fh; open_by_handle_at(0, &
fh, 0); }
EOF
if
compile_prog
""
""
;
then
open_by_handle_at
=
yes
...
...
fsdev/file-op-9p.h
浏览文件 @
d439b79d
...
...
@@ -56,10 +56,12 @@ typedef struct extended_ops {
* On failure ignore the error.
*/
#define V9FS_SM_NONE 0x00000010
#define V9FS_RDONLY 0x00000020
#define V9FS_SEC_MASK 0x0000001C
typedef
struct
FsContext
{
uid_t
uid
;
...
...
@@ -76,6 +78,8 @@ typedef struct V9fsPath {
char
*
data
;
}
V9fsPath
;
typedef
union
V9fsFidOpenState
V9fsFidOpenState
;
void
cred_init
(
FsCred
*
);
typedef
struct
FileOperations
...
...
@@ -92,22 +96,26 @@ typedef struct FileOperations
const
char
*
,
FsCred
*
);
int
(
*
link
)(
FsContext
*
,
V9fsPath
*
,
V9fsPath
*
,
const
char
*
);
int
(
*
setuid
)(
FsContext
*
,
uid_t
);
int
(
*
close
)(
FsContext
*
,
int
);
int
(
*
closedir
)(
FsContext
*
,
DIR
*
);
DIR
*
(
*
opendir
)(
FsContext
*
,
V9fsPath
*
);
int
(
*
open
)(
FsContext
*
,
V9fsPath
*
,
int
);
int
(
*
open2
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
int
,
FsCred
*
);
void
(
*
rewinddir
)(
FsContext
*
,
DIR
*
);
off_t
(
*
telldir
)(
FsContext
*
,
DIR
*
);
int
(
*
readdir_r
)(
FsContext
*
,
DIR
*
,
struct
dirent
*
,
struct
dirent
**
);
void
(
*
seekdir
)(
FsContext
*
,
DIR
*
,
off_t
);
ssize_t
(
*
preadv
)(
FsContext
*
,
int
,
const
struct
iovec
*
,
int
,
off_t
);
ssize_t
(
*
pwritev
)(
FsContext
*
,
int
,
const
struct
iovec
*
,
int
,
off_t
);
int
(
*
close
)(
FsContext
*
,
V9fsFidOpenState
*
);
int
(
*
closedir
)(
FsContext
*
,
V9fsFidOpenState
*
);
int
(
*
opendir
)(
FsContext
*
,
V9fsPath
*
,
V9fsFidOpenState
*
);
int
(
*
open
)(
FsContext
*
,
V9fsPath
*
,
int
,
V9fsFidOpenState
*
);
int
(
*
open2
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
int
,
FsCred
*
,
V9fsFidOpenState
*
);
void
(
*
rewinddir
)(
FsContext
*
,
V9fsFidOpenState
*
);
off_t
(
*
telldir
)(
FsContext
*
,
V9fsFidOpenState
*
);
int
(
*
readdir_r
)(
FsContext
*
,
V9fsFidOpenState
*
,
struct
dirent
*
,
struct
dirent
**
);
void
(
*
seekdir
)(
FsContext
*
,
V9fsFidOpenState
*
,
off_t
);
ssize_t
(
*
preadv
)(
FsContext
*
,
V9fsFidOpenState
*
,
const
struct
iovec
*
,
int
,
off_t
);
ssize_t
(
*
pwritev
)(
FsContext
*
,
V9fsFidOpenState
*
,
const
struct
iovec
*
,
int
,
off_t
);
int
(
*
mkdir
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
FsCred
*
);
int
(
*
fstat
)(
FsContext
*
,
int
,
struct
stat
*
);
int
(
*
fstat
)(
FsContext
*
,
V9fsFidOpenState
*
,
struct
stat
*
);
int
(
*
rename
)(
FsContext
*
,
const
char
*
,
const
char
*
);
int
(
*
truncate
)(
FsContext
*
,
V9fsPath
*
,
off_t
);
int
(
*
fsync
)(
FsContext
*
,
int
,
int
);
int
(
*
fsync
)(
FsContext
*
,
V9fsFidOpenState
*
,
int
);
int
(
*
statfs
)(
FsContext
*
s
,
V9fsPath
*
path
,
struct
statfs
*
stbuf
);
ssize_t
(
*
lgetxattr
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
void
*
,
size_t
);
...
...
fsdev/qemu-fsdev.c
浏览文件 @
d439b79d
...
...
@@ -24,6 +24,7 @@ static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries =
static
FsDriverTable
FsDrivers
[]
=
{
{
.
name
=
"local"
,
.
ops
=
&
local_ops
},
{
.
name
=
"handle"
,
.
ops
=
&
handle_ops
},
{
.
name
=
"synth"
,
.
ops
=
&
synth_ops
},
};
int
qemu_fsdev_add
(
QemuOpts
*
opts
)
...
...
@@ -35,7 +36,7 @@ int qemu_fsdev_add(QemuOpts *opts)
const
char
*
path
=
qemu_opt_get
(
opts
,
"path"
);
const
char
*
sec_model
=
qemu_opt_get
(
opts
,
"security_model"
);
const
char
*
writeout
=
qemu_opt_get
(
opts
,
"writeout"
);
bool
ro
=
qemu_opt_get_bool
(
opts
,
"readonly"
,
0
);
if
(
!
fsdev_id
)
{
fprintf
(
stderr
,
"fsdev: No id specified
\n
"
);
...
...
@@ -86,6 +87,11 @@ int qemu_fsdev_add(QemuOpts *opts)
fsle
->
fse
.
export_flags
|=
V9FS_IMMEDIATE_WRITEOUT
;
}
}
if
(
ro
)
{
fsle
->
fse
.
export_flags
|=
V9FS_RDONLY
;
}
else
{
fsle
->
fse
.
export_flags
&=
~
V9FS_RDONLY
;
}
if
(
strcmp
(
fsdriver
,
"local"
))
{
goto
done
;
...
...
fsdev/qemu-fsdev.h
浏览文件 @
d439b79d
...
...
@@ -53,4 +53,5 @@ int qemu_fsdev_add(QemuOpts *opts);
FsDriverEntry
*
get_fsdev_fsentry
(
char
*
id
);
extern
FileOperations
local_ops
;
extern
FileOperations
handle_ops
;
extern
FileOperations
synth_ops
;
#endif
hw/9pfs/codir.c
浏览文件 @
d439b79d
...
...
@@ -29,7 +29,7 @@ int v9fs_co_readdir_r(V9fsPDU *pdu, V9fsFidState *fidp, struct dirent *dent,
v9fs_co_run_in_worker
(
{
errno
=
0
;
err
=
s
->
ops
->
readdir_r
(
&
s
->
ctx
,
fidp
->
fs
.
dir
,
dent
,
result
);
err
=
s
->
ops
->
readdir_r
(
&
s
->
ctx
,
&
fidp
->
fs
,
dent
,
result
);
if
(
!*
result
&&
errno
)
{
err
=
-
errno
;
}
else
{
...
...
@@ -49,7 +49,7 @@ off_t v9fs_co_telldir(V9fsPDU *pdu, V9fsFidState *fidp)
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
telldir
(
&
s
->
ctx
,
fidp
->
fs
.
dir
);
err
=
s
->
ops
->
telldir
(
&
s
->
ctx
,
&
fidp
->
fs
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
@@ -65,7 +65,7 @@ void v9fs_co_seekdir(V9fsPDU *pdu, V9fsFidState *fidp, off_t offset)
}
v9fs_co_run_in_worker
(
{
s
->
ops
->
seekdir
(
&
s
->
ctx
,
fidp
->
fs
.
dir
,
offset
);
s
->
ops
->
seekdir
(
&
s
->
ctx
,
&
fidp
->
fs
,
offset
);
});
}
...
...
@@ -77,7 +77,7 @@ void v9fs_co_rewinddir(V9fsPDU *pdu, V9fsFidState *fidp)
}
v9fs_co_run_in_worker
(
{
s
->
ops
->
rewinddir
(
&
s
->
ctx
,
fidp
->
fs
.
dir
);
s
->
ops
->
rewinddir
(
&
s
->
ctx
,
&
fidp
->
fs
);
});
}
...
...
@@ -129,8 +129,8 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
fidp
->
fs
.
dir
=
s
->
ops
->
opendir
(
&
s
->
ctx
,
&
fidp
->
path
);
if
(
!
fidp
->
fs
.
dir
)
{
err
=
s
->
ops
->
opendir
(
&
s
->
ctx
,
&
fidp
->
path
,
&
fidp
->
fs
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
else
{
err
=
0
;
...
...
@@ -146,7 +146,7 @@ int v9fs_co_opendir(V9fsPDU *pdu, V9fsFidState *fidp)
return
err
;
}
int
v9fs_co_closedir
(
V9fsPDU
*
pdu
,
DIR
*
dir
)
int
v9fs_co_closedir
(
V9fsPDU
*
pdu
,
V9fsFidOpenState
*
fs
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
...
...
@@ -156,7 +156,7 @@ int v9fs_co_closedir(V9fsPDU *pdu, DIR *dir)
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
closedir
(
&
s
->
ctx
,
dir
);
err
=
s
->
ops
->
closedir
(
&
s
->
ctx
,
fs
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
hw/9pfs/cofile.c
浏览文件 @
d439b79d
...
...
@@ -61,7 +61,7 @@ int v9fs_co_lstat(V9fsPDU *pdu, V9fsPath *path, struct stat *stbuf)
return
err
;
}
int
v9fs_co_fstat
(
V9fsPDU
*
pdu
,
int
fd
,
struct
stat
*
stbuf
)
int
v9fs_co_fstat
(
V9fsPDU
*
pdu
,
V9fsFidState
*
fidp
,
struct
stat
*
stbuf
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
...
...
@@ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, int fd, struct stat *stbuf)
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
fstat
(
&
s
->
ctx
,
fd
,
stbuf
);
err
=
s
->
ops
->
fstat
(
&
s
->
ctx
,
&
fidp
->
fs
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
@@ -90,8 +90,8 @@ int v9fs_co_open(V9fsPDU *pdu, V9fsFidState *fidp, int flags)
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
fidp
->
fs
.
fd
=
s
->
ops
->
open
(
&
s
->
ctx
,
&
fidp
->
path
,
flag
s
);
if
(
fidp
->
fs
.
fd
==
-
1
)
{
err
=
s
->
ops
->
open
(
&
s
->
ctx
,
&
fidp
->
path
,
flags
,
&
fidp
->
f
s
);
if
(
err
==
-
1
)
{
err
=
-
errno
;
}
else
{
err
=
0
;
...
...
@@ -130,9 +130,9 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
fidp
->
fs
.
fd
=
s
->
ops
->
open2
(
&
s
->
ctx
,
&
fidp
->
path
,
name
->
data
,
flags
,
&
cred
);
if
(
fidp
->
fs
.
fd
==
-
1
)
{
err
=
s
->
ops
->
open2
(
&
s
->
ctx
,
&
fidp
->
path
,
name
->
data
,
flags
,
&
cred
,
&
fidp
->
fs
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
else
{
v9fs_path_init
(
&
path
);
...
...
@@ -141,12 +141,12 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
&
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
s
->
ops
->
close
(
&
s
->
ctx
,
fidp
->
fs
.
fd
);
s
->
ops
->
close
(
&
s
->
ctx
,
&
fidp
->
fs
);
}
else
{
v9fs_path_copy
(
&
fidp
->
path
,
&
path
);
}
}
else
{
s
->
ops
->
close
(
&
s
->
ctx
,
fidp
->
fs
.
fd
);
s
->
ops
->
close
(
&
s
->
ctx
,
&
fidp
->
fs
);
}
v9fs_path_free
(
&
path
);
}
...
...
@@ -161,7 +161,7 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, gid_t gid,
return
err
;
}
int
v9fs_co_close
(
V9fsPDU
*
pdu
,
int
fd
)
int
v9fs_co_close
(
V9fsPDU
*
pdu
,
V9fsFidOpenState
*
fs
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
...
...
@@ -171,7 +171,7 @@ int v9fs_co_close(V9fsPDU *pdu, int fd)
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
close
(
&
s
->
ctx
,
f
d
);
err
=
s
->
ops
->
close
(
&
s
->
ctx
,
f
s
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
@@ -184,16 +184,15 @@ int v9fs_co_close(V9fsPDU *pdu, int fd)
int
v9fs_co_fsync
(
V9fsPDU
*
pdu
,
V9fsFidState
*
fidp
,
int
datasync
)
{
int
fd
,
err
;
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
fd
=
fidp
->
fs
.
fd
;
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
fsync
(
&
s
->
ctx
,
fd
,
datasync
);
err
=
s
->
ops
->
fsync
(
&
s
->
ctx
,
&
fidp
->
fs
,
datasync
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
@@ -226,16 +225,15 @@ int v9fs_co_link(V9fsPDU *pdu, V9fsFidState *oldfid,
int
v9fs_co_pwritev
(
V9fsPDU
*
pdu
,
V9fsFidState
*
fidp
,
struct
iovec
*
iov
,
int
iovcnt
,
int64_t
offset
)
{
int
fd
,
err
;
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
fd
=
fidp
->
fs
.
fd
;
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
pwritev
(
&
s
->
ctx
,
fd
,
iov
,
iovcnt
,
offset
);
err
=
s
->
ops
->
pwritev
(
&
s
->
ctx
,
&
fidp
->
fs
,
iov
,
iovcnt
,
offset
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
@@ -246,16 +244,15 @@ int v9fs_co_pwritev(V9fsPDU *pdu, V9fsFidState *fidp,
int
v9fs_co_preadv
(
V9fsPDU
*
pdu
,
V9fsFidState
*
fidp
,
struct
iovec
*
iov
,
int
iovcnt
,
int64_t
offset
)
{
int
fd
,
err
;
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
fd
=
fidp
->
fs
.
fd
;
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
preadv
(
&
s
->
ctx
,
fd
,
iov
,
iovcnt
,
offset
);
err
=
s
->
ops
->
preadv
(
&
s
->
ctx
,
&
fidp
->
fs
,
iov
,
iovcnt
,
offset
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
...
...
hw/9pfs/virtio-9p-coth.h
浏览文件 @
d439b79d
...
...
@@ -80,7 +80,7 @@ extern int v9fs_co_rename(V9fsPDU *, V9fsPath *, V9fsPath *);
extern
int
v9fs_co_unlinkat
(
V9fsPDU
*
,
V9fsPath
*
,
V9fsString
*
,
int
flags
);
extern
int
v9fs_co_renameat
(
V9fsPDU
*
,
V9fsPath
*
,
V9fsString
*
,
V9fsPath
*
,
V9fsString
*
);
extern
int
v9fs_co_fstat
(
V9fsPDU
*
,
int
,
struct
stat
*
);
extern
int
v9fs_co_fstat
(
V9fsPDU
*
,
V9fsFidState
*
,
struct
stat
*
);
extern
int
v9fs_co_opendir
(
V9fsPDU
*
,
V9fsFidState
*
);
extern
int
v9fs_co_open
(
V9fsPDU
*
,
V9fsFidState
*
,
int
);
extern
int
v9fs_co_open2
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsString
*
,
...
...
@@ -88,8 +88,8 @@ extern int v9fs_co_open2(V9fsPDU *, V9fsFidState *, V9fsString *,
extern
int
v9fs_co_lsetxattr
(
V9fsPDU
*
,
V9fsPath
*
,
V9fsString
*
,
void
*
,
size_t
,
int
);
extern
int
v9fs_co_lremovexattr
(
V9fsPDU
*
,
V9fsPath
*
,
V9fsString
*
);
extern
int
v9fs_co_closedir
(
V9fsPDU
*
,
DIR
*
);
extern
int
v9fs_co_close
(
V9fsPDU
*
,
int
);
extern
int
v9fs_co_closedir
(
V9fsPDU
*
,
V9fsFidOpenState
*
);
extern
int
v9fs_co_close
(
V9fsPDU
*
,
V9fsFidOpenState
*
);
extern
int
v9fs_co_fsync
(
V9fsPDU
*
,
V9fsFidState
*
,
int
);
extern
int
v9fs_co_symlink
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsString
*
,
const
char
*
,
gid_t
,
struct
stat
*
);
...
...
hw/9pfs/virtio-9p-handle.c
浏览文件 @
d439b79d
...
...
@@ -133,81 +133,91 @@ static ssize_t handle_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
return
ret
;
}
static
int
handle_close
(
FsContext
*
ctx
,
int
fd
)
static
int
handle_close
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
close
(
fd
);
return
close
(
f
s
->
f
d
);
}
static
int
handle_closedir
(
FsContext
*
ctx
,
DIR
*
dir
)
static
int
handle_closedir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
closedir
(
dir
);
return
closedir
(
fs
->
dir
);
}
static
int
handle_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
int
flags
)
static
int
handle_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
int
flags
,
V9fsFidOpenState
*
fs
)
{
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
return
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
flags
);
fs
->
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
flags
);
return
fs
->
fd
;
}
static
DIR
*
handle_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
)
static
int
handle_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
V9fsFidOpenState
*
fs
)
{
int
fd
;
fd
=
handle_open
(
ctx
,
fs_path
,
O_DIRECTORY
);
if
(
fd
<
0
)
{
return
NULL
;
int
ret
;
ret
=
handle_open
(
ctx
,
fs_path
,
O_DIRECTORY
,
fs
);
if
(
ret
<
0
)
{
return
-
1
;
}
fs
->
dir
=
fdopendir
(
ret
);
if
(
!
fs
->
dir
)
{
return
-
1
;
}
return
fdopendir
(
fd
)
;
return
0
;
}
static
void
handle_rewinddir
(
FsContext
*
ctx
,
DIR
*
dir
)
static
void
handle_rewinddir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
rewinddir
(
dir
);
return
rewinddir
(
fs
->
dir
);
}
static
off_t
handle_telldir
(
FsContext
*
ctx
,
DIR
*
dir
)
static
off_t
handle_telldir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
telldir
(
dir
);
return
telldir
(
fs
->
dir
);
}
static
int
handle_readdir_r
(
FsContext
*
ctx
,
DIR
*
dir
,
struct
dirent
*
entry
,
static
int
handle_readdir_r
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
struct
dirent
*
entry
,
struct
dirent
**
result
)
{
return
readdir_r
(
dir
,
entry
,
result
);
return
readdir_r
(
fs
->
dir
,
entry
,
result
);
}
static
void
handle_seekdir
(
FsContext
*
ctx
,
DIR
*
dir
,
off_t
off
)
static
void
handle_seekdir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
off_t
off
)
{
return
seekdir
(
dir
,
off
);
return
seekdir
(
fs
->
dir
,
off
);
}
static
ssize_t
handle_preadv
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
static
ssize_t
handle_preadv
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
#ifdef CONFIG_PREADV
return
preadv
(
fd
,
iov
,
iovcnt
,
offset
);
return
preadv
(
f
s
->
f
d
,
iov
,
iovcnt
,
offset
);
#else
int
err
=
lseek
(
fd
,
offset
,
SEEK_SET
);
int
err
=
lseek
(
f
s
->
f
d
,
offset
,
SEEK_SET
);
if
(
err
==
-
1
)
{
return
err
;
}
else
{
return
readv
(
fd
,
iov
,
iovcnt
);
return
readv
(
f
s
->
f
d
,
iov
,
iovcnt
);
}
#endif
}
static
ssize_t
handle_pwritev
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
static
ssize_t
handle_pwritev
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
ssize_t
ret
;
#ifdef CONFIG_PREADV
ret
=
pwritev
(
fd
,
iov
,
iovcnt
,
offset
);
ret
=
pwritev
(
f
s
->
f
d
,
iov
,
iovcnt
,
offset
);
#else
int
err
=
lseek
(
fd
,
offset
,
SEEK_SET
);
int
err
=
lseek
(
f
s
->
f
d
,
offset
,
SEEK_SET
);
if
(
err
==
-
1
)
{
return
err
;
}
else
{
ret
=
writev
(
fd
,
iov
,
iovcnt
);
ret
=
writev
(
f
s
->
f
d
,
iov
,
iovcnt
);
}
#endif
#ifdef CONFIG_SYNC_FILE_RANGE
...
...
@@ -217,7 +227,7 @@ static ssize_t handle_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
* We want to ensure that we don't leave dirty pages in the cache
* after write when writeout=immediate is sepcified.
*/
sync_file_range
(
fd
,
offset
,
ret
,
sync_file_range
(
f
s
->
f
d
,
offset
,
ret
,
SYNC_FILE_RANGE_WAIT_BEFORE
|
SYNC_FILE_RANGE_WRITE
);
}
#endif
...
...
@@ -274,13 +284,14 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
return
ret
;
}
static
int
handle_fstat
(
FsContext
*
fs_ctx
,
int
fd
,
struct
stat
*
stbuf
)
static
int
handle_fstat
(
FsContext
*
fs_ctx
,
V9fsFidOpenState
*
fs
,
struct
stat
*
stbuf
)
{
return
fstat
(
fd
,
stbuf
);
return
fstat
(
f
s
->
f
d
,
stbuf
);
}
static
int
handle_open2
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
int
flags
,
FsCred
*
credp
)
int
flags
,
FsCred
*
credp
,
V9fsFidOpenState
*
fs
)
{
int
ret
;
int
dirfd
,
fd
;
...
...
@@ -296,6 +307,8 @@ static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
if
(
ret
<
0
)
{
close
(
fd
);
fd
=
ret
;
}
else
{
fs
->
fd
=
fd
;
}
}
close
(
dirfd
);
...
...
@@ -411,12 +424,12 @@ static int handle_remove(FsContext *ctx, const char *path)
return
-
1
;
}
static
int
handle_fsync
(
FsContext
*
ctx
,
int
fd
,
int
datasync
)
static
int
handle_fsync
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
int
datasync
)
{
if
(
datasync
)
{
return
qemu_fdatasync
(
fd
);
return
qemu_fdatasync
(
f
s
->
f
d
);
}
else
{
return
fsync
(
fd
);
return
fsync
(
f
s
->
f
d
);
}
}
...
...
@@ -575,7 +588,8 @@ static int handle_unlinkat(FsContext *ctx, V9fsPath *dir,
static
int
handle_ioc_getversion
(
FsContext
*
ctx
,
V9fsPath
*
path
,
mode_t
st_mode
,
uint64_t
*
st_gen
)
{
int
err
,
fd
;
int
err
;
V9fsFidOpenState
fid_open
;
/*
* Do not try to open special files like device nodes, fifos etc
...
...
@@ -584,12 +598,12 @@ static int handle_ioc_getversion(FsContext *ctx, V9fsPath *path,
if
(
!
S_ISREG
(
st_mode
)
&&
!
S_ISDIR
(
st_mode
))
{
return
0
;
}
fd
=
handle_open
(
ctx
,
path
,
O_RDONLY
);
if
(
fd
<
0
)
{
return
fd
;
err
=
handle_open
(
ctx
,
path
,
O_RDONLY
,
&
fid_open
);
if
(
err
<
0
)
{
return
err
;
}
err
=
ioctl
(
fd
,
FS_IOC_GETVERSION
,
st_gen
);
handle_close
(
ctx
,
fd
);
err
=
ioctl
(
f
id_open
.
f
d
,
FS_IOC_GETVERSION
,
st_gen
);
handle_close
(
ctx
,
&
fid_open
);
return
err
;
}
...
...
hw/9pfs/virtio-9p-local.c
浏览文件 @
d439b79d
...
...
@@ -156,81 +156,91 @@ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
return
tsize
;
}
static
int
local_close
(
FsContext
*
ctx
,
int
fd
)
static
int
local_close
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
close
(
fd
);
return
close
(
f
s
->
f
d
);
}
static
int
local_closedir
(
FsContext
*
ctx
,
DIR
*
dir
)
static
int
local_closedir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
closedir
(
dir
);
return
closedir
(
fs
->
dir
);
}
static
int
local_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
int
flags
)
static
int
local_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
int
flags
,
V9fsFidOpenState
*
fs
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
return
open
(
rpath
(
ctx
,
path
,
buffer
),
flags
);
fs
->
fd
=
open
(
rpath
(
ctx
,
path
,
buffer
),
flags
);
return
fs
->
fd
;
}
static
DIR
*
local_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
)
static
int
local_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
V9fsFidOpenState
*
fs
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
return
opendir
(
rpath
(
ctx
,
path
,
buffer
));
fs
->
dir
=
opendir
(
rpath
(
ctx
,
path
,
buffer
));
if
(
!
fs
->
dir
)
{
return
-
1
;
}
return
0
;
}
static
void
local_rewinddir
(
FsContext
*
ctx
,
DIR
*
dir
)
static
void
local_rewinddir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
rewinddir
(
dir
);
return
rewinddir
(
fs
->
dir
);
}
static
off_t
local_telldir
(
FsContext
*
ctx
,
DIR
*
dir
)
static
off_t
local_telldir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
return
telldir
(
dir
);
return
telldir
(
fs
->
dir
);
}
static
int
local_readdir_r
(
FsContext
*
ctx
,
DIR
*
dir
,
struct
dirent
*
entry
,
static
int
local_readdir_r
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
struct
dirent
*
entry
,
struct
dirent
**
result
)
{
return
readdir_r
(
dir
,
entry
,
result
);
return
readdir_r
(
fs
->
dir
,
entry
,
result
);
}
static
void
local_seekdir
(
FsContext
*
ctx
,
DIR
*
dir
,
off_t
off
)
static
void
local_seekdir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
off_t
off
)
{
return
seekdir
(
dir
,
off
);
return
seekdir
(
fs
->
dir
,
off
);
}
static
ssize_t
local_preadv
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
static
ssize_t
local_preadv
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
#ifdef CONFIG_PREADV
return
preadv
(
fd
,
iov
,
iovcnt
,
offset
);
return
preadv
(
f
s
->
f
d
,
iov
,
iovcnt
,
offset
);
#else
int
err
=
lseek
(
fd
,
offset
,
SEEK_SET
);
int
err
=
lseek
(
f
s
->
f
d
,
offset
,
SEEK_SET
);
if
(
err
==
-
1
)
{
return
err
;
}
else
{
return
readv
(
fd
,
iov
,
iovcnt
);
return
readv
(
f
s
->
f
d
,
iov
,
iovcnt
);
}
#endif
}
static
ssize_t
local_pwritev
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
static
ssize_t
local_pwritev
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
ssize_t
ret
;
#ifdef CONFIG_PREADV
ret
=
pwritev
(
fd
,
iov
,
iovcnt
,
offset
);
ret
=
pwritev
(
f
s
->
f
d
,
iov
,
iovcnt
,
offset
);
#else
int
err
=
lseek
(
fd
,
offset
,
SEEK_SET
);
int
err
=
lseek
(
f
s
->
f
d
,
offset
,
SEEK_SET
);
if
(
err
==
-
1
)
{
return
err
;
}
else
{
ret
=
writev
(
fd
,
iov
,
iovcnt
);
ret
=
writev
(
f
s
->
f
d
,
iov
,
iovcnt
);
}
#endif
#ifdef CONFIG_SYNC_FILE_RANGE
...
...
@@ -240,7 +250,7 @@ static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
* We want to ensure that we don't leave dirty pages in the cache
* after write when writeout=immediate is sepcified.
*/
sync_file_range
(
fd
,
offset
,
ret
,
sync_file_range
(
f
s
->
f
d
,
offset
,
ret
,
SYNC_FILE_RANGE_WAIT_BEFORE
|
SYNC_FILE_RANGE_WRITE
);
}
#endif
...
...
@@ -281,7 +291,7 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
if
(
err
==
-
1
)
{
goto
out
;
}
local_set_xattr
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
);
err
=
local_set_xattr
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
);
if
(
err
==
-
1
)
{
serrno
=
errno
;
goto
err_end
;
...
...
@@ -356,10 +366,11 @@ out:
return
err
;
}
static
int
local_fstat
(
FsContext
*
fs_ctx
,
int
fd
,
struct
stat
*
stbuf
)
static
int
local_fstat
(
FsContext
*
fs_ctx
,
V9fsFidOpenState
*
fs
,
struct
stat
*
stbuf
)
{
int
err
;
err
=
fstat
(
fd
,
stbuf
);
err
=
fstat
(
f
s
->
f
d
,
stbuf
);
if
(
err
)
{
return
err
;
}
...
...
@@ -370,16 +381,20 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf)
mode_t
tmp_mode
;
dev_t
tmp_dev
;
if
(
fgetxattr
(
fd
,
"user.virtfs.uid"
,
&
tmp_uid
,
sizeof
(
uid_t
))
>
0
)
{
if
(
fgetxattr
(
fs
->
fd
,
"user.virtfs.uid"
,
&
tmp_uid
,
sizeof
(
uid_t
))
>
0
)
{
stbuf
->
st_uid
=
tmp_uid
;
}
if
(
fgetxattr
(
fd
,
"user.virtfs.gid"
,
&
tmp_gid
,
sizeof
(
gid_t
))
>
0
)
{
if
(
fgetxattr
(
fs
->
fd
,
"user.virtfs.gid"
,
&
tmp_gid
,
sizeof
(
gid_t
))
>
0
)
{
stbuf
->
st_gid
=
tmp_gid
;
}
if
(
fgetxattr
(
fd
,
"user.virtfs.mode"
,
&
tmp_mode
,
sizeof
(
mode_t
))
>
0
)
{
if
(
fgetxattr
(
fs
->
fd
,
"user.virtfs.mode"
,
&
tmp_mode
,
sizeof
(
mode_t
))
>
0
)
{
stbuf
->
st_mode
=
tmp_mode
;
}
if
(
fgetxattr
(
fd
,
"user.virtfs.rdev"
,
&
tmp_dev
,
sizeof
(
dev_t
))
>
0
)
{
if
(
fgetxattr
(
fs
->
fd
,
"user.virtfs.rdev"
,
&
tmp_dev
,
sizeof
(
dev_t
))
>
0
)
{
stbuf
->
st_rdev
=
tmp_dev
;
}
}
...
...
@@ -387,7 +402,7 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf)
}
static
int
local_open2
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
int
flags
,
FsCred
*
credp
)
int
flags
,
FsCred
*
credp
,
V9fsFidOpenState
*
fs
)
{
char
*
path
;
int
fd
=
-
1
;
...
...
@@ -428,6 +443,7 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
}
}
err
=
fd
;
fs
->
fd
=
fd
;
goto
out
;
err_end:
...
...
@@ -551,15 +567,12 @@ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
char
*
path
=
fs_path
->
data
;
if
((
credp
->
fc_uid
==
-
1
&&
credp
->
fc_gid
==
-
1
)
||
(
fs_ctx
->
export_flags
&
V9FS_SM_PASSTHROUGH
))
{
return
lchown
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_uid
,
credp
->
fc_gid
);
(
fs_ctx
->
export_flags
&
V9FS_SM_PASSTHROUGH
)
||
(
fs_ctx
->
export_flags
&
V9FS_SM_NONE
))
{
return
lchown
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_uid
,
credp
->
fc_gid
);
}
else
if
(
fs_ctx
->
export_flags
&
V9FS_SM_MAPPED
)
{
return
local_set_xattr
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
);
}
else
if
((
fs_ctx
->
export_flags
&
V9FS_SM_PASSTHROUGH
)
||
(
fs_ctx
->
export_flags
&
V9FS_SM_NONE
))
{
return
lchown
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_uid
,
credp
->
fc_gid
);
}
return
-
1
;
}
...
...
@@ -580,12 +593,12 @@ static int local_remove(FsContext *ctx, const char *path)
return
remove
(
rpath
(
ctx
,
path
,
buffer
));
}
static
int
local_fsync
(
FsContext
*
ctx
,
int
fd
,
int
datasync
)
static
int
local_fsync
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
int
datasync
)
{
if
(
datasync
)
{
return
qemu_fdatasync
(
fd
);
return
qemu_fdatasync
(
f
s
->
f
d
);
}
else
{
return
fsync
(
fd
);
return
fsync
(
f
s
->
f
d
);
}
}
...
...
@@ -680,7 +693,9 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
static
int
local_ioc_getversion
(
FsContext
*
ctx
,
V9fsPath
*
path
,
mode_t
st_mode
,
uint64_t
*
st_gen
)
{
int
err
,
fd
;
int
err
;
V9fsFidOpenState
fid_open
;
/*
* Do not try to open special files like device nodes, fifos etc
* We can get fd for regular files and directories only
...
...
@@ -688,12 +703,12 @@ static int local_ioc_getversion(FsContext *ctx, V9fsPath *path,
if
(
!
S_ISREG
(
st_mode
)
&&
!
S_ISDIR
(
st_mode
))
{
return
0
;
}
fd
=
local_open
(
ctx
,
path
,
O_RDONLY
);
if
(
fd
<
0
)
{
return
fd
;
err
=
local_open
(
ctx
,
path
,
O_RDONLY
,
&
fid_open
);
if
(
err
<
0
)
{
return
err
;
}
err
=
ioctl
(
fd
,
FS_IOC_GETVERSION
,
st_gen
);
local_close
(
ctx
,
fd
);
err
=
ioctl
(
f
id_open
.
f
d
,
FS_IOC_GETVERSION
,
st_gen
);
local_close
(
ctx
,
&
fid_open
);
return
err
;
}
...
...
hw/9pfs/virtio-9p-synth.c
0 → 100644
浏览文件 @
d439b79d
/*
* Virtio 9p synthetic file system support
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Malahal Naineni <malahal@us.ibm.com>
* Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
#include "hw/virtio.h"
#include "virtio-9p.h"
#include "virtio-9p-xattr.h"
#include "fsdev/qemu-fsdev.h"
#include "virtio-9p-synth.h"
#include <sys/stat.h>
/* Root node for synth file system */
V9fsSynthNode
v9fs_synth_root
=
{
.
name
=
"/"
,
.
actual_attr
=
{
.
mode
=
0555
|
S_IFDIR
,
.
nlink
=
1
,
},
.
attr
=
&
v9fs_synth_root
.
actual_attr
,
};
static
QemuMutex
v9fs_synth_mutex
;
static
int
v9fs_synth_node_count
;
/* set to 1 when the synth fs is ready */
static
int
v9fs_synth_fs
;
static
V9fsSynthNode
*
v9fs_add_dir_node
(
V9fsSynthNode
*
parent
,
int
mode
,
const
char
*
name
,
V9fsSynthNodeAttr
*
attr
,
int
inode
)
{
V9fsSynthNode
*
node
;
/* Add directory type and remove write bits */
mode
=
((
mode
&
0777
)
|
S_IFDIR
)
&
~
(
S_IWUSR
|
S_IWGRP
|
S_IWOTH
);
node
=
g_malloc0
(
sizeof
(
V9fsSynthNode
));
if
(
attr
)
{
/* We are adding .. or . entries */
node
->
attr
=
attr
;
node
->
attr
->
nlink
++
;
}
else
{
node
->
attr
=
&
node
->
actual_attr
;
node
->
attr
->
inode
=
inode
;
node
->
attr
->
nlink
=
1
;
/* We don't allow write to directories */
node
->
attr
->
mode
=
mode
;
node
->
attr
->
write
=
NULL
;
node
->
attr
->
read
=
NULL
;
}
node
->
private
=
node
;
strncpy
(
node
->
name
,
name
,
sizeof
(
node
->
name
));
QLIST_INSERT_HEAD_RCU
(
&
parent
->
child
,
node
,
sibling
);
return
node
;
}
int
qemu_v9fs_synth_mkdir
(
V9fsSynthNode
*
parent
,
int
mode
,
const
char
*
name
,
V9fsSynthNode
**
result
)
{
int
ret
;
V9fsSynthNode
*
node
,
*
tmp
;
if
(
!
v9fs_synth_fs
)
{
return
EAGAIN
;
}
if
(
!
name
||
(
strlen
(
name
)
>=
NAME_MAX
))
{
return
EINVAL
;
}
if
(
!
parent
)
{
parent
=
&
v9fs_synth_root
;
}
qemu_mutex_lock
(
&
v9fs_synth_mutex
);
QLIST_FOREACH
(
tmp
,
&
parent
->
child
,
sibling
)
{
if
(
!
strcmp
(
tmp
->
name
,
name
))
{
ret
=
EEXIST
;
goto
err_out
;
}
}
/* Add the name */
node
=
v9fs_add_dir_node
(
parent
,
mode
,
name
,
NULL
,
v9fs_synth_node_count
++
);
v9fs_add_dir_node
(
node
,
parent
->
attr
->
mode
,
".."
,
parent
->
attr
,
parent
->
attr
->
inode
);
v9fs_add_dir_node
(
node
,
node
->
attr
->
mode
,
"."
,
node
->
attr
,
node
->
attr
->
inode
);
*
result
=
node
;
ret
=
0
;
err_out:
qemu_mutex_unlock
(
&
v9fs_synth_mutex
);
return
ret
;
}
int
qemu_v9fs_synth_add_file
(
V9fsSynthNode
*
parent
,
int
mode
,
const
char
*
name
,
v9fs_synth_read
read
,
v9fs_synth_write
write
,
void
*
arg
)
{
int
ret
;
V9fsSynthNode
*
node
,
*
tmp
;
if
(
!
v9fs_synth_fs
)
{
return
EAGAIN
;
}
if
(
!
name
||
(
strlen
(
name
)
>=
NAME_MAX
))
{
return
EINVAL
;
}
if
(
!
parent
)
{
parent
=
&
v9fs_synth_root
;
}
qemu_mutex_lock
(
&
v9fs_synth_mutex
);
QLIST_FOREACH
(
tmp
,
&
parent
->
child
,
sibling
)
{
if
(
!
strcmp
(
tmp
->
name
,
name
))
{
ret
=
EEXIST
;
goto
err_out
;
}
}
/* Add file type and remove write bits */
mode
=
((
mode
&
0777
)
|
S_IFREG
);
node
=
g_malloc0
(
sizeof
(
V9fsSynthNode
));
node
->
attr
=
&
node
->
actual_attr
;
node
->
attr
->
inode
=
v9fs_synth_node_count
++
;
node
->
attr
->
nlink
=
1
;
node
->
attr
->
read
=
read
;
node
->
attr
->
write
=
write
;
node
->
attr
->
mode
=
mode
;
node
->
private
=
arg
;
strncpy
(
node
->
name
,
name
,
sizeof
(
node
->
name
));
QLIST_INSERT_HEAD_RCU
(
&
parent
->
child
,
node
,
sibling
);
ret
=
0
;
err_out:
qemu_mutex_unlock
(
&
v9fs_synth_mutex
);
return
ret
;
}
static
void
v9fs_synth_fill_statbuf
(
V9fsSynthNode
*
node
,
struct
stat
*
stbuf
)
{
stbuf
->
st_dev
=
0
;
stbuf
->
st_ino
=
node
->
attr
->
inode
;
stbuf
->
st_mode
=
node
->
attr
->
mode
;
stbuf
->
st_nlink
=
node
->
attr
->
nlink
;
stbuf
->
st_uid
=
0
;
stbuf
->
st_gid
=
0
;
stbuf
->
st_rdev
=
0
;
stbuf
->
st_size
=
0
;
stbuf
->
st_blksize
=
0
;
stbuf
->
st_blocks
=
0
;
stbuf
->
st_atime
=
0
;
stbuf
->
st_mtime
=
0
;
stbuf
->
st_ctime
=
0
;
}
static
int
v9fs_synth_lstat
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_path
,
struct
stat
*
stbuf
)
{
V9fsSynthNode
*
node
=
*
(
V9fsSynthNode
**
)
fs_path
->
data
;
v9fs_synth_fill_statbuf
(
node
,
stbuf
);
return
0
;
}
static
int
v9fs_synth_fstat
(
FsContext
*
fs_ctx
,
V9fsFidOpenState
*
fs
,
struct
stat
*
stbuf
)
{
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
v9fs_synth_fill_statbuf
(
synth_open
->
node
,
stbuf
);
return
0
;
}
static
int
v9fs_synth_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
V9fsFidOpenState
*
fs
)
{
V9fsSynthOpenState
*
synth_open
;
V9fsSynthNode
*
node
=
*
(
V9fsSynthNode
**
)
fs_path
->
data
;
synth_open
=
g_malloc
(
sizeof
(
*
synth_open
));
synth_open
->
node
=
node
;
node
->
open_count
++
;
fs
->
private
=
synth_open
;
return
0
;
}
static
int
v9fs_synth_closedir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
V9fsSynthNode
*
node
=
synth_open
->
node
;
node
->
open_count
--
;
g_free
(
synth_open
);
fs
->
private
=
NULL
;
return
0
;
}
static
off_t
v9fs_synth_telldir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
return
synth_open
->
offset
;
}
static
void
v9fs_synth_seekdir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
off_t
off
)
{
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
synth_open
->
offset
=
off
;
}
static
void
v9fs_synth_rewinddir
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
v9fs_synth_seekdir
(
ctx
,
fs
,
0
);
}
static
void
v9fs_synth_direntry
(
V9fsSynthNode
*
node
,
struct
dirent
*
entry
,
off_t
off
)
{
strcpy
(
entry
->
d_name
,
node
->
name
);
entry
->
d_ino
=
node
->
attr
->
inode
;
entry
->
d_off
=
off
+
1
;
}
static
int
v9fs_synth_get_dentry
(
V9fsSynthNode
*
dir
,
struct
dirent
*
entry
,
struct
dirent
**
result
,
off_t
off
)
{
int
i
=
0
;
V9fsSynthNode
*
node
;
rcu_read_lock
();
QLIST_FOREACH
(
node
,
&
dir
->
child
,
sibling
)
{
/* This is the off child of the directory */
if
(
i
==
off
)
{
break
;
}
i
++
;
}
rcu_read_unlock
();
if
(
!
node
)
{
/* end of directory */
*
result
=
NULL
;
return
0
;
}
v9fs_synth_direntry
(
node
,
entry
,
off
);
*
result
=
entry
;
return
0
;
}
static
int
v9fs_synth_readdir_r
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
struct
dirent
*
entry
,
struct
dirent
**
result
)
{
int
ret
;
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
V9fsSynthNode
*
node
=
synth_open
->
node
;
ret
=
v9fs_synth_get_dentry
(
node
,
entry
,
result
,
synth_open
->
offset
);
if
(
!
ret
&&
*
result
!=
NULL
)
{
synth_open
->
offset
++
;
}
return
ret
;
}
static
int
v9fs_synth_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
int
flags
,
V9fsFidOpenState
*
fs
)
{
V9fsSynthOpenState
*
synth_open
;
V9fsSynthNode
*
node
=
*
(
V9fsSynthNode
**
)
fs_path
->
data
;
synth_open
=
g_malloc
(
sizeof
(
*
synth_open
));
synth_open
->
node
=
node
;
node
->
open_count
++
;
fs
->
private
=
synth_open
;
return
0
;
}
static
int
v9fs_synth_open2
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
int
flags
,
FsCred
*
credp
,
V9fsFidOpenState
*
fs
)
{
errno
=
ENOSYS
;
return
-
1
;
}
static
int
v9fs_synth_close
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
)
{
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
V9fsSynthNode
*
node
=
synth_open
->
node
;
node
->
open_count
--
;
g_free
(
synth_open
);
fs
->
private
=
NULL
;
return
0
;
}
static
ssize_t
v9fs_synth_pwritev
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
int
i
,
count
=
0
,
wcount
;
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
V9fsSynthNode
*
node
=
synth_open
->
node
;
if
(
!
node
->
attr
->
write
)
{
errno
=
EPERM
;
return
-
1
;
}
for
(
i
=
0
;
i
<
iovcnt
;
i
++
)
{
wcount
=
node
->
attr
->
write
(
iov
[
i
].
iov_base
,
iov
[
i
].
iov_len
,
offset
,
node
->
private
);
offset
+=
wcount
;
count
+=
wcount
;
/* If we wrote less than requested. we are done */
if
(
wcount
<
iov
[
i
].
iov_len
)
{
break
;
}
}
return
count
;
}
static
ssize_t
v9fs_synth_preadv
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
int
i
,
count
=
0
,
rcount
;
V9fsSynthOpenState
*
synth_open
=
fs
->
private
;
V9fsSynthNode
*
node
=
synth_open
->
node
;
if
(
!
node
->
attr
->
read
)
{
errno
=
EPERM
;
return
-
1
;
}
for
(
i
=
0
;
i
<
iovcnt
;
i
++
)
{
rcount
=
node
->
attr
->
read
(
iov
[
i
].
iov_base
,
iov
[
i
].
iov_len
,
offset
,
node
->
private
);
offset
+=
rcount
;
count
+=
rcount
;
/* If we read less than requested. we are done */
if
(
rcount
<
iov
[
i
].
iov_len
)
{
break
;
}
}
return
count
;
}
static
int
v9fs_synth_truncate
(
FsContext
*
ctx
,
V9fsPath
*
path
,
off_t
offset
)
{
errno
=
ENOSYS
;
return
-
1
;
}
static
int
v9fs_synth_chmod
(
FsContext
*
fs_ctx
,
V9fsPath
*
path
,
FsCred
*
credp
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_mknod
(
FsContext
*
fs_ctx
,
V9fsPath
*
path
,
const
char
*
buf
,
FsCred
*
credp
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_mkdir
(
FsContext
*
fs_ctx
,
V9fsPath
*
path
,
const
char
*
buf
,
FsCred
*
credp
)
{
errno
=
EPERM
;
return
-
1
;
}
static
ssize_t
v9fs_synth_readlink
(
FsContext
*
fs_ctx
,
V9fsPath
*
path
,
char
*
buf
,
size_t
bufsz
)
{
errno
=
ENOSYS
;
return
-
1
;
}
static
int
v9fs_synth_symlink
(
FsContext
*
fs_ctx
,
const
char
*
oldpath
,
V9fsPath
*
newpath
,
const
char
*
buf
,
FsCred
*
credp
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_link
(
FsContext
*
fs_ctx
,
V9fsPath
*
oldpath
,
V9fsPath
*
newpath
,
const
char
*
buf
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_rename
(
FsContext
*
ctx
,
const
char
*
oldpath
,
const
char
*
newpath
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_chown
(
FsContext
*
fs_ctx
,
V9fsPath
*
path
,
FsCred
*
credp
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_utimensat
(
FsContext
*
fs_ctx
,
V9fsPath
*
path
,
const
struct
timespec
*
buf
)
{
errno
=
EPERM
;
return
0
;
}
static
int
v9fs_synth_remove
(
FsContext
*
ctx
,
const
char
*
path
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_fsync
(
FsContext
*
ctx
,
V9fsFidOpenState
*
fs
,
int
datasync
)
{
errno
=
ENOSYS
;
return
0
;
}
static
int
v9fs_synth_statfs
(
FsContext
*
s
,
V9fsPath
*
fs_path
,
struct
statfs
*
stbuf
)
{
stbuf
->
f_type
=
0xABCD
;
stbuf
->
f_bsize
=
512
;
stbuf
->
f_blocks
=
0
;
stbuf
->
f_files
=
v9fs_synth_node_count
;
stbuf
->
f_namelen
=
NAME_MAX
;
return
0
;
}
static
ssize_t
v9fs_synth_lgetxattr
(
FsContext
*
ctx
,
V9fsPath
*
path
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
errno
=
ENOTSUP
;
return
-
1
;
}
static
ssize_t
v9fs_synth_llistxattr
(
FsContext
*
ctx
,
V9fsPath
*
path
,
void
*
value
,
size_t
size
)
{
errno
=
ENOTSUP
;
return
-
1
;
}
static
int
v9fs_synth_lsetxattr
(
FsContext
*
ctx
,
V9fsPath
*
path
,
const
char
*
name
,
void
*
value
,
size_t
size
,
int
flags
)
{
errno
=
ENOTSUP
;
return
-
1
;
}
static
int
v9fs_synth_lremovexattr
(
FsContext
*
ctx
,
V9fsPath
*
path
,
const
char
*
name
)
{
errno
=
ENOTSUP
;
return
-
1
;
}
static
int
v9fs_synth_name_to_path
(
FsContext
*
ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
V9fsPath
*
target
)
{
V9fsSynthNode
*
node
;
V9fsSynthNode
*
dir_node
;
/* "." and ".." are not allowed */
if
(
!
strcmp
(
name
,
"."
)
||
!
strcmp
(
name
,
".."
))
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
!
dir_path
)
{
dir_node
=
&
v9fs_synth_root
;
}
else
{
dir_node
=
*
(
V9fsSynthNode
**
)
dir_path
->
data
;
}
if
(
!
strcmp
(
name
,
"/"
))
{
node
=
dir_node
;
goto
out
;
}
/* search for the name in the childern */
rcu_read_lock
();
QLIST_FOREACH
(
node
,
&
dir_node
->
child
,
sibling
)
{
if
(
!
strcmp
(
node
->
name
,
name
))
{
break
;
}
}
rcu_read_unlock
();
if
(
!
node
)
{
errno
=
ENOENT
;
return
-
1
;
}
out:
/* Copy the node pointer to fid */
target
->
data
=
g_malloc
(
sizeof
(
void
*
));
memcpy
(
target
->
data
,
&
node
,
sizeof
(
void
*
));
target
->
size
=
sizeof
(
void
*
);
return
0
;
}
static
int
v9fs_synth_renameat
(
FsContext
*
ctx
,
V9fsPath
*
olddir
,
const
char
*
old_name
,
V9fsPath
*
newdir
,
const
char
*
new_name
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_unlinkat
(
FsContext
*
ctx
,
V9fsPath
*
dir
,
const
char
*
name
,
int
flags
)
{
errno
=
EPERM
;
return
-
1
;
}
static
int
v9fs_synth_init
(
FsContext
*
ctx
)
{
QLIST_INIT
(
&
v9fs_synth_root
.
child
);
qemu_mutex_init
(
&
v9fs_synth_mutex
);
/* Add "." and ".." entries for root */
v9fs_add_dir_node
(
&
v9fs_synth_root
,
v9fs_synth_root
.
attr
->
mode
,
".."
,
v9fs_synth_root
.
attr
,
v9fs_synth_root
.
attr
->
inode
);
v9fs_add_dir_node
(
&
v9fs_synth_root
,
v9fs_synth_root
.
attr
->
mode
,
"."
,
v9fs_synth_root
.
attr
,
v9fs_synth_root
.
attr
->
inode
);
/* Mark the subsystem is ready for use */
v9fs_synth_fs
=
1
;
return
0
;
}
FileOperations
synth_ops
=
{
.
init
=
v9fs_synth_init
,
.
lstat
=
v9fs_synth_lstat
,
.
readlink
=
v9fs_synth_readlink
,
.
close
=
v9fs_synth_close
,
.
closedir
=
v9fs_synth_closedir
,
.
open
=
v9fs_synth_open
,
.
opendir
=
v9fs_synth_opendir
,
.
rewinddir
=
v9fs_synth_rewinddir
,
.
telldir
=
v9fs_synth_telldir
,
.
readdir_r
=
v9fs_synth_readdir_r
,
.
seekdir
=
v9fs_synth_seekdir
,
.
preadv
=
v9fs_synth_preadv
,
.
pwritev
=
v9fs_synth_pwritev
,
.
chmod
=
v9fs_synth_chmod
,
.
mknod
=
v9fs_synth_mknod
,
.
mkdir
=
v9fs_synth_mkdir
,
.
fstat
=
v9fs_synth_fstat
,
.
open2
=
v9fs_synth_open2
,
.
symlink
=
v9fs_synth_symlink
,
.
link
=
v9fs_synth_link
,
.
truncate
=
v9fs_synth_truncate
,
.
rename
=
v9fs_synth_rename
,
.
chown
=
v9fs_synth_chown
,
.
utimensat
=
v9fs_synth_utimensat
,
.
remove
=
v9fs_synth_remove
,
.
fsync
=
v9fs_synth_fsync
,
.
statfs
=
v9fs_synth_statfs
,
.
lgetxattr
=
v9fs_synth_lgetxattr
,
.
llistxattr
=
v9fs_synth_llistxattr
,
.
lsetxattr
=
v9fs_synth_lsetxattr
,
.
lremovexattr
=
v9fs_synth_lremovexattr
,
.
name_to_path
=
v9fs_synth_name_to_path
,
.
renameat
=
v9fs_synth_renameat
,
.
unlinkat
=
v9fs_synth_unlinkat
,
};
hw/9pfs/virtio-9p-synth.h
0 → 100644
浏览文件 @
d439b79d
/*
* Virtio 9p
*
* Copyright IBM, Corp. 2011
*
* Authors:
* Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*
*/
#include <unistd.h>
#include <sys/types.h>
#include <limits.h>
typedef
struct
V9fsSynthNode
V9fsSynthNode
;
typedef
ssize_t
(
*
v9fs_synth_read
)(
void
*
buf
,
int
len
,
off_t
offset
,
void
*
arg
);
typedef
ssize_t
(
*
v9fs_synth_write
)(
void
*
buf
,
int
len
,
off_t
offset
,
void
*
arg
);
typedef
struct
V9fsSynthNodeAttr
{
int
mode
;
int
inode
;
int
nlink
;
v9fs_synth_read
read
;
v9fs_synth_write
write
;
}
V9fsSynthNodeAttr
;
struct
V9fsSynthNode
{
QLIST_HEAD
(,
V9fsSynthNode
)
child
;
QLIST_ENTRY
(
V9fsSynthNode
)
sibling
;
char
name
[
NAME_MAX
];
V9fsSynthNodeAttr
*
attr
;
V9fsSynthNodeAttr
actual_attr
;
void
*
private
;
int
open_count
;
};
typedef
struct
V9fsSynthOpenState
{
off_t
offset
;
V9fsSynthNode
*
node
;
}
V9fsSynthOpenState
;
extern
int
qemu_v9fs_synth_mkdir
(
V9fsSynthNode
*
parent
,
int
mode
,
const
char
*
name
,
V9fsSynthNode
**
result
);
extern
int
qemu_v9fs_synth_add_file
(
V9fsSynthNode
*
parent
,
int
mode
,
const
char
*
name
,
v9fs_synth_read
read
,
v9fs_synth_write
write
,
void
*
arg
);
hw/9pfs/virtio-9p.c
浏览文件 @
d439b79d
...
...
@@ -455,11 +455,11 @@ static int free_fid(V9fsPDU *pdu, V9fsFidState *fidp)
if
(
fidp
->
fid_type
==
P9_FID_FILE
)
{
/* If we reclaimed the fd no need to close */
if
(
fidp
->
fs
.
fd
!=
-
1
)
{
retval
=
v9fs_co_close
(
pdu
,
fidp
->
fs
.
fd
);
retval
=
v9fs_co_close
(
pdu
,
&
fidp
->
fs
);
}
}
else
if
(
fidp
->
fid_type
==
P9_FID_DIR
)
{
if
(
fidp
->
fs
.
dir
!=
NULL
)
{
retval
=
v9fs_co_closedir
(
pdu
,
fidp
->
fs
.
dir
);
retval
=
v9fs_co_closedir
(
pdu
,
&
fidp
->
fs
);
}
}
else
if
(
fidp
->
fid_type
==
P9_FID_XATTR
)
{
retval
=
v9fs_xattr_fid_clunk
(
pdu
,
fidp
);
...
...
@@ -567,9 +567,9 @@ void v9fs_reclaim_fd(V9fsPDU *pdu)
f
=
reclaim_list
;
reclaim_list
=
f
->
rclm_lst
;
if
(
f
->
fid_type
==
P9_FID_FILE
)
{
v9fs_co_close
(
pdu
,
f
->
fs_reclaim
.
fd
);
v9fs_co_close
(
pdu
,
&
f
->
fs_reclaim
);
}
else
if
(
f
->
fid_type
==
P9_FID_DIR
)
{
v9fs_co_closedir
(
pdu
,
f
->
fs_reclaim
.
dir
);
v9fs_co_closedir
(
pdu
,
&
f
->
fs_reclaim
);
}
f
->
rclm_lst
=
NULL
;
/*
...
...
@@ -1271,6 +1271,11 @@ static void v9fs_fix_path(V9fsPath *dst, V9fsPath *src, int len)
dst
->
size
++
;
}
static
inline
bool
is_ro_export
(
FsContext
*
ctx
)
{
return
ctx
->
export_flags
&
V9FS_RDONLY
;
}
static
void
v9fs_version
(
void
*
opaque
)
{
V9fsPDU
*
pdu
=
opaque
;
...
...
@@ -1690,6 +1695,14 @@ static void v9fs_open(void *opaque)
}
else
{
flags
=
omode_to_uflags
(
mode
);
}
if
(
is_ro_export
(
&
s
->
ctx
))
{
if
(
mode
&
O_WRONLY
||
mode
&
O_RDWR
||
mode
&
O_APPEND
||
mode
&
O_TRUNC
)
{
err
=
-
EROFS
;
goto
out
;
}
flags
|=
O_NOATIME
;
}
err
=
v9fs_co_open
(
pdu
,
fidp
,
flags
);
if
(
err
<
0
)
{
goto
out
;
...
...
@@ -2996,7 +3009,7 @@ static void v9fs_lock(void *opaque)
err
=
-
ENOENT
;
goto
out_nofid
;
}
err
=
v9fs_co_fstat
(
pdu
,
fidp
->
fs
.
fd
,
&
stbuf
);
err
=
v9fs_co_fstat
(
pdu
,
fidp
,
&
stbuf
);
if
(
err
<
0
)
{
goto
out
;
}
...
...
@@ -3039,7 +3052,7 @@ static void v9fs_getlock(void *opaque)
err
=
-
ENOENT
;
goto
out_nofid
;
}
err
=
v9fs_co_fstat
(
pdu
,
fidp
->
fs
.
fd
,
&
stbuf
);
err
=
v9fs_co_fstat
(
pdu
,
fidp
,
&
stbuf
);
if
(
err
<
0
)
{
goto
out
;
}
...
...
@@ -3309,6 +3322,39 @@ static void v9fs_op_not_supp(void *opaque)
complete_pdu
(
pdu
->
s
,
pdu
,
-
EOPNOTSUPP
);
}
static
void
v9fs_fs_ro
(
void
*
opaque
)
{
V9fsPDU
*
pdu
=
opaque
;
complete_pdu
(
pdu
->
s
,
pdu
,
-
EROFS
);
}
static
inline
bool
is_read_only_op
(
V9fsPDU
*
pdu
)
{
switch
(
pdu
->
id
)
{
case
P9_TREADDIR
:
case
P9_TSTATFS
:
case
P9_TGETATTR
:
case
P9_TXATTRWALK
:
case
P9_TLOCK
:
case
P9_TGETLOCK
:
case
P9_TREADLINK
:
case
P9_TVERSION
:
case
P9_TLOPEN
:
case
P9_TATTACH
:
case
P9_TSTAT
:
case
P9_TWALK
:
case
P9_TCLUNK
:
case
P9_TFSYNC
:
case
P9_TOPEN
:
case
P9_TREAD
:
case
P9_TAUTH
:
case
P9_TFLUSH
:
return
1
;
default:
return
0
;
}
}
static
void
submit_pdu
(
V9fsState
*
s
,
V9fsPDU
*
pdu
)
{
Coroutine
*
co
;
...
...
@@ -3320,6 +3366,10 @@ static void submit_pdu(V9fsState *s, V9fsPDU *pdu)
}
else
{
handler
=
pdu_co_handlers
[
pdu
->
id
];
}
if
(
is_ro_export
(
&
s
->
ctx
)
&&
!
is_read_only_op
(
pdu
))
{
handler
=
v9fs_fs_ro
;
}
co
=
qemu_coroutine_create
(
handler
);
qemu_coroutine_enter
(
co
,
pdu
);
}
...
...
hw/9pfs/virtio-9p.h
浏览文件 @
d439b79d
...
...
@@ -204,20 +204,29 @@ typedef struct V9fsXattr
int
flags
;
}
V9fsXattr
;
/*
* Filled by fs driver on open and other
* calls.
*/
union
V9fsFidOpenState
{
int
fd
;
DIR
*
dir
;
V9fsXattr
xattr
;
/*
* private pointer for fs drivers, that
* have its own internal representation of
* open files.
*/
void
*
private
;
};
struct
V9fsFidState
{
int
fid_type
;
int32_t
fid
;
V9fsPath
path
;
union
{
int
fd
;
DIR
*
dir
;
V9fsXattr
xattr
;
}
fs
;
union
{
int
fd
;
DIR
*
dir
;
}
fs_reclaim
;
V9fsFidOpenState
fs
;
V9fsFidOpenState
fs_reclaim
;
int
flags
;
int
open_flags
;
uid_t
uid
;
...
...
qemu-config.c
浏览文件 @
d439b79d
...
...
@@ -180,7 +180,11 @@ QemuOptsList qemu_fsdev_opts = {
},
{
.
name
=
"writeout"
,
.
type
=
QEMU_OPT_STRING
,
},
{
.
name
=
"readonly"
,
.
type
=
QEMU_OPT_BOOL
,
},
{
/*End of list */
}
},
};
...
...
@@ -205,6 +209,9 @@ QemuOptsList qemu_virtfs_opts = {
},
{
.
name
=
"writeout"
,
.
type
=
QEMU_OPT_STRING
,
},
{
.
name
=
"readonly"
,
.
type
=
QEMU_OPT_BOOL
,
},
{
/*End of list */
}
...
...
qemu-option.c
浏览文件 @
d439b79d
...
...
@@ -168,7 +168,7 @@ QEMUOptionParameter *get_option_parameter(QEMUOptionParameter *list,
return
NULL
;
}
static
int
parse_option_bool
(
const
char
*
name
,
const
char
*
value
,
int
*
ret
)
static
int
parse_option_bool
(
const
char
*
name
,
const
char
*
value
,
bool
*
ret
)
{
if
(
value
!=
NULL
)
{
if
(
!
strcmp
(
value
,
"on"
))
{
...
...
@@ -258,7 +258,7 @@ static int parse_option_size(const char *name, const char *value, uint64_t *ret)
int
set_option_parameter
(
QEMUOptionParameter
*
list
,
const
char
*
name
,
const
char
*
value
)
{
int
flag
;
bool
flag
;
// Find a matching parameter
list
=
get_option_parameter
(
list
,
name
);
...
...
@@ -508,7 +508,7 @@ struct QemuOpt {
const
QemuOptDesc
*
desc
;
union
{
int
boolean
;
bool
boolean
;
uint64_t
uint
;
}
value
;
...
...
@@ -542,7 +542,7 @@ const char *qemu_opt_get(QemuOpts *opts, const char *name)
return
opt
?
opt
->
str
:
NULL
;
}
int
qemu_opt_get_bool
(
QemuOpts
*
opts
,
const
char
*
name
,
int
defval
)
bool
qemu_opt_get_bool
(
QemuOpts
*
opts
,
const
char
*
name
,
bool
defval
)
{
QemuOpt
*
opt
=
qemu_opt_find
(
opts
,
name
);
...
...
@@ -636,6 +636,37 @@ int qemu_opt_set(QemuOpts *opts, const char *name, const char *value)
return
0
;
}
int
qemu_opt_set_bool
(
QemuOpts
*
opts
,
const
char
*
name
,
bool
val
)
{
QemuOpt
*
opt
;
const
QemuOptDesc
*
desc
=
opts
->
list
->
desc
;
int
i
;
for
(
i
=
0
;
desc
[
i
].
name
!=
NULL
;
i
++
)
{
if
(
strcmp
(
desc
[
i
].
name
,
name
)
==
0
)
{
break
;
}
}
if
(
desc
[
i
].
name
==
NULL
)
{
if
(
i
==
0
)
{
/* empty list -> allow any */
;
}
else
{
qerror_report
(
QERR_INVALID_PARAMETER
,
name
);
return
-
1
;
}
}
opt
=
g_malloc0
(
sizeof
(
*
opt
));
opt
->
name
=
g_strdup
(
name
);
opt
->
opts
=
opts
;
QTAILQ_INSERT_TAIL
(
&
opts
->
head
,
opt
,
next
);
if
(
desc
[
i
].
name
!=
NULL
)
{
opt
->
desc
=
desc
+
i
;
}
opt
->
value
.
boolean
=
!!
val
;
return
0
;
}
int
qemu_opt_foreach
(
QemuOpts
*
opts
,
qemu_opt_loopfunc
func
,
void
*
opaque
,
int
abort_on_failure
)
{
...
...
qemu-option.h
浏览文件 @
d439b79d
...
...
@@ -105,10 +105,11 @@ struct QemuOptsList {
};
const
char
*
qemu_opt_get
(
QemuOpts
*
opts
,
const
char
*
name
);
int
qemu_opt_get_bool
(
QemuOpts
*
opts
,
const
char
*
name
,
int
defval
);
bool
qemu_opt_get_bool
(
QemuOpts
*
opts
,
const
char
*
name
,
bool
defval
);
uint64_t
qemu_opt_get_number
(
QemuOpts
*
opts
,
const
char
*
name
,
uint64_t
defval
);
uint64_t
qemu_opt_get_size
(
QemuOpts
*
opts
,
const
char
*
name
,
uint64_t
defval
);
int
qemu_opt_set
(
QemuOpts
*
opts
,
const
char
*
name
,
const
char
*
value
);
int
qemu_opt_set_bool
(
QemuOpts
*
opts
,
const
char
*
name
,
bool
val
);
typedef
int
(
*
qemu_opt_loopfunc
)(
const
char
*
name
,
const
char
*
value
,
void
*
opaque
);
int
qemu_opt_foreach
(
QemuOpts
*
opts
,
qemu_opt_loopfunc
func
,
void
*
opaque
,
int
abort_on_failure
);
...
...
qemu-options.hx
浏览文件 @
d439b79d
...
...
@@ -528,12 +528,12 @@ DEFHEADING(File system options:)
DEF("fsdev", HAS_ARG, QEMU_OPTION_fsdev,
"-fsdev fsdriver,id=id,path=path,[security_model={mapped|passthrough|none}]\n"
" [,writeout=immediate]\n",
" [,writeout=immediate]
[,readonly]
\n",
QEMU_ARCH_ALL)
STEXI
@item -fsdev @var{fsdriver},id=@var{id},path=@var{path},[security_model=@var{security_model}][,writeout=@var{writeout}]
@item -fsdev @var{fsdriver},id=@var{id},path=@var{path},[security_model=@var{security_model}][,writeout=@var{writeout}]
[,readonly]
@findex -fsdev
Define a new file system device. Valid options are:
@table @option
...
...
@@ -563,6 +563,9 @@ This is an optional argument. The only supported value is "immediate".
This means that host page cache will be used to read and write data but
write notification will be sent to the guest only when the data has been
reported as written by the storage subsystem.
@item readonly
Enables exporting 9p share as a readonly mount for guests. By default
read-write access is given.
@end table
-fsdev option is used along with -device driver "virtio-9p-pci".
...
...
@@ -583,12 +586,12 @@ DEFHEADING(Virtual File system pass-through options:)
DEF("virtfs", HAS_ARG, QEMU_OPTION_virtfs,
"-virtfs local,path=path,mount_tag=tag,security_model=[mapped|passthrough|none]\n"
" [,writeout=immediate]\n",
" [,writeout=immediate]
[,readonly]
\n",
QEMU_ARCH_ALL)
STEXI
@item -virtfs @var{fsdriver},path=@var{path},mount_tag=@var{mount_tag},security_model=@var{security_model}[,writeout=@var{writeout}]
@item -virtfs @var{fsdriver},path=@var{path},mount_tag=@var{mount_tag},security_model=@var{security_model}[,writeout=@var{writeout}]
[,readonly]
@findex -virtfs
The general form of a Virtual File system pass-through options are:
...
...
@@ -619,9 +622,21 @@ This is an optional argument. The only supported value is "immediate".
This means that host page cache will be used to read and write data but
write notification will be sent to the guest only when the data has been
reported as written by the storage subsystem.
@item readonly
Enables exporting 9p share as a readonly mount for guests. By default
read-write access is given.
@end table
ETEXI
DEF("virtfs_synth", 0, QEMU_OPTION_virtfs_synth,
"-virtfs_synth Create synthetic file system image\n",
QEMU_ARCH_ALL)
STEXI
@item -virtfs_synth
@findex -virtfs_synth
Create synthetic file system image
ETEXI
DEFHEADING()
DEF("name", HAS_ARG, QEMU_OPTION_name,
...
...
qemu-queue.h
浏览文件 @
d439b79d
...
...
@@ -76,6 +76,8 @@
* For details on the use of these macros, see the queue(3) manual page.
*/
#include "qemu-barrier.h"
/* for smp_wmb() */
/*
* List definitions.
*/
...
...
@@ -122,6 +124,17 @@ struct { \
(elm)->field.le_prev = &(head)->lh_first; \
} while (
/*CONSTCOND*/
0)
#define QLIST_INSERT_HEAD_RCU(head, elm, field) do { \
(elm)->field.le_prev = &(head)->lh_first; \
(elm)->field.le_next = (head)->lh_first; \
smp_wmb();
/* fill elm before linking it */
\
if ((head)->lh_first != NULL) { \
(head)->lh_first->field.le_prev = &(elm)->field.le_next; \
} \
(head)->lh_first = (elm); \
smp_wmb(); \
} while (
/* CONSTCOND*/
0)
#define QLIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
...
...
qemu-thread.h
浏览文件 @
d439b79d
...
...
@@ -19,6 +19,9 @@ void qemu_mutex_lock(QemuMutex *mutex);
int
qemu_mutex_trylock
(
QemuMutex
*
mutex
);
void
qemu_mutex_unlock
(
QemuMutex
*
mutex
);
#define rcu_read_lock() do { } while (0)
#define rcu_read_unlock() do { } while (0)
void
qemu_cond_init
(
QemuCond
*
cond
);
void
qemu_cond_destroy
(
QemuCond
*
cond
);
...
...
vl.c
浏览文件 @
d439b79d
...
...
@@ -2707,6 +2707,8 @@ int main(int argc, char **argv, char **envp)
qemu_opt_set
(
fsdev
,
"security_model"
,
qemu_opt_get
(
opts
,
"security_model"
));
qemu_opt_set_bool
(
fsdev
,
"readonly"
,
qemu_opt_get_bool
(
opts
,
"readonly"
,
0
));
device
=
qemu_opts_create
(
qemu_find_opts
(
"device"
),
NULL
,
0
);
qemu_opt_set
(
device
,
"driver"
,
"virtio-9p-pci"
);
qemu_opt_set
(
device
,
"fsdev"
,
...
...
@@ -2715,6 +2717,24 @@ int main(int argc, char **argv, char **envp)
qemu_opt_get
(
opts
,
"mount_tag"
));
break
;
}
case
QEMU_OPTION_virtfs_synth
:
{
QemuOpts
*
fsdev
;
QemuOpts
*
device
;
fsdev
=
qemu_opts_create
(
qemu_find_opts
(
"fsdev"
),
"v_synth"
,
1
);
if
(
!
fsdev
)
{
fprintf
(
stderr
,
"duplicate option: %s
\n
"
,
"virtfs_synth"
);
exit
(
1
);
}
qemu_opt_set
(
fsdev
,
"fsdriver"
,
"synth"
);
qemu_opt_set
(
fsdev
,
"path"
,
"/"
);
/* ignored */
device
=
qemu_opts_create
(
qemu_find_opts
(
"device"
),
NULL
,
0
);
qemu_opt_set
(
device
,
"driver"
,
"virtio-9p-pci"
);
qemu_opt_set
(
device
,
"fsdev"
,
"v_synth"
);
qemu_opt_set
(
device
,
"mount_tag"
,
"v_synth"
);
break
;
}
case
QEMU_OPTION_serial
:
add_device_config
(
DEV_SERIAL
,
optarg
);
default_serial
=
0
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录