xfstests/xfs/080 fix

Let's say there are 2 extents: one unwritten and the other written.

rwtest.file:
 EXT: FILE-OFFSET       BLOCK-RANGE      AG AG-OFFSET        TOTAL FLAGS
   0: [0..15]:          160..175          0 (160..175)          16 10000
   1: [16..63]:         176..223          0 (176..223)          48 00000

Then we do a direct io write to these 2 extends.

root@block:/mnt/test# xfs_io
xfs_io> open -d rwtest.file
xfs_io> pwrite -b 32768 0 32768

EXT 0 should be converted to written extent.

rwtest.file:
 EXT: FILE-OFFSET       BLOCK-RANGE      AG AG-OFFSET        TOTAL FLAGS
   0: [0..63]:          160..223          0 (160..223)          64 00000

There was a bug that caused dio->bi_privte set to NULL, so below code path
was not executed, so the extent not converted from unwritten to written.

[   72.328096] Call Trace:
[   72.328786]  [<ffffffff8169c2f3>] dump_stack+0x4f/0x7b
[   72.330002]  [<ffffffff8127140f>] xfs_bmapi_convert_unwritten+0x73/0x176
[   72.331565]  [<ffffffff8126cd9d>] ? xfs_bmap_search_extents+0x60/0xd6
[   72.333059]  [<ffffffff812c96f1>] ? kmem_zone_alloc+0x6e/0xba
[   72.334412]  [<ffffffff8127a233>] xfs_bmapi_write+0x2a0/0x7ee
[   72.335777]  [<ffffffff812b9455>] xfs_iomap_write_unwritten+0x205/0x413
[   72.337300]  [<ffffffff8129d7e2>] xfs_end_io+0x50/0x75
[   72.338495]  [<ffffffff8129dab9>] xfs_end_io_direct_write+0x176/0x26c
[   72.339952]  [<ffffffff810d20a4>] ? delayacct_end+0x55/0x5e
[   72.341238]  [<ffffffff8118759d>] dio_complete+0x7c/0x134
[   72.342488]  [<ffffffff811882a7>] __blockdev_direct_IO+0x633/0x666
[   72.343908]  [<ffffffff8129fdbb>] ? xfs_get_blocks+0x13/0x13
[   72.345263]  [<ffffffff8129d890>] xfs_vm_direct_IO+0x89/0x90
[   72.346598]  [<ffffffff8129d943>] ? xfs_setfilesize_trans_alloc+0xac/0xac
[   72.348185]  [<ffffffff8169ae5e>] xfs_file_dio_aio_write+0x2e0/0x449
[   72.349652]  [<ffffffff813e1028>] ? __clear_user+0x36/0x5b
[   72.350950]  [<ffffffff812af9c6>] xfs_file_write_iter+0x75/0x105
[   72.352369]  [<ffffffff81151524>] __vfs_write+0x97/0xc0
[   72.353607]  [<ffffffff81151b1f>] vfs_write+0xb5/0x16f
[   72.354832]  [<ffffffff811522c3>] SyS_write+0x4a/0x94
[   72.356060]  [<ffffffff816a4b17>] system_call_fastpath+0x12/0x6f

The bug is the local "map_bh" in get_blocks().

For XFS:
map_bh->b_private saves "ioend"(see xfs_map_direct()).
We need to pass map_bh->b_private to next call of get_blocks().

Fixed it by moving "map_bh" to dio_alloc_bios(),
then it's passed down to dio_send_bio() -> get_blocks().
1 file changed