Merge branch 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 25 Jun 2016 15:42:31 +0000 (08:42 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 25 Jun 2016 15:42:31 +0000 (08:42 -0700)
Pull btrfs fixes from Chris Mason:
 "I have a two part pull this time because one of the patches Dave
  Sterba collected needed to be against v4.7-rc2 or higher (we used
  rc4).  I try to make my for-linus-xx branch testable on top of the
  last major so we can hand fixes to people on the list more easily, so
  I've split this pull in two.

  This first part has some fixes and two performance improvements that
  we've been testing for some time.

  Josef's two performance fixes are most notable.  The transid tracking
  patch makes a big improvement on pretty much every workload"

* 'for-linus-4.7' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: Force stripesize to the value of sectorsize
  btrfs: fix disk_i_size update bug when fallocate() fails
  Btrfs: fix error handling in map_private_extent_buffer
  Btrfs: fix error return code in btrfs_init_test_fs()
  Btrfs: don't do nocow check unless we have to
  btrfs: fix deadlock in delayed_ref_async_start
  Btrfs: track transid for delayed ref flushing

1  2 
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/volumes.c

diff --combined fs/btrfs/file.c
@@@ -1534,30 -1534,30 +1534,30 @@@ static noinline ssize_t __btrfs_buffere
                reserve_bytes = round_up(write_bytes + sector_offset,
                                root->sectorsize);
  
-               if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
-                                             BTRFS_INODE_PREALLOC)) &&
-                   check_can_nocow(inode, pos, &write_bytes) > 0) {
-                       /*
-                        * For nodata cow case, no need to reserve
-                        * data space.
-                        */
-                       only_release_metadata = true;
-                       /*
-                        * our prealloc extent may be smaller than
-                        * write_bytes, so scale down.
-                        */
-                       num_pages = DIV_ROUND_UP(write_bytes + offset,
-                                                PAGE_SIZE);
-                       reserve_bytes = round_up(write_bytes + sector_offset,
-                                       root->sectorsize);
-                       goto reserve_metadata;
-               }
                ret = btrfs_check_data_free_space(inode, pos, write_bytes);
-               if (ret < 0)
-                       break;
+               if (ret < 0) {
+                       if ((BTRFS_I(inode)->flags & (BTRFS_INODE_NODATACOW |
+                                                     BTRFS_INODE_PREALLOC)) &&
+                           check_can_nocow(inode, pos, &write_bytes) > 0) {
+                               /*
+                                * For nodata cow case, no need to reserve
+                                * data space.
+                                */
+                               only_release_metadata = true;
+                               /*
+                                * our prealloc extent may be smaller than
+                                * write_bytes, so scale down.
+                                */
+                               num_pages = DIV_ROUND_UP(write_bytes + offset,
+                                                        PAGE_SIZE);
+                               reserve_bytes = round_up(write_bytes +
+                                                        sector_offset,
+                                                        root->sectorsize);
+                       } else {
+                               break;
+                       }
+               }
  
