Merge branch 'char-misc-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregk...
[pandora-kernel.git] / fs / btrfs / free-space-cache.c
index f49475d..181760f 100644 (file)
@@ -198,14 +198,24 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
                                    struct inode *inode)
 {
        struct btrfs_block_rsv *rsv;
+       u64 needed_bytes;
        loff_t oldsize;
        int ret = 0;
 
        rsv = trans->block_rsv;
-       trans->block_rsv = root->orphan_block_rsv;
-       ret = btrfs_block_rsv_check(root, root->orphan_block_rsv, 5);
-       if (ret)
-               return ret;
+       trans->block_rsv = &root->fs_info->global_block_rsv;
+
+       /* 1 for slack space, 1 for updating the inode */
+       needed_bytes = btrfs_calc_trunc_metadata_size(root, 1) +
+               btrfs_calc_trans_metadata_size(root, 1);
+
+       spin_lock(&trans->block_rsv->lock);
+       if (trans->block_rsv->reserved < needed_bytes) {
+               spin_unlock(&trans->block_rsv->lock);
+               trans->block_rsv = rsv;
+               return -ENOSPC;
+       }
+       spin_unlock(&trans->block_rsv->lock);
 
        oldsize = i_size_read(inode);
        btrfs_i_size_write(inode, 0);
@@ -218,13 +228,15 @@ int btrfs_truncate_free_space_cache(struct btrfs_root *root,
        ret = btrfs_truncate_inode_items(trans, root, inode,
                                         0, BTRFS_EXTENT_DATA_KEY);
 
-       trans->block_rsv = rsv;
        if (ret) {
+               trans->block_rsv = rsv;
                WARN_ON(1);
                return ret;
        }
 
        ret = btrfs_update_inode(trans, root, inode);
+       trans->block_rsv = rsv;
+
        return ret;
 }
 
@@ -525,6 +537,13 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl,
                            struct btrfs_free_space *entry, u8 *type)
 {
        struct btrfs_free_space_entry *e;
+       int ret;
+
+       if (!io_ctl->cur) {
+               ret = io_ctl_check_crc(io_ctl, io_ctl->index);
+               if (ret)
+                       return ret;
+       }
 
        e = io_ctl->cur;
        entry->offset = le64_to_cpu(e->offset);
@@ -538,10 +557,7 @@ static int io_ctl_read_entry(struct io_ctl *io_ctl,
 
        io_ctl_unmap_page(io_ctl);
 
-       if (io_ctl->index >= io_ctl->num_pages)
-               return 0;
-
-       return io_ctl_check_crc(io_ctl, io_ctl->index);
+       return 0;
 }
 
 static int io_ctl_read_bitmap(struct io_ctl *io_ctl,
@@ -549,9 +565,6 @@ static int io_ctl_read_bitmap(struct io_ctl *io_ctl,
 {
        int ret;
 
-       if (io_ctl->cur && io_ctl->cur != io_ctl->orig)
-               io_ctl_unmap_page(io_ctl);
-
        ret = io_ctl_check_crc(io_ctl, io_ctl->index);
        if (ret)
                return ret;
@@ -687,6 +700,8 @@ int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
                num_entries--;
        }
 
+       io_ctl_unmap_page(&io_ctl);
+
        /*
         * We add the bitmaps at the end of the entries in order that
         * the bitmap entries are added to the cache.