hw/9pfs: Read-only support for 9p export
A new fsdev parameter "readonly" is introduced to control accessing 9p export. "readonly" can be used to specify the access type. By default "rw" access is given to 9p export. Signed-off-by: M. Mohan Kumar <mohan@in.ibm.com> Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
This commit is contained in:
parent
f02b77c9bf
commit
2c74c2cb4b
@ -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;
|
||||
|
@ -35,7 +35,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 +86,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;
|
||||
|
@ -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;
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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 */ }
|
||||
|
@ -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,6 +622,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
|
||||
ETEXI
|
||||
|
||||
|
2
vl.c
2
vl.c
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user