Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Jun 2012 20:41:07 +0000 (13:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 21 Jun 2012 20:41:07 +0000 (13:41 -0700)
Pull btrfs fixes from Chris Mason:
 "This is a small pull with btrfs fixes.  The biggest of the bunch is
  another fix for the new backref walking code.

  We're still hammering out one btrfs dio vs buffered reads problem, but
  that one will have to wait for the next rc."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: delay iput with async extents
  Btrfs: add a missing spin_lock
  Btrfs: don't assume to be on the correct extent in add_all_parents
  Btrfs: introduce btrfs_next_old_item

1  2 
fs/btrfs/ctree.h
fs/btrfs/disk-io.c
fs/btrfs/inode.c

diff --combined fs/btrfs/ctree.h
index 8b73b2d4deb7ea532915e0409cbcda8a9155755b,84ac723f58f8c90d49a2c553d0d19f27a7fe1010..fa5c45b39075d858e9803c6cb1044338c7ee5d35
@@@ -2755,13 -2755,18 +2755,18 @@@ static inline int btrfs_insert_empty_it
  int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path);
  int btrfs_next_old_leaf(struct btrfs_root *root, struct btrfs_path *path,
                        u64 time_seq);
- static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p)
+ static inline int btrfs_next_old_item(struct btrfs_root *root,
+                                     struct btrfs_path *p, u64 time_seq)
  {
        ++p->slots[0];
        if (p->slots[0] >= btrfs_header_nritems(p->nodes[0]))
-               return btrfs_next_leaf(root, p);
+               return btrfs_next_old_leaf(root, p, time_seq);
        return 0;
  }
