Jens Axboe [off-list ref] writes:
quoted hunk
On 10/21/21 12:05 PM, Jeff Moyer wrote:
quoted
quoted
quoted
I'll follow up if there are issues.
s390 (big endian, 64 bit) is failing libaio test 21:
# harness/cases/21.p
Expected -EAGAIN, got 4294967285
If I print out both res and res2 using %lx, you'll see what happened:
Expected -EAGAIN, got fffffff5,ffffffff
The sign extension is being split up.
Funky, does it work if you apply this on top?
diff --git a/fs/aio.c b/fs/aio.c
index 3674abc43788..c56437908339 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1442,8 +1442,8 @@ static void aio_complete_rw(struct kiocb *kiocb, u64 res)
* 32-bits of value at most for either value, bundle these up and
* pass them in one u64 value.
*/
- iocb->ki_res.res = lower_32_bits(res);
- iocb->ki_res.res2 = upper_32_bits(res);
+ iocb->ki_res.res = (long) (res & 0xffffffff);
+ iocb->ki_res.res2 = (long) (res >> 32);
iocb_put(iocb);
}
I think you'll also need to clamp any ki_complete() call sites to 32
bits (cast to int, or what have you). Otherwise that sign extension
will spill over into res2.
fwiw, I tested with this:
iocb->ki_res.res = (long)(int)lower_32_bits(res);
iocb->ki_res.res2 = (long)(int)upper_32_bits(res);
Coupled with the call site changes, that made things work for me.
-Jeff