]> Pileus Git - ~andy/linux/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Jul 2009 21:27:06 +0000 (14:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 28 Jul 2009 21:27:06 +0000 (14:27 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (22 commits)
  Btrfs: Fix async caching interaction with unmount
  Btrfs: change how we unpin extents
  Btrfs: Correct redundant test in add_inode_ref
  Btrfs: find smallest available device extent during chunk allocation
  Btrfs: clear all space_info->full after removing a block group
  Btrfs: make flushoncommit mount option correctly wait on ordered_extents
  Btrfs: Avoid delayed reference update looping
  Btrfs: Fix ordering of key field checks in btrfs_previous_item
  Btrfs: find_free_dev_extent doesn't handle holes at the start of the device
  Btrfs: Remove code duplication in comp_keys
  Btrfs: async block group caching
  Btrfs: use hybrid extents+bitmap rb tree for free space
  Btrfs: Fix crash on read failures at mount
  Btrfs: remove of redundant btrfs_header_level
  Btrfs: adjust NULL test
  Btrfs: Remove broken sanity check from btrfs_rmap_block()
  Btrfs: convert nested spin_lock_irqsave to spin_lock
  Btrfs: make sure all dirty blocks are written at commit time
  Btrfs: fix locking issue in btrfs_find_next_key
  Btrfs: fix double increment of path->slots[0] in btrfs_next_leaf
  ...

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

diff --combined fs/btrfs/ctree.h
index 98a87383871722fbddc36590cae9e60a512ef53a,17ad92c29cfd2d71009a91380f40bc9a39d4ffb0..215ef8cae823ce53cf91e559ebfe7ed602eda214
@@@ -41,6 -41,8 +41,6 @@@ struct btrfs_ordered_sum
  
  #define BTRFS_MAGIC "_BHRfS_M"
  
 -#define BTRFS_ACL_NOT_CACHED    ((void *)-1)
 -
  #define BTRFS_MAX_LEVEL 8
  
  #define BTRFS_COMPAT_EXTENT_TREE_V0
@@@ -481,7 -483,7 +481,7 @@@ struct btrfs_shared_data_ref 
  
  struct btrfs_extent_inline_ref {
        u8 type;
-       u64 offset;
+       __le64 offset;
  } __attribute__ ((__packed__));
  
  /* old style backrefs item */
@@@ -689,6 -691,7 +689,7 @@@ struct btrfs_space_info 
        struct list_head block_groups;
        spinlock_t lock;
        struct rw_semaphore groups_sem;
+       atomic_t caching_threads;
  };
  
  /*
@@@ -707,6 -710,9 +708,9 @@@ struct btrfs_free_cluster 
        /* first extent starting offset */
        u64 window_start;
  
+       /* if this cluster simply points at a bitmap in the block group */
+       bool points_to_bitmap;
        struct btrfs_block_group_cache *block_group;
        /*
         * when a cluster is allocated from a block group, we put the
        struct list_head block_group_list;
  };
  
+ enum btrfs_caching_type {
+       BTRFS_CACHE_NO          = 0,
+       BTRFS_CACHE_STARTED     = 1,
+       BTRFS_CACHE_FINISHED    = 2,
+ };
  struct btrfs_block_group_cache {
        struct btrfs_key key;
        struct btrfs_block_group_item item;
+       struct btrfs_fs_info *fs_info;
        spinlock_t lock;
-       struct mutex cache_mutex;
        u64 pinned;
        u64 reserved;
        u64 flags;
-       int cached;
+       u64 sectorsize;
+       int extents_thresh;
+       int free_extents;
+       int total_bitmaps;
        int ro;
        int dirty;
  
+       /* cache tracking stuff */
+       wait_queue_head_t caching_q;
+       int cached;
        struct btrfs_space_info *space_info;
  
        /* free space cache stuff */
        spinlock_t tree_lock;
-       struct rb_root free_space_bytes;
        struct rb_root free_space_offset;
+       u64 free_space;
  
        /* block group cache stuff */
        struct rb_node cache_node;
@@@ -942,6 -961,9 +959,9 @@@ struct btrfs_root 
        /* the node lock is held while changing the node pointer */
        spinlock_t node_lock;
  
+       /* taken when updating the commit root */
+       struct rw_semaphore commit_root_sem;
        struct extent_buffer *commit_root;
        struct btrfs_root *log_root;
        struct btrfs_root *reloc_root;
@@@ -1988,6 -2010,7 +2008,7 @@@ void btrfs_delalloc_reserve_space(struc
                                 u64 bytes);
  void btrfs_delalloc_free_space(struct btrfs_root *root, struct inode *inode,
                              u64 bytes);
+ void btrfs_free_pinned_extents(struct btrfs_fs_info *info);
  /* ctree.c */
  int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,
                     int level, int *slot);
