mm: page_mkwrite change prototype to match fault
[safe/jmp/linux-2.6] / fs / btrfs / inode.c
index e64a4fe..ec54237 100644 (file)
@@ -34,7 +34,6 @@
 #include <linux/statfs.h>
 #include <linux/compat.h>
 #include <linux/bit_spinlock.h>
-#include <linux/version.h>
 #include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/falloc.h>
@@ -51,6 +50,7 @@
 #include "tree-log.h"
 #include "ref-cache.h"
 #include "compression.h"
+#include "locking.h"
 
 struct btrfs_iget_args {
        u64 ino;
@@ -91,33 +91,14 @@ static noinline int cow_file_range(struct inode *inode,
                                   u64 start, u64 end, int *page_started,
                                   unsigned long *nr_written, int unlock);
 
-/*
- * a very lame attempt at stopping writes when the FS is 85% full.  There
- * are countless ways this is incorrect, but it is better than nothing.
- */
-int btrfs_check_free_space(struct btrfs_root *root, u64 num_required,
-                          int for_del)
+static int btrfs_init_inode_security(struct inode *inode,  struct inode *dir)
 {
-       u64 total;
-       u64 used;
-       u64 thresh;
-       unsigned long flags;
-       int ret = 0;
-
-       spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
-       total = btrfs_super_total_bytes(&root->fs_info->super_copy);
-       used = btrfs_super_bytes_used(&root->fs_info->super_copy);
-       if (for_del)
-               thresh = total * 90;
-       else
-               thresh = total * 85;
-
-       do_div(thresh, 100);
+       int err;
 
-       if (used + root->fs_info->delalloc_bytes + num_required > thresh)
-               ret = -ENOSPC;
-       spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
-       return ret;
+       err = btrfs_init_acl(inode, dir);
+       if (!err)
+               err = btrfs_xattr_security_init(inode, dir);
+       return err;
 }
 
 /*
@@ -125,7 +106,7 @@ int btrfs_check_free_space(struct btrfs_root *root, u64 num_required,
  * the btree.  The caller should have done a btrfs_drop_extents so that
  * no overlapping inline items exist in the btree
  */
-static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
+static noinline int insert_inline_extent(struct btrfs_trans_handle *trans,
                                struct btrfs_root *root, struct inode *inode,
                                u64 start, size_t size, size_t compressed_size,
                                struct page **compressed_pages)
@@ -149,7 +130,8 @@ static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
                cur_size = compressed_size;
        }
 
-       path = btrfs_alloc_path(); if (!path)
+       path = btrfs_alloc_path();
+       if (!path)
                return -ENOMEM;
 
        btrfs_set_trans_block_group(trans, inode);
@@ -157,7 +139,6 @@ static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
        key.objectid = inode->i_ino;
        key.offset = start;
        btrfs_set_key_type(&key, BTRFS_EXTENT_DATA_KEY);
-       inode_add_bytes(inode, size);
        datasize = btrfs_file_extent_calc_inline_size(cur_size);
 
        inode_add_bytes(inode, size);
@@ -166,7 +147,6 @@ static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
        BUG_ON(ret);
        if (ret) {
                err = ret;
-               printk("got bad ret %d\n", ret);
                goto fail;
        }
        leaf = path->nodes[0];
