Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 17 Mar 2013 18:04:14 +0000 (11:04 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 17 Mar 2013 18:04:14 +0000 (11:04 -0700)
Pull btrfs fixes from Chris Mason:
 "Eric's rcu barrier patch fixes a long standing problem with our
  unmount code hanging on to devices in workqueue helpers.  Liu Bo
  nailed down a difficult assertion for in-memory extent mappings."

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix warning of free_extent_map
  Btrfs: fix warning when creating snapshots
  Btrfs: return as soon as possible when edquot happens
  Btrfs: return EIO if we have extent tree corruption
  btrfs: use rcu_barrier() to wait for bdev puts at unmount
  Btrfs: remove btrfs_try_spin_lock
  Btrfs: get better concurrency for snapshot-aware defrag work

1  2 
fs/btrfs/extent-tree.c
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/transaction.c

diff --combined fs/btrfs/extent-tree.c
index 3e074dab2d57a3e39ad16538f7a51bfde8e4ed91,350b9b18140c500e4b9a23acae2a5b34ad376e8d..9ac2eca681ebb09c605612dd563bc4417e4fc587
@@@ -1467,8 -1467,11 +1467,11 @@@ int lookup_inline_extent_backref(struc
        if (ret && !insert) {
                err = -ENOENT;
                goto out;
+       } else if (ret) {
+               err = -EIO;
+               WARN_ON(1);
+               goto out;
        }
-       BUG_ON(ret); /* Corruption */
  
        leaf = path->nodes[0];
        item_size = btrfs_item_size_nr(leaf, path->slots[0]);
@@@ -3800,6 -3803,23 +3803,6 @@@ static int can_overcommit(struct btrfs_
        return 0;
  }
  
 -static inline int writeback_inodes_sb_nr_if_idle_safe(struct super_block *sb,
 -                                                    unsigned long nr_pages,
 -                                                    enum wb_reason reason)
 -{
 -      /* the flusher is dealing with the dirty inodes now. */
 -      if (writeback_in_progress(sb->s_bdi))
 -              return 1;
 -
 -      if (down_read_trylock(&sb->s_umount)) {
 -              writeback_inodes_sb_nr(sb, nr_pages, reason);
 -              up_read(&sb->s_umount);
 -              return 1;
 -      }
 -
 -      return 0;
 -}
 -
  void btrfs_writeback_inodes_sb_nr(struct btrfs_root *root,
                                  unsigned long nr_pages)
  {
        int started;
  
        /* If we can not start writeback, just sync all the delalloc file. */
 -      started = writeback_inodes_sb_nr_if_idle_safe(sb, nr_pages,
 +      started = try_to_writeback_inodes_sb_nr(sb, nr_pages,
                                                      WB_REASON_FS_FREE_SPACE);
        if (!started) {
                /*
@@@ -6699,7 -6719,7 +6702,7 @@@ reada
  }
  
  /*
 - * hepler to process tree block while walking down the tree.
 + * helper to process tree block while walking down the tree.
   *
   * when wc->stage == UPDATE_BACKREF, this function updates
   * back refs for pointers in the block.
@@@ -6774,7 -6794,7 +6777,7 @@@ static noinline int walk_down_proc(stru
  }
  
  /*
 - * hepler to process tree block pointer.
 + * helper to process tree block pointer.
   *
   * when wc->stage == DROP_REFERENCE, this function checks
   * reference count of the block pointed to. if the block
@@@ -6912,7 -6932,7 +6915,7 @@@ skip
  }
  
  /*
 - * hepler to process tree block while walking up the tree.
 + * helper to process tree block while walking up the tree.
   *
   * when wc->stage == DROP_REFERENCE, this function drops
   * reference count on the block.
diff --combined fs/btrfs/file.c
index af1d0605a5c1e74b3f30392d4e28c0faf34400ad,7bdb47faa12ed7a024bf014d33c46e88ce9f43ac..5b4ea5f55b8f47d0bf9a90992dd9da2d33880e14
@@@ -591,6 -591,7 +591,7 @@@ void btrfs_drop_extent_cache(struct ino
                }
                compressed = test_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
                clear_bit(EXTENT_FLAG_PINNED, &em->flags);
+               clear_bit(EXTENT_FLAG_LOGGING, &flags);
                remove_extent_mapping(em_tree, em);
                if (no_splits)
                        goto next;
@@@ -1229,7 -1230,7 +1230,7 @@@ static noinline int prepare_pages(struc
        struct extent_state *cached_state = NULL;
        int i;
        unsigned long index = pos >> PAGE_CACHE_SHIFT;
 -      struct inode *inode = fdentry(file)->d_inode;
 +      struct inode *inode = file_inode(file);
        gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
        int err = 0;
        int faili = 0;
@@@ -1316,7 -1317,7 +1317,7 @@@ static noinline ssize_t __btrfs_buffere
                                               struct iov_iter *i,
                                               loff_t pos)
  {
 -      struct inode *inode = fdentry(file)->d_inode;
 +      struct inode *inode = file_inode(file);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct page **pages = NULL;
        unsigned long first_index;
@@@ -1504,7 -1505,7 +1505,7 @@@ static ssize_t btrfs_file_aio_write(str
                                    unsigned long nr_segs, loff_t pos)
  {
        struct file *file = iocb->ki_filp;
 -      struct inode *inode = fdentry(file)->d_inode;
 +      struct inode *inode = file_inode(file);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        loff_t *ppos = &iocb->ki_pos;
        u64 start_pos;
@@@ -2139,7 -2140,7 +2140,7 @@@ out
  static long btrfs_fallocate(struct file *file, int mode,
                            loff_t offset, loff_t len)
  {
 -      struct inode *inode = file->f_path.dentry->d_inode;
 +      struct inode *inode = file_inode(file);
        struct extent_state *cached_state = NULL;
        u64 cur_offset;
        u64 last_byte;
diff --combined fs/btrfs/inode.c
index d1470adca8f87aafa6a028995eeac0e91ee781db,1f26888825e22c2f36c9cfe95f2f6ae5cba11061..ca1b767d51f760672f8de72c48efbf3df8e58a75
@@@ -2312,6 -2312,7 +2312,7 @@@ again
        key.type = BTRFS_EXTENT_DATA_KEY;
        key.offset = start;
  
+       path->leave_spinning = 1;
        if (merge) {
                struct btrfs_file_extent_item *fi;
                u64 extent_len;
  
        btrfs_mark_buffer_dirty(leaf);
        inode_add_bytes(inode, len);
+       btrfs_release_path(path);
  
        ret = btrfs_inc_extent_ref(trans, root, new->bytenr,
                        new->disk_len, 0,
        ret = 1;
  out_free_path:
        btrfs_release_path(path);
+       path->leave_spinning = 0;
        btrfs_end_transaction(trans, root);
  out_unlock:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, lock_start, lock_end,
@@@ -5107,7 -5110,7 +5110,7 @@@ unsigned char btrfs_filetype_table[] = 
  static int btrfs_real_readdir(struct file *filp, void *dirent,
                              filldir_t filldir)
  {
 -      struct inode *inode = filp->f_dentry->d_inode;
 +      struct inode *inode = file_inode(filp);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_item *item;
        struct btrfs_dir_item *di;
@@@ -7529,7 -7532,7 +7532,7 @@@ static void btrfs_invalidatepage(struc
  int btrfs_page_mkwrite(struct vm_area_struct *vma, struct vm_fault *vmf)
  {
        struct page *page = vmf->page;
 -      struct inode *inode = fdentry(vma->vm_file)->d_inode;
 +      struct inode *inode = file_inode(vma->vm_file);
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
        struct btrfs_ordered_extent *ordered;
diff --combined fs/btrfs/transaction.c
index 9250b9c4f01e1b826e25414e6ace942487e2ccca,c4a1531c52d8ac5870270f3a1df6b30a73fa1652..50767bbaad6c6bfeb40e4d0e815446effd5392b3
@@@ -123,6 -123,7 +123,6 @@@ loop
                 * to redo the trans_no_join checks above
                 */
                kmem_cache_free(btrfs_transaction_cachep, cur_trans);
 -              cur_trans = fs_info->running_transaction;
                goto loop;
        } else if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) {
                spin_unlock(&fs_info->trans_lock);
@@@ -625,14 -626,13 +625,13 @@@ static int __btrfs_end_transaction(stru
  
        btrfs_trans_release_metadata(trans, root);
        trans->block_rsv = NULL;
-       /*
-        * the same root has to be passed to start_transaction and
-        * end_transaction. Subvolume quota depends on this.
-        */
-       WARN_ON(trans->root != root);
  
        if (trans->qgroup_reserved) {
-               btrfs_qgroup_free(root, trans->qgroup_reserved);
+               /*
+                * the same root has to be passed here between start_transaction
+                * and end_transaction. Subvolume quota depends on this.
+                */
+               btrfs_qgroup_free(trans->root, trans->qgroup_reserved);
                trans->qgroup_reserved = 0;
        }