Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
qemu
提交
62ec6073
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,发现更多精彩内容 >>
提交
62ec6073
编写于
9月 29, 2011
作者:
A
Anthony Liguori
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'aneesh/for-upstream-5' into staging
上级
0bce98df
5f542225
变更
14
展开全部
隐藏空白更改
内联
并排
Showing
14 changed file
with
1712 addition
and
538 deletion
+1712
-538
Makefile.objs
Makefile.objs
+4
-4
fsdev/file-op-9p.h
fsdev/file-op-9p.h
+36
-18
fsdev/qemu-fsdev.c
fsdev/qemu-fsdev.c
+1
-0
fsdev/qemu-fsdev.h
fsdev/qemu-fsdev.h
+1
-0
hw/9pfs/codir.c
hw/9pfs/codir.c
+54
-10
hw/9pfs/cofile.c
hw/9pfs/cofile.c
+87
-23
hw/9pfs/cofs.c
hw/9pfs/cofs.c
+174
-21
hw/9pfs/coxattr.c
hw/9pfs/coxattr.c
+32
-9
hw/9pfs/virtio-9p-coth.h
hw/9pfs/virtio-9p-coth.h
+40
-32
hw/9pfs/virtio-9p-device.c
hw/9pfs/virtio-9p-device.c
+9
-1
hw/9pfs/virtio-9p-handle.c
hw/9pfs/virtio-9p-handle.c
+611
-0
hw/9pfs/virtio-9p-local.c
hw/9pfs/virtio-9p-local.c
+172
-41
hw/9pfs/virtio-9p.c
hw/9pfs/virtio-9p.c
+443
-377
hw/9pfs/virtio-9p.h
hw/9pfs/virtio-9p.h
+48
-2
未找到文件。
Makefile.objs
浏览文件 @
62ec6073
...
...
@@ -304,11 +304,11 @@ sound-obj-$(CONFIG_HDA) += intel-hda.o hda-audio.o
adlib.o fmopl.o
:
QEMU_CFLAGS += -DBUILD_Y8950=0
hw-obj-$(CONFIG_SOUND)
+=
$
(
sound-obj-y
)
9pfs-nested-$(CONFIG_VIRTFS)
=
virtio-9p.o virtio-9p-debug.o
9pfs-nested-$(CONFIG_VIRTFS)
+=
virtio-9p-local.o virtio-9p-xattr.o
9pfs-nested-$(CONFIG_VIRTFS)
+=
virtio-9p-xattr-user.o virtio-9p-posix-acl.o
9pfs-nested-$(CONFIG_VIRTFS)
=
virtio-9p.o virtio-9p-debug.o
9pfs-nested-$(CONFIG_VIRTFS)
+=
virtio-9p-local.o virtio-9p-xattr.o
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
9pfs-nested-$(CONFIG_VIRTFS)
+=
coxattr.o
virtio-9p-handle.o
hw-obj-$(CONFIG_REALLY_VIRTFS)
+=
$(
addprefix
9pfs/,
$
(
9pfs-nested-y
))
$(addprefix 9pfs/, $(9pfs-nested-y))
:
QEMU_CFLAGS+=$(GLIB_CFLAGS)
...
...
fsdev/file-op-9p.h
浏览文件 @
62ec6073
...
...
@@ -19,6 +19,7 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/vfs.h>
#define SM_LOCAL_MODE_BITS 0600
#define SM_LOCAL_DIR_MODE_BITS 0700
...
...
@@ -49,51 +50,68 @@ typedef struct FsCred
struct
xattr_operations
;
/* FsContext flag values */
#define PATHNAME_FSCONTEXT 0x1
typedef
struct
FsContext
{
int
flags
;
char
*
fs_root
;
SecModel
fs_sm
;
uid_t
uid
;
struct
xattr_operations
**
xops
;
/* fs driver specific data */
void
*
private
;
}
FsContext
;
typedef
struct
V9fsPath
{
int16_t
size
;
char
*
data
;
}
V9fsPath
;
void
cred_init
(
FsCred
*
);
typedef
struct
FileOperations
{
int
(
*
lstat
)(
FsContext
*
,
const
char
*
,
struct
stat
*
);
ssize_t
(
*
readlink
)(
FsContext
*
,
const
char
*
,
char
*
,
size_t
);
int
(
*
chmod
)(
FsContext
*
,
const
char
*
,
FsCred
*
);
int
(
*
chown
)(
FsContext
*
,
const
char
*
,
FsCred
*
);
int
(
*
mknod
)(
FsContext
*
,
const
char
*
,
FsCred
*
);
int
(
*
utimensat
)(
FsContext
*
,
const
char
*
,
const
struct
timespec
*
);
int
(
*
init
)(
struct
FsContext
*
);
int
(
*
lstat
)(
FsContext
*
,
V9fsPath
*
,
struct
stat
*
);
ssize_t
(
*
readlink
)(
FsContext
*
,
V9fsPath
*
,
char
*
,
size_t
);
int
(
*
chmod
)(
FsContext
*
,
V9fsPath
*
,
FsCred
*
);
int
(
*
chown
)(
FsContext
*
,
V9fsPath
*
,
FsCred
*
);
int
(
*
mknod
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
FsCred
*
);
int
(
*
utimensat
)(
FsContext
*
,
V9fsPath
*
,
const
struct
timespec
*
);
int
(
*
remove
)(
FsContext
*
,
const
char
*
);
int
(
*
symlink
)(
FsContext
*
,
const
char
*
,
const
char
*
,
FsCred
*
);
int
(
*
link
)(
FsContext
*
,
const
char
*
,
const
char
*
);
int
(
*
symlink
)(
FsContext
*
,
const
char
*
,
V9fsPath
*
,
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
*
,
const
char
*
);
int
(
*
open
)(
FsContext
*
,
const
char
*
,
int
);
int
(
*
open2
)(
FsContext
*
,
const
char
*
,
int
,
FsCred
*
);
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
(
*
mkdir
)(
FsContext
*
,
const
char
*
,
FsCred
*
);
int
(
*
mkdir
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
FsCred
*
);
int
(
*
fstat
)(
FsContext
*
,
int
,
struct
stat
*
);
int
(
*
rename
)(
FsContext
*
,
const
char
*
,
const
char
*
);
int
(
*
truncate
)(
FsContext
*
,
const
char
*
,
off_t
);
int
(
*
truncate
)(
FsContext
*
,
V9fsPath
*
,
off_t
);
int
(
*
fsync
)(
FsContext
*
,
int
,
int
);
int
(
*
statfs
)(
FsContext
*
s
,
const
char
*
path
,
struct
statfs
*
stbuf
);
ssize_t
(
*
lgetxattr
)(
FsContext
*
,
const
char
*
,
int
(
*
statfs
)(
FsContext
*
s
,
V9fsPath
*
path
,
struct
statfs
*
stbuf
);
ssize_t
(
*
lgetxattr
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
void
*
,
size_t
);
ssize_t
(
*
llistxattr
)(
FsContext
*
,
const
char
*
,
void
*
,
size_t
);
int
(
*
lsetxattr
)(
FsContext
*
,
const
char
*
,
ssize_t
(
*
llistxattr
)(
FsContext
*
,
V9fsPath
*
,
void
*
,
size_t
);
int
(
*
lsetxattr
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
void
*
,
size_t
,
int
);
int
(
*
lremovexattr
)(
FsContext
*
,
const
char
*
,
const
char
*
);
int
(
*
lremovexattr
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
);
int
(
*
name_to_path
)(
FsContext
*
,
V9fsPath
*
,
const
char
*
,
V9fsPath
*
);
int
(
*
renameat
)(
FsContext
*
ctx
,
V9fsPath
*
olddir
,
const
char
*
old_name
,
V9fsPath
*
newdir
,
const
char
*
new_name
);
int
(
*
unlinkat
)(
FsContext
*
ctx
,
V9fsPath
*
dir
,
const
char
*
name
,
int
flags
);
void
*
opaque
;
}
FileOperations
;
...
...
fsdev/qemu-fsdev.c
浏览文件 @
62ec6073
...
...
@@ -23,6 +23,7 @@ static QTAILQ_HEAD(FsTypeEntry_head, FsTypeListEntry) fstype_entries =
static
FsTypeTable
FsTypes
[]
=
{
{
.
name
=
"local"
,
.
ops
=
&
local_ops
},
{
.
name
=
"handle"
,
.
ops
=
&
handle_ops
},
};
int
qemu_fsdev_add
(
QemuOpts
*
opts
)
...
...
fsdev/qemu-fsdev.h
浏览文件 @
62ec6073
...
...
@@ -52,4 +52,5 @@ typedef struct FsTypeListEntry {
int
qemu_fsdev_add
(
QemuOpts
*
opts
);
FsTypeEntry
*
get_fsdev_fsentry
(
char
*
id
);
extern
FileOperations
local_ops
;
extern
FileOperations
handle_ops
;
#endif
hw/9pfs/codir.c
浏览文件 @
62ec6073
...
...
@@ -17,11 +17,15 @@
#include "qemu-coroutine.h"
#include "virtio-9p-coth.h"
int
v9fs_co_readdir_r
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
struct
dirent
*
dent
,
int
v9fs_co_readdir_r
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
struct
dirent
*
dent
,
struct
dirent
**
result
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
errno
=
0
;
...
...
@@ -35,10 +39,14 @@ int v9fs_co_readdir_r(V9fsState *s, V9fsFidState *fidp, struct dirent *dent,
return
err
;
}
off_t
v9fs_co_telldir
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
)
off_t
v9fs_co_telldir
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
)
{
off_t
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
telldir
(
&
s
->
ctx
,
fidp
->
fs
.
dir
);
...
...
@@ -49,67 +57,103 @@ off_t v9fs_co_telldir(V9fsState *s, V9fsFidState *fidp)
return
err
;
}
void
v9fs_co_seekdir
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
off_t
offset
)
void
v9fs_co_seekdir
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
off_t
offset
)
{
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
;
}
v9fs_co_run_in_worker
(
{
s
->
ops
->
seekdir
(
&
s
->
ctx
,
fidp
->
fs
.
dir
,
offset
);
});
}
void
v9fs_co_rewinddir
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
)
void
v9fs_co_rewinddir
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
)
{
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
;
}
v9fs_co_run_in_worker
(
{
s
->
ops
->
rewinddir
(
&
s
->
ctx
,
fidp
->
fs
.
dir
);
});
}
int
v9fs_co_mkdir
(
V9fsState
*
s
,
char
*
name
,
mode_t
mode
,
uid_t
uid
,
gid_t
gid
)
int
v9fs_co_mkdir
(
V9fsPDU
*
pdu
,
V9fsFidState
*
fidp
,
V9fsString
*
name
,
mode_t
mode
,
uid_t
uid
,
gid_t
gid
,
struct
stat
*
stbuf
)
{
int
err
;
FsCred
cred
;
V9fsPath
path
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;;
}
cred_init
(
&
cred
);
cred
.
fc_mode
=
mode
;
cred
.
fc_uid
=
uid
;
cred
.
fc_gid
=
gid
;
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
mkdir
(
&
s
->
ctx
,
name
,
&
cred
);
err
=
s
->
ops
->
mkdir
(
&
s
->
ctx
,
&
fidp
->
path
,
name
->
data
,
&
cred
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
else
{
v9fs_path_init
(
&
path
);
err
=
v9fs_name_to_path
(
s
,
&
fidp
->
path
,
name
->
data
,
&
path
);
if
(
!
err
)
{
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
&
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
}
v9fs_path_free
(
&
path
);
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_opendir
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
)
int
v9fs_co_opendir
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
fidp
->
fs
.
dir
=
s
->
ops
->
opendir
(
&
s
->
ctx
,
fidp
->
path
.
data
);
fidp
->
fs
.
dir
=
s
->
ops
->
opendir
(
&
s
->
ctx
,
&
fidp
->
path
);
if
(
!
fidp
->
fs
.
dir
)
{
err
=
-
errno
;
}
else
{
err
=
0
;
}
});
v9fs_path_unlock
(
s
);
if
(
!
err
)
{
total_open_fd
++
;
if
(
total_open_fd
>
open_fd_hw
)
{
v9fs_reclaim_fd
(
s
);
v9fs_reclaim_fd
(
pdu
);
}
}
return
err
;
}
int
v9fs_co_closedir
(
V9fs
State
*
s
,
DIR
*
dir
)
int
v9fs_co_closedir
(
V9fs
PDU
*
pdu
,
DIR
*
dir
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
closedir
(
&
s
->
ctx
,
dir
);
...
...
hw/9pfs/cofile.c
浏览文件 @
62ec6073
...
...
@@ -17,24 +17,34 @@
#include "qemu-coroutine.h"
#include "virtio-9p-coth.h"
int
v9fs_co_lstat
(
V9fs
State
*
s
,
V9fsString
*
path
,
struct
stat
*
stbuf
)
int
v9fs_co_lstat
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
struct
stat
*
stbuf
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
path
->
data
,
stbuf
);
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_fstat
(
V9fs
State
*
s
,
int
fd
,
struct
stat
*
stbuf
)
int
v9fs_co_fstat
(
V9fs
PDU
*
pdu
,
int
fd
,
struct
stat
*
stbuf
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
fstat
(
&
s
->
ctx
,
fd
,
stbuf
);
...
...
@@ -45,59 +55,96 @@ int v9fs_co_fstat(V9fsState *s, int fd, struct stat *stbuf)
return
err
;
}
int
v9fs_co_open
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
int
flags
)
int
v9fs_co_open
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
int
flags
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
fidp
->
fs
.
fd
=
s
->
ops
->
open
(
&
s
->
ctx
,
fidp
->
path
.
data
,
flags
);
fidp
->
fs
.
fd
=
s
->
ops
->
open
(
&
s
->
ctx
,
&
fidp
->
path
,
flags
);
if
(
fidp
->
fs
.
fd
==
-
1
)
{
err
=
-
errno
;
}
else
{
err
=
0
;
}
});
v9fs_path_unlock
(
s
);
if
(
!
err
)
{
total_open_fd
++
;
if
(
total_open_fd
>
open_fd_hw
)
{
v9fs_reclaim_fd
(
s
);
v9fs_reclaim_fd
(
pdu
);
}
}
return
err
;
}
int
v9fs_co_open2
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
char
*
full
name
,
gid_t
gid
,
int
flags
,
int
mode
)
int
v9fs_co_open2
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
V9fsString
*
name
,
gid_t
gid
,
int
flags
,
int
mode
,
struct
stat
*
stbuf
)
{
int
err
;
FsCred
cred
;
V9fsPath
path
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
cred_init
(
&
cred
);
cred
.
fc_mode
=
mode
&
07777
;
cred
.
fc_uid
=
fidp
->
uid
;
cred
.
fc_gid
=
gid
;
/*
* Hold the directory fid lock so that directory path name
* don't change. Read lock is fine because this fid cannot
* be used by any other operation.
*/
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
fidp
->
fs
.
fd
=
s
->
ops
->
open2
(
&
s
->
ctx
,
fullname
,
flags
,
&
cred
);
err
=
0
;
fidp
->
fs
.
fd
=
s
->
ops
->
open2
(
&
s
->
ctx
,
&
fidp
->
path
,
name
->
data
,
flags
,
&
cred
)
;
if
(
fidp
->
fs
.
fd
==
-
1
)
{
err
=
-
errno
;
}
else
{
v9fs_path_init
(
&
path
);
err
=
v9fs_name_to_path
(
s
,
&
fidp
->
path
,
name
->
data
,
&
path
);
if
(
!
err
)
{
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
&
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
s
->
ops
->
close
(
&
s
->
ctx
,
fidp
->
fs
.
fd
);
}
else
{
v9fs_path_copy
(
&
fidp
->
path
,
&
path
);
}
}
else
{
s
->
ops
->
close
(
&
s
->
ctx
,
fidp
->
fs
.
fd
);
}
v9fs_path_free
(
&
path
);
}
});
v9fs_path_unlock
(
s
);
if
(
!
err
)
{
total_open_fd
++
;
if
(
total_open_fd
>
open_fd_hw
)
{
v9fs_reclaim_fd
(
s
);
v9fs_reclaim_fd
(
pdu
);
}
}
return
err
;
}
int
v9fs_co_close
(
V9fs
State
*
s
,
int
fd
)
int
v9fs_co_close
(
V9fs
PDU
*
pdu
,
int
fd
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
close
(
&
s
->
ctx
,
fd
);
...
...
@@ -111,11 +158,14 @@ int v9fs_co_close(V9fsState *s, int fd)
return
err
;
}
int
v9fs_co_fsync
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
int
datasync
)
int
v9fs_co_fsync
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
int
datasync
)
{
int
fd
;
int
err
;
int
fd
,
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
fd
=
fidp
->
fs
.
fd
;
v9fs_co_run_in_worker
(
{
...
...
@@ -127,26 +177,37 @@ int v9fs_co_fsync(V9fsState *s, V9fsFidState *fidp, int datasync)
return
err
;
}
int
v9fs_co_link
(
V9fsState
*
s
,
V9fsString
*
oldpath
,
V9fsString
*
newpath
)
int
v9fs_co_link
(
V9fsPDU
*
pdu
,
V9fsFidState
*
oldfid
,
V9fsFidState
*
newdirfid
,
V9fsString
*
name
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
link
(
&
s
->
ctx
,
oldpath
->
data
,
newpath
->
data
);
err
=
s
->
ops
->
link
(
&
s
->
ctx
,
&
oldfid
->
path
,
&
newdirfid
->
path
,
name
->
data
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_pwritev
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
int
v9fs_co_pwritev
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
struct
iovec
*
iov
,
int
iovcnt
,
int64_t
offset
)
{
int
fd
;
int
err
;
int
fd
,
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
fd
=
fidp
->
fs
.
fd
;
v9fs_co_run_in_worker
(
{
...
...
@@ -158,12 +219,15 @@ int v9fs_co_pwritev(V9fsState *s, V9fsFidState *fidp,
return
err
;
}
int
v9fs_co_preadv
(
V9fs
State
*
s
,
V9fsFidState
*
fidp
,
int
v9fs_co_preadv
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
struct
iovec
*
iov
,
int
iovcnt
,
int64_t
offset
)
{
int
fd
;
int
err
;
int
fd
,
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
fd
=
fidp
->
fs
.
fd
;
v9fs_co_run_in_worker
(
{
...
...
hw/9pfs/cofs.c
浏览文件 @
62ec6073
...
...
@@ -17,15 +17,20 @@
#include "qemu-coroutine.h"
#include "virtio-9p-coth.h"
int
v9fs_co_readlink
(
V9fs
State
*
s
,
V9fsString
*
path
,
V9fsString
*
buf
)
int
v9fs_co_readlink
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
V9fsString
*
buf
)
{
int
err
;
ssize_t
len
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
buf
->
data
=
g_malloc
(
PATH_MAX
);
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
len
=
s
->
ops
->
readlink
(
&
s
->
ctx
,
path
->
data
,
len
=
s
->
ops
->
readlink
(
&
s
->
ctx
,
path
,
buf
->
data
,
PATH_MAX
-
1
);
if
(
len
>
-
1
)
{
buf
->
size
=
len
;
...
...
@@ -35,6 +40,7 @@ int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
if
(
err
)
{
g_free
(
buf
->
data
);
buf
->
data
=
NULL
;
...
...
@@ -43,109 +49,162 @@ int v9fs_co_readlink(V9fsState *s, V9fsString *path, V9fsString *buf)
return
err
;
}
int
v9fs_co_statfs
(
V9fs
State
*
s
,
V9fsString
*
path
,
struct
statfs
*
stbuf
)
int
v9fs_co_statfs
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
struct
statfs
*
stbuf
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
statfs
(
&
s
->
ctx
,
path
->
data
,
stbuf
);
err
=
s
->
ops
->
statfs
(
&
s
->
ctx
,
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_chmod
(
V9fs
State
*
s
,
V9fsString
*
path
,
mode_t
mode
)
int
v9fs_co_chmod
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
mode_t
mode
)
{
int
err
;
FsCred
cred
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
cred_init
(
&
cred
);
cred
.
fc_mode
=
mode
;
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
chmod
(
&
s
->
ctx
,
path
->
data
,
&
cred
);
err
=
s
->
ops
->
chmod
(
&
s
->
ctx
,
path
,
&
cred
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_utimensat
(
V9fs
State
*
s
,
V9fsString
*
path
,
int
v9fs_co_utimensat
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
struct
timespec
times
[
2
])
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
utimensat
(
&
s
->
ctx
,
path
->
data
,
times
);
err
=
s
->
ops
->
utimensat
(
&
s
->
ctx
,
path
,
times
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_chown
(
V9fs
State
*
s
,
V9fsString
*
path
,
uid_t
uid
,
gid_t
gid
)
int
v9fs_co_chown
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
uid_t
uid
,
gid_t
gid
)
{
int
err
;
FsCred
cred
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
cred_init
(
&
cred
);
cred
.
fc_uid
=
uid
;
cred
.
fc_gid
=
gid
;
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
chown
(
&
s
->
ctx
,
path
->
data
,
&
cred
);
err
=
s
->
ops
->
chown
(
&
s
->
ctx
,
path
,
&
cred
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_truncate
(
V9fs
State
*
s
,
V9fsString
*
path
,
off_t
size
)
int
v9fs_co_truncate
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
off_t
size
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
truncate
(
&
s
->
ctx
,
path
->
data
,
size
);
err
=
s
->
ops
->
truncate
(
&
s
->
ctx
,
path
,
size
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_mknod
(
V9fs
State
*
s
,
V9fsString
*
path
,
uid_t
uid
,
gid_t
gid
,
dev_t
dev
,
mode_t
mode
)
int
v9fs_co_mknod
(
V9fs
PDU
*
pdu
,
V9fsFidState
*
fidp
,
V9fsString
*
name
,
uid_t
uid
,
gid_t
gid
,
dev_t
dev
,
mode_t
mode
,
struct
stat
*
stbuf
)
{
int
err
;
V9fsPath
path
;
FsCred
cred
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
cred_init
(
&
cred
);
cred
.
fc_uid
=
uid
;
cred
.
fc_gid
=
gid
;
cred
.
fc_mode
=
mode
;
cred
.
fc_rdev
=
dev
;
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
mknod
(
&
s
->
ctx
,
path
->
data
,
&
cred
);
err
=
s
->
ops
->
mknod
(
&
s
->
ctx
,
&
fidp
->
path
,
name
->
data
,
&
cred
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
else
{
v9fs_path_init
(
&
path
);
err
=
v9fs_name_to_path
(
s
,
&
fidp
->
path
,
name
->
data
,
&
path
);
if
(
!
err
)
{
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
&
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
}
v9fs_path_free
(
&
path
);
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_remove
(
V9fsState
*
s
,
V9fsString
*
path
)
/* Only works with path name based fid */
int
v9fs_co_remove
(
V9fsPDU
*
pdu
,
V9fsPath
*
path
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
remove
(
&
s
->
ctx
,
path
->
data
);
...
...
@@ -153,13 +212,39 @@ int v9fs_co_remove(V9fsState *s, V9fsString *path)
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_unlinkat
(
V9fsPDU
*
pdu
,
V9fsPath
*
path
,
V9fsString
*
name
,
int
flags
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
unlinkat
(
&
s
->
ctx
,
path
,
name
->
data
,
flags
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_rename
(
V9fsState
*
s
,
V9fsString
*
oldpath
,
V9fsString
*
newpath
)
/* Only work with path name based fid */
int
v9fs_co_rename
(
V9fsPDU
*
pdu
,
V9fsPath
*
oldpath
,
V9fsPath
*
newpath
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
rename
(
&
s
->
ctx
,
oldpath
->
data
,
newpath
->
data
);
...
...
@@ -170,22 +255,90 @@ int v9fs_co_rename(V9fsState *s, V9fsString *oldpath, V9fsString *newpath)
return
err
;
}
int
v9fs_co_symlink
(
V9fsState
*
s
,
V9fsFidState
*
fidp
,
const
char
*
oldpath
,
const
char
*
newpath
,
gid_t
gid
)
int
v9fs_co_renameat
(
V9fsPDU
*
pdu
,
V9fsPath
*
olddirpath
,
V9fsString
*
oldname
,
V9fsPath
*
newdirpath
,
V9fsString
*
newname
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
renameat
(
&
s
->
ctx
,
olddirpath
,
oldname
->
data
,
newdirpath
,
newname
->
data
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
return
err
;
}
int
v9fs_co_symlink
(
V9fsPDU
*
pdu
,
V9fsFidState
*
dfidp
,
V9fsString
*
name
,
const
char
*
oldpath
,
gid_t
gid
,
struct
stat
*
stbuf
)
{
int
err
;
FsCred
cred
;
V9fsPath
path
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
cred_init
(
&
cred
);
cred
.
fc_uid
=
fidp
->
uid
;
cred
.
fc_uid
=
d
fidp
->
uid
;
cred
.
fc_gid
=
gid
;
cred
.
fc_mode
=
0777
;
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
symlink
(
&
s
->
ctx
,
oldpath
,
newpath
,
&
cred
);
err
=
s
->
ops
->
symlink
(
&
s
->
ctx
,
oldpath
,
&
dfidp
->
path
,
name
->
data
,
&
cred
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
else
{
v9fs_path_init
(
&
path
);
err
=
v9fs_name_to_path
(
s
,
&
dfidp
->
path
,
name
->
data
,
&
path
);
if
(
!
err
)
{
err
=
s
->
ops
->
lstat
(
&
s
->
ctx
,
&
path
,
stbuf
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
}
v9fs_path_free
(
&
path
);
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
/*
* For path name based fid we don't block. So we can
* directly call the fs driver ops.
*/
int
v9fs_co_name_to_path
(
V9fsPDU
*
pdu
,
V9fsPath
*
dirpath
,
const
char
*
name
,
V9fsPath
*
path
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
s
->
ctx
.
flags
&
PATHNAME_FSCONTEXT
)
{
err
=
s
->
ops
->
name_to_path
(
&
s
->
ctx
,
dirpath
,
name
,
path
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
}
else
{
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
name_to_path
(
&
s
->
ctx
,
dirpath
,
name
,
path
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
}
return
err
;
}
hw/9pfs/coxattr.c
浏览文件 @
62ec6073
...
...
@@ -17,68 +17,91 @@
#include "qemu-coroutine.h"
#include "virtio-9p-coth.h"
int
v9fs_co_llistxattr
(
V9fs
State
*
s
,
V9fsString
*
path
,
void
*
value
,
size_t
size
)
int
v9fs_co_llistxattr
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
void
*
value
,
size_t
size
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
llistxattr
(
&
s
->
ctx
,
path
->
data
,
value
,
size
);
err
=
s
->
ops
->
llistxattr
(
&
s
->
ctx
,
path
,
value
,
size
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_lgetxattr
(
V9fs
State
*
s
,
V9fsString
*
path
,
int
v9fs_co_lgetxattr
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
V9fsString
*
xattr_name
,
void
*
value
,
size_t
size
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
lgetxattr
(
&
s
->
ctx
,
path
->
data
,
err
=
s
->
ops
->
lgetxattr
(
&
s
->
ctx
,
path
,
xattr_name
->
data
,
value
,
size
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_lsetxattr
(
V9fs
State
*
s
,
V9fsString
*
path
,
int
v9fs_co_lsetxattr
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
V9fsString
*
xattr_name
,
void
*
value
,
size_t
size
,
int
flags
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
lsetxattr
(
&
s
->
ctx
,
path
->
data
,
err
=
s
->
ops
->
lsetxattr
(
&
s
->
ctx
,
path
,
xattr_name
->
data
,
value
,
size
,
flags
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
int
v9fs_co_lremovexattr
(
V9fs
State
*
s
,
V9fsString
*
path
,
int
v9fs_co_lremovexattr
(
V9fs
PDU
*
pdu
,
V9fsPath
*
path
,
V9fsString
*
xattr_name
)
{
int
err
;
V9fsState
*
s
=
pdu
->
s
;
if
(
v9fs_request_cancelled
(
pdu
))
{
return
-
EINTR
;
}
v9fs_path_read_lock
(
s
);
v9fs_co_run_in_worker
(
{
err
=
s
->
ops
->
lremovexattr
(
&
s
->
ctx
,
path
->
data
,
xattr_name
->
data
);
err
=
s
->
ops
->
lremovexattr
(
&
s
->
ctx
,
path
,
xattr_name
->
data
);
if
(
err
<
0
)
{
err
=
-
errno
;
}
});
v9fs_path_unlock
(
s
);
return
err
;
}
hw/9pfs/virtio-9p-coth.h
浏览文件 @
62ec6073
...
...
@@ -56,41 +56,49 @@ typedef struct V9fsThPool {
extern
void
co_run_in_worker_bh
(
void
*
);
extern
int
v9fs_init_worker_threads
(
void
);
extern
int
v9fs_co_readlink
(
V9fs
State
*
,
V9fsString
*
,
V9fsString
*
);
extern
int
v9fs_co_readdir_r
(
V9fs
State
*
,
V9fsFidState
*
,
extern
int
v9fs_co_readlink
(
V9fs
PDU
*
,
V9fsPath
*
,
V9fsString
*
);
extern
int
v9fs_co_readdir_r
(
V9fs
PDU
*
,
V9fsFidState
*
,
struct
dirent
*
,
struct
dirent
**
result
);
extern
off_t
v9fs_co_telldir
(
V9fs
State
*
,
V9fsFidState
*
);
extern
void
v9fs_co_seekdir
(
V9fs
State
*
,
V9fsFidState
*
,
off_t
);
extern
void
v9fs_co_rewinddir
(
V9fs
State
*
,
V9fsFidState
*
);
extern
int
v9fs_co_statfs
(
V9fs
State
*
,
V9fsString
*
,
struct
statfs
*
);
extern
int
v9fs_co_lstat
(
V9fs
State
*
,
V9fsString
*
,
struct
stat
*
);
extern
int
v9fs_co_chmod
(
V9fs
State
*
,
V9fsString
*
,
mode_t
);
extern
int
v9fs_co_utimensat
(
V9fs
State
*
,
V9fsString
*
,
struct
timespec
[
2
]);
extern
int
v9fs_co_chown
(
V9fs
State
*
,
V9fsString
*
,
uid_t
,
gid_t
);
extern
int
v9fs_co_truncate
(
V9fs
State
*
,
V9fsString
*
,
off_t
);
extern
int
v9fs_co_llistxattr
(
V9fs
State
*
,
V9fsString
*
,
void
*
,
size_t
);
extern
int
v9fs_co_lgetxattr
(
V9fs
State
*
,
V9fsString
*
,
extern
off_t
v9fs_co_telldir
(
V9fs
PDU
*
,
V9fsFidState
*
);
extern
void
v9fs_co_seekdir
(
V9fs
PDU
*
,
V9fsFidState
*
,
off_t
);
extern
void
v9fs_co_rewinddir
(
V9fs
PDU
*
,
V9fsFidState
*
);
extern
int
v9fs_co_statfs
(
V9fs
PDU
*
,
V9fsPath
*
,
struct
statfs
*
);
extern
int
v9fs_co_lstat
(
V9fs
PDU
*
,
V9fsPath
*
,
struct
stat
*
);
extern
int
v9fs_co_chmod
(
V9fs
PDU
*
,
V9fsPath
*
,
mode_t
);
extern
int
v9fs_co_utimensat
(
V9fs
PDU
*
,
V9fsPath
*
,
struct
timespec
[
2
]);
extern
int
v9fs_co_chown
(
V9fs
PDU
*
,
V9fsPath
*
,
uid_t
,
gid_t
);
extern
int
v9fs_co_truncate
(
V9fs
PDU
*
,
V9fsPath
*
,
off_t
);
extern
int
v9fs_co_llistxattr
(
V9fs
PDU
*
,
V9fsPath
*
,
void
*
,
size_t
);
extern
int
v9fs_co_lgetxattr
(
V9fs
PDU
*
,
V9fsPath
*
,
V9fsString
*
,
void
*
,
size_t
);
extern
int
v9fs_co_mknod
(
V9fsState
*
,
V9fsString
*
,
uid_t
,
gid_t
,
dev_t
,
mode_t
);
extern
int
v9fs_co_mkdir
(
V9fsState
*
,
char
*
,
mode_t
,
uid_t
,
gid_t
);
extern
int
v9fs_co_remove
(
V9fsState
*
,
V9fsString
*
);
extern
int
v9fs_co_rename
(
V9fsState
*
,
V9fsString
*
,
V9fsString
*
);
extern
int
v9fs_co_fstat
(
V9fsState
*
,
int
,
struct
stat
*
);
extern
int
v9fs_co_opendir
(
V9fsState
*
,
V9fsFidState
*
);
extern
int
v9fs_co_open
(
V9fsState
*
,
V9fsFidState
*
,
int
);
extern
int
v9fs_co_open2
(
V9fsState
*
,
V9fsFidState
*
,
char
*
,
gid_t
,
int
,
int
);
extern
int
v9fs_co_lsetxattr
(
V9fsState
*
,
V9fsString
*
,
V9fsString
*
,
extern
int
v9fs_co_mknod
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsString
*
,
uid_t
,
gid_t
,
dev_t
,
mode_t
,
struct
stat
*
);
extern
int
v9fs_co_mkdir
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsString
*
,
mode_t
,
uid_t
,
gid_t
,
struct
stat
*
);
extern
int
v9fs_co_remove
(
V9fsPDU
*
,
V9fsPath
*
);
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_opendir
(
V9fsPDU
*
,
V9fsFidState
*
);
extern
int
v9fs_co_open
(
V9fsPDU
*
,
V9fsFidState
*
,
int
);
extern
int
v9fs_co_open2
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsString
*
,
gid_t
,
int
,
int
,
struct
stat
*
);
extern
int
v9fs_co_lsetxattr
(
V9fsPDU
*
,
V9fsPath
*
,
V9fsString
*
,
void
*
,
size_t
,
int
);
extern
int
v9fs_co_lremovexattr
(
V9fsState
*
,
V9fsString
*
,
V9fsString
*
);
extern
int
v9fs_co_closedir
(
V9fsState
*
,
DIR
*
);
extern
int
v9fs_co_close
(
V9fsState
*
,
int
);
extern
int
v9fs_co_fsync
(
V9fsState
*
,
V9fsFidState
*
,
int
);
extern
int
v9fs_co_symlink
(
V9fsState
*
,
V9fsFidState
*
,
const
char
*
,
const
char
*
,
gid_t
);
extern
int
v9fs_co_link
(
V9fsState
*
,
V9fsString
*
,
V9fsString
*
);
extern
int
v9fs_co_pwritev
(
V9fsState
*
,
V9fsFidState
*
,
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_fsync
(
V9fsPDU
*
,
V9fsFidState
*
,
int
);
extern
int
v9fs_co_symlink
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsString
*
,
const
char
*
,
gid_t
,
struct
stat
*
);
extern
int
v9fs_co_link
(
V9fsPDU
*
,
V9fsFidState
*
,
V9fsFidState
*
,
V9fsString
*
);
extern
int
v9fs_co_pwritev
(
V9fsPDU
*
,
V9fsFidState
*
,
struct
iovec
*
,
int
,
int64_t
);
extern
int
v9fs_co_preadv
(
V9fs
State
*
,
V9fsFidState
*
,
extern
int
v9fs_co_preadv
(
V9fs
PDU
*
,
V9fsFidState
*
,
struct
iovec
*
,
int
,
int64_t
);
extern
int
v9fs_co_name_to_path
(
V9fsPDU
*
,
V9fsPath
*
,
const
char
*
,
V9fsPath
*
);
#endif
hw/9pfs/virtio-9p-device.c
浏览文件 @
62ec6073
...
...
@@ -45,7 +45,7 @@ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
}
VirtIODevice
*
virtio_9p_init
(
DeviceState
*
dev
,
V9fsConf
*
conf
)
{
{
V9fsState
*
s
;
int
i
,
len
;
struct
stat
stat
;
...
...
@@ -58,6 +58,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
sizeof
(
V9fsState
));
/* initialize pdu allocator */
QLIST_INIT
(
&
s
->
free_list
);
QLIST_INIT
(
&
s
->
active_list
);
for
(
i
=
0
;
i
<
(
MAX_REQ
-
1
);
i
++
)
{
QLIST_INSERT_HEAD
(
&
s
->
free_list
,
&
s
->
pdus
[
i
],
next
);
}
...
...
@@ -124,6 +125,7 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
memcpy
(
s
->
tag
,
conf
->
tag
,
len
);
s
->
tag_len
=
len
;
s
->
ctx
.
uid
=
-
1
;
s
->
ctx
.
flags
=
0
;
s
->
ops
=
fse
->
ops
;
s
->
vdev
.
get_features
=
virtio_9p_get_features
;
...
...
@@ -131,7 +133,13 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
s
->
tag_len
;
s
->
vdev
.
get_config
=
virtio_9p_get_config
;
s
->
fid_list
=
NULL
;
qemu_co_rwlock_init
(
&
s
->
rename_lock
);
if
(
s
->
ops
->
init
(
&
s
->
ctx
)
<
0
)
{
fprintf
(
stderr
,
"Virtio-9p Failed to initialize fs-driver with id:%s"
" and export path:%s
\n
"
,
conf
->
fsdev_id
,
s
->
ctx
.
fs_root
);
exit
(
1
);
}
if
(
v9fs_init_worker_threads
()
<
0
)
{
fprintf
(
stderr
,
"worker thread initialization failed
\n
"
);
exit
(
1
);
...
...
hw/9pfs/virtio-9p-handle.c
0 → 100644
浏览文件 @
62ec6073
/*
* Virtio 9p handle callback
*
* 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 "hw/virtio.h"
#include "virtio-9p.h"
#include "virtio-9p-xattr.h"
#include <arpa/inet.h>
#include <pwd.h>
#include <grp.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <attr/xattr.h>
#include <unistd.h>
struct
handle_data
{
int
mountfd
;
int
handle_bytes
;
};
#if __GLIBC__ <= 2 && __GLIBC_MINOR__ < 14
struct
file_handle
{
unsigned
int
handle_bytes
;
int
handle_type
;
unsigned
char
handle
[
0
];
};
#endif
#ifndef AT_EMPTY_PATH
#define AT_EMPTY_PATH 0x1000
/* Allow empty relative pathname */
#endif
#ifndef O_PATH
#define O_PATH 010000000
#endif
#ifndef __NR_name_to_handle_at
#if defined(__i386__)
#define __NR_name_to_handle_at 341
#define __NR_open_by_handle_at 342
#elif defined(__x86_64__)
#define __NR_name_to_handle_at 303
#define __NR_open_by_handle_at 304
#endif
#endif
#ifdef __NR_name_to_handle_at
static
inline
int
name_to_handle
(
int
dirfd
,
const
char
*
name
,
struct
file_handle
*
fh
,
int
*
mnt_id
,
int
flags
)
{
return
syscall
(
__NR_name_to_handle_at
,
dirfd
,
name
,
fh
,
mnt_id
,
flags
);
}
static
inline
int
open_by_handle
(
int
mountfd
,
const
char
*
fh
,
int
flags
)
{
return
syscall
(
__NR_open_by_handle_at
,
mountfd
,
fh
,
flags
);
}
#else
static
inline
int
name_to_handle
(
int
dirfd
,
const
char
*
name
,
struct
file_handle
*
fh
,
int
*
mnt_id
,
int
flags
)
{
errno
=
ENOSYS
;
return
-
1
;
}
static
inline
int
open_by_handle
(
int
mountfd
,
const
char
*
fh
,
int
flags
)
{
errno
=
ENOSYS
;
return
-
1
;
}
#endif
static
int
handle_update_file_cred
(
int
dirfd
,
const
char
*
name
,
FsCred
*
credp
)
{
int
fd
,
ret
;
fd
=
openat
(
dirfd
,
name
,
O_NONBLOCK
|
O_NOFOLLOW
);;
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fchmod
(
fd
,
credp
->
fc_mode
&
07777
);
if
(
ret
<
0
)
{
goto
err_out
;
}
ret
=
fchownat
(
fd
,
""
,
credp
->
fc_uid
,
credp
->
fc_gid
,
AT_EMPTY_PATH
);
err_out:
close
(
fd
);
return
ret
;
}
static
int
handle_lstat
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_path
,
struct
stat
*
stbuf
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_PATH
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fstatat
(
fd
,
""
,
stbuf
,
AT_EMPTY_PATH
);
close
(
fd
);
return
ret
;
}
static
ssize_t
handle_readlink
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_path
,
char
*
buf
,
size_t
bufsz
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_PATH
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
readlinkat
(
fd
,
""
,
buf
,
bufsz
);
close
(
fd
);
return
ret
;
}
static
int
handle_close
(
FsContext
*
ctx
,
int
fd
)
{
return
close
(
fd
);
}
static
int
handle_closedir
(
FsContext
*
ctx
,
DIR
*
dir
)
{
return
closedir
(
dir
);
}
static
int
handle_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
int
flags
)
{
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
return
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
flags
);
}
static
DIR
*
handle_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
)
{
int
fd
;
fd
=
handle_open
(
ctx
,
fs_path
,
O_DIRECTORY
);
if
(
fd
<
0
)
{
return
NULL
;
}
return
fdopendir
(
fd
);
}
static
void
handle_rewinddir
(
FsContext
*
ctx
,
DIR
*
dir
)
{
return
rewinddir
(
dir
);
}
static
off_t
handle_telldir
(
FsContext
*
ctx
,
DIR
*
dir
)
{
return
telldir
(
dir
);
}
static
int
handle_readdir_r
(
FsContext
*
ctx
,
DIR
*
dir
,
struct
dirent
*
entry
,
struct
dirent
**
result
)
{
return
readdir_r
(
dir
,
entry
,
result
);
}
static
void
handle_seekdir
(
FsContext
*
ctx
,
DIR
*
dir
,
off_t
off
)
{
return
seekdir
(
dir
,
off
);
}
static
ssize_t
handle_preadv
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
#ifdef CONFIG_PREADV
return
preadv
(
fd
,
iov
,
iovcnt
,
offset
);
#else
int
err
=
lseek
(
fd
,
offset
,
SEEK_SET
);
if
(
err
==
-
1
)
{
return
err
;
}
else
{
return
readv
(
fd
,
iov
,
iovcnt
);
}
#endif
}
static
ssize_t
handle_pwritev
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
{
#ifdef CONFIG_PREADV
return
pwritev
(
fd
,
iov
,
iovcnt
,
offset
);
#else
int
err
=
lseek
(
fd
,
offset
,
SEEK_SET
);
if
(
err
==
-
1
)
{
return
err
;
}
else
{
return
writev
(
fd
,
iov
,
iovcnt
);
}
#endif
}
static
int
handle_chmod
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_path
,
FsCred
*
credp
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fchmod
(
fd
,
credp
->
fc_mode
);
close
(
fd
);
return
ret
;
}
static
int
handle_mknod
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
FsCred
*
credp
)
{
int
dirfd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
dirfd
=
open_by_handle
(
data
->
mountfd
,
dir_path
->
data
,
O_PATH
);
if
(
dirfd
<
0
)
{
return
dirfd
;
}
ret
=
mknodat
(
dirfd
,
name
,
credp
->
fc_mode
,
credp
->
fc_rdev
);
if
(
!
ret
)
{
ret
=
handle_update_file_cred
(
dirfd
,
name
,
credp
);
}
close
(
dirfd
);
return
ret
;
}
static
int
handle_mkdir
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
FsCred
*
credp
)
{
int
dirfd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
dirfd
=
open_by_handle
(
data
->
mountfd
,
dir_path
->
data
,
O_PATH
);
if
(
dirfd
<
0
)
{
return
dirfd
;
}
ret
=
mkdirat
(
dirfd
,
name
,
credp
->
fc_mode
);
if
(
!
ret
)
{
ret
=
handle_update_file_cred
(
dirfd
,
name
,
credp
);
}
close
(
dirfd
);
return
ret
;
}
static
int
handle_fstat
(
FsContext
*
fs_ctx
,
int
fd
,
struct
stat
*
stbuf
)
{
return
fstat
(
fd
,
stbuf
);
}
static
int
handle_open2
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
int
flags
,
FsCred
*
credp
)
{
int
ret
;
int
dirfd
,
fd
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
dirfd
=
open_by_handle
(
data
->
mountfd
,
dir_path
->
data
,
O_PATH
);
if
(
dirfd
<
0
)
{
return
dirfd
;
}
fd
=
openat
(
dirfd
,
name
,
flags
|
O_NOFOLLOW
,
credp
->
fc_mode
);
if
(
fd
>=
0
)
{
ret
=
handle_update_file_cred
(
dirfd
,
name
,
credp
);
if
(
ret
<
0
)
{
close
(
fd
);
fd
=
ret
;
}
}
close
(
dirfd
);
return
fd
;
}
static
int
handle_symlink
(
FsContext
*
fs_ctx
,
const
char
*
oldpath
,
V9fsPath
*
dir_path
,
const
char
*
name
,
FsCred
*
credp
)
{
int
fd
,
dirfd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
dirfd
=
open_by_handle
(
data
->
mountfd
,
dir_path
->
data
,
O_PATH
);
if
(
dirfd
<
0
)
{
return
dirfd
;
}
ret
=
symlinkat
(
oldpath
,
dirfd
,
name
);
if
(
!
ret
)
{
fd
=
openat
(
dirfd
,
name
,
O_PATH
|
O_NOFOLLOW
);
if
(
fd
<
0
)
{
ret
=
fd
;
goto
err_out
;
}
ret
=
fchownat
(
fd
,
""
,
credp
->
fc_uid
,
credp
->
fc_gid
,
AT_EMPTY_PATH
);
close
(
fd
);
}
err_out:
close
(
dirfd
);
return
ret
;
}
static
int
handle_link
(
FsContext
*
ctx
,
V9fsPath
*
oldpath
,
V9fsPath
*
dirpath
,
const
char
*
name
)
{
int
oldfd
,
newdirfd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
oldfd
=
open_by_handle
(
data
->
mountfd
,
oldpath
->
data
,
O_PATH
);
if
(
oldfd
<
0
)
{
return
oldfd
;
}
newdirfd
=
open_by_handle
(
data
->
mountfd
,
dirpath
->
data
,
O_PATH
);
if
(
newdirfd
<
0
)
{
close
(
oldfd
);
return
newdirfd
;
}
ret
=
linkat
(
oldfd
,
""
,
newdirfd
,
name
,
AT_EMPTY_PATH
);
close
(
newdirfd
);
close
(
oldfd
);
return
ret
;
}
static
int
handle_truncate
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
off_t
size
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
|
O_WRONLY
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
ftruncate
(
fd
,
size
);
close
(
fd
);
return
ret
;
}
static
int
handle_rename
(
FsContext
*
ctx
,
const
char
*
oldpath
,
const
char
*
newpath
)
{
errno
=
EOPNOTSUPP
;
return
-
1
;
}
static
int
handle_chown
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_path
,
FsCred
*
credp
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
fs_ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_PATH
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fchownat
(
fd
,
""
,
credp
->
fc_uid
,
credp
->
fc_gid
,
AT_EMPTY_PATH
);
close
(
fd
);
return
ret
;
}
static
int
handle_utimensat
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
const
struct
timespec
*
buf
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
futimens
(
fd
,
buf
);
close
(
fd
);
return
ret
;
}
static
int
handle_remove
(
FsContext
*
ctx
,
const
char
*
path
)
{
errno
=
EOPNOTSUPP
;
return
-
1
;
}
static
int
handle_fsync
(
FsContext
*
ctx
,
int
fd
,
int
datasync
)
{
if
(
datasync
)
{
return
qemu_fdatasync
(
fd
);
}
else
{
return
fsync
(
fd
);
}
}
static
int
handle_statfs
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
struct
statfs
*
stbuf
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fstatfs
(
fd
,
stbuf
);
close
(
fd
);
return
ret
;
}
static
ssize_t
handle_lgetxattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fgetxattr
(
fd
,
name
,
value
,
size
);
close
(
fd
);
return
ret
;
}
static
ssize_t
handle_llistxattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
void
*
value
,
size_t
size
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
flistxattr
(
fd
,
value
,
size
);
close
(
fd
);
return
ret
;
}
static
int
handle_lsetxattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
const
char
*
name
,
void
*
value
,
size_t
size
,
int
flags
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fsetxattr
(
fd
,
name
,
value
,
size
,
flags
);
close
(
fd
);
return
ret
;
}
static
int
handle_lremovexattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
const
char
*
name
)
{
int
fd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
fd
=
open_by_handle
(
data
->
mountfd
,
fs_path
->
data
,
O_NONBLOCK
);
if
(
fd
<
0
)
{
return
fd
;
}
ret
=
fremovexattr
(
fd
,
name
);
close
(
fd
);
return
ret
;
}
static
int
handle_name_to_path
(
FsContext
*
ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
V9fsPath
*
target
)
{
char
buffer
[
PATH_MAX
];
struct
file_handle
*
fh
;
int
dirfd
,
ret
,
mnt_id
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
/* "." and ".." are not allowed */
if
(
!
strcmp
(
name
,
"."
)
||
!
strcmp
(
name
,
".."
))
{
errno
=
EINVAL
;
return
-
1
;
}
if
(
dir_path
)
{
dirfd
=
open_by_handle
(
data
->
mountfd
,
dir_path
->
data
,
O_PATH
);
}
else
{
/* relative to export root */
dirfd
=
open
(
rpath
(
ctx
,
"."
,
buffer
),
O_DIRECTORY
);
}
if
(
dirfd
<
0
)
{
return
dirfd
;
}
fh
=
g_malloc
(
sizeof
(
struct
file_handle
)
+
data
->
handle_bytes
);
fh
->
handle_bytes
=
data
->
handle_bytes
;
/* add a "./" at the begining of the path */
snprintf
(
buffer
,
PATH_MAX
,
"./%s"
,
name
);
/* flag = 0 imply don't follow symlink */
ret
=
name_to_handle
(
dirfd
,
buffer
,
fh
,
&
mnt_id
,
0
);
if
(
!
ret
)
{
target
->
data
=
(
char
*
)
fh
;
target
->
size
=
sizeof
(
struct
file_handle
)
+
data
->
handle_bytes
;
}
else
{
g_free
(
fh
);
}
close
(
dirfd
);
return
ret
;
}
static
int
handle_renameat
(
FsContext
*
ctx
,
V9fsPath
*
olddir
,
const
char
*
old_name
,
V9fsPath
*
newdir
,
const
char
*
new_name
)
{
int
olddirfd
,
newdirfd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
olddirfd
=
open_by_handle
(
data
->
mountfd
,
olddir
->
data
,
O_PATH
);
if
(
olddirfd
<
0
)
{
return
olddirfd
;
}
newdirfd
=
open_by_handle
(
data
->
mountfd
,
newdir
->
data
,
O_PATH
);
if
(
newdirfd
<
0
)
{
close
(
olddirfd
);
return
newdirfd
;
}
ret
=
renameat
(
olddirfd
,
old_name
,
newdirfd
,
new_name
);
close
(
newdirfd
);
close
(
olddirfd
);
return
ret
;
}
static
int
handle_unlinkat
(
FsContext
*
ctx
,
V9fsPath
*
dir
,
const
char
*
name
,
int
flags
)
{
int
dirfd
,
ret
;
struct
handle_data
*
data
=
(
struct
handle_data
*
)
ctx
->
private
;
dirfd
=
open_by_handle
(
data
->
mountfd
,
dir
->
data
,
O_PATH
);
if
(
dirfd
<
0
)
{
return
dirfd
;
}
ret
=
unlinkat
(
dirfd
,
name
,
flags
);
close
(
dirfd
);
return
ret
;
}
static
int
handle_init
(
FsContext
*
ctx
)
{
int
ret
,
mnt_id
;
struct
file_handle
fh
;
struct
handle_data
*
data
=
g_malloc
(
sizeof
(
struct
handle_data
));
data
->
mountfd
=
open
(
ctx
->
fs_root
,
O_DIRECTORY
);
if
(
data
->
mountfd
<
0
)
{
ret
=
data
->
mountfd
;
goto
err_out
;
}
memset
(
&
fh
,
0
,
sizeof
(
struct
file_handle
));
ret
=
name_to_handle
(
data
->
mountfd
,
"."
,
&
fh
,
&
mnt_id
,
0
);
if
(
ret
&&
errno
==
EOVERFLOW
)
{
data
->
handle_bytes
=
fh
.
handle_bytes
;
ctx
->
private
=
data
;
ret
=
0
;
goto
out
;
}
/* we got 0 byte handle ? */
ret
=
-
1
;
close
(
data
->
mountfd
);
err_out:
g_free
(
data
);
out:
return
ret
;
}
FileOperations
handle_ops
=
{
.
init
=
handle_init
,
.
lstat
=
handle_lstat
,
.
readlink
=
handle_readlink
,
.
close
=
handle_close
,
.
closedir
=
handle_closedir
,
.
open
=
handle_open
,
.
opendir
=
handle_opendir
,
.
rewinddir
=
handle_rewinddir
,
.
telldir
=
handle_telldir
,
.
readdir_r
=
handle_readdir_r
,
.
seekdir
=
handle_seekdir
,
.
preadv
=
handle_preadv
,
.
pwritev
=
handle_pwritev
,
.
chmod
=
handle_chmod
,
.
mknod
=
handle_mknod
,
.
mkdir
=
handle_mkdir
,
.
fstat
=
handle_fstat
,
.
open2
=
handle_open2
,
.
symlink
=
handle_symlink
,
.
link
=
handle_link
,
.
truncate
=
handle_truncate
,
.
rename
=
handle_rename
,
.
chown
=
handle_chown
,
.
utimensat
=
handle_utimensat
,
.
remove
=
handle_remove
,
.
fsync
=
handle_fsync
,
.
statfs
=
handle_statfs
,
.
lgetxattr
=
handle_lgetxattr
,
.
llistxattr
=
handle_llistxattr
,
.
lsetxattr
=
handle_lsetxattr
,
.
lremovexattr
=
handle_lremovexattr
,
.
name_to_path
=
handle_name_to_path
,
.
renameat
=
handle_renameat
,
.
unlinkat
=
handle_unlinkat
,
};
hw/9pfs/virtio-9p-local.c
浏览文件 @
62ec6073
...
...
@@ -21,11 +21,12 @@
#include <sys/un.h>
#include <attr/xattr.h>
static
int
local_lstat
(
FsContext
*
fs_ctx
,
const
char
*
path
,
struct
stat
*
stbuf
)
static
int
local_lstat
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_path
,
struct
stat
*
stbuf
)
{
int
err
;
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
err
=
lstat
(
rpath
(
fs_ctx
,
path
,
buffer
),
stbuf
);
if
(
err
)
{
return
err
;
...
...
@@ -59,6 +60,7 @@ static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
static
int
local_set_xattr
(
const
char
*
path
,
FsCred
*
credp
)
{
int
err
;
if
(
credp
->
fc_uid
!=
-
1
)
{
err
=
setxattr
(
path
,
"user.virtfs.uid"
,
&
credp
->
fc_uid
,
sizeof
(
uid_t
),
0
);
...
...
@@ -91,9 +93,10 @@ static int local_set_xattr(const char *path, FsCred *credp)
}
static
int
local_post_create_passthrough
(
FsContext
*
fs_ctx
,
const
char
*
path
,
FsCred
*
credp
)
FsCred
*
credp
)
{
char
buffer
[
PATH_MAX
];
if
(
chmod
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_mode
&
07777
)
<
0
)
{
return
-
1
;
}
...
...
@@ -110,11 +113,13 @@ static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
return
0
;
}
static
ssize_t
local_readlink
(
FsContext
*
fs_ctx
,
const
char
*
path
,
char
*
buf
,
size_t
bufsz
)
static
ssize_t
local_readlink
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_
path
,
char
*
buf
,
size_t
bufsz
)
{
ssize_t
tsize
=
-
1
;
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
if
(
fs_ctx
->
fs_sm
==
SM_MAPPED
)
{
int
fd
;
fd
=
open
(
rpath
(
fs_ctx
,
path
,
buffer
),
O_RDONLY
);
...
...
@@ -143,15 +148,19 @@ static int local_closedir(FsContext *ctx, DIR *dir)
return
closedir
(
dir
);
}
static
int
local_open
(
FsContext
*
ctx
,
const
char
*
path
,
int
flags
)
static
int
local_open
(
FsContext
*
ctx
,
V9fsPath
*
fs_
path
,
int
flags
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
return
open
(
rpath
(
ctx
,
path
,
buffer
),
flags
);
}
static
DIR
*
local_opendir
(
FsContext
*
ctx
,
const
char
*
path
)
static
DIR
*
local_opendir
(
FsContext
*
ctx
,
V9fsPath
*
fs_
path
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
return
opendir
(
rpath
(
ctx
,
path
,
buffer
));
}
...
...
@@ -166,7 +175,7 @@ static off_t local_telldir(FsContext *ctx, DIR *dir)
}
static
int
local_readdir_r
(
FsContext
*
ctx
,
DIR
*
dir
,
struct
dirent
*
entry
,
struct
dirent
**
result
)
struct
dirent
**
result
)
{
return
readdir_r
(
dir
,
entry
,
result
);
}
...
...
@@ -192,7 +201,7 @@ static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov,
}
static
ssize_t
local_pwritev
(
FsContext
*
ctx
,
int
fd
,
const
struct
iovec
*
iov
,
int
iovcnt
,
off_t
offset
)
int
iovcnt
,
off_t
offset
)
{
#ifdef CONFIG_PREADV
return
pwritev
(
fd
,
iov
,
iovcnt
,
offset
);
...
...
@@ -206,9 +215,11 @@ static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
#endif
}
static
int
local_chmod
(
FsContext
*
fs_ctx
,
const
char
*
path
,
FsCred
*
credp
)
static
int
local_chmod
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_
path
,
FsCred
*
credp
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
if
(
fs_ctx
->
fs_sm
==
SM_MAPPED
)
{
return
local_set_xattr
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
);
}
else
if
((
fs_ctx
->
fs_sm
==
SM_PASSTHROUGH
)
||
...
...
@@ -218,18 +229,25 @@ static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
return
-
1
;
}
static
int
local_mknod
(
FsContext
*
fs_ctx
,
const
char
*
path
,
FsCred
*
credp
)
static
int
local_mknod
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
FsCred
*
credp
)
{
char
*
path
;
int
err
=
-
1
;
int
serrno
=
0
;
V9fsString
fullname
;
char
buffer
[
PATH_MAX
];
v9fs_string_init
(
&
fullname
);
v9fs_string_sprintf
(
&
fullname
,
"%s/%s"
,
dir_path
->
data
,
name
);
path
=
fullname
.
data
;
/* Determine the security model */
if
(
fs_ctx
->
fs_sm
==
SM_MAPPED
)
{
err
=
mknod
(
rpath
(
fs_ctx
,
path
,
buffer
),
SM_LOCAL_MODE_BITS
|
S_IFREG
,
0
);
if
(
err
==
-
1
)
{
return
err
;
goto
out
;
}
local_set_xattr
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
);
if
(
err
==
-
1
)
{
...
...
@@ -241,7 +259,7 @@ static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp)
err
=
mknod
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_mode
,
credp
->
fc_rdev
);
if
(
err
==
-
1
)
{
return
err
;
goto
out
;
}
err
=
local_post_create_passthrough
(
fs_ctx
,
path
,
credp
);
if
(
err
==
-
1
)
{
...
...
@@ -249,25 +267,34 @@ static int local_mknod(FsContext *fs_ctx, const char *path, FsCred *credp)
goto
err_end
;
}
}
return
err
;
goto
out
;
err_end:
remove
(
rpath
(
fs_ctx
,
path
,
buffer
));
errno
=
serrno
;
out:
v9fs_string_free
(
&
fullname
);
return
err
;
}
static
int
local_mkdir
(
FsContext
*
fs_ctx
,
const
char
*
path
,
FsCred
*
credp
)
static
int
local_mkdir
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
FsCred
*
credp
)
{
char
*
path
;
int
err
=
-
1
;
int
serrno
=
0
;
V9fsString
fullname
;
char
buffer
[
PATH_MAX
];
v9fs_string_init
(
&
fullname
);
v9fs_string_sprintf
(
&
fullname
,
"%s/%s"
,
dir_path
->
data
,
name
);
path
=
fullname
.
data
;
/* Determine the security model */
if
(
fs_ctx
->
fs_sm
==
SM_MAPPED
)
{
err
=
mkdir
(
rpath
(
fs_ctx
,
path
,
buffer
),
SM_LOCAL_DIR_MODE_BITS
);
if
(
err
==
-
1
)
{
return
err
;
goto
out
;
}
credp
->
fc_mode
=
credp
->
fc_mode
|
S_IFDIR
;
err
=
local_set_xattr
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
);
...
...
@@ -279,7 +306,7 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
(
fs_ctx
->
fs_sm
==
SM_NONE
))
{
err
=
mkdir
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_mode
);
if
(
err
==
-
1
)
{
return
err
;
goto
out
;
}
err
=
local_post_create_passthrough
(
fs_ctx
,
path
,
credp
);
if
(
err
==
-
1
)
{
...
...
@@ -287,11 +314,13 @@ static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp)
goto
err_end
;
}
}
return
err
;
goto
out
;
err_end:
remove
(
rpath
(
fs_ctx
,
path
,
buffer
));
errno
=
serrno
;
out:
v9fs_string_free
(
&
fullname
);
return
err
;
}
...
...
@@ -325,19 +354,26 @@ static int local_fstat(FsContext *fs_ctx, int fd, struct stat *stbuf)
return
err
;
}
static
int
local_open2
(
FsContext
*
fs_ctx
,
const
char
*
path
,
int
flags
,
FsCred
*
credp
)
static
int
local_open2
(
FsContext
*
fs_ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
int
flags
,
FsCred
*
credp
)
{
char
*
path
;
int
fd
=
-
1
;
int
err
=
-
1
;
int
serrno
=
0
;
V9fsString
fullname
;
char
buffer
[
PATH_MAX
];
v9fs_string_init
(
&
fullname
);
v9fs_string_sprintf
(
&
fullname
,
"%s/%s"
,
dir_path
->
data
,
name
);
path
=
fullname
.
data
;
/* Determine the security model */
if
(
fs_ctx
->
fs_sm
==
SM_MAPPED
)
{
fd
=
open
(
rpath
(
fs_ctx
,
path
,
buffer
),
flags
,
SM_LOCAL_MODE_BITS
);
if
(
fd
==
-
1
)
{
return
fd
;
err
=
fd
;
goto
out
;
}
credp
->
fc_mode
=
credp
->
fc_mode
|
S_IFREG
;
/* Set cleint credentials in xattr */
...
...
@@ -350,7 +386,8 @@ static int local_open2(FsContext *fs_ctx, const char *path, int flags,
(
fs_ctx
->
fs_sm
==
SM_NONE
))
{
fd
=
open
(
rpath
(
fs_ctx
,
path
,
buffer
),
flags
,
credp
->
fc_mode
);
if
(
fd
==
-
1
)
{
return
fd
;
err
=
fd
;
goto
out
;
}
err
=
local_post_create_passthrough
(
fs_ctx
,
path
,
credp
);
if
(
err
==
-
1
)
{
...
...
@@ -358,23 +395,32 @@ static int local_open2(FsContext *fs_ctx, const char *path, int flags,
goto
err_end
;
}
}
return
fd
;
err
=
fd
;
goto
out
;
err_end:
close
(
fd
);
remove
(
rpath
(
fs_ctx
,
path
,
buffer
));
errno
=
serrno
;
out:
v9fs_string_free
(
&
fullname
);
return
err
;
}
static
int
local_symlink
(
FsContext
*
fs_ctx
,
const
char
*
oldpath
,
const
char
*
newpath
,
FsCred
*
credp
)
V9fsPath
*
dir_path
,
const
char
*
name
,
FsCred
*
credp
)
{
int
err
=
-
1
;
int
serrno
=
0
;
char
*
newpath
;
V9fsString
fullname
;
char
buffer
[
PATH_MAX
];
v9fs_string_init
(
&
fullname
);
v9fs_string_sprintf
(
&
fullname
,
"%s/%s"
,
dir_path
->
data
,
name
);
newpath
=
fullname
.
data
;
/* Determine the security model */
if
(
fs_ctx
->
fs_sm
==
SM_MAPPED
)
{
int
fd
;
...
...
@@ -382,7 +428,8 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
fd
=
open
(
rpath
(
fs_ctx
,
newpath
,
buffer
),
O_CREAT
|
O_EXCL
|
O_RDWR
,
SM_LOCAL_MODE_BITS
);
if
(
fd
==
-
1
)
{
return
fd
;
err
=
fd
;
goto
out
;
}
/* Write the oldpath (target) to the file. */
oldpath_size
=
strlen
(
oldpath
);
...
...
@@ -408,10 +455,10 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
(
fs_ctx
->
fs_sm
==
SM_NONE
))
{
err
=
symlink
(
oldpath
,
rpath
(
fs_ctx
,
newpath
,
buffer
));
if
(
err
)
{
return
err
;
goto
out
;
}
err
=
lchown
(
rpath
(
fs_ctx
,
newpath
,
buffer
),
credp
->
fc_uid
,
credp
->
fc_gid
);
credp
->
fc_gid
);
if
(
err
==
-
1
)
{
/*
* If we fail to change ownership and if we are
...
...
@@ -424,24 +471,37 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
err
=
0
;
}
}
return
err
;
goto
out
;
err_end:
remove
(
rpath
(
fs_ctx
,
newpath
,
buffer
));
errno
=
serrno
;
out:
v9fs_string_free
(
&
fullname
);
return
err
;
}
static
int
local_link
(
FsContext
*
ctx
,
const
char
*
oldpath
,
const
char
*
newpath
)
static
int
local_link
(
FsContext
*
ctx
,
V9fsPath
*
oldpath
,
V9fsPath
*
dirpath
,
const
char
*
name
)
{
int
ret
;
V9fsString
newpath
;
char
buffer
[
PATH_MAX
],
buffer1
[
PATH_MAX
];
return
link
(
rpath
(
ctx
,
oldpath
,
buffer
),
rpath
(
ctx
,
newpath
,
buffer1
));
v9fs_string_init
(
&
newpath
);
v9fs_string_sprintf
(
&
newpath
,
"%s/%s"
,
dirpath
->
data
,
name
);
ret
=
link
(
rpath
(
ctx
,
oldpath
->
data
,
buffer
),
rpath
(
ctx
,
newpath
.
data
,
buffer1
));
v9fs_string_free
(
&
newpath
);
return
ret
;
}
static
int
local_truncate
(
FsContext
*
ctx
,
const
char
*
path
,
off_t
size
)
static
int
local_truncate
(
FsContext
*
ctx
,
V9fsPath
*
fs_
path
,
off_t
size
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
return
truncate
(
rpath
(
ctx
,
path
,
buffer
),
size
);
}
...
...
@@ -453,9 +513,11 @@ static int local_rename(FsContext *ctx, const char *oldpath,
return
rename
(
rpath
(
ctx
,
oldpath
,
buffer
),
rpath
(
ctx
,
newpath
,
buffer1
));
}
static
int
local_chown
(
FsContext
*
fs_ctx
,
const
char
*
path
,
FsCred
*
credp
)
static
int
local_chown
(
FsContext
*
fs_ctx
,
V9fsPath
*
fs_
path
,
FsCred
*
credp
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
if
((
credp
->
fc_uid
==
-
1
&&
credp
->
fc_gid
==
-
1
)
||
(
fs_ctx
->
fs_sm
==
SM_PASSTHROUGH
))
{
return
lchown
(
rpath
(
fs_ctx
,
path
,
buffer
),
credp
->
fc_uid
,
...
...
@@ -470,12 +532,14 @@ static int local_chown(FsContext *fs_ctx, const char *path, FsCred *credp)
return
-
1
;
}
static
int
local_utimensat
(
FsContext
*
s
,
const
char
*
path
,
static
int
local_utimensat
(
FsContext
*
s
,
V9fsPath
*
fs_
path
,
const
struct
timespec
*
buf
)
{
char
buffer
[
PATH_MAX
];
char
*
path
=
fs_path
->
data
;
return
qemu_utimensat
(
AT_FDCWD
,
rpath
(
s
,
path
,
buffer
),
buf
,
AT_SYMLINK_NOFOLLOW
);
AT_SYMLINK_NOFOLLOW
);
}
static
int
local_remove
(
FsContext
*
ctx
,
const
char
*
path
)
...
...
@@ -493,38 +557,102 @@ static int local_fsync(FsContext *ctx, int fd, int datasync)
}
}
static
int
local_statfs
(
FsContext
*
s
,
const
char
*
path
,
struct
statfs
*
stbuf
)
static
int
local_statfs
(
FsContext
*
s
,
V9fsPath
*
fs_
path
,
struct
statfs
*
stbuf
)
{
char
buffer
[
PATH_MAX
];
return
statfs
(
rpath
(
s
,
path
,
buffer
),
stbuf
);
char
*
path
=
fs_path
->
data
;
return
statfs
(
rpath
(
s
,
path
,
buffer
),
stbuf
);
}
static
ssize_t
local_lgetxattr
(
FsContext
*
ctx
,
const
char
*
path
,
static
ssize_t
local_lgetxattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_
path
,
const
char
*
name
,
void
*
value
,
size_t
size
)
{
char
*
path
=
fs_path
->
data
;
return
v9fs_get_xattr
(
ctx
,
path
,
name
,
value
,
size
);
}
static
ssize_t
local_llistxattr
(
FsContext
*
ctx
,
const
char
*
path
,
static
ssize_t
local_llistxattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_
path
,
void
*
value
,
size_t
size
)
{
char
*
path
=
fs_path
->
data
;
return
v9fs_list_xattr
(
ctx
,
path
,
value
,
size
);
}
static
int
local_lsetxattr
(
FsContext
*
ctx
,
const
char
*
path
,
const
char
*
name
,
static
int
local_lsetxattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_
path
,
const
char
*
name
,
void
*
value
,
size_t
size
,
int
flags
)
{
char
*
path
=
fs_path
->
data
;
return
v9fs_set_xattr
(
ctx
,
path
,
name
,
value
,
size
,
flags
);
}
static
int
local_lremovexattr
(
FsContext
*
ctx
,
const
char
*
path
,
const
char
*
name
)
static
int
local_lremovexattr
(
FsContext
*
ctx
,
V9fsPath
*
fs_path
,
const
char
*
name
)
{
char
*
path
=
fs_path
->
data
;
return
v9fs_remove_xattr
(
ctx
,
path
,
name
);
}
static
int
local_name_to_path
(
FsContext
*
ctx
,
V9fsPath
*
dir_path
,
const
char
*
name
,
V9fsPath
*
target
)
{
if
(
dir_path
)
{
v9fs_string_sprintf
((
V9fsString
*
)
target
,
"%s/%s"
,
dir_path
->
data
,
name
);
}
else
{
v9fs_string_sprintf
((
V9fsString
*
)
target
,
"%s"
,
name
);
}
/* Bump the size for including terminating NULL */
target
->
size
++
;
return
0
;
}
static
int
local_renameat
(
FsContext
*
ctx
,
V9fsPath
*
olddir
,
const
char
*
old_name
,
V9fsPath
*
newdir
,
const
char
*
new_name
)
{
int
ret
;
V9fsString
old_full_name
,
new_full_name
;
v9fs_string_init
(
&
old_full_name
);
v9fs_string_init
(
&
new_full_name
);
v9fs_string_sprintf
(
&
old_full_name
,
"%s/%s"
,
olddir
->
data
,
old_name
);
v9fs_string_sprintf
(
&
new_full_name
,
"%s/%s"
,
newdir
->
data
,
new_name
);
ret
=
local_rename
(
ctx
,
old_full_name
.
data
,
new_full_name
.
data
);
v9fs_string_free
(
&
old_full_name
);
v9fs_string_free
(
&
new_full_name
);
return
ret
;
}
static
int
local_unlinkat
(
FsContext
*
ctx
,
V9fsPath
*
dir
,
const
char
*
name
,
int
flags
)
{
int
ret
;
V9fsString
fullname
;
char
buffer
[
PATH_MAX
];
v9fs_string_init
(
&
fullname
);
v9fs_string_sprintf
(
&
fullname
,
"%s/%s"
,
dir
->
data
,
name
);
ret
=
remove
(
rpath
(
ctx
,
fullname
.
data
,
buffer
));
v9fs_string_free
(
&
fullname
);
return
ret
;
}
static
int
local_init
(
FsContext
*
ctx
)
{
ctx
->
flags
|=
PATHNAME_FSCONTEXT
;
return
0
;
}
FileOperations
local_ops
=
{
.
init
=
local_init
,
.
lstat
=
local_lstat
,
.
readlink
=
local_readlink
,
.
close
=
local_close
,
...
...
@@ -555,4 +683,7 @@ FileOperations local_ops = {
.
llistxattr
=
local_llistxattr
,
.
lsetxattr
=
local_lsetxattr
,
.
lremovexattr
=
local_lremovexattr
,
.
name_to_path
=
local_name_to_path
,
.
renameat
=
local_renameat
,
.
unlinkat
=
local_unlinkat
,
};
hw/9pfs/virtio-9p.c
浏览文件 @
62ec6073
此差异已折叠。
点击以展开。
hw/9pfs/virtio-9p.h
浏览文件 @
62ec6073
...
...
@@ -8,6 +8,8 @@
#include <sys/resource.h>
#include "hw/virtio.h"
#include "fsdev/file-op-9p.h"
#include "qemu-thread.h"
#include "qemu-coroutine.h"
/* The feature bitmap for virtio 9P */
/* The mount point is specified in a config variable */
...
...
@@ -129,6 +131,8 @@ struct V9fsPDU
uint32_t
size
;
uint16_t
tag
;
uint8_t
id
;
uint8_t
cancelled
;
CoQueue
complete
;
VirtQueueElement
elem
;
struct
V9fsState
*
s
;
QLIST_ENTRY
(
V9fsPDU
)
next
;
...
...
@@ -204,7 +208,7 @@ struct V9fsFidState
{
int
fid_type
;
int32_t
fid
;
V9fs
String
path
;
V9fs
Path
path
;
union
{
int
fd
;
DIR
*
dir
;
...
...
@@ -229,6 +233,7 @@ typedef struct V9fsState
VirtQueue
*
vq
;
V9fsPDU
pdus
[
MAX_REQ
];
QLIST_HEAD
(,
V9fsPDU
)
free_list
;
QLIST_HEAD
(,
V9fsPDU
)
active_list
;
V9fsFidState
*
fid_list
;
FileOperations
*
ops
;
FsContext
ctx
;
...
...
@@ -237,6 +242,11 @@ typedef struct V9fsState
size_t
config_size
;
enum
p9_proto_version
proto_version
;
int32_t
msize
;
/*
* lock ensuring atomic path update
* on rename.
*/
CoRwlock
rename_lock
;
}
V9fsState
;
typedef
struct
V9fsStatState
{
...
...
@@ -381,7 +391,43 @@ static inline size_t do_pdu_unpack(void *dst, struct iovec *sg, int sg_count,
return
pdu_packunpack
(
dst
,
sg
,
sg_count
,
offset
,
size
,
0
);
}
static
inline
void
v9fs_path_write_lock
(
V9fsState
*
s
)
{
if
(
s
->
ctx
.
flags
&
PATHNAME_FSCONTEXT
)
{
qemu_co_rwlock_wrlock
(
&
s
->
rename_lock
);
}
}
static
inline
void
v9fs_path_read_lock
(
V9fsState
*
s
)
{
if
(
s
->
ctx
.
flags
&
PATHNAME_FSCONTEXT
)
{
qemu_co_rwlock_rdlock
(
&
s
->
rename_lock
);
}
}
static
inline
void
v9fs_path_unlock
(
V9fsState
*
s
)
{
if
(
s
->
ctx
.
flags
&
PATHNAME_FSCONTEXT
)
{
qemu_co_rwlock_unlock
(
&
s
->
rename_lock
);
}
}
static
inline
uint8_t
v9fs_request_cancelled
(
V9fsPDU
*
pdu
)
{
return
pdu
->
cancelled
;
}
extern
void
handle_9p_output
(
VirtIODevice
*
vdev
,
VirtQueue
*
vq
);
extern
void
virtio_9p_set_fd_limit
(
void
);
extern
void
v9fs_reclaim_fd
(
V9fsState
*
s
);
extern
void
v9fs_reclaim_fd
(
V9fsPDU
*
pdu
);
extern
void
v9fs_string_init
(
V9fsString
*
str
);
extern
void
v9fs_string_free
(
V9fsString
*
str
);
extern
void
v9fs_string_null
(
V9fsString
*
str
);
extern
void
v9fs_string_sprintf
(
V9fsString
*
str
,
const
char
*
fmt
,
...);
extern
void
v9fs_string_copy
(
V9fsString
*
lhs
,
V9fsString
*
rhs
);
extern
void
v9fs_path_init
(
V9fsPath
*
path
);
extern
void
v9fs_path_free
(
V9fsPath
*
path
);
extern
void
v9fs_path_copy
(
V9fsPath
*
lhs
,
V9fsPath
*
rhs
);
extern
int
v9fs_name_to_path
(
V9fsState
*
s
,
V9fsPath
*
dirpath
,
const
char
*
name
,
V9fsPath
*
path
);
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录