Merge tag 'iomap-5.9-merge-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Aug 2020 02:35:12 +0000 (19:35 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Aug 2020 02:35:12 +0000 (19:35 -0700)
Pull iomap updates from Darrick Wong:
 "The most notable changes are:

   - iomap no longer invalidates the page cache when performing a direct
     read, since doing so is unnecessary and the old directio code
     doesn't do that either.

   - iomap embraced the use of returning ENOTBLK from a direct write to
     trigger falling back to a buffered write since ext4 already did
     this and btrfs wants it for their port.

   - iomap falls back to buffered writes if we're doing a direct write
     and the page cache invalidation after the flush fails; this was
     necessary to handle a corner case in the btrfs port.

   - Remove email virus scanner detritus that was accidentally included
     in yesterday's pull request. Clearly I need(ed) to update my git
     branch checker scripts. :("

* tag 'iomap-5.9-merge-5' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux:
  iomap: fall back to buffered writes for invalidation failures
  xfs: use ENOTBLK for direct I/O to buffered I/O fallback
  iomap: Only invalidate page cache pages on direct IO writes
  iomap: Make sure iomap_end is called after iomap_begin

1  2 
fs/gfs2/file.c
fs/xfs/xfs_file.c
fs/zonefs/super.c

diff --combined fs/gfs2/file.c
@@@ -558,29 -558,8 +558,29 @@@ out_uninit
        return block_page_mkwrite_return(ret);
  }
  
 +static vm_fault_t gfs2_fault(struct vm_fault *vmf)
 +{
 +      struct inode *inode = file_inode(vmf->vma->vm_file);
 +      struct gfs2_inode *ip = GFS2_I(inode);
 +      struct gfs2_holder gh;
 +      vm_fault_t ret;
 +      int err;
 +
 +      gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
 +      err = gfs2_glock_nq(&gh);
 +      if (err) {
 +              ret = block_page_mkwrite_return(err);
 +              goto out_uninit;
 +      }
 +      ret = filemap_fault(vmf);
 +      gfs2_glock_dq(&gh);
 +out_uninit:
 +      gfs2_holder_uninit(&gh);
 +      return ret;
 +}
 +
  static const struct vm_operations_struct gfs2_vm_ops = {
 -      .fault = filemap_fault,
 +      .fault = gfs2_fault,
        .map_pages = filemap_map_pages,
        .page_mkwrite = gfs2_page_mkwrite,
  };
@@@ -835,7 -814,8 +835,8 @@@ static ssize_t gfs2_file_direct_write(s
  
        ret = iomap_dio_rw(iocb, from, &gfs2_iomap_ops, NULL,
                           is_sync_kiocb(iocb));
+       if (ret == -ENOTBLK)
+               ret = 0;
  out:
        gfs2_glock_dq(&gh);
  out_uninit:
  
  static ssize_t gfs2_file_read_iter(struct kiocb *iocb, struct iov_iter *to)
  {
 +      struct gfs2_inode *ip;
 +      struct gfs2_holder gh;
 +      size_t written = 0;
        ssize_t ret;
  
        if (iocb->ki_flags & IOCB_DIRECT) {
                        return ret;
                iocb->ki_flags &= ~IOCB_DIRECT;
        }
 -      return generic_file_read_iter(iocb, to);
 +      iocb->ki_flags |= IOCB_NOIO;
 +      ret = generic_file_read_iter(iocb, to);
 +      iocb->ki_flags &= ~IOCB_NOIO;
 +      if (ret >= 0) {
 +              if (!iov_iter_count(to))
 +                      return ret;
 +              written = ret;
 +      } else {
 +              if (ret != -EAGAIN)
 +                      return ret;
 +              if (iocb->ki_flags & IOCB_NOWAIT)
 +                      return ret;
 +      }
 +      ip = GFS2_I(iocb->ki_filp->f_mapping->host);
 +      gfs2_holder_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
 +      ret = gfs2_glock_nq(&gh);
 +      if (ret)
 +              goto out_uninit;
 +      ret = generic_file_read_iter(iocb, to);
 +      if (ret > 0)
 +              written += ret;
 +      gfs2_glock_dq(&gh);
 +out_uninit:
 +      gfs2_holder_uninit(&gh);
 +      return written ? written : ret;
  }
  
  /**
diff --combined fs/xfs/xfs_file.c
@@@ -505,7 -505,7 +505,7 @@@ xfs_file_dio_aio_write
                 */
                if (xfs_is_cow_inode(ip)) {
                        trace_xfs_reflink_bounce_dio_write(ip, iocb->ki_pos, count);
-                       return -EREMCHG;
+                       return -ENOTBLK;
                }
                iolock = XFS_IOLOCK_EXCL;
        } else {
@@@ -553,8 -553,8 +553,8 @@@ out
        xfs_iunlock(ip, iolock);
  
        /*
-        * No fallback to buffered IO on errors for XFS, direct IO will either
-        * complete fully or fail.
+        * No fallback to buffered IO after short writes for XFS, direct I/O
+        * will either complete fully or return an error.
         */
        ASSERT(ret < 0 || ret == count);
        return ret;
@@@ -714,7 -714,7 +714,7 @@@ xfs_file_write_iter
                 * allow an operation to fall back to buffered mode.
                 */
                ret = xfs_file_dio_aio_write(iocb, from);
-               if (ret != -EREMCHG)
+               if (ret != -ENOTBLK)
                        return ret;
        }
  
