When acb->cmd is WRITE or DISCARD block/rbd stores rcb->size into acb->ret
Look here:
if (acb->cmd == RBD_AIO_WRITE ||
acb->cmd == RBD_AIO_DISCARD) {
if (r< 0) {
acb->ret = r;
acb->error = 1;
} else if (!acb->error) {
acb->ret = rcb->size;
}
right now acb->ret is just an int and we might get an overflow if size is too
big.
For discards rcb->size holds the size of the discard - this might be some TB if
you
discard a whole device.
The steps to reproduce are:
mkfs.xfs -f a whole device bigger than int in bytes. mkfs.xfs sends a discard.
Important is that you use scsi-hd and set discard_granularity=512. Otherwise
rbd disabled discard support.
---
block/rbd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/block/rbd.c b/block/rbd.c
index 5a0f79f..0384c6c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -69,7 +69,7 @@ typedef enum {
typedef struct RBDAIOCB {
BlockDriverAIOCB common;
QEMUBH *bh;
- int ret;
+ ssize_t ret;
QEMUIOVector *qiov;
char *bounce;
RBDAIOCmd cmd;
@@ -86,7 +86,7 @@ typedef struct RADOSCB {
int done;
int64_t size;
char *buf;
- int ret;
+ ssize_t ret;
} RADOSCB;
#define RBD_FD_READ 0