diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index 454761d81d..1d931144f4 100644 --- a/fsdev/file-op-9p.h +++ b/fsdev/file-op-9p.h @@ -101,6 +101,8 @@ typedef struct FsDriverEntry { FsThrottle fst; mode_t fmode; mode_t dmode; + /* temporary storage for parse_opts only */ + uint32_t max_xattr; } FsDriverEntry; struct FsContext { diff --git a/fsdev/qemu-fsdev-opts.c b/fsdev/qemu-fsdev-opts.c index 07a18c6e48..c2c1e83611 100644 --- a/fsdev/qemu-fsdev-opts.c +++ b/fsdev/qemu-fsdev-opts.c @@ -46,6 +46,9 @@ static QemuOptsList qemu_fsdev_opts = { }, { .name = "dmode", .type = QEMU_OPT_NUMBER, + }, { + .name = "max_xattr", + .type = QEMU_OPT_NUMBER, }, THROTTLE_OPTS, @@ -92,6 +95,9 @@ static QemuOptsList qemu_virtfs_opts = { }, { .name = "dmode", .type = QEMU_OPT_NUMBER, + }, { + .name = "max_xattr", + .type = QEMU_OPT_NUMBER, }, { /*End of list */ } diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c index 57877dad0a..f97103cf44 100644 --- a/fsdev/qemu-fsdev.c +++ b/fsdev/qemu-fsdev.c @@ -45,7 +45,7 @@ typedef struct FsDriverListEntry { static QTAILQ_HEAD(, FsDriverListEntry) fsdriver_entries = QTAILQ_HEAD_INITIALIZER(fsdriver_entries); -#define COMMON_FS_DRIVER_OPTIONS "id", "fsdriver", "readonly" +#define COMMON_FS_DRIVER_OPTIONS "id", "fsdriver", "readonly", "max_xattr" static FsDriverTable FsDrivers[] = { { diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index aa48306b0e..4708e170a4 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -1527,6 +1527,15 @@ static int local_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp) const char *path = qemu_opt_get(opts, "path"); const char *multidevs = qemu_opt_get(opts, "multidevs"); + uint64_t val = qemu_opt_get_number(opts, "max_xattr", + V9FS_MAX_XATTR_DEFAULT); + if (val > UINT32_MAX) { + error_setg(errp, "max_xattr value '%s' too large", + qemu_opt_get(opts, "max_xattr")); + return -1; + } + fse->max_xattr = val; + if (!sec_model) { error_setg(errp, "security_model property not set"); error_append_security_model_hint(errp); diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c index b3743f6169..322dc3bb69 100644 --- a/hw/9pfs/9p-synth.c +++ b/hw/9pfs/9p-synth.c @@ -25,6 +25,8 @@ #include "qemu/rcu_queue.h" #include "qemu/cutils.h" #include "system/qtest.h" +#include "qapi/error.h" +#include "qemu/option.h" /* Root node for synth file system */ static V9fsSynthNode synth_root = { @@ -629,12 +631,27 @@ static int synth_init(FsContext *ctx, Error **errp) return 0; } +static int synth_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp) +{ + uint64_t val = qemu_opt_get_number(opts, "max_xattr", + V9FS_MAX_XATTR_DEFAULT); + if (val > UINT32_MAX) { + error_setg(errp, "max_xattr value '%s' too large", + qemu_opt_get(opts, "max_xattr")); + return -1; + } + fse->max_xattr = val; + + return 0; +} + static bool synth_has_valid_file_handle(int fid_type, V9fsFidOpenState *fs) { return false; } FileOperations synth_ops = { + .parse_opts = synth_parse_opts, .init = synth_init, .lstat = synth_lstat, .readlink = synth_readlink, diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index e737629581..d1ec3c0c14 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -4483,8 +4483,8 @@ int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t, s->reclaiming = false; - /* init xattr FID limit */ - s->ctx.xattr_fid_limit = V9FS_MAX_XATTR_DEFAULT; + /* init xattr FID limit from fsdev config */ + s->ctx.xattr_fid_limit = fse->max_xattr; s->ctx.xattr_fid_count = 0; rc = 0; diff --git a/system/vl.c b/system/vl.c index 1c0da7df29..1d14e2e207 100644 --- a/system/vl.c +++ b/system/vl.c @@ -3260,7 +3260,7 @@ void qemu_init(int argc, char **argv) QemuOpts *fsdev; QemuOpts *device; const char *writeout, *sock_fd, *socket, *path, *security_model, - *multidevs; + *multidevs, *max_xattr_str; olist = qemu_find_opts("virtfs"); if (!olist) { @@ -3324,6 +3324,11 @@ void qemu_init(int argc, char **argv) if (multidevs) { qemu_opt_set(fsdev, "multidevs", multidevs, &error_abort); } + max_xattr_str = qemu_opt_get(opts, "max_xattr"); + if (max_xattr_str) { + qemu_opt_set(fsdev, "max_xattr", max_xattr_str, + &error_abort); + } device = qemu_opts_create(qemu_find_opts("device"), NULL, 0, &error_abort); qemu_opt_set(device, "driver", "virtio-9p-pci", &error_abort);