+ static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p)
+ {
+       return btrfs_next_old_item(root, p, 0);
+ }
  int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path);
  int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf);
  int __must_check btrfs_drop_snapshot(struct btrfs_root *root,
@@@ -2976,6 -2981,7 +2981,6 @@@ int btrfs_readpage(struct file *file, s
  void btrfs_evict_inode(struct inode *inode);
  int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
  int btrfs_dirty_inode(struct inode *inode);
 -int btrfs_update_time(struct file *file);
  struct inode *btrfs_alloc_inode(struct super_block *sb);
  void btrfs_destroy_inode(struct inode *inode);
  int btrfs_drop_inode(struct inode *inode);
diff --combined fs/btrfs/disk-io.c
index e1890b1d3075ae36a1cec85dbd3d5ee1aa5f1e08,7d7bc8eace86bf95b3a80e9ea14c3facf41d108a..7b845ff4af99fb643bd959e52dd6f202b7dee7ef
@@@ -2773,7 -2773,7 +2773,7 @@@ static int write_dev_flush(struct btrfs
         * one reference for us, and we leave it for the
         * caller
         */
 -      device->flush_bio = NULL;;
 +      device->flush_bio = NULL;
        bio = bio_alloc(GFP_NOFS, 0);
        if (!bio)
                return -ENOMEM;
@@@ -3426,6 -3426,7 +3426,7 @@@ int btrfs_destroy_delayed_refs(struct b
                                mutex_unlock(&head->mutex);
                                btrfs_put_delayed_ref(ref);
  
+                               spin_lock(&delayed_refs->lock);
                                continue;
                        }
  
diff --combined fs/btrfs/inode.c
index a4f02501da402f594bfee8d471c48b8be5fe8293,4a4f2d59a64bd770a95ecde054ea913f7692580d..d8bb0dbc4941ca3f288119134df64eeb1eb679da
@@@ -987,7 -987,7 +987,7 @@@ static noinline void async_cow_start(st
                            async_cow->start, async_cow->end, async_cow,
                            &num_added);
        if (num_added == 0) {
-               iput(async_cow->inode);
+               btrfs_add_delayed_iput(async_cow->inode);
                async_cow->inode = NULL;
        }
  }
@@@ -1023,7 -1023,7 +1023,7 @@@ static noinline void async_cow_free(str
        struct async_cow *async_cow;
        async_cow = container_of(work, struct async_cow, work);
        if (async_cow->inode)
-               iput(async_cow->inode);
+               btrfs_add_delayed_iput(async_cow->inode);
        kfree(async_cow);
  }
  
@@@ -3840,7 -3840,7 +3840,7 @@@ void btrfs_evict_inode(struct inode *in
        btrfs_end_transaction(trans, root);
        btrfs_btree_balance_dirty(root, nr);
  no_delete:
 -      end_writeback(inode);
 +      clear_inode(inode);
        return;
  }
  
@@@ -4515,18 -4515,46 +4515,18 @@@ int btrfs_dirty_inode(struct inode *ino
   * This is a copy of file_update_time.  We need this so we can return error on
   * ENOSPC for updating the inode in the case of file write and mmap writes.
   */
 -int btrfs_update_time(struct file *file)
 +static int btrfs_update_time(struct inode *inode, struct timespec *now,
 +                           int flags)
  {
 -      struct inode *inode = file->f_path.dentry->d_inode;
 -      struct timespec now;
 -      int ret;
 -      enum { S_MTIME = 1, S_CTIME = 2, S_VERSION = 4 } sync_it = 0;
 -
 -      /* First try to exhaust all avenues to not sync */
 -      if (IS_NOCMTIME(inode))
 -              return 0;
 -
 -      now = current_fs_time(inode->i_sb);
 -      if (!timespec_equal(&inode->i_mtime, &now))
 -              sync_it = S_MTIME;
 -
 -      if (!timespec_equal(&inode->i_ctime, &now))
 -              sync_it |= S_CTIME;
 -
 -      if (IS_I_VERSION(inode))
 -              sync_it |= S_VERSION;
 -
 -      if (!sync_it)
 -              return 0;
 -
 -      /* Finally allowed to write? Takes lock. */
 -      if (mnt_want_write_file(file))
 -              return 0;
 -
 -      /* Only change inode inside the lock region */
 -      if (sync_it & S_VERSION)
 +      if (flags & S_VERSION)
                inode_inc_iversion(inode);
 -      if (sync_it & S_CTIME)
 -              inode->i_ctime = now;
 -      if (sync_it & S_MTIME)
 -              inode->i_mtime = now;
 -      ret = btrfs_dirty_inode(inode);
 -      if (!ret)
 -              mark_inode_dirty_sync(inode);
 -      mnt_drop_write(file->f_path.mnt);
 -      return ret;
 +      if (flags & S_CTIME)
 +              inode->i_ctime = *now;
 +      if (flags & S_MTIME)
 +              inode->i_mtime = *now;
 +      if (flags & S_ATIME)
 +              inode->i_atime = *now;
 +      return btrfs_dirty_inode(inode);
  }
  
  /*
@@@ -6577,7 -6605,7 +6577,7 @@@ int btrfs_page_mkwrite(struct vm_area_s
  
        ret  = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE);
        if (!ret) {
 -              ret = btrfs_update_time(vma->vm_file);
 +              ret = file_update_time(vma->vm_file);
                reserved = 1;
        }
        if (ret) {
@@@ -7650,7 -7678,6 +7650,7 @@@ static const struct inode_operations bt
        .permission     = btrfs_permission,
        .fiemap         = btrfs_fiemap,
        .get_acl        = btrfs_get_acl,
 +      .update_time    = btrfs_update_time,
  };
  static const struct inode_operations btrfs_special_inode_operations = {
        .getattr        = btrfs_getattr,
        .listxattr      = btrfs_listxattr,
        .removexattr    = btrfs_removexattr,
        .get_acl        = btrfs_get_acl,
 +      .update_time    = btrfs_update_time,
  };
  static const struct inode_operations btrfs_symlink_inode_operations = {
        .readlink       = generic_readlink,
        .listxattr      = btrfs_listxattr,
        .removexattr    = btrfs_removexattr,
        .get_acl        = btrfs_get_acl,
 +      .update_time    = btrfs_update_time,
  };
  
  const struct dentry_operations btrfs_dentry_operations = {