Merge branch 'integration' into for-linus
authorChris Mason <chris.mason@oracle.com>
Wed, 27 Jul 2011 20:13:10 +0000 (16:13 -0400)
committerChris Mason <chris.mason@oracle.com>
Wed, 27 Jul 2011 20:18:13 +0000 (16:18 -0400)
1  2 
fs/btrfs/ctree.h
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/relocation.c

diff --combined fs/btrfs/ctree.h
@@@ -19,6 -19,7 +19,6 @@@
  #ifndef __BTRFS_CTREE__
  #define __BTRFS_CTREE__
  
 -#include <linux/version.h>
  #include <linux/mm.h>
  #include <linux/highmem.h>
  #include <linux/fs.h>
@@@ -755,6 -756,8 +755,8 @@@ struct btrfs_space_info 
                                   chunks for this space */
        unsigned int chunk_alloc:1;     /* set if we are allocating a chunk */
  
+       unsigned int flush:1;           /* set if we are trying to make space */
        unsigned int force_alloc;       /* set if we need to force a chunk
                                           alloc for this space */
  
        struct list_head block_groups[BTRFS_NR_RAID_TYPES];
        spinlock_t lock;
        struct rw_semaphore groups_sem;
-       atomic_t caching_threads;
+       wait_queue_head_t wait;
  };
  
  struct btrfs_block_rsv {
@@@ -824,6 -827,7 +826,7 @@@ struct btrfs_caching_control 
        struct list_head list;
        struct mutex mutex;
        wait_queue_head_t wait;
+       struct btrfs_work work;
        struct btrfs_block_group_cache *block_group;
        u64 progress;
        atomic_t count;
@@@ -1032,6 -1036,8 +1035,8 @@@ struct btrfs_fs_info 
        struct btrfs_workers endio_write_workers;
        struct btrfs_workers endio_freespace_worker;
        struct btrfs_workers submit_workers;
+       struct btrfs_workers caching_workers;
        /*
         * fixup workers take dirty pages that didn't properly go through
         * the cow mechanism and make them safe to write.  It happens
@@@ -2128,7 -2134,7 +2133,7 @@@ static inline bool btrfs_mixed_space_in
  
  /* extent-tree.c */
  static inline u64 btrfs_calc_trans_metadata_size(struct btrfs_root *root,
-                                                int num_items)
+                                                unsigned num_items)
  {
        return (root->leafsize + root->nodesize * (BTRFS_MAX_LEVEL - 1)) *
                3 * num_items;
@@@ -2222,9 -2228,6 +2227,6 @@@ void btrfs_set_inode_space_info(struct 
  void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
  int btrfs_check_data_free_space(struct inode *inode, u64 bytes);
  void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes);
- int btrfs_trans_reserve_metadata(struct btrfs_trans_handle *trans,
-                               struct btrfs_root *root,
-                               int num_items);
  void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root);
  int btrfs_orphan_reserve_metadata(struct btrfs_trans_handle *trans,
@@@ -2330,7 -2333,7 +2332,7 @@@ struct btrfs_path *btrfs_alloc_path(voi
  void btrfs_free_path(struct btrfs_path *p);
  void btrfs_set_path_blocking(struct btrfs_path *p);
  void btrfs_clear_path_blocking(struct btrfs_path *p,
-                              struct extent_buffer *held);
+                              struct extent_buffer *held, int held_rw);
  void btrfs_unlock_up_safe(struct btrfs_path *p, int level);
  
  int btrfs_del_items(struct btrfs_trans_handle *trans, struct btrfs_root *root,
@@@ -2553,7 -2556,7 +2555,7 @@@ int btrfs_page_mkwrite(struct vm_area_s
  int btrfs_readpage(struct file *file, struct page *page);
  void btrfs_evict_inode(struct inode *inode);
  int btrfs_write_inode(struct inode *inode, struct writeback_control *wbc);
 -void btrfs_dirty_inode(struct inode *inode);
 +void btrfs_dirty_inode(struct inode *inode, int flags);
  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/extent_io.c
@@@ -10,8 -10,6 +10,8 @@@
  #include <linux/swap.h>
  #include <linux/writeback.h>
  #include <linux/pagevec.h>
 +#include <linux/prefetch.h>
 +#include <linux/cleancache.h>
  #include "extent_io.h"
  #include "extent_map.h"
  #include "compat.h"
@@@ -281,11 -279,10 +281,10 @@@ static int merge_state(struct extent_io
                if (other->start == state->end + 1 &&
                    other->state == state->state) {
                        merge_cb(tree, state, other);
-                       other->start = state->start;
-                       state->tree = NULL;
-                       rb_erase(&state->rb_node, &tree->state);
-                       free_extent_state(state);
-                       state = NULL;
+                       state->end = other->end;
+                       other->tree = NULL;
+                       rb_erase(&other->rb_node, &tree->state);
+                       free_extent_state(other);
                }
        }
  
@@@ -351,7 -348,6 +350,6 @@@ static int insert_state(struct extent_i
                       "%llu %llu\n", (unsigned long long)found->start,
                       (unsigned long long)found->end,
                       (unsigned long long)start, (unsigned long long)end);
-               free_extent_state(state);
                return -EEXIST;
        }
        state->tree = tree;
@@@ -500,7 -496,8 +498,8 @@@ again
                        cached_state = NULL;
                }
  
-               if (cached && cached->tree && cached->start == start) {
+               if (cached && cached->tree && cached->start <= start &&
+                   cached->end > start) {
                        if (clear)
                                atomic_dec(&cached->refs);
                        state = cached;
@@@ -742,7 -739,8 +741,8 @@@ again
        spin_lock(&tree->lock);
        if (cached_state && *cached_state) {
                state = *cached_state;
-               if (state->start == start && state->tree) {
+               if (state->start <= start && state->end > start &&
+                   state->tree) {
                        node = &state->rb_node;
                        goto hit_next;
                }
@@@ -783,13 -781,13 +783,13 @@@ hit_next
                if (err)
                        goto out;
  
-               next_node = rb_next(node);
                cache_state(state, cached_state);
                merge_state(tree, state);
                if (last_end == (u64)-1)
                        goto out;
  
                start = last_end + 1;
+               next_node = rb_next(&state->rb_node);
                if (next_node && start < end && prealloc && !need_resched()) {
                        state = rb_entry(next_node, struct extent_state,
                                         rb_node);
                 * Avoid to free 'prealloc' if it can be merged with
                 * the later extent.
                 */
-               atomic_inc(&prealloc->refs);
                err = insert_state(tree, prealloc, start, this_end,
                                   &bits);
                BUG_ON(err == -EEXIST);
                        goto out;
                }
                cache_state(prealloc, cached_state);
-               free_extent_state(prealloc);
                prealloc = NULL;
                start = this_end + 1;
                goto search_again;
@@@ -1564,7 -1560,8 +1562,8 @@@ int test_range_bit(struct extent_io_tre
        int bitset = 0;
  
        spin_lock(&tree->lock);
-       if (cached && cached->tree && cached->start == start)
+       if (cached && cached->tree && cached->start <= start &&
+           cached->end > start)
                node = &cached->rb_node;
        else
                node = tree_search(tree, start);
@@@ -1971,13 -1968,6 +1970,13 @@@ static int __extent_read_full_page(stru
  
        set_page_extent_mapped(page);
  
 +      if (!PageUptodate(page)) {
 +              if (cleancache_get_page(page) == 0) {
 +                      BUG_ON(blocksize != PAGE_SIZE);
 +                      goto out;
 +              }
 +      }
 +
        end = page_end;
        while (1) {
                lock_extent(tree, start, end, GFP_NOFS);
                cur = cur + iosize;
                pg_offset += iosize;
        }
 +out:
        if (!nr) {
                if (!PageError(page))
                        SetPageUptodate(page);
@@@ -2432,6 -2421,7 +2431,7 @@@ static int extent_write_cache_pages(str
        pgoff_t index;
        pgoff_t end;            /* Inclusive */
        int scanned = 0;
+       int tag;
  
        pagevec_init(&pvec, 0);
        if (wbc->range_cyclic) {
                end = wbc->range_end >> PAGE_CACHE_SHIFT;
                scanned = 1;
        }
+       if (wbc->sync_mode == WB_SYNC_ALL)
+               tag = PAGECACHE_TAG_TOWRITE;
+       else
+               tag = PAGECACHE_TAG_DIRTY;
  retry:
+       if (wbc->sync_mode == WB_SYNC_ALL)
+               tag_pages_for_writeback(mapping, index, end);
        while (!done && !nr_to_write_done && (index <= end) &&
-              (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index,
-                             PAGECACHE_TAG_DIRTY, min(end - index,
-                                 (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
+              (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, tag,
+                       min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) {
                unsigned i;
  
                scanned = 1;
@@@ -3022,8 -3017,15 +3027,15 @@@ static struct extent_buffer *__alloc_ex
                return NULL;
        eb->start = start;
        eb->len = len;
-       spin_lock_init(&eb->lock);
-       init_waitqueue_head(&eb->lock_wq);
+       rwlock_init(&eb->lock);
+       atomic_set(&eb->write_locks, 0);
+       atomic_set(&eb->read_locks, 0);
+       atomic_set(&eb->blocking_readers, 0);
+       atomic_set(&eb->blocking_writers, 0);
+       atomic_set(&eb->spinning_readers, 0);
+       atomic_set(&eb->spinning_writers, 0);
+       init_waitqueue_head(&eb->write_lock_wq);
+       init_waitqueue_head(&eb->read_lock_wq);
  
  #if LEAK_DEBUG
        spin_lock_irqsave(&leak_lock, flags);
@@@ -3119,7 -3121,7 +3131,7 @@@ struct extent_buffer *alloc_extent_buff
                i = 0;
        }
        for (; i < num_pages; i++, index++) {
-               p = find_or_create_page(mapping, index, GFP_NOFS | __GFP_HIGHMEM);
+               p = find_or_create_page(mapping, index, GFP_NOFS);
                if (!p) {
                        WARN_ON(1);
                        goto free_eb;
@@@ -3266,6 -3268,22 +3278,22 @@@ int set_extent_buffer_dirty(struct exte
        return was_dirty;
  }
  
+ static int __eb_straddles_pages(u64 start, u64 len)
+ {
+       if (len < PAGE_CACHE_SIZE)
+               return 1;
+       if (start & (PAGE_CACHE_SIZE - 1))
+               return 1;
+       if ((start + len) & (PAGE_CACHE_SIZE - 1))
+               return 1;
+       return 0;
+ }
+ static int eb_straddles_pages(struct extent_buffer *eb)
+ {
+       return __eb_straddles_pages(eb->start, eb->len);
+ }
  int clear_extent_buffer_uptodate(struct extent_io_tree *tree,
                                struct extent_buffer *eb,
                                struct extent_state **cached_state)
        num_pages = num_extent_pages(eb->start, eb->len);
        clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags);
  
-       clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
-                             cached_state, GFP_NOFS);
+       if (eb_straddles_pages(eb)) {
+               clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
+                                     cached_state, GFP_NOFS);
+       }
        for (i = 0; i < num_pages; i++) {
                page = extent_buffer_page(eb, i);
                if (page)
@@@ -3296,8 -3316,10 +3326,10 @@@ int set_extent_buffer_uptodate(struct e
  
        num_pages = num_extent_pages(eb->start, eb->len);
  
-       set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
-                           NULL, GFP_NOFS);
+       if (eb_straddles_pages(eb)) {
+               set_extent_uptodate(tree, eb->start, eb->start + eb->len - 1,
+                                   NULL, GFP_NOFS);
+       }
        for (i = 0; i < num_pages; i++) {
                page = extent_buffer_page(eb, i);
                if ((i == 0 && (eb->start & (PAGE_CACHE_SIZE - 1))) ||
@@@ -3320,9 -3342,12 +3352,12 @@@ int extent_range_uptodate(struct extent
        int uptodate;
        unsigned long index;
  
-       ret = test_range_bit(tree, start, end, EXTENT_UPTODATE, 1, NULL);
-       if (ret)
-               return 1;
+       if (__eb_straddles_pages(start, end - start + 1)) {
+               ret = test_range_bit(tree, start, end,
+                                    EXTENT_UPTODATE, 1, NULL);
+               if (ret)
+                       return 1;
+       }
        while (start <= end) {
                index = start >> PAGE_CACHE_SHIFT;
                page = find_get_page(tree->mapping, index);
@@@ -3350,10 -3375,12 +3385,12 @@@ int extent_buffer_uptodate(struct exten
        if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
                return 1;
  
-       ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
-                          EXTENT_UPTODATE, 1, cached_state);
-       if (ret)
-               return ret;
+       if (eb_straddles_pages(eb)) {
+               ret = test_range_bit(tree, eb->start, eb->start + eb->len - 1,
+                                  EXTENT_UPTODATE, 1, cached_state);
+               if (ret)
+                       return ret;
+       }
  
        num_pages = num_extent_pages(eb->start, eb->len);
        for (i = 0; i < num_pages; i++) {
@@@ -3386,9 -3413,11 +3423,11 @@@ int read_extent_buffer_pages(struct ext
        if (test_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags))
                return 0;
  
-       if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
-                          EXTENT_UPTODATE, 1, NULL)) {
-               return 0;
+       if (eb_straddles_pages(eb)) {
+               if (test_range_bit(tree, eb->start, eb->start + eb->len - 1,
+                                  EXTENT_UPTODATE, 1, NULL)) {
+                       return 0;
+               }
        }
  
        if (start) {
@@@ -3492,9 -3521,8 +3531,8 @@@ void read_extent_buffer(struct extent_b
                page = extent_buffer_page(eb, i);
  
                cur = min(len, (PAGE_CACHE_SIZE - offset));
-               kaddr = kmap_atomic(page, KM_USER1);
+               kaddr = page_address(page);
                memcpy(dst, kaddr + offset, cur);
-               kunmap_atomic(kaddr, KM_USER1);
  
                dst += cur;
                len -= cur;
  }
  
  int map_private_extent_buffer(struct extent_buffer *eb, unsigned long start,
-                              unsigned long min_len, char **token, char **map,
+                              unsigned long min_len, char **map,
                               unsigned long *map_start,
-                              unsigned long *map_len, int km)
+                              unsigned long *map_len)
  {
        size_t offset = start & (PAGE_CACHE_SIZE - 1);
        char *kaddr;
        }
  
        p = extent_buffer_page(eb, i);
-       kaddr = kmap_atomic(p, km);
-       *token = kaddr;
+       kaddr = page_address(p);
        *map = kaddr + offset;
        *map_len = PAGE_CACHE_SIZE - offset;
        return 0;
  }
  
- int map_extent_buffer(struct extent_buffer *eb, unsigned long start,
-                     unsigned long min_len,
-                     char **token, char **map,
-                     unsigned long *map_start,
-                     unsigned long *map_len, int km)
- {
-       int err;
-       int save = 0;
-       if (eb->map_token) {
-               unmap_extent_buffer(eb, eb->map_token, km);
-               eb->map_token = NULL;
-               save = 1;
-       }
-       err = map_private_extent_buffer(eb, start, min_len, token, map,
-                                      map_start, map_len, km);
-       if (!err && save) {
-               eb->map_token = *token;
-               eb->kaddr = *map;
-               eb->map_start = *map_start;
-               eb->map_len = *map_len;
-       }
-       return err;
- }
- void unmap_extent_buffer(struct extent_buffer *eb, char *token, int km)
- {
-       kunmap_atomic(token, km);
- }
  int memcmp_extent_buffer(struct extent_buffer *eb, const void *ptrv,
                          unsigned long start,
                          unsigned long len)
  
                cur = min(len, (PAGE_CACHE_SIZE - offset));
  
-               kaddr = kmap_atomic(page, KM_USER0);
+               kaddr = page_address(page);
                ret = memcmp(ptr, kaddr + offset, cur);
-               kunmap_atomic(kaddr, KM_USER0);
                if (ret)
                        break;
  
@@@ -3630,9 -3627,8 +3637,8 @@@ void write_extent_buffer(struct extent_
                WARN_ON(!PageUptodate(page));
  
                cur = min(len, PAGE_CACHE_SIZE - offset);
-               kaddr = kmap_atomic(page, KM_USER1);
+               kaddr = page_address(page);
                memcpy(kaddr + offset, src, cur);
-               kunmap_atomic(kaddr, KM_USER1);
  
                src += cur;
                len -= cur;
@@@ -3661,9 -3657,8 +3667,8 @@@ void memset_extent_buffer(struct extent
                WARN_ON(!PageUptodate(page));
  
                cur = min(len, PAGE_CACHE_SIZE - offset);
-               kaddr = kmap_atomic(page, KM_USER0);
+               kaddr = page_address(page);
                memset(kaddr + offset, c, cur);
-               kunmap_atomic(kaddr, KM_USER0);
  
                len -= cur;
                offset = 0;
@@@ -3694,9 -3689,8 +3699,8 @@@ void copy_extent_buffer(struct extent_b
  
                cur = min(len, (unsigned long)(PAGE_CACHE_SIZE - offset));
  
-               kaddr = kmap_atomic(page, KM_USER0);
+               kaddr = page_address(page);
                read_extent_buffer(src, kaddr + offset, src_offset, cur);
-               kunmap_atomic(kaddr, KM_USER0);
  
                src_offset += cur;
                len -= cur;
@@@ -3709,20 -3703,17 +3713,17 @@@ static void move_pages(struct page *dst
                       unsigned long dst_off, unsigned long src_off,
                       unsigned long len)
  {
-       char *dst_kaddr = kmap_atomic(dst_page, KM_USER0);
+       char *dst_kaddr = page_address(dst_page);
        if (dst_page == src_page) {
                memmove(dst_kaddr + dst_off, dst_kaddr + src_off, len);
        } else {
-               char *src_kaddr = kmap_atomic(src_page, KM_USER1);
+               char *src_kaddr = page_address(src_page);
                char *p = dst_kaddr + dst_off + len;
                char *s = src_kaddr + src_off + len;
  
                while (len--)
                        *--p = *--s;
-               kunmap_atomic(src_kaddr, KM_USER1);
        }
-       kunmap_atomic(dst_kaddr, KM_USER0);
  }
  
  static inline bool areas_overlap(unsigned long src, unsigned long dst, unsigned long len)
@@@ -3735,20 -3726,17 +3736,17 @@@ static void copy_pages(struct page *dst
                       unsigned long dst_off, unsigned long src_off,
                       unsigned long len)
  {
-       char *dst_kaddr = kmap_atomic(dst_page, KM_USER0);
+       char *dst_kaddr = page_address(dst_page);
        char *src_kaddr;
  
        if (dst_page != src_page) {
-               src_kaddr = kmap_atomic(src_page, KM_USER1);
+               src_kaddr = page_address(src_page);
        } else {
                src_kaddr = dst_kaddr;
                BUG_ON(areas_overlap(src_off, dst_off, len));
        }
  
        memcpy(dst_kaddr + dst_off, src_kaddr + src_off, len);
-       kunmap_atomic(dst_kaddr, KM_USER0);
-       if (dst_page != src_page)
-               kunmap_atomic(src_kaddr, KM_USER1);
  }
  
  void memcpy_extent_buffer(struct extent_buffer *dst, unsigned long dst_offset,
diff --combined fs/btrfs/inode.c
@@@ -750,15 -750,6 +750,6 @@@ static u64 get_extent_allocation_hint(s
        return alloc_hint;
  }
  
- static inline bool is_free_space_inode(struct btrfs_root *root,
-                                      struct inode *inode)
- {
-       if (root == root->fs_info->tree_root ||
-           BTRFS_I(inode)->location.objectid == BTRFS_FREE_INO_OBJECTID)
-               return true;
-       return false;
- }
  /*
   * when extent_io.c finds a delayed allocation range in the file,
   * the call backs end up in this code.  The basic idea is to
@@@ -791,7 -782,7 +782,7 @@@ static noinline int cow_file_range(stru
        struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
        int ret = 0;
  
-       BUG_ON(is_free_space_inode(root, inode));
+       BUG_ON(btrfs_is_free_space_inode(root, inode));
        trans = btrfs_join_transaction(root);
        BUG_ON(IS_ERR(trans));
        trans->block_rsv = &root->fs_info->delalloc_block_rsv;
@@@ -1072,7 -1063,7 +1063,7 @@@ static noinline int run_delalloc_nocow(
        path = btrfs_alloc_path();
        BUG_ON(!path);
  
-       nolock = is_free_space_inode(root, inode);
+       nolock = btrfs_is_free_space_inode(root, inode);
  
        if (nolock)
                trans = btrfs_join_transaction_nolock(root);
@@@ -1298,7 -1289,9 +1289,9 @@@ static int btrfs_split_extent_hook(stru
        if (!(orig->state & EXTENT_DELALLOC))
                return 0;
  
-       atomic_inc(&BTRFS_I(inode)->outstanding_extents);
+       spin_lock(&BTRFS_I(inode)->lock);
+       BTRFS_I(inode)->outstanding_extents++;
+       spin_unlock(&BTRFS_I(inode)->lock);
        return 0;
  }
  
@@@ -1316,7 -1309,9 +1309,9 @@@ static int btrfs_merge_extent_hook(stru
        if (!(other->state & EXTENT_DELALLOC))
                return 0;
  
-       atomic_dec(&BTRFS_I(inode)->outstanding_extents);
+       spin_lock(&BTRFS_I(inode)->lock);
+       BTRFS_I(inode)->outstanding_extents--;
+       spin_unlock(&BTRFS_I(inode)->lock);
        return 0;
  }
  
@@@ -1337,12 -1332,15 +1332,15 @@@ static int btrfs_set_bit_hook(struct in
        if (!(state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
                u64 len = state->end + 1 - state->start;
-               bool do_list = !is_free_space_inode(root, inode);
+               bool do_list = !btrfs_is_free_space_inode(root, inode);
  
-               if (*bits & EXTENT_FIRST_DELALLOC)
+               if (*bits & EXTENT_FIRST_DELALLOC) {
                        *bits &= ~EXTENT_FIRST_DELALLOC;
-               else
-                       atomic_inc(&BTRFS_I(inode)->outstanding_extents);
+               } else {
+                       spin_lock(&BTRFS_I(inode)->lock);
+                       BTRFS_I(inode)->outstanding_extents++;
+                       spin_unlock(&BTRFS_I(inode)->lock);
+               }
  
                spin_lock(&root->fs_info->delalloc_lock);
                BTRFS_I(inode)->delalloc_bytes += len;
@@@ -1370,12 -1368,15 +1368,15 @@@ static int btrfs_clear_bit_hook(struct 
        if ((state->state & EXTENT_DELALLOC) && (*bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
                u64 len = state->end + 1 - state->start;
-               bool do_list = !is_free_space_inode(root, inode);
+               bool do_list = !btrfs_is_free_space_inode(root, inode);
  
-               if (*bits & EXTENT_FIRST_DELALLOC)
+               if (*bits & EXTENT_FIRST_DELALLOC) {
                        *bits &= ~EXTENT_FIRST_DELALLOC;
-               else if (!(*bits & EXTENT_DO_ACCOUNTING))
-                       atomic_dec(&BTRFS_I(inode)->outstanding_extents);
+               } else if (!(*bits & EXTENT_DO_ACCOUNTING)) {
+                       spin_lock(&BTRFS_I(inode)->lock);
+                       BTRFS_I(inode)->outstanding_extents--;
+                       spin_unlock(&BTRFS_I(inode)->lock);
+               }
  
                if (*bits & EXTENT_DO_ACCOUNTING)
                        btrfs_delalloc_release_metadata(inode, len);
@@@ -1477,7 -1478,7 +1478,7 @@@ static int btrfs_submit_bio_hook(struc
  
        skip_sum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
  
-       if (is_free_space_inode(root, inode))
+       if (btrfs_is_free_space_inode(root, inode))
                ret = btrfs_bio_wq_end_io(root->fs_info, bio, 2);
        else
                ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
@@@ -1726,7 -1727,7 +1727,7 @@@ static int btrfs_finish_ordered_io(stru
                return 0;
        BUG_ON(!ordered_extent);
  
-       nolock = is_free_space_inode(root, inode);
+       nolock = btrfs_is_free_space_inode(root, inode);
  
        if (test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags)) {
                BUG_ON(!list_empty(&ordered_extent->list));
@@@ -2531,13 -2532,6 +2532,6 @@@ static void btrfs_read_locked_inode(str
  
        inode_item = btrfs_item_ptr(leaf, path->slots[0],
                                    struct btrfs_inode_item);
-       if (!leaf->map_token)
-               map_private_extent_buffer(leaf, (unsigned long)inode_item,
-                                         sizeof(struct btrfs_inode_item),
-                                         &leaf->map_token, &leaf->kaddr,
-                                         &leaf->map_start, &leaf->map_len,
-                                         KM_USER1);
        inode->i_mode = btrfs_inode_mode(leaf, inode_item);
        inode->i_nlink = btrfs_inode_nlink(leaf, inode_item);
        inode->i_uid = btrfs_inode_uid(leaf, inode_item);
@@@ -2575,11 -2569,6 +2569,6 @@@ cache_acl
        if (!maybe_acls)
                cache_no_acl(inode);
  
-       if (leaf->map_token) {
-               unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
-               leaf->map_token = NULL;
-       }
        btrfs_free_path(path);
  
        switch (inode->i_mode & S_IFMT) {
@@@ -2624,13 -2613,6 +2613,6 @@@ static void fill_inode_item(struct btrf
                            struct btrfs_inode_item *item,
                            struct inode *inode)
  {
-       if (!leaf->map_token)
-               map_private_extent_buffer(leaf, (unsigned long)item,
-                                         sizeof(struct btrfs_inode_item),
-                                         &leaf->map_token, &leaf->kaddr,
-                                         &leaf->map_start, &leaf->map_len,
-                                         KM_USER1);
        btrfs_set_inode_uid(leaf, item, inode->i_uid);
        btrfs_set_inode_gid(leaf, item, inode->i_gid);
        btrfs_set_inode_size(leaf, item, BTRFS_I(inode)->disk_i_size);
        btrfs_set_inode_rdev(leaf, item, inode->i_rdev);
        btrfs_set_inode_flags(leaf, item, BTRFS_I(inode)->flags);
        btrfs_set_inode_block_group(leaf, item, 0);
-       if (leaf->map_token) {
-               unmap_extent_buffer(leaf, leaf->map_token, KM_USER1);
-               leaf->map_token = NULL;
-       }
  }
  
  /*
@@@ -2684,7 -2661,7 +2661,7 @@@ noinline int btrfs_update_inode(struct 
         * The data relocation inode should also be directly updated
         * without delay
         */
-       if (!is_free_space_inode(root, inode)
+       if (!btrfs_is_free_space_inode(root, inode)
            && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) {
                ret = btrfs_delayed_update_inode(trans, root, inode);
                if (!ret)
@@@ -3398,7 -3375,7 +3375,7 @@@ static int btrfs_truncate_page(struct a
  
        ret = -ENOMEM;
  again:
-       page = grab_cache_page(mapping, index);
+       page = find_or_create_page(mapping, index, GFP_NOFS);
        if (!page) {
                btrfs_delalloc_release_space(inode, PAGE_CACHE_SIZE);
                goto out;
@@@ -3634,7 -3611,7 +3611,7 @@@ void btrfs_evict_inode(struct inode *in
  
        truncate_inode_pages(&inode->i_data, 0);
        if (inode->i_nlink && (btrfs_root_refs(&root->root_item) != 0 ||
-                              is_free_space_inode(root, inode)))
+                              btrfs_is_free_space_inode(root, inode)))
                goto no_delete;
  
        if (is_bad_inode(inode)) {
@@@ -4277,7 -4254,7 +4254,7 @@@ int btrfs_write_inode(struct inode *ino
        if (BTRFS_I(inode)->dummy_inode)
                return 0;
  
-       if (btrfs_fs_closing(root->fs_info) && is_free_space_inode(root, inode))
+       if (btrfs_fs_closing(root->fs_info) && btrfs_is_free_space_inode(root, inode))
                nolock = true;
  
        if (wbc->sync_mode == WB_SYNC_ALL) {
   * FIXME, needs more benchmarking...there are no reasons other than performance
   * to keep or drop this code.
   */
 -void btrfs_dirty_inode(struct inode *inode)
 +void btrfs_dirty_inode(struct inode *inode, int flags)
  {
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
@@@ -6735,8 -6712,9 +6712,9 @@@ struct inode *btrfs_alloc_inode(struct 
        ei->index_cnt = (u64)-1;
        ei->last_unlink_trans = 0;
  
-       atomic_set(&ei->outstanding_extents, 0);
-       atomic_set(&ei->reserved_extents, 0);
+       spin_lock_init(&ei->lock);
+       ei->outstanding_extents = 0;
+       ei->reserved_extents = 0;
  
        ei->ordered_data_close = 0;
        ei->orphan_meta_reserved = 0;
@@@ -6774,8 -6752,8 +6752,8 @@@ void btrfs_destroy_inode(struct inode *
  
        WARN_ON(!list_empty(&inode->i_dentry));
        WARN_ON(inode->i_data.nrpages);
-       WARN_ON(atomic_read(&BTRFS_I(inode)->outstanding_extents));
-       WARN_ON(atomic_read(&BTRFS_I(inode)->reserved_extents));
+       WARN_ON(BTRFS_I(inode)->outstanding_extents);
+       WARN_ON(BTRFS_I(inode)->reserved_extents);
  
        /*
         * This can happen where we create an inode, but somebody else also
@@@ -6830,7 -6808,7 +6808,7 @@@ int btrfs_drop_inode(struct inode *inod
        struct btrfs_root *root = BTRFS_I(inode)->root;
  
        if (btrfs_root_refs(&root->root_item) == 0 &&
-           !is_free_space_inode(root, inode))
+           !btrfs_is_free_space_inode(root, inode))
                return 1;
        else
                return generic_drop_inode(inode);
diff --combined fs/btrfs/relocation.c
@@@ -712,7 -712,7 +712,7 @@@ again
        WARN_ON(cur->checked);
        if (!list_empty(&cur->upper)) {
                /*
 -               * the backref was added previously when processsing
 +               * the backref was added previously when processing
                 * backref of type BTRFS_TREE_BLOCK_REF_KEY
                 */
                BUG_ON(!list_is_singular(&cur->upper));
@@@ -2955,7 -2955,8 +2955,8 @@@ static int relocate_file_extent_cluster
                        page_cache_sync_readahead(inode->i_mapping,
                                                  ra, NULL, index,
                                                  last_index + 1 - index);
-                       page = grab_cache_page(inode->i_mapping, index);
+                       page = find_or_create_page(inode->i_mapping, index,
+                                                  GFP_NOFS);
                        if (!page) {
                                btrfs_delalloc_release_metadata(inode,
                                                        PAGE_CACHE_SIZE);