- reserve_metadata:
                ret = btrfs_delalloc_reserve_metadata(inode, reserve_bytes);
                if (ret) {
                        if (!only_release_metadata)
@@@ -1712,17 -1712,18 +1712,17 @@@ again
        return num_written ? num_written : ret;
  }
  
 -static ssize_t __btrfs_direct_write(struct kiocb *iocb,
 -                                  struct iov_iter *from,
 -                                  loff_t pos)
 +static ssize_t __btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from)
  {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
 +      loff_t pos = iocb->ki_pos;
        ssize_t written;
        ssize_t written_buffered;
        loff_t endbyte;
        int err;
  
 -      written = generic_file_direct_write(iocb, from, pos);
 +      written = generic_file_direct_write(iocb, from);
  
        if (written < 0 || !iov_iter_count(from))
                return written;
@@@ -1840,7 -1841,7 +1840,7 @@@ static ssize_t btrfs_file_write_iter(st
                atomic_inc(&BTRFS_I(inode)->sync_writers);
  
        if (iocb->ki_flags & IOCB_DIRECT) {
 -              num_written = __btrfs_direct_write(iocb, from, pos);
 +              num_written = __btrfs_direct_write(iocb, from);
        } else {
                num_written = __btrfs_buffered_write(file, from, pos);
                if (num_written > 0)
        spin_lock(&BTRFS_I(inode)->lock);
        BTRFS_I(inode)->last_sub_trans = root->log_transid;
        spin_unlock(&BTRFS_I(inode)->lock);
 -      if (num_written > 0) {
 -              err = generic_write_sync(file, pos, num_written);
 -              if (err < 0)
 -                      num_written = err;
 -      }
 +      if (num_written > 0)
 +              num_written = generic_write_sync(iocb, num_written);
  
        if (sync)
                atomic_dec(&BTRFS_I(inode)->sync_writers);
diff --combined fs/btrfs/inode.c
@@@ -4558,6 -4558,7 +4558,7 @@@ delete
                        BUG_ON(ret);
                        if (btrfs_should_throttle_delayed_refs(trans, root))
                                btrfs_async_run_delayed_refs(root,
+                                                            trans->transid,
                                        trans->delayed_ref_updates * 2, 0);
                        if (be_nice) {
                                if (truncate_space_check(trans, root,
        return retval;
  }
  
 -static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 -                             loff_t offset)
 +static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
  {
        struct file *file = iocb->ki_filp;
        struct inode *inode = file->f_mapping->host;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_dio_data dio_data = { 0 };
 +      loff_t offset = iocb->ki_pos;
        size_t count = 0;
        int flags = 0;
        bool wakeup = true;
  
        ret = __blockdev_direct_IO(iocb, inode,
                                   BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev,
 -                                 iter, offset, btrfs_get_blocks_direct, NULL,
 +                                 iter, btrfs_get_blocks_direct, NULL,
                                   btrfs_submit_direct, flags);
        if (iov_iter_rw(iter) == WRITE) {
                current->journal_info = NULL;
@@@ -10513,10 -10514,10 +10514,10 @@@ static const struct inode_operations bt
        .symlink        = btrfs_symlink,
        .setattr        = btrfs_setattr,
        .mknod          = btrfs_mknod,
 -      .setxattr       = btrfs_setxattr,
 +      .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
        .listxattr      = btrfs_listxattr,
 -      .removexattr    = btrfs_removexattr,
 +      .removexattr    = generic_removexattr,
        .permission     = btrfs_permission,
        .get_acl        = btrfs_get_acl,
        .set_acl        = btrfs_set_acl,
@@@ -10590,10 -10591,10 +10591,10 @@@ static const struct address_space_opera
  static const struct inode_operations btrfs_file_inode_operations = {
        .getattr        = btrfs_getattr,
        .setattr        = btrfs_setattr,
 -      .setxattr       = btrfs_setxattr,
 +      .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
        .listxattr      = btrfs_listxattr,
 -      .removexattr    = btrfs_removexattr,
 +      .removexattr    = generic_removexattr,
        .permission     = btrfs_permission,
        .fiemap         = btrfs_fiemap,
        .get_acl        = btrfs_get_acl,
@@@ -10604,10 -10605,10 +10605,10 @@@ static const struct inode_operations bt
        .getattr        = btrfs_getattr,
        .setattr        = btrfs_setattr,
        .permission     = btrfs_permission,
 -      .setxattr       = btrfs_setxattr,
 +      .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
        .listxattr      = btrfs_listxattr,
 -      .removexattr    = btrfs_removexattr,
 +      .removexattr    = generic_removexattr,
        .get_acl        = btrfs_get_acl,
        .set_acl        = btrfs_set_acl,
        .update_time    = btrfs_update_time,
@@@ -10618,10 -10619,10 +10619,10 @@@ static const struct inode_operations bt
        .getattr        = btrfs_getattr,
        .setattr        = btrfs_setattr,
        .permission     = btrfs_permission,
 -      .setxattr       = btrfs_setxattr,
 +      .setxattr       = generic_setxattr,
        .getxattr       = generic_getxattr,
        .listxattr      = btrfs_listxattr,
 -      .removexattr    = btrfs_removexattr,
 +      .removexattr    = generic_removexattr,
        .update_time    = btrfs_update_time,
  };
  
diff --combined fs/btrfs/volumes.c
  #include <linux/slab.h>
  #include <linux/buffer_head.h>
  #include <linux/blkdev.h>
 -#include <linux/random.h>
  #include <linux/iocontext.h>
  #include <linux/capability.h>
  #include <linux/ratelimit.h>
  #include <linux/kthread.h>
  #include <linux/raid/pq.h>
  #include <linux/semaphore.h>
 +#include <linux/uuid.h>
  #include <asm/div64.h>
  #include "ctree.h"
  #include "extent_map.h"
@@@ -4694,12 -4694,12 +4694,12 @@@ static int __btrfs_alloc_chunk(struct b
  
        if (type & BTRFS_BLOCK_GROUP_RAID5) {
                raid_stripe_len = find_raid56_stripe_len(ndevs - 1,
-                                btrfs_super_stripesize(info->super_copy));
+                                               extent_root->stripesize);
                data_stripes = num_stripes - 1;
        }
        if (type & BTRFS_BLOCK_GROUP_RAID6) {
                raid_stripe_len = find_raid56_stripe_len(ndevs - 2,
-                                btrfs_super_stripesize(info->super_copy));
+                                               extent_root->stripesize);
                data_stripes = num_stripes - 2;
        }