@@ -182,7 +162,7 @@ static int noinline insert_inline_extent(struct btrfs_trans_handle *trans,
        if (use_compress) {
                struct page *cpage;
                int i = 0;
-               while(compressed_size > 0) {
+               while (compressed_size > 0) {
                        cpage = compressed_pages[i];
                        cur_size = min_t(unsigned long, compressed_size,
                                       PAGE_CACHE_SIZE);
@@ -332,6 +312,7 @@ static noinline int compress_file_range(struct inode *inode,
        u64 disk_num_bytes;
        u64 blocksize = root->sectorsize;
        u64 actual_end;
+       u64 isize = i_size_read(inode);
        int ret = 0;
        struct page **pages = NULL;
        unsigned long nr_pages;
@@ -345,12 +326,25 @@ static noinline int compress_file_range(struct inode *inode,
 
        orig_start = start;
 
+       actual_end = min_t(u64, isize, end + 1);
 again:
        will_compress = 0;
        nr_pages = (end >> PAGE_CACHE_SHIFT) - (start >> PAGE_CACHE_SHIFT) + 1;
        nr_pages = min(nr_pages, (128 * 1024UL) / PAGE_CACHE_SIZE);
 
-       actual_end = min_t(u64, i_size_read(inode), end + 1);
+       /*
+        * we don't want to send crud past the end of i_size through
+        * compression, that's just a waste of CPU time.  So, if the
+        * end of the file is before the start of our current
+        * requested range of bytes, we bail out to the uncompressed
+        * cleanup code that can deal with all of this.
+        *
+        * It isn't really the fastest way to fix things, but this is a
+        * very uncommon corner.
+        */
+       if (actual_end <= start)
+               goto cleanup_and_bail_uncompressed;
+
        total_compressed = actual_end - start;
 
        /* we want to make sure that amount of ram required to uncompress
@@ -488,13 +482,14 @@ again:
                add_async_extent(async_cow, start, num_bytes,
                                 total_compressed, pages, nr_pages_ret);
 
-               if (start + num_bytes < end) {
+               if (start + num_bytes < end && start + num_bytes < actual_end) {
                        start += num_bytes;
                        pages = NULL;
                        cond_resched();
                        goto again;
                }
        } else {
+cleanup_and_bail_uncompressed:
                /*
                 * No compression, but we still need to write the pages in
                 * the file we've been given so far.  redirty the locked
@@ -519,8 +514,7 @@ free_pages_out:
                WARN_ON(pages[i]->mapping);
                page_cache_release(pages[i]);
        }
-       if (pages)
-               kfree(pages);
+       kfree(pages);
 
        goto out;
 }
@@ -549,7 +543,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
 
        trans = btrfs_join_transaction(root, 1);
 
-       while(!list_empty(&async_cow->extents)) {
+       while (!list_empty(&async_cow->extents)) {
                async_extent = list_entry(async_cow->extents.next,
                                          struct async_extent, list);
                list_del(&async_extent->list);
@@ -562,8 +556,8 @@ static noinline int submit_compressed_extents(struct inode *inode,
                        unsigned long nr_written = 0;
 
                        lock_extent(io_tree, async_extent->start,
-                                   async_extent->start + async_extent->ram_size - 1,
-                                   GFP_NOFS);
+                                   async_extent->start +
+                                   async_extent->ram_size - 1, GFP_NOFS);
 
                        /* allocate blocks */
                        cow_file_range(inode, async_cow->locked_page,
@@ -581,7 +575,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
                        if (!page_started)
                                extent_write_locked_range(io_tree,
                                                  inode, async_extent->start,
-                                                 async_extent->start +
+                                                 async_extent->start +
                                                  async_extent->ram_size - 1,
                                                  btrfs_get_extent,
                                                  WB_SYNC_ALL);
@@ -618,7 +612,7 @@ static noinline int submit_compressed_extents(struct inode *inode,
                set_bit(EXTENT_FLAG_PINNED, &em->flags);
                set_bit(EXTENT_FLAG_COMPRESSED, &em->flags);
 
-               while(1) {
+               while (1) {
                        spin_lock(&em_tree->lock);
                        ret = add_extent_mapping(em_tree, em);
                        spin_unlock(&em_tree->lock);
@@ -651,11 +645,11 @@ static noinline int submit_compressed_extents(struct inode *inode,
                                             NULL, 1, 1, 0, 1, 1, 0);
 
                ret = btrfs_submit_compressed_write(inode,
-                                        async_extent->start,
-                                        async_extent->ram_size,
-                                        ins.objectid,
-                                        ins.offset, async_extent->pages,
-                                        async_extent->nr_pages);
+                                   async_extent->start,
+                                   async_extent->ram_size,
+                                   ins.objectid,
+                                   ins.offset, async_extent->pages,
+                                   async_extent->nr_pages);
 
                BUG_ON(ret);
                trans = btrfs_join_transaction(root, 1);
@@ -696,6 +690,7 @@ static noinline int cow_file_range(struct inode *inode,
        u64 cur_alloc_size;
        u64 blocksize = root->sectorsize;
        u64 actual_end;
+       u64 isize = i_size_read(inode);
        struct btrfs_key ins;
        struct extent_map *em;
        struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
@@ -705,7 +700,7 @@ static noinline int cow_file_range(struct inode *inode,
        BUG_ON(!trans);
        btrfs_set_trans_block_group(trans, inode);
 
-       actual_end = min_t(u64, i_size_read(inode), end + 1);
+       actual_end = min_t(u64, isize, end + 1);
 
        num_bytes = (end - start + blocksize) & ~(blocksize - 1);
        num_bytes = max(blocksize,  num_bytes);
@@ -734,14 +729,13 @@ static noinline int cow_file_range(struct inode *inode,
 
        btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0);
 
-       while(disk_num_bytes > 0) {
+       while (disk_num_bytes > 0) {
                cur_alloc_size = min(disk_num_bytes, root->fs_info->max_extent);
                ret = btrfs_reserve_extent(trans, root, cur_alloc_size,
                                           root->sectorsize, 0, alloc_hint,
                                           (u64)-1, &ins, 1);
-               if (ret) {
-                       BUG();
-               }
+               BUG_ON(ret);
+
                em = alloc_extent_map(GFP_NOFS);
                em->start = start;
                em->orig_start = em->start;
@@ -754,7 +748,7 @@ static noinline int cow_file_range(struct inode *inode,
                em->bdev = root->fs_info->fs_devices->latest_bdev;
                set_bit(EXTENT_FLAG_PINNED, &em->flags);
 
-               while(1) {
+               while (1) {
                        spin_lock(&em_tree->lock);
                        ret = add_extent_mapping(em_tree, em);
                        spin_unlock(&em_tree->lock);
@@ -778,11 +772,9 @@ static noinline int cow_file_range(struct inode *inode,
                        BUG_ON(ret);
                }
 
-               if (disk_num_bytes < cur_alloc_size) {
-                       printk("num_bytes %Lu cur_alloc %Lu\n", disk_num_bytes,
-                              cur_alloc_size);
+               if (disk_num_bytes < cur_alloc_size)
                        break;
-               }
+
                /* we're not doing compressed IO, don't unlock the first
                 * page (which the caller expects to stay locked), don't
                 * clear any dirty bits and don't set any writeback bits
@@ -841,9 +833,8 @@ static noinline void async_cow_submit(struct btrfs_work *work)
            waitqueue_active(&root->fs_info->async_submit_wait))
                wake_up(&root->fs_info->async_submit_wait);
 
-       if (async_cow->inode) {
+       if (async_cow->inode)
                submit_compressed_extents(async_cow->inode, async_cow);
-       }
 }
 
 static noinline void async_cow_free(struct btrfs_work *work)
@@ -870,7 +861,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
 
        clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED |
                         EXTENT_DELALLOC, 1, 0, GFP_NOFS);
-       while(start < end) {
+       while (start < end) {
                async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS);
                async_cow->inode = inode;
                async_cow->root = root;
@@ -903,7 +894,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
                            limit));
                }
 
-               while(atomic_read(&root->fs_info->async_submit_draining) &&
+               while (atomic_read(&root->fs_info->async_submit_draining) &&
                      atomic_read(&root->fs_info->async_delalloc_pages)) {
                        wait_event(root->fs_info->async_submit_wait,
                          (atomic_read(&root->fs_info->async_delalloc_pages) ==
@@ -917,15 +908,15 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page,
        return 0;
 }
 
-static int noinline csum_exist_in_range(struct btrfs_root *root,
+static noinline int csum_exist_in_range(struct btrfs_root *root,
                                        u64 bytenr, u64 num_bytes)
 {
        int ret;
        struct btrfs_ordered_sum *sums;
        LIST_HEAD(list);
 
-       ret = btrfs_lookup_csums_range(root, bytenr, bytenr + num_bytes - 1,
-                                      &list);
+       ret = btrfs_lookup_csums_range(root->fs_info->csum_root, bytenr,
+                                      bytenr + num_bytes - 1, &list);
        if (ret == 0 && list_empty(&list))
                return 0;
 
@@ -1145,13 +1136,13 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
 
        if (btrfs_test_flag(inode, NODATACOW))
                ret = run_delalloc_nocow(inode, locked_page, start, end,
-                                        page_started, 1, nr_written);
+                                        page_started, 1, nr_written);
        else if (btrfs_test_flag(inode, PREALLOC))
                ret = run_delalloc_nocow(inode, locked_page, start, end,
-                                        page_started, 0, nr_written);
+                                        page_started, 0, nr_written);
        else
                ret = cow_file_range_async(inode, locked_page, start, end,
-                                    page_started, nr_written);
+                                          page_started, nr_written);
 
        return ret;
 }
@@ -1164,17 +1155,22 @@ static int run_delalloc_range(struct inode *inode, struct page *locked_page,
 static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
                       unsigned long old, unsigned long bits)
 {
-       unsigned long flags;
+       /*
+        * set_bit and clear bit hooks normally require _irqsave/restore
+        * but in this case, we are only testeing for the DELALLOC
+        * bit, which is only set or cleared with irqs on
+        */
        if (!(old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
-               spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
+               btrfs_delalloc_reserve_space(root, inode, end - start + 1);
+               spin_lock(&root->fs_info->delalloc_lock);
                BTRFS_I(inode)->delalloc_bytes += end - start + 1;
                root->fs_info->delalloc_bytes += end - start + 1;
                if (list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
                        list_add_tail(&BTRFS_I(inode)->delalloc_inodes,
                                      &root->fs_info->delalloc_inodes);
                }
-               spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
+               spin_unlock(&root->fs_info->delalloc_lock);
        }
        return 0;
 }
@@ -1185,17 +1181,27 @@ static int btrfs_set_bit_hook(struct inode *inode, u64 start, u64 end,
 static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
                         unsigned long old, unsigned long bits)
 {
+       /*
+        * set_bit and clear bit hooks normally require _irqsave/restore
+        * but in this case, we are only testeing for the DELALLOC
+        * bit, which is only set or cleared with irqs on
+        */
        if ((old & EXTENT_DELALLOC) && (bits & EXTENT_DELALLOC)) {
                struct btrfs_root *root = BTRFS_I(inode)->root;
-               unsigned long flags;
 
-               spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
+               spin_lock(&root->fs_info->delalloc_lock);
                if (end - start + 1 > root->fs_info->delalloc_bytes) {
-                       printk("warning: delalloc account %Lu %Lu\n",
-                              end - start + 1, root->fs_info->delalloc_bytes);
+                       printk(KERN_INFO "btrfs warning: delalloc account "
+                              "%llu %llu\n",
+                              (unsigned long long)end - start + 1,
+                              (unsigned long long)
+                              root->fs_info->delalloc_bytes);
+                       btrfs_delalloc_free_space(root, inode, (u64)-1);
                        root->fs_info->delalloc_bytes = 0;
                        BTRFS_I(inode)->delalloc_bytes = 0;
                } else {
+                       btrfs_delalloc_free_space(root, inode,
+                                                 end - start + 1);
                        root->fs_info->delalloc_bytes -= end - start + 1;
                        BTRFS_I(inode)->delalloc_bytes -= end - start + 1;
                }
@@ -1203,7 +1209,7 @@ static int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
                    !list_empty(&BTRFS_I(inode)->delalloc_inodes)) {
                        list_del_init(&BTRFS_I(inode)->delalloc_inodes);
                }
-               spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
+               spin_unlock(&root->fs_info->delalloc_lock);
        }
        return 0;
 }
@@ -1232,9 +1238,8 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
        ret = btrfs_map_block(map_tree, READ, logical,
                              &map_length, NULL, 0);
 
-       if (map_length < length + size) {
+       if (map_length < length + size)
                return 1;
-       }
        return 0;
 }
 
@@ -1246,8 +1251,9 @@ int btrfs_merge_bio_hook(struct page *page, unsigned long offset,
  * At IO completion time the cums attached on the ordered extent record
  * are inserted into the btree
  */
-static int __btrfs_submit_bio_start(struct inode *inode, int rw, struct bio *bio,
-                         int mirror_num, unsigned long bio_flags)
+static int __btrfs_submit_bio_start(struct inode *inode, int rw,
+                                   struct bio *bio, int mirror_num,
+                                   unsigned long bio_flags)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
        int ret = 0;
@@ -1273,8 +1279,8 @@ static int __btrfs_submit_bio_done(struct inode *inode, int rw, struct bio *bio,
 }
 
 /*
- * extent_io.c submission hook. This does the right thing for csum calculation on write,
- * or reading the csums from the tree before a read
+ * extent_io.c submission hook. This does the right thing for csum calculation
+ * on write, or reading the csums from the tree before a read
  */
 static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
                          int mirror_num, unsigned long bio_flags)
@@ -1283,11 +1289,11 @@ static int btrfs_submit_bio_hook(struct inode *inode, int rw, struct bio *bio,
        int ret = 0;
        int skip_sum;
 
+       skip_sum = btrfs_test_flag(inode, NODATASUM);
+
        ret = btrfs_bio_wq_end_io(root->fs_info, bio, 0);
        BUG_ON(ret);
 
-       skip_sum = btrfs_test_flag(inode, NODATASUM);
-
        if (!(rw & (1 << BIO_RW))) {
                if (bio_flags & EXTENT_BIO_COMPRESSED) {
                        return btrfs_submit_compressed_read(inode, bio,
@@ -1318,12 +1324,11 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
                             struct inode *inode, u64 file_offset,
                             struct list_head *list)
 {
-       struct list_head *cur;
        struct btrfs_ordered_sum *sum;
 
        btrfs_set_trans_block_group(trans, inode);
-       list_for_each(cur, list) {
-               sum = list_entry(cur, struct btrfs_ordered_sum, list);
+
+       list_for_each_entry(sum, list, list) {
                btrfs_csum_file_blocks(trans,
                       BTRFS_I(inode)->root->fs_info->csum_root, sum);
        }
@@ -1332,9 +1337,8 @@ static noinline int add_pending_csums(struct btrfs_trans_handle *trans,
 
 int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end)
 {
-       if ((end & (PAGE_CACHE_SIZE - 1)) == 0) {
+       if ((end & (PAGE_CACHE_SIZE - 1)) == 0)
                WARN_ON(1);
-       }
        return set_extent_delalloc(&BTRFS_I(inode)->io_tree, start, end,
                                   GFP_NOFS);
 }
@@ -1639,13 +1643,13 @@ static int btrfs_io_failed_hook(struct bio *failed_bio,
                              failrec->logical, failrec->len);
        failrec->last_mirror++;
        if (!state) {
-               spin_lock_irq(&BTRFS_I(inode)->io_tree.lock);
+               spin_lock(&BTRFS_I(inode)->io_tree.lock);
                state = find_first_extent_bit_state(&BTRFS_I(inode)->io_tree,
                                                    failrec->start,
                                                    EXTENT_LOCKED);
                if (state && state->start != failrec->start)
                        state = NULL;
-               spin_unlock_irq(&BTRFS_I(inode)->io_tree.lock);
+               spin_unlock(&BTRFS_I(inode)->io_tree.lock);
        }
        if (!state || failrec->last_mirror > num_copies) {
                set_state_private(failure_tree, failrec->start, 0);
@@ -1722,7 +1726,6 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
        int ret;
        struct btrfs_root *root = BTRFS_I(inode)->root;
        u32 csum = ~(u32)0;
-       unsigned long flags;
 
        if (PageChecked(page)) {
                ClearPageChecked(page);
@@ -1744,18 +1747,16 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end,
        } else {
                ret = get_state_private(io_tree, start, &private);
        }
-       local_irq_save(flags);
-       kaddr = kmap_atomic(page, KM_IRQ0);
-       if (ret) {
+       kaddr = kmap_atomic(page, KM_USER0);
+       if (ret)
                goto zeroit;
-       }
+
        csum = btrfs_csum_data(root, kaddr + offset, csum,  end - start + 1);
        btrfs_csum_final(csum, (char *)&csum);
-       if (csum != private) {
+       if (csum != private)
                goto zeroit;
-       }
-       kunmap_atomic(kaddr, KM_IRQ0);
-       local_irq_restore(flags);
+
+       kunmap_atomic(kaddr, KM_USER0);
 good:
        /* if the io failure tree for this inode is non-empty,
         * check to see if we've recovered from a failed IO
@@ -1764,13 +1765,13 @@ good:
        return 0;
 
 zeroit:
-       printk("btrfs csum failed ino %lu off %llu csum %u private %Lu\n",
-              page->mapping->host->i_ino, (unsigned long long)start, csum,
-              private);
+       printk(KERN_INFO "btrfs csum failed ino %lu off %llu csum %u "
+              "private %llu\n", page->mapping->host->i_ino,
+              (unsigned long long)start, csum,
+              (unsigned long long)private);
        memset(kaddr + offset, 1, end - start + 1);
        flush_dcache_page(page);
-       kunmap_atomic(kaddr, KM_IRQ0);
-       local_irq_restore(flags);
+       kunmap_atomic(kaddr, KM_USER0);
        if (private == 0)
                return 0;
        return -EIO;
@@ -2011,6 +2012,7 @@ void btrfs_read_locked_inode(struct inode *inode)
        BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
 
        alloc_group_block = btrfs_inode_block_group(leaf, inode_item);
+
        BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
                                                alloc_group_block, 0);
        btrfs_free_path(path);
@@ -2037,6 +2039,7 @@ void btrfs_read_locked_inode(struct inode *inode)
                inode->i_mapping->backing_dev_info = &root->fs_info->bdi;
                break;
        default:
+               inode->i_op = &btrfs_special_inode_operations;
                init_special_inode(inode, inode->i_mode, rdev);
                break;
        }
@@ -2088,9 +2091,8 @@ static void fill_inode_item(struct btrfs_trans_handle *trans,
 /*
  * copy everything in the in-memory inode into the btree.
  */
-int noinline btrfs_update_inode(struct btrfs_trans_handle *trans,
-                             struct btrfs_root *root,
-                             struct inode *inode)
+noinline int btrfs_update_inode(struct btrfs_trans_handle *trans,
+                               struct btrfs_root *root, struct inode *inode)
 {
        struct btrfs_inode_item *inode_item;
        struct btrfs_path *path;
@@ -2107,6 +2109,7 @@ int noinline btrfs_update_inode(struct btrfs_trans_handle *trans,
                goto failed;
        }
 
+       btrfs_unlock_up_safe(path, 1);
        leaf = path->nodes[0];
        inode_item = btrfs_item_ptr(leaf, path->slots[0],
                                  struct btrfs_inode_item);
@@ -2165,7 +2168,7 @@ int btrfs_unlink_inode(struct btrfs_trans_handle *trans,
                                  inode->i_ino,
                                  dir->i_ino, &index);
        if (ret) {
-               printk("failed to delete reference to %.*s, "
+               printk(KERN_INFO "btrfs failed to delete reference to %.*s, "
                       "inode %lu parent %lu\n", name_len, name,
                       inode->i_ino, dir->i_ino);
                goto err;
@@ -2218,10 +2221,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
 
        root = BTRFS_I(dir)->root;
 
-       ret = btrfs_check_free_space(root, 1, 1);
-       if (ret)
-               goto fail;
-
        trans = btrfs_start_transaction(root, 1);
 
        btrfs_set_trans_block_group(trans, dir);
@@ -2234,7 +2233,6 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
        nr = trans->blocks_used;
 
        btrfs_end_transaction_throttle(trans, root);
-fail:
        btrfs_btree_balance_dirty(root, nr);
        return ret;
 }
@@ -2257,10 +2255,6 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
                return -ENOTEMPTY;
        }
 
-       ret = btrfs_check_free_space(root, 1, 1);
-       if (ret)
-               goto fail;
-
        trans = btrfs_start_transaction(root, 1);
        btrfs_set_trans_block_group(trans, dir);
 
@@ -2271,14 +2265,12 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry)
        /* now the directory is empty */
        err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode,
                                 dentry->d_name.name, dentry->d_name.len);
-       if (!err) {
+       if (!err)
                btrfs_i_size_write(inode, 0);
-       }
 
 fail_trans:
        nr = trans->blocks_used;
        ret = btrfs_end_transaction_throttle(trans, root);
-fail:
        btrfs_btree_balance_dirty(root, nr);
 
        if (ret && !err)
@@ -2429,6 +2421,8 @@ next_node:
                        ref->generation = leaf_gen;
                        ref->nritems = 0;
 
+                       btrfs_sort_leaf_ref(ref);
+
                        ret = btrfs_add_leaf_ref(root, ref, 0);
                        WARN_ON(ret);
                        btrfs_free_leaf_ref(root, ref);
@@ -2476,7 +2470,7 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
        struct btrfs_path *path;
        struct btrfs_key key;
        struct btrfs_key found_key;
-       u32 found_type;
+       u32 found_type = (u8)-1;
        struct extent_buffer *leaf;
        struct btrfs_file_extent_item *fi;
        u64 extent_start = 0;
@@ -2503,13 +2497,11 @@ noinline int btrfs_truncate_inode_items(struct btrfs_trans_handle *trans,
        key.offset = (u64)-1;
        key.type = (u8)-1;
 
-       btrfs_init_path(path);
-
 search_again:
        ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
-       if (ret < 0) {
+       if (ret < 0)
                goto error;
-       }
+
        if (ret > 0) {
                /* there are no items in the tree for us to truncate, we're
                 * done
@@ -2521,7 +2513,7 @@ search_again:
                path->slots[0]--;
        }
 
-       while(1) {
+       while (1) {
                fi = NULL;
                leaf = path->nodes[0];
                btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0]);
@@ -2553,19 +2545,18 @@ search_again:
                        item_end--;
                }
                if (item_end < new_size) {
-                       if (found_type == BTRFS_DIR_ITEM_KEY) {
+                       if (found_type == BTRFS_DIR_ITEM_KEY)
                                found_type = BTRFS_INODE_ITEM_KEY;
-                       } else if (found_type == BTRFS_EXTENT_ITEM_KEY) {
+                       else if (found_type == BTRFS_EXTENT_ITEM_KEY)
                                found_type = BTRFS_EXTENT_DATA_KEY;
-                       } else if (found_type == BTRFS_EXTENT_DATA_KEY) {
+                       else if (found_type == BTRFS_EXTENT_DATA_KEY)
                                found_type = BTRFS_XATTR_ITEM_KEY;
-                       } else if (found_type == BTRFS_XATTR_ITEM_KEY) {
+                       else if (found_type == BTRFS_XATTR_ITEM_KEY)
                                found_type = BTRFS_INODE_REF_KEY;
-                       } else if (found_type) {
+                       else if (found_type)
                                found_type--;
-                       } else {
+                       else
                                break;
-                       }
                        btrfs_set_key_type(&key, found_type);
                        goto next;
                }
@@ -2647,7 +2638,7 @@ delete:
                                pending_del_nr++;
                                pending_del_slot = path->slots[0];
                        } else {
-                               printk("bad pending slot %d pending_del_nr %d pending_del_slot %d\n", path->slots[0], pending_del_nr, pending_del_slot);
+                               BUG();
                        }
                } else {
                        break;
@@ -2664,6 +2655,8 @@ next:
                        if (pending_del_nr)
                                goto del_pending;
                        btrfs_release_path(root, path);
+                       if (found_type == BTRFS_INODE_ITEM_KEY)
+                               break;
                        goto search_again;
                }
 
@@ -2680,6 +2673,8 @@ del_pending:
                        BUG_ON(ret);
                        pending_del_nr = 0;
                        btrfs_release_path(root, path);
+                       if (found_type == BTRFS_INODE_ITEM_KEY)
+                               break;
                        goto search_again;
                }
        }
@@ -2789,7 +2784,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size)
        if (size <= hole_start)
                return 0;
 
-       err = btrfs_check_free_space(root, 1, 0);
+       err = btrfs_check_metadata_free_space(root);
        if (err)
                return err;
 
@@ -2882,7 +2877,7 @@ void btrfs_delete_inode(struct inode *inode)
        btrfs_wait_ordered_range(inode, 0, (u64)-1);
 
        btrfs_i_size_write(inode, 0);
-       trans = btrfs_start_transaction(root, 1);
+       trans = btrfs_join_transaction(root, 1);
 
        btrfs_set_trans_block_group(trans, inode);
        ret = btrfs_truncate_inode_items(trans, root, inode, inode->i_size, 0);
@@ -2929,9 +2924,10 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
                                    namelen, 0);
        if (IS_ERR(di))
                ret = PTR_ERR(di);
-       if (!di || IS_ERR(di)) {
+
+       if (!di || IS_ERR(di))
                goto out_err;
-       }
+
        btrfs_dir_item_key_to_cpu(path->nodes[0], di, location);
 out:
        btrfs_free_path(path);
@@ -2984,6 +2980,7 @@ static noinline void init_btrfs_i(struct inode *inode)
        bi->last_trans = 0;
        bi->logged_trans = 0;
        bi->delalloc_bytes = 0;
+       bi->reserved_bytes = 0;
        bi->disk_i_size = 0;
        bi->flags = 0;
        bi->index_cnt = (u64)-1;
@@ -3005,14 +3002,15 @@ static int btrfs_init_locked_inode(struct inode *inode, void *p)
        inode->i_ino = args->ino;
        init_btrfs_i(inode);
        BTRFS_I(inode)->root = args->root;
+       btrfs_set_inode_space_info(args->root, inode);
        return 0;
 }
 
 static int btrfs_find_actor(struct inode *inode, void *opaque)
 {
        struct btrfs_iget_args *args = opaque;
-       return (args->ino == inode->i_ino &&
-               args->root == BTRFS_I(inode)->root);
+       return args->ino == inode->i_ino &&
+               args->root == BTRFS_I(inode)->root;
 }
 
 struct inode *btrfs_ilookup(struct super_block *s, u64 objectid,
@@ -3076,7 +3074,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
 
 struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
 {
-       struct inode * inode;
+       struct inode *inode;
        struct btrfs_inode *bi = BTRFS_I(dir);
        struct btrfs_root *root = bi->root;
        struct btrfs_root *sub_root = root;
@@ -3265,7 +3263,7 @@ skip:
 
        /* Reached end of directory/root. Bump pos past the last item. */
        if (key_type == BTRFS_DIR_INDEX_KEY)
-               filp->f_pos = INT_LIMIT(typeof(filp->f_pos));
+               filp->f_pos = INT_LIMIT(off_t);
        else
                filp->f_pos++;
 nopos:
@@ -3376,9 +3374,8 @@ int btrfs_set_inode_index(struct inode *dir, u64 *index)
 
        if (BTRFS_I(dir)->index_cnt == (u64)-1) {
                ret = btrfs_set_inode_index_count(dir);
-               if (ret) {
+               if (ret)
                        return ret;
-               }
        }
 
        *index = BTRFS_I(dir)->index_cnt;
@@ -3426,6 +3423,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        BTRFS_I(inode)->index_cnt = 2;
        BTRFS_I(inode)->root = root;
        BTRFS_I(inode)->generation = trans->transid;
+       btrfs_set_inode_space_info(root, inode);
 
        if (mode & S_IFDIR)
                owner = 0;
@@ -3459,7 +3457,14 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
                root->highest_inode = objectid;
 
        inode->i_uid = current_fsuid();
-       inode->i_gid = current_fsgid();
+
+       if (dir && (dir->i_mode & S_ISGID)) {
+               inode->i_gid = dir->i_gid;
+               if (S_ISDIR(mode))
+                       mode |= S_ISGID;
+       } else
+               inode->i_gid = current_fsgid();
+
        inode->i_mode = mode;
        inode->i_ino = objectid;
        inode_set_bytes(inode, 0);
@@ -3566,7 +3571,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        if (!new_valid_dev(rdev))
                return -EINVAL;
 
-       err = btrfs_check_free_space(root, 1, 0);
+       err = btrfs_check_metadata_free_space(root);
        if (err)
                goto fail;
 
@@ -3587,7 +3592,7 @@ static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -3629,7 +3634,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        u64 objectid;
        u64 index = 0;
 
-       err = btrfs_check_free_space(root, 1, 0);
+       err = btrfs_check_metadata_free_space(root);
        if (err)
                goto fail;
        trans = btrfs_start_transaction(root, 1);
@@ -3650,7 +3655,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -3697,7 +3702,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
                return -ENOENT;
 
        btrfs_inc_nlink(inode);
-       err = btrfs_check_free_space(root, 1, 0);
+       err = btrfs_check_metadata_free_space(root);
        if (err)
                goto fail;
        err = btrfs_set_inode_index(dir, &index);
@@ -3743,7 +3748,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
        u64 index = 0;
        unsigned long nr = 1;
 
-       err = btrfs_check_free_space(root, 1, 0);
+       err = btrfs_check_metadata_free_space(root);
        if (err)
                goto out_unlock;
 
@@ -3773,7 +3778,7 @@ static int btrfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
 
        drop_on_err = 1;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err)
                goto out_fail;
 
@@ -3870,12 +3875,13 @@ static noinline int uncompress_inline(struct btrfs_path *path,
 
 /*
  * a bit scary, this does extent mapping from logical file offset to the disk.
- * the ugly parts come from merging extents from the disk with the
- * in-ram representation.  This gets more complex because of the data=ordered code,
+ * the ugly parts come from merging extents from the disk with the in-ram
+ * representation.  This gets more complex because of the data=ordered code,
  * where the in-ram extents might be locked pending data=ordered completion.
  *
  * This also copies inline extents directly into the page.
  */
+
 struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page,
                                    size_t pg_offset, u64 start, u64 len,
                                    int create)
@@ -4072,7 +4078,7 @@ again:
                                    extent_map_end(em) - 1, GFP_NOFS);
                goto insert;
        } else {
-               printk("unkknown found_type %d\n", found_type);
+               printk(KERN_ERR "btrfs unknown found_type %d\n", found_type);
                WARN_ON(1);
        }
 not_found:
@@ -4084,7 +4090,11 @@ not_found_em:
 insert:
        btrfs_release_path(root, path);
        if (em->start > start || extent_map_end(em) <= start) {
-               printk("bad extent! em: [%Lu %Lu] passed [%Lu %Lu]\n", em->start, em->len, start, len);
+               printk(KERN_ERR "Btrfs: bad extent! em: [%llu %llu] passed "
+                      "[%llu %llu]\n", (unsigned long long)em->start,
+                      (unsigned long long)em->len,
+                      (unsigned long long)start,
+                      (unsigned long long)len);
                err = -EIO;
                goto out;
        }
@@ -4121,8 +4131,6 @@ insert:
                                }
                        } else {
                                err = -EIO;
-                               printk("failing to insert %Lu %Lu\n",
-                                      start, len);
                                free_extent_map(em);
                                em = NULL;
                        }
@@ -4138,9 +4146,8 @@ out:
                btrfs_free_path(path);
        if (trans) {
                ret = btrfs_end_transaction(trans, root);
-               if (!err) {
+               if (!err)
                        err = ret;
-               }
        }
        if (err) {
                free_extent_map(em);
@@ -4157,9 +4164,10 @@ static ssize_t btrfs_direct_IO(int rw, struct kiocb *iocb,
        return -EINVAL;
 }
 
-static sector_t btrfs_bmap(struct address_space *mapping, sector_t iblock)
+static int btrfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
+               __u64 start, __u64 len)
 {
-       return extent_bmap(mapping, iblock, btrfs_get_extent);
+       return extent_fiemap(inode, fieinfo, start, len, btrfs_get_extent);
 }
 
 int btrfs_readpage(struct file *file, struct page *page)
@@ -4222,7 +4230,7 @@ static int btrfs_releasepage(struct page *page, gfp_t gfp_flags)
 {
        if (PageWriteback(page) || PageDirty(page))
                return 0;
-       return __btrfs_releasepage(page, gfp_flags);
+       return __btrfs_releasepage(page, gfp_flags & GFP_NOFS);
 }
 
 static void btrfs_invalidatepage(struct page *page, unsigned long offset)
@@ -4284,8 +4292,9 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
  * beyond EOF, then the page is guaranteed safe against truncation until we
  * unlock the page.
  */
-int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
+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 btrfs_root *root = BTRFS_I(inode)->root;
        struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
@@ -4297,7 +4306,7 @@ int btrfs_page_mkwrite(struct vm_area_struct *vma, struct page *page)
        u64 page_start;
        u64 page_end;
 
-       ret = btrfs_check_free_space(root, PAGE_CACHE_SIZE, 0);
+       ret = btrfs_check_data_free_space(root, inode, PAGE_CACHE_SIZE);
        if (ret)
                goto out;
 
@@ -4310,6 +4319,7 @@ again:
 
        if ((page->mapping != inode->i_mapping) ||
            (page_start >= size)) {
+               btrfs_free_reserved_data_space(root, inode, PAGE_CACHE_SIZE);
                /* page got truncated out from underneath us */
                goto out_unlock;
        }
@@ -4353,6 +4363,8 @@ again:
 out_unlock:
        unlock_page(page);
 out:
+       if (ret)
+               ret = VM_FAULT_SIGBUS;
        return ret;
 }
 
@@ -4473,13 +4485,15 @@ void btrfs_destroy_inode(struct inode *inode)
        }
        spin_unlock(&BTRFS_I(inode)->root->list_lock);
 
-       while(1) {
+       while (1) {
                ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1);
                if (!ordered)
                        break;
                else {
-                       printk("found ordered extent %Lu %Lu\n",
-                              ordered->file_offset, ordered->len);
+                       printk(KERN_ERR "btrfs found ordered "
+                              "extent %llu %llu on inode cleanup\n",
+                              (unsigned long long)ordered->file_offset,
+                              (unsigned long long)ordered->len);
                        btrfs_remove_ordered_extent(inode, ordered);
                        btrfs_put_ordered_extent(ordered);
                        btrfs_put_ordered_extent(ordered);
@@ -4563,8 +4577,8 @@ static int btrfs_getattr(struct vfsmount *mnt,
        return 0;
 }
 
-static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
-                          struct inode * new_dir,struct dentry *new_dentry)
+static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry,
+                          struct inode *new_dir, struct dentry *new_dentry)
 {
        struct btrfs_trans_handle *trans;
        struct btrfs_root *root = BTRFS_I(old_dir)->root;
@@ -4590,7 +4604,7 @@ static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
        if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
                return -EXDEV;
 
-       ret = btrfs_check_free_space(root, 1, 0);
+       ret = btrfs_check_metadata_free_space(root);
        if (ret)
                goto out_unlock;
 
@@ -4649,34 +4663,33 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root)
        struct list_head *head = &root->fs_info->delalloc_inodes;
        struct btrfs_inode *binode;
        struct inode *inode;
-       unsigned long flags;
 
        if (root->fs_info->sb->s_flags & MS_RDONLY)
                return -EROFS;
 
-       spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
-       while(!list_empty(head)) {
+       spin_lock(&root->fs_info->delalloc_lock);
+       while (!list_empty(head)) {
                binode = list_entry(head->next, struct btrfs_inode,
                                    delalloc_inodes);
                inode = igrab(&binode->vfs_inode);
                if (!inode)
                        list_del_init(&binode->delalloc_inodes);
-               spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
+               spin_unlock(&root->fs_info->delalloc_lock);
                if (inode) {
                        filemap_flush(inode->i_mapping);
                        iput(inode);
                }
                cond_resched();
-               spin_lock_irqsave(&root->fs_info->delalloc_lock, flags);
+               spin_lock(&root->fs_info->delalloc_lock);
        }
-       spin_unlock_irqrestore(&root->fs_info->delalloc_lock, flags);
+       spin_unlock(&root->fs_info->delalloc_lock);
 
        /* the filemap_flush will queue IO into the worker threads, but
         * we have to make sure the IO is actually started and that
         * ordered extents get created before we return
         */
        atomic_inc(&root->fs_info->async_submit_draining);
-       while(atomic_read(&root->fs_info->nr_async_submits) ||
+       while (atomic_read(&root->fs_info->nr_async_submits) ||
              atomic_read(&root->fs_info->async_delalloc_pages)) {
                wait_event(root->fs_info->async_submit_wait,
                   (atomic_read(&root->fs_info->nr_async_submits) == 0 &&
@@ -4709,7 +4722,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        if (name_len > BTRFS_MAX_INLINE_DATA_SIZE(root))
                return -ENAMETOOLONG;
 
-       err = btrfs_check_free_space(root, 1, 0);
+       err = btrfs_check_metadata_free_space(root);
        if (err)
                goto out_fail;
 
@@ -4731,7 +4744,7 @@ static int btrfs_symlink(struct inode *dir, struct dentry *dentry,
        if (IS_ERR(inode))
                goto out_unlock;
 
-       err = btrfs_init_acl(inode, dir);
+       err = btrfs_init_inode_security(inode, dir);
        if (err) {
                drop_inode = 1;
                goto out_unlock;
@@ -4985,13 +4998,24 @@ static struct extent_io_ops btrfs_extent_io_ops = {
        .clear_bit_hook = btrfs_clear_bit_hook,
 };
 
+/*
+ * btrfs doesn't support the bmap operation because swapfiles
+ * use bmap to make a mapping of extents in the file.  They assume
+ * these extents won't change over the life of the file and they
+ * use the bmap result to do IO directly to the drive.
+ *
+ * the btrfs bmap call would return logical addresses that aren't
+ * suitable for IO and they also will change frequently as COW
+ * operations happen.  So, swapfile + btrfs == corruption.
+ *
+ * For now we're avoiding this by dropping bmap.
+ */
 static struct address_space_operations btrfs_aops = {
        .readpage       = btrfs_readpage,
        .writepage      = btrfs_writepage,
        .writepages     = btrfs_writepages,
        .readpages      = btrfs_readpages,
        .sync_page      = block_sync_page,
-       .bmap           = btrfs_bmap,
        .direct_IO      = btrfs_direct_IO,
        .invalidatepage = btrfs_invalidatepage,
        .releasepage    = btrfs_releasepage,
@@ -5015,6 +5039,7 @@ static struct inode_operations btrfs_file_inode_operations = {
        .removexattr    = btrfs_removexattr,
        .permission     = btrfs_permission,
        .fallocate      = btrfs_fallocate,
+       .fiemap         = btrfs_fiemap,
 };
 static struct inode_operations btrfs_special_inode_operations = {
        .getattr        = btrfs_getattr,
@@ -5030,4 +5055,8 @@ static struct inode_operations btrfs_symlink_inode_operations = {
        .follow_link    = page_follow_link_light,
        .put_link       = page_put_link,
        .permission     = btrfs_permission,
+       .setxattr       = btrfs_setxattr,
+       .getxattr       = btrfs_getxattr,
+       .listxattr      = btrfs_listxattr,
+       .removexattr    = btrfs_removexattr,
 };