From: Christian Schoenebeck <[email protected]> Previous patch introduced a limit of max. 1024 simultaneous xattr FIDs.
This patch introduces an option "max_attr" that allows to override this limit, just for the case that some user might run into this limit for some reason, even if unlikely; or for reducing the limit further down (e.g. that default limit of 1024 would cap at max. 64 MiB host memory, at least on Linux hosts where the limit per xattr is 64k). This new "max_xattr" option can be specified with both -fsdev and -virtfs command line options, with the "local" and the "synth" fs drivers. The previous limit of 1024 is preserved as the default value. Link: https://lore.kernel.org/qemu-devel/b7631ac0d8dde0629bc7c4f2c4185d9f57b962b4.1781361555.git.qemu_...@crudebyte.com Signed-off-by: Christian Schoenebeck <[email protected]> (cherry picked from commit e6116a81f04c48af9530d984d16ef4ed4346e865) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h index 454761d81d7..1d931144f40 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 07a18c6e48d..c2c1e83611b 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 57877dad0a7..f97103cf442 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 aa48306b0ee..4708e170a42 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 b3743f61696..322dc3bb690 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 437588f9d5c..1b064a27fc5 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -4505,8 +4505,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 246623b3196..806327bd39a 100644 --- a/system/vl.c +++ b/system/vl.c @@ -3254,7 +3254,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) { @@ -3318,6 +3318,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); -- 2.47.3
