• Chaitanya Kulkarni's avatar
    nvmet: fix inline bio check for bdev-ns · 608a9690
    Chaitanya Kulkarni authored
    When handling rw commands, for inline bio case we only consider
    transfer size. This works well when req->sg_cnt fits into the
    req->inline_bvec, but it will result in the warning in
    __bio_add_page() when req->sg_cnt > NVMET_MAX_INLINE_BVEC.
    
    Consider an I/O size 32768 and first page is not aligned to the page
    boundary, then I/O is split in following manner :-
    
    [ 2206.256140] nvmet: sg->length 3440 sg->offset 656
    [ 2206.256144] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256148] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256152] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256155] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256159] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256163] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256166] nvmet: sg->length 4096 sg->offset 0
    [ 2206.256170] nvmet: sg->length 656 sg->offset 0
    
    Now the req->transfer_size == NVMET_MAX_INLINE_DATA_LEN i.e. 32768, but
    the req->sg_cnt is (9) > NVMET_MAX_INLINE_BIOVEC which is (8).
    This will result in the following warning message :-
    
    nvmet_bdev_execute_rw()
    	bio_add_page()
    		__bio_add_page()
    			WARN_ON_ONCE(bio_full(bio, len));
    
    This scenario is very hard to reproduce on the nvme-loop transport only
    with rw commands issued with the passthru IOCTL interface from the host
    application and the data buffer is allocated with the malloc() and not
    the posix_memalign().
    
    Fixes: 73383adf ("nvmet: don't split large I/Os unconditionally")
    Signed-off-by: default avatarChaitanya Kulkarni <chaitanya.kulkarni@wdc.com>
    Reviewed-by: default avatarSagi Grimberg <sagi@grimberg.me>
    Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
    608a9690
nvmet.h 16.9 KB