Merge tag 'dax-fixes-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Feb 2020 00:52:08 +0000 (16:52 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 12 Feb 2020 00:52:08 +0000 (16:52 -0800)
Pull dax fixes from Dan Williams:
 "A fix for an xfstest failure and some and an update that removes an
  fsdax dependency on block devices.

  Summary:

   - Fix RWF_NOWAIT writes to properly return -EAGAIN

   - Clean up an unused helper

   - Update dax_writeback_mapping_range to not need a block_device
     argument"

* tag 'dax-fixes-5.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm:
  dax: pass NOWAIT flag to iomap_apply
  dax: Get rid of fs_dax_get_by_host() helper
  dax: Pass dax_dev instead of bdev to dax_writeback_mapping_range()

1  2 
fs/ext4/inode.c

diff --combined fs/ext4/inode.c
@@@ -48,6 -48,8 +48,6 @@@
  
  #include <trace/events/ext4.h>
  
 -#define MPAGE_DA_EXTENT_TAIL 0x01
 -
  static __u32 ext4_inode_csum(struct inode *inode, struct ext4_inode *raw,
                              struct ext4_inode_info *ei)
  {
@@@ -269,7 -271,6 +269,7 @@@ void ext4_evict_inode(struct inode *ino
        if (inode->i_blocks) {
                err = ext4_truncate(inode);
                if (err) {
 +                      ext4_set_errno(inode->i_sb, -err);
                        ext4_error(inode->i_sb,
                                   "couldn't truncate inode %lu (err %d)",
                                   inode->i_ino, err);
@@@ -401,7 -402,7 +401,7 @@@ int ext4_issue_zeroout(struct inode *in
  {
        int ret;
  
 -      if (IS_ENCRYPTED(inode))
 +      if (IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode))
                return fscrypt_zeroout_range(inode, lblk, pblk, len);
  
        ret = sb_issue_zeroout(inode->i_sb, pblk, len, GFP_NOFS);
@@@ -2477,12 -2478,10 +2477,12 @@@ update_disksize
                        EXT4_I(inode)->i_disksize = disksize;
                up_write(&EXT4_I(inode)->i_data_sem);
                err2 = ext4_mark_inode_dirty(handle, inode);
 -              if (err2)
 +              if (err2) {
 +                      ext4_set_errno(inode->i_sb, -err2);
                        ext4_error(inode->i_sb,
                                   "Failed to mark inode %lu dirty",
                                   inode->i_ino);
 +              }
                if (!err)
                        err = err2;
        }
@@@ -2867,7 -2866,7 +2867,7 @@@ static int ext4_dax_writepages(struct a
        percpu_down_read(&sbi->s_journal_flag_rwsem);
        trace_ext4_writepages(inode, wbc);
  
-       ret = dax_writeback_mapping_range(mapping, inode->i_sb->s_bdev, wbc);
+       ret = dax_writeback_mapping_range(mapping, sbi->s_daxdev, wbc);
        trace_ext4_writepages_result(inode, wbc, ret,
                                     nr_to_write - wbc->nr_to_write);
        percpu_up_read(&sbi->s_journal_flag_rwsem);
@@@ -3449,22 -3448,6 +3449,22 @@@ static int ext4_iomap_begin(struct inod
        return 0;
  }
  
 +static int ext4_iomap_overwrite_begin(struct inode *inode, loff_t offset,
 +              loff_t length, unsigned flags, struct iomap *iomap,
 +              struct iomap *srcmap)
 +{
 +      int ret;
 +
 +      /*
 +       * Even for writes we don't need to allocate blocks, so just pretend
 +       * we are reading to save overhead of starting a transaction.
 +       */
 +      flags &= ~IOMAP_WRITE;
 +      ret = ext4_iomap_begin(inode, offset, length, flags, iomap, srcmap);
 +      WARN_ON_ONCE(iomap->type != IOMAP_MAPPED);
 +      return ret;
 +}
 +
  static int ext4_iomap_end(struct inode *inode, loff_t offset, loff_t length,
                          ssize_t written, unsigned flags, struct iomap *iomap)
  {
@@@ -3486,11 -3469,6 +3486,11 @@@ const struct iomap_ops ext4_iomap_ops 
        .iomap_end              = ext4_iomap_end,
  };
  
 +const struct iomap_ops ext4_iomap_overwrite_ops = {
 +      .iomap_begin            = ext4_iomap_overwrite_begin,
 +      .iomap_end              = ext4_iomap_end,
 +};
 +
  static bool ext4_iomap_is_delalloc(struct inode *inode,
                                   struct ext4_map_blocks *map)
  {
@@@ -3723,12 -3701,8 +3723,12 @@@ static int __ext4_block_zero_page_range
                if (S_ISREG(inode->i_mode) && IS_ENCRYPTED(inode)) {
                        /* We expect the key to be set. */
                        BUG_ON(!fscrypt_has_encryption_key(inode));
 -                      WARN_ON_ONCE(fscrypt_decrypt_pagecache_blocks(
 -                                      page, blocksize, bh_offset(bh)));
 +                      err = fscrypt_decrypt_pagecache_blocks(page, blocksize,
 +                                                             bh_offset(bh));
 +                      if (err) {
 +                              clear_buffer_uptodate(bh);
 +                              goto unlock;
 +                      }
                }
        }
        if (ext4_should_journal_data(inode)) {
@@@ -3938,6 -3912,9 +3938,6 @@@ int ext4_punch_hole(struct inode *inode
        unsigned int credits;
        int ret = 0;
  
 -      if (!S_ISREG(inode->i_mode))
 -              return -EOPNOTSUPP;
 -
        trace_ext4_punch_hole(inode, offset, length, 0);
  
        ext4_clear_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA);
@@@ -4263,8 -4240,6 +4263,8 @@@ static int __ext4_get_inode_loc(struct 
        bh = sb_getblk(sb, block);
        if (unlikely(!bh))
                return -ENOMEM;
 +      if (ext4_simulate_fail(sb, EXT4_SIM_INODE_EIO))
 +              goto simulate_eio;
        if (!buffer_uptodate(bh)) {
                lock_buffer(bh);
  
@@@ -4363,8 -4338,6 +4363,8 @@@ make_io
                blk_finish_plug(&plug);
                wait_on_buffer(bh);
                if (!buffer_uptodate(bh)) {
 +              simulate_eio:
 +                      ext4_set_errno(inode->i_sb, EIO);
                        EXT4_ERROR_INODE_BLOCK(inode, block,
                                               "unable to read itable block");
                        brelse(bh);
@@@ -4578,9 -4551,7 +4578,9 @@@ struct inode *__ext4_iget(struct super_
                                              sizeof(gen));
        }
  
 -      if (!ext4_inode_csum_verify(inode, raw_inode, ei)) {
 +      if (!ext4_inode_csum_verify(inode, raw_inode, ei) ||
 +          ext4_simulate_fail(sb, EXT4_SIM_INODE_CRC)) {
 +              ext4_set_errno(inode->i_sb, EFSBADCRC);
                ext4_error_inode(inode, function, line, 0,
                                 "iget: checksum invalid");
                ret = -EFSBADCRC;
@@@ -5119,7 -5090,6 +5119,7 @@@ int ext4_write_inode(struct inode *inod
                if (wbc->sync_mode == WB_SYNC_ALL && !wbc->for_sync)
                        sync_dirty_buffer(iloc.bh);
                if (buffer_req(iloc.bh) && !buffer_uptodate(iloc.bh)) {
 +                      ext4_set_errno(inode->i_sb, EIO);
                        EXT4_ERROR_INODE_BLOCK(inode, iloc.bh->b_blocknr,
                                         "IO error syncing inode");
                        err = -EIO;
@@@ -5398,8 -5368,7 +5398,8 @@@ int ext4_getattr(const struct path *pat
        struct ext4_inode_info *ei = EXT4_I(inode);
        unsigned int flags;
  
 -      if (EXT4_FITS_IN_INODE(raw_inode, ei, i_crtime)) {
 +      if ((request_mask & STATX_BTIME) &&
 +          EXT4_FITS_IN_INODE(raw_inode, ei, i_crtime)) {
                stat->result_mask |= STATX_BTIME;
                stat->btime.tv_sec = ei->i_crtime.tv_sec;
                stat->btime.tv_nsec = ei->i_crtime.tv_nsec;
@@@ -5723,7 -5692,7 +5723,7 @@@ int ext4_expand_extra_isize(struct inod
        error = ext4_journal_get_write_access(handle, iloc->bh);
        if (error) {
                brelse(iloc->bh);
 -              goto out_stop;
 +              goto out_unlock;
        }
  
        error = __ext4_expand_extra_isize(inode, new_extra_isize, iloc,
        if (!error)
                error = rc;
  
 +out_unlock:
        ext4_write_unlock_xattr(inode, &no_expand);
 -out_stop:
        ext4_journal_stop(handle);
        return error;
  }