Skip to content

Commit

Permalink
[openSUSE] block: Add a thread-pool version of fstat (bsc#1211000)
Browse files Browse the repository at this point in the history
The fstat call can take a long time to finish when running over
NFS. Add a version of it that runs in the thread pool.

Adapt one of its users, raw_co_get_allocated_file size to use the new
version. That function is called via QMP under the qemu_global_mutex
so it has a large chance of blocking VCPU threads in case it takes too
long to finish.

Link: https://lore.kernel.org/r/[email protected]
Reviewed-by: Claudio Fontana <[email protected]>
Reviewed-by: Hanna Czenczek <[email protected]>
Signed-off-by: João Silva <[email protected]>
References: bsc#1211000
Signed-off-by: Fabiano Rosas <[email protected]>
Signed-off-by: Dario Faggioli <[email protected]>
  • Loading branch information
João Silva authored and dfaggioli committed Dec 18, 2024
1 parent 0084778 commit 45f2f0c
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 4 deletions.
40 changes: 37 additions & 3 deletions block/file-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ typedef struct RawPosixAIOData {
struct {
unsigned long op;
} zone_mgmt;
struct {
struct stat *st;
} fstat;
};
} RawPosixAIOData;

Expand Down Expand Up @@ -2624,6 +2627,34 @@ static void raw_close(BlockDriverState *bs)
}
}

static int handle_aiocb_fstat(void *opaque)
{
RawPosixAIOData *aiocb = opaque;

if (fstat(aiocb->aio_fildes, aiocb->fstat.st) < 0) {
return -errno;
}

return 0;
}

static int coroutine_fn raw_co_fstat(BlockDriverState *bs, struct stat *st)
{
BDRVRawState *s = bs->opaque;
RawPosixAIOData acb;

acb = (RawPosixAIOData) {
.bs = bs,
.aio_fildes = s->fd,
.aio_type = QEMU_AIO_FSTAT,
.fstat = {
.st = st,
},
};

return raw_thread_pool_submit(handle_aiocb_fstat, &acb);
}

/**
* Truncates the given regular file @fd to @offset and, when growing, fills the
* new space according to @prealloc.
Expand Down Expand Up @@ -2868,11 +2899,14 @@ static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs)
static int64_t coroutine_fn raw_co_get_allocated_file_size(BlockDriverState *bs)
{
struct stat st;
BDRVRawState *s = bs->opaque;
int ret;

if (fstat(s->fd, &st) < 0) {
return -errno;
ret = raw_co_fstat(bs, &st);

if (ret) {
return ret;
}

return (int64_t)st.st_blocks * 512;
}

Expand Down
4 changes: 3 additions & 1 deletion include/block/raw-aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define QEMU_AIO_ZONE_REPORT 0x0100
#define QEMU_AIO_ZONE_MGMT 0x0200
#define QEMU_AIO_ZONE_APPEND 0x0400
#define QEMU_AIO_FSTAT 0x0800
#define QEMU_AIO_TYPE_MASK \
(QEMU_AIO_READ | \
QEMU_AIO_WRITE | \
Expand All @@ -42,7 +43,8 @@
QEMU_AIO_TRUNCATE | \
QEMU_AIO_ZONE_REPORT | \
QEMU_AIO_ZONE_MGMT | \
QEMU_AIO_ZONE_APPEND)
QEMU_AIO_ZONE_APPEND | \
QEMU_AIO_FSTAT)

/* AIO flags */
#define QEMU_AIO_MISALIGNED 0x1000
Expand Down

0 comments on commit 45f2f0c

Please sign in to comment.