Bug 1303001 - read() return -1 ENOMEM (Cannot allocate memory) when open() with O_DIRECT parameter
read() return -1 ENOMEM (Cannot allocate memory) when open() with O_DIRECT p...
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: kernel-aarch64 (Show other bugs)
aarch64 Linux
unspecified Severity unspecified
: rc
: ---
Assigned To: Dave Anderson
Red Hat Kernel QE team
Depends On:
  Show dependency treegraph
Reported: 2016-01-29 04:22 EST by Li Wang
Modified: 2016-02-11 15:38 EST (History)
3 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2016-02-11 15:38:35 EST
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)

  None (edit)
Description Li Wang 2016-01-29 04:22:23 EST
Description of problem:

ltp/diotest4 failed on 4.4.0-0.rc4.21.el7.aarch64 as:
tag=dio04 stime=1454038921
diotest4    1  TPASS  :  Negative Offset
diotest4    2  TPASS  :  removed
diotest4    3  TPASS  :  Odd count of read and write
diotest4    4  TFAIL  :  diotest4.c:294: allows read beyond file size. returns -1: Cannot allocate memory
diotest4    5  TPASS  :  Invalid file descriptor
diotest4    6  TPASS  :  Out of range file descriptor
diotest4    7  TPASS  :  Closed file descriptor
diotest4    8  TPASS  :  removed
diotest4    9  TCONF  :  diotest4.c:344: Direct I/O on /dev/null is not supported
diotest4   10  TFAIL  :  diotest4.c:150: read failed for mmapped file. returns -1: Cannot allocate memory
diotest4   11  TFAIL  :  diotest4.c:182: read, write to a mmaped file
diotest4   12  TPASS  :  read, write to an unmapped file
diotest4   13  TPASS  :  read from file not open for reading
diotest4   14  TPASS  :  write to file not open for writing
diotest4   15  TPASS  :  read, write with non-aligned buffer
diotest4   16  TPASS  :  read, write buffer in read-only space
diotest4   17  TPASS  :  read, write in non-existant space
diotest4   18  TPASS  :  read, write for file with O_SYNC
diotest4    0  TINFO  :  2/15 test blocks failed

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:

Actual results:

Expected results:

Additional info:
Comment 3 Larry Woodman 2016-02-04 08:11:03 EST
This is most likely a side effect of the 64KB pages used in PPC64.

Comment 4 Dave Anderson 2016-02-11 15:38:35 EST
This bug was recently introduced into the upstream kernel by this commit:

  commit 74cedf9b6c603f2278a05bc91b140b32b434d0b5
  Author: Jan Kara <jack@suse.cz>
  Date:   Mon Nov 30 10:15:42 2015 -0700

    direct-io: Fix negative return from dio read beyond eof
    Assume a filesystem with 4KB blocks. When a file has size 1000 bytes and
    we issue direct IO read at offset 1024, blockdev_direct_IO() reads the
    tail of the last block and the logic for handling short DIO reads in
    dio_complete() results in a return value -24 (1000 - 1024) which
    obviously confuses userspace.
    Fix the problem by bailing out early once we sample i_size and can
    reliably check that direct IO read starts beyond i_size.
    Reported-by: Avi Kivity <avi@scylladb.com>
    Fixes: 9fe55eea7e4b444bafc42fa0000cc2d1d2847275
    CC: stable@vger.kernel.org
    CC: Steven Whitehouse <swhiteho@redhat.com>
    Signed-off-by: Jan Kara <jack@suse.cz>
    Signed-off-by: Jens Axboe <axboe@fb.com>

which was in 4.4-rc4: 

  # git describe --contains 74cedf9b6c603f2278a05bc91b140b32b434d0b5

It was subsequently fixed by this commit:

  commit 2d4594acbf6d8f75a27f3578476b6a27d8b13ebb
  Author: Al Viro <viro@zeniv.linux.org.uk>
  Date:   Tue Dec 8 12:22:47 2015 -0500

    fix the regression from "direct-io: Fix negative return from dio read beyond eof"
    Sure, it's better to bail out of past-the-eof read and return 0 than return
    a bogus negative value on such.  Only we'd better make sure we are bailing out
    with 0 and not -ENOMEM...
    Cc: stable@vger.kernel.org
    Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>

which was in 4.4-rc5:

  git describe --contains 2d4594acbf6d8f75a27f3578476b6a27d8b13ebb

The 4.4.0-0.rc4.21.el7 kernel-aarch64 snapshot just happened to 
be taken in between the two commits above:

  %define rpmversion 4.4.0
  %define pkgrelease 0.rc4.21.el7

The current kernel-aarch64 kernel is version 4.5.0-0.rc3.27.el7, which
has Al Viro's fix, and which passes the test as expected:
  # uname -r
  # ./diotest4
  PASS! Read beyond the file size

Note You need to log in before you can comment on or make changes to this bug.