@@@ -1080,7 -1080,7 +1080,7 @@@ xfs_file_open
                return -EFBIG;
        if (XFS_FORCED_SHUTDOWN(XFS_M(inode->i_sb)))
                return -EIO;
 -      file->f_mode |= FMODE_NOWAIT;
 +      file->f_mode |= FMODE_NOWAIT | FMODE_BUF_RASYNC;
        return 0;
  }
  
diff --combined fs/zonefs/super.c
@@@ -607,14 -607,14 +607,14 @@@ static ssize_t zonefs_file_dio_append(s
        int nr_pages;
        ssize_t ret;
  
 -      nr_pages = iov_iter_npages(from, BIO_MAX_PAGES);
 -      if (!nr_pages)
 -              return 0;
 -
        max = queue_max_zone_append_sectors(bdev_get_queue(bdev));
        max = ALIGN_DOWN(max << SECTOR_SHIFT, inode->i_sb->s_blocksize);
        iov_iter_truncate(from, max);
  
 +      nr_pages = iov_iter_npages(from, BIO_MAX_PAGES);
 +      if (!nr_pages)
 +              return 0;
 +
        bio = bio_alloc_bioset(GFP_NOFS, nr_pages, &fs_bio_set);
        if (!bio)
                return -ENOMEM;
@@@ -786,8 -786,11 +786,11 @@@ static ssize_t zonefs_file_write_iter(s
        if (iocb->ki_pos >= ZONEFS_I(inode)->i_max_size)
                return -EFBIG;
  
-       if (iocb->ki_flags & IOCB_DIRECT)
-               return zonefs_file_dio_write(iocb, from);
+       if (iocb->ki_flags & IOCB_DIRECT) {
+               ssize_t ret = zonefs_file_dio_write(iocb, from);
+               if (ret != -ENOTBLK)
+                       return ret;
+       }
  
        return zonefs_file_buffered_write(iocb, from);
  }
@@@ -1119,7 -1122,7 +1122,7 @@@ static int zonefs_create_zgroup(struct 
        char *file_name;
        struct dentry *dir;
        unsigned int n = 0;
 -      int ret = -ENOMEM;
 +      int ret;
  
        /* If the group is empty, there is nothing to do */
        if (!zd->nr_zones[type])
                zgroup_name = "seq";
  
        dir = zonefs_create_inode(sb->s_root, zgroup_name, NULL, type);
 -      if (!dir)
 +      if (!dir) {
 +              ret = -ENOMEM;
                goto free;
 +      }
  
        /*
         * The first zone contains the super block: skip it.
                 * Use the file number within its group as file name.
                 */
                snprintf(file_name, ZONEFS_NAME_MAX - 1, "%u", n);
 -              if (!zonefs_create_inode(dir, file_name, zone, type))
 +              if (!zonefs_create_inode(dir, file_name, zone, type)) {
 +                      ret = -ENOMEM;
                        goto free;
 +              }
  
                n++;
        }