The first write after file create fails to take the direct IO (Peer-to-Peer) path and falls back to slower software copy. The function get_more_block() sets 'create' to 0 after comparing 'unsigned long fs_startblk = 0' with 'long long (i_size_read(dio->inode) - 1) >> i_blkbits = 0xfffffffffffff'. v2: Instead of casting to loff_t check explicitly if i_size > 0 v3: Use cached dio->i_size instead of i_size_read() which isn't cheap on 32-bit SMP Signed-off-by: Harish Kasiviswanathan <Harish.Kasiviswanathan@xxxxxxx> --- fs/direct-io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/direct-io.c b/fs/direct-io.c index 3aafb33..1c33830 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -686,9 +686,8 @@ static int get_more_blocks(struct dio *dio, struct dio_submit *sdio, * buffer head. */ create = dio->op == REQ_OP_WRITE; - if (dio->flags & DIO_SKIP_HOLES) { - if (fs_startblk <= ((i_size_read(dio->inode) - 1) >> - i_blkbits)) + if (dio->flags & DIO_SKIP_HOLES && dio->i_size) { + if (fs_startblk <= ((dio->i_size - 1) >> i_blkbits)) create = 0; } -- 2.7.4