Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Dec 2016 02:44:00 +0000 (18:44 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 18 Dec 2016 02:44:00 +0000 (18:44 -0800)
Pull more vfs updates from Al Viro:
 "In this pile:

   - autofs-namespace series
   - dedupe stuff
   - more struct path constification"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: (40 commits)
  ocfs2: implement the VFS clone_range, copy_range, and dedupe_range features
  ocfs2: charge quota for reflinked blocks
  ocfs2: fix bad pointer cast
  ocfs2: always unlock when completing dio writes
  ocfs2: don't eat io errors during _dio_end_io_write
  ocfs2: budget for extent tree splits when adding refcount flag
  ocfs2: prohibit refcounted swapfiles
  ocfs2: add newlines to some error messages
  ocfs2: convert inode refcount test to a helper
  simple_write_end(): don't zero in short copy into uptodate
  exofs: don't mess with simple_write_{begin,end}
  9p: saner ->write_end() on failing copy into non-uptodate page
  fix gfs2_stuffed_write_end() on short copies
  fix ceph_write_end()
  nfs_write_end(): fix handling of short copies
  vfs: refactor clone/dedupe_file_range common functions
  fs: try to clone files first in vfs_copy_file_range
  vfs: misc struct path constification
  namespace.c: constify struct path passed to a bunch of primitives
  quota: constify struct path in quota_on
  ...

20 files changed:
1  2 
Documentation/filesystems/Locking
fs/9p/vfs_addr.c
fs/btrfs/ctree.h
fs/btrfs/file.c
fs/btrfs/ioctl.c
fs/ceph/addr.c
fs/ext4/super.c
fs/internal.h
fs/namei.c
fs/nfs/file.c
fs/ocfs2/aops.c
fs/ocfs2/refcounttree.c
fs/read_write.c
fs/xfs/xfs_file.c
fs/xfs/xfs_reflink.c
include/linux/fs.h
kernel/audit.c
kernel/audit_fsnotify.c
kernel/audit_tree.c
kernel/audit_watch.c

Simple merge
Simple merge
index 50bcfb80d33a012e0b0dc0daa6fe1aeb03d5b2cd,05f75a949af4deb69eab8f33bbd0ac4eed0de5e6..6a823719b6c580557cccab3d01123d50857ad334
@@@ -3228,13 -3227,11 +3228,10 @@@ int btrfs_drop_extents(struct btrfs_tra
  int btrfs_mark_extent_written(struct btrfs_trans_handle *trans,
                              struct inode *inode, u64 start, u64 end);
  int btrfs_release_file(struct inode *inode, struct file *file);
 -int btrfs_dirty_pages(struct btrfs_root *root, struct inode *inode,
 -                    struct page **pages, size_t num_pages,
 -                    loff_t pos, size_t write_bytes,
 +int btrfs_dirty_pages(struct inode *inode, struct page **pages,
 +                    size_t num_pages, loff_t pos, size_t write_bytes,
                      struct extent_state **cached);
  int btrfs_fdatawrite_range(struct inode *inode, loff_t start, loff_t end);
- ssize_t btrfs_copy_file_range(struct file *file_in, loff_t pos_in,
-                             struct file *file_out, loff_t pos_out,
-                             size_t len, unsigned int flags);
  int btrfs_clone_file_range(struct file *file_in, loff_t pos_in,
                           struct file *file_out, loff_t pos_out, u64 len);
  
diff --cc fs/btrfs/file.c
Simple merge
Simple merge
diff --cc fs/ceph/addr.c
Simple merge
diff --cc fs/ext4/super.c
Simple merge
diff --cc fs/internal.h
Simple merge
diff --cc fs/namei.c
Simple merge
diff --cc fs/nfs/file.c
Simple merge
diff --cc fs/ocfs2/aops.c
Simple merge
Simple merge
diff --cc fs/read_write.c
index 53bccd1c786e783b9e4083658a864a880c65c11f,dbf3f7ffdf3f69201f90314daac7f75d221650cf..da6de12b5c46d4a56e15e892f527153682ff6e30
@@@ -1538,16 -1538,34 +1538,32 @@@ ssize_t vfs_copy_file_range(struct fil
        if (len == 0)
                return 0;
  
 -      ret = mnt_want_write_file(file_out);
 -      if (ret)
 -              return ret;
 +      sb_start_write(inode_out->i_sb);
  
-       ret = -EOPNOTSUPP;
-       if (file_out->f_op->copy_file_range)
+       /*
+        * Try cloning first, this is supported by more file systems, and
+        * more efficient if both clone and copy are supported (e.g. NFS).
+        */
+       if (file_in->f_op->clone_file_range) {
+               ret = file_in->f_op->clone_file_range(file_in, pos_in,
+                               file_out, pos_out, len);
+               if (ret == 0) {
+                       ret = len;
+                       goto done;
+               }
+       }
+       if (file_out->f_op->copy_file_range) {
                ret = file_out->f_op->copy_file_range(file_in, pos_in, file_out,
                                                      pos_out, len, flags);
-       if (ret == -EOPNOTSUPP)
-               ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out,
-                               len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
+               if (ret != -EOPNOTSUPP)
+                       goto done;
+       }
+       ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out,
+                       len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0);
  
+ done:
        if (ret > 0) {
                fsnotify_access(file_in);
                add_rchar(current, ret);
Simple merge
index 88fd03c66e990a02aa444ccae9bf0227ed70fc50,95d6828967f095dd95b23ce878362f0ce5673ec6..aca2d4bd4303b07b41a86d0bbe1e43bb4fe88308
@@@ -1251,32 -1194,16 +1143,14 @@@ xfs_reflink_remap_range
                return -EIO;
  
        /* Lock both files against IO */
 -      if (same_inode) {
 -              xfs_ilock(src, XFS_IOLOCK_EXCL);
 +      lock_two_nondirectories(inode_in, inode_out);
 +      if (same_inode)
                xfs_ilock(src, XFS_MMAPLOCK_EXCL);
 -      } else {
 -              xfs_lock_two_inodes(src, dest, XFS_IOLOCK_EXCL);
 +      else
                xfs_lock_two_inodes(src, dest, XFS_MMAPLOCK_EXCL);
 -      }
  
-       /* Don't touch certain kinds of inodes */
-       ret = -EPERM;
-       if (IS_IMMUTABLE(inode_out))
-               goto out_unlock;
-       ret = -ETXTBSY;
-       if (IS_SWAPFILE(inode_in) || IS_SWAPFILE(inode_out))
-               goto out_unlock;
-       /* Don't reflink dirs, pipes, sockets... */
-       ret = -EISDIR;
-       if (S_ISDIR(inode_in->i_mode) || S_ISDIR(inode_out->i_mode))
-               goto out_unlock;
+       /* Check file eligibility and prepare for block sharing. */
        ret = -EINVAL;
-       if (S_ISFIFO(inode_in->i_mode) || S_ISFIFO(inode_out->i_mode))
-               goto out_unlock;
-       if (!S_ISREG(inode_in->i_mode) || !S_ISREG(inode_out->i_mode))
-               goto out_unlock;
        /* Don't reflink realtime inodes */
        if (XFS_IS_REALTIME_INODE(src) || XFS_IS_REALTIME_INODE(dest))
                goto out_unlock;
Simple merge
diff --cc kernel/audit.c
Simple merge
Simple merge
Simple merge
Simple merge