Skip to content

Commit

Permalink
f2fs: Return EOF on unaligned end of file DIO read
Browse files Browse the repository at this point in the history
Reading past end of file returns EOF for aligned reads but -EINVAL for
unaligned reads on f2fs.  While documentation is not strict about this
corner case, most filesystem returns EOF on this case, like iomap
filesystems.  This patch consolidates the behavior for f2fs, by making
it return EOF(0).

it can be verified by a read loop on a file that does a partial read
before EOF (A file that doesn't end at an aligned address).  The
following code fails on an unaligned file on f2fs, but not on
btrfs, ext4, and xfs.

  while (done < total) {
    ssize_t delta = pread(fd, buf + done, total - done, off + done);
    if (!delta)
      break;
    ...
  }

It is arguable whether filesystems should actually return EOF or
-EINVAL, but since iomap filesystems support it, and so does the
original DIO code, it seems reasonable to consolidate on that.

Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
Reviewed-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
  • Loading branch information
krisman-at-collabora authored and Jaegeuk Kim committed Sep 9, 2020
1 parent e2cab03 commit 20d0a10
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fs/f2fs/data.c
Original file line number Diff line number Diff line change
Expand Up @@ -3550,6 +3550,9 @@ static int check_direct_IO(struct inode *inode, struct iov_iter *iter,
unsigned long align = offset | iov_iter_alignment(iter);
struct block_device *bdev = inode->i_sb->s_bdev;

if (iov_iter_rw(iter) == READ && offset >= i_size_read(inode))
return 1;

if (align & blocksize_mask) {
if (bdev)
blkbits = blksize_bits(bdev_logical_block_size(bdev));
Expand Down

0 comments on commit 20d0a10

Please sign in to comment.