diff --combined fs/btrfs/disk-io.c
index d28d29c95f7ca23a91e9ccf3c306840484ea29ed,3a9b8875988018bd2782f919631f54335de1e0d1..7dcaa8138864b455ea0314bcf78d17fe820c2f5d
@@@ -42,8 -42,6 +42,8 @@@
  static struct extent_io_ops btree_extent_io_ops;
  static void end_workqueue_fn(struct btrfs_work *work);
  
 +static atomic_t btrfs_bdi_num = ATOMIC_INIT(0);
 +
  /*
   * end_io_wq structs are used to do processing in task context when an IO is
   * complete.  This is used during reads to verify checksums, and it is used
@@@ -909,6 -907,7 +909,7 @@@ static int __setup_root(u32 nodesize, u
        spin_lock_init(&root->inode_lock);
        mutex_init(&root->objectid_mutex);
        mutex_init(&root->log_mutex);
+       init_rwsem(&root->commit_root_sem);
        init_waitqueue_head(&root->log_writer_wait);
        init_waitqueue_head(&root->log_commit_wait[0]);
        init_waitqueue_head(&root->log_commit_wait[1]);
@@@ -1344,25 -1343,12 +1345,25 @@@ static void btrfs_unplug_io_fn(struct b
        free_extent_map(em);
  }
  
 +/*
 + * If this fails, caller must call bdi_destroy() to get rid of the
 + * bdi again.
 + */
  static int setup_bdi(struct btrfs_fs_info *info, struct backing_dev_info *bdi)
  {
 -      bdi_init(bdi);
 +      int err;
 +
 +      bdi->capabilities = BDI_CAP_MAP_COPY;
 +      err = bdi_init(bdi);
 +      if (err)
 +              return err;
 +
 +      err = bdi_register(bdi, NULL, "btrfs-%d",
 +                              atomic_inc_return(&btrfs_bdi_num));
 +      if (err)
 +              return err;
 +
        bdi->ra_pages   = default_backing_dev_info.ra_pages;
 -      bdi->state              = 0;
 -      bdi->capabilities       = default_backing_dev_info.capabilities;
        bdi->unplug_io_fn       = btrfs_unplug_io_fn;
        bdi->unplug_io_data     = info;
        bdi->congested_fn       = btrfs_congested_fn;
@@@ -1584,8 -1570,7 +1585,8 @@@ struct btrfs_root *open_ctree(struct su
        fs_info->sb = sb;
        fs_info->max_extent = (u64)-1;
        fs_info->max_inline = 8192 * 1024;
 -      setup_bdi(fs_info, &fs_info->bdi);
 +      if (setup_bdi(fs_info, &fs_info->bdi))
 +              goto fail_bdi;
        fs_info->btree_inode = new_inode(sb);
        fs_info->btree_inode->i_ino = 1;
        fs_info->btree_inode->i_nlink = 1;
                                           btrfs_super_chunk_root(disk_super),
                                           blocksize, generation);
        BUG_ON(!chunk_root->node);
+       if (!test_bit(EXTENT_BUFFER_UPTODATE, &chunk_root->node->bflags)) {
+               printk(KERN_WARNING "btrfs: failed to read chunk root on %s\n",
+                      sb->s_id);
+               goto fail_chunk_root;
+       }
        btrfs_set_root_node(&chunk_root->root_item, chunk_root->node);
        chunk_root->commit_root = btrfs_root_node(chunk_root);
  
                                          blocksize, generation);
        if (!tree_root->node)
                goto fail_chunk_root;
+       if (!test_bit(EXTENT_BUFFER_UPTODATE, &tree_root->node->bflags)) {
+               printk(KERN_WARNING "btrfs: failed to read tree root on %s\n",
+                      sb->s_id);
+               goto fail_tree_root;
+       }
        btrfs_set_root_node(&tree_root->root_item, tree_root->node);
        tree_root->commit_root = btrfs_root_node(tree_root);
  
@@@ -1962,8 -1957,8 +1973,8 @@@ fail_iput
  
        btrfs_close_devices(fs_info->fs_devices);
        btrfs_mapping_tree_free(&fs_info->mapping_tree);
 +fail_bdi:
        bdi_destroy(&fs_info->bdi);
 -
  fail:
        kfree(extent_root);
        kfree(tree_root);
@@@ -2322,6 -2317,9 +2333,9 @@@ int close_ctree(struct btrfs_root *root
                        printk(KERN_ERR "btrfs: commit super ret %d\n", ret);
        }
  
+       fs_info->closing = 2;
+       smp_mb();
        if (fs_info->delalloc_bytes) {
                printk(KERN_INFO "btrfs: at unmount delalloc count %llu\n",
                       (unsigned long long)fs_info->delalloc_bytes);
        free_extent_buffer(root->fs_info->csum_root->commit_root);
  
        btrfs_free_block_groups(root->fs_info);
+       btrfs_free_pinned_extents(root->fs_info);
  
        del_fs_roots(fs_info);
  
diff --combined fs/btrfs/inode.c
index 791eab19e330b46f93086ac92b7f1b150b5e1513,3ea827ddf0fe6701c5a1f64bc5a61cc79e3dda42..56fe83fa60c445d365f4339d1aa472cf875490d3
@@@ -26,6 -26,7 +26,6 @@@
  #include <linux/time.h>
  #include <linux/init.h>
  #include <linux/string.h>
 -#include <linux/smp_lock.h>
  #include <linux/backing-dev.h>
  #include <linux/mpage.h>
  #include <linux/swap.h>
@@@ -2121,8 -2122,10 +2121,8 @@@ static void btrfs_read_locked_inode(str
         * any xattrs or acls
         */
        maybe_acls = acls_after_inode_item(leaf, path->slots[0], inode->i_ino);
 -      if (!maybe_acls) {
 -              BTRFS_I(inode)->i_acl = NULL;
 -              BTRFS_I(inode)->i_default_acl = NULL;
 -      }
 +      if (!maybe_acls)
 +              cache_no_acl(inode);
  
        BTRFS_I(inode)->block_group = btrfs_find_block_group(root, 0,
                                                alloc_group_block, 0);
@@@ -2319,6 -2322,7 +2319,6 @@@ err
        btrfs_update_inode(trans, root, dir);
        btrfs_drop_nlink(inode);
        ret = btrfs_update_inode(trans, root, inode);
 -      dir->i_sb->s_dirt = 1;
  out:
        return ret;
  }
@@@ -2603,8 -2607,8 +2603,8 @@@ noinline int btrfs_truncate_inode_items
        if (root->ref_cows)
                btrfs_drop_extent_cache(inode, new_size & (~mask), (u64)-1, 0);
        path = btrfs_alloc_path();
-       path->reada = -1;
        BUG_ON(!path);
+       path->reada = -1;
  
        /* FIXME, add redo link to tree so we don't leak on crash */
        key.objectid = inode->i_ino;
@@@ -2802,6 -2806,7 +2802,6 @@@ error
                                      pending_del_nr);
        }
        btrfs_free_path(path);
 -      inode->i_sb->s_dirt = 1;
        return ret;
  }
  
@@@ -3138,6 -3143,9 +3138,6 @@@ static noinline void init_btrfs_i(struc
  {
        struct btrfs_inode *bi = BTRFS_I(inode);
  
 -      bi->i_acl = BTRFS_ACL_NOT_CACHED;
 -      bi->i_default_acl = BTRFS_ACL_NOT_CACHED;
 -
        bi->generation = 0;
        bi->sequence = 0;
        bi->last_trans = 0;
@@@ -3761,6 -3769,7 +3761,6 @@@ static int btrfs_mknod(struct inode *di
                init_special_inode(inode, inode->i_mode, rdev);
                btrfs_update_inode(trans, root, inode);
        }
 -      dir->i_sb->s_dirt = 1;
        btrfs_update_inode_block_group(trans, inode);
        btrfs_update_inode_block_group(trans, dir);
  out_unlock:
@@@ -3825,6 -3834,7 +3825,6 @@@ static int btrfs_create(struct inode *d
                inode->i_op = &btrfs_file_inode_operations;
                BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
        }
 -      dir->i_sb->s_dirt = 1;
        btrfs_update_inode_block_group(trans, inode);
        btrfs_update_inode_block_group(trans, dir);
  out_unlock:
@@@ -3871,6 -3881,7 +3871,6 @@@ static int btrfs_link(struct dentry *ol
        if (err)
                drop_inode = 1;
  
 -      dir->i_sb->s_dirt = 1;
        btrfs_update_inode_block_group(trans, dir);
        err = btrfs_update_inode(trans, root, inode);
  
@@@ -3952,6 -3963,7 +3952,6 @@@ static int btrfs_mkdir(struct inode *di
  
        d_instantiate(dentry, inode);
        drop_on_err = 0;
 -      dir->i_sb->s_dirt = 1;
        btrfs_update_inode_block_group(trans, inode);
        btrfs_update_inode_block_group(trans, dir);
  
@@@ -4635,6 -4647,8 +4635,6 @@@ struct inode *btrfs_alloc_inode(struct 
        ei->last_trans = 0;
        ei->logged_trans = 0;
        btrfs_ordered_inode_tree_init(&ei->ordered_tree);
 -      ei->i_acl = BTRFS_ACL_NOT_CACHED;
 -      ei->i_default_acl = BTRFS_ACL_NOT_CACHED;
        INIT_LIST_HEAD(&ei->i_orphan);
        INIT_LIST_HEAD(&ei->ordered_operations);
        return &ei->vfs_inode;
@@@ -4648,6 -4662,13 +4648,6 @@@ void btrfs_destroy_inode(struct inode *
        WARN_ON(!list_empty(&inode->i_dentry));
        WARN_ON(inode->i_data.nrpages);
  
 -      if (BTRFS_I(inode)->i_acl &&
 -          BTRFS_I(inode)->i_acl != BTRFS_ACL_NOT_CACHED)
 -              posix_acl_release(BTRFS_I(inode)->i_acl);
 -      if (BTRFS_I(inode)->i_default_acl &&
 -          BTRFS_I(inode)->i_default_acl != BTRFS_ACL_NOT_CACHED)
 -              posix_acl_release(BTRFS_I(inode)->i_default_acl);
 -
        /*
         * Make sure we're properly removed from the ordered operation
         * lists.
@@@ -4971,6 -4992,7 +4971,6 @@@ static int btrfs_symlink(struct inode *
                inode->i_op = &btrfs_file_inode_operations;
                BTRFS_I(inode)->io_tree.ops = &btrfs_extent_io_ops;
        }
 -      dir->i_sb->s_dirt = 1;
        btrfs_update_inode_block_group(trans, inode);
        btrfs_update_inode_block_group(trans, dir);
        if (drop_inode)