Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux...
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 1 Dec 2011 16:28:53 +0000 (08:28 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 1 Dec 2011 16:28:53 +0000 (08:28 -0800)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
  Btrfs: fix meta data raid-repair merge problem
  Btrfs: skip allocation attempt from empty cluster
  Btrfs: skip block groups without enough space for a cluster
  Btrfs: start search for new cluster at the beginning
  Btrfs: reset cluster's max_size when creating bitmap
  Btrfs: initialize new bitmaps' list
  Btrfs: fix oops when calling statfs on readonly device
  Btrfs: Don't error on resizing FS to same size
  Btrfs: fix deadlock on metadata reservation when evicting a inode
  Fix URL of btrfs-progs git repository in docs
  btrfs scrub: handle -ENOMEM from init_ipath()

1  2 
fs/btrfs/extent-tree.c
fs/btrfs/inode.c
fs/btrfs/super.c

diff --combined fs/btrfs/extent-tree.c
@@@ -3416,8 -3416,7 +3416,8 @@@ static int shrink_delalloc(struct btrfs
                smp_mb();
                nr_pages = min_t(unsigned long, nr_pages,
                       root->fs_info->delalloc_bytes >> PAGE_CACHE_SHIFT);
 -              writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages);
 +              writeback_inodes_sb_nr_if_idle(root->fs_info->sb, nr_pages,
 +                                              WB_REASON_FS_FREE_SPACE);
  
                spin_lock(&space_info->lock);
                if (reserved > space_info->bytes_may_use)
@@@ -3888,9 -3887,9 +3888,9 @@@ int btrfs_block_rsv_check(struct btrfs_
        return ret;
  }
  
int btrfs_block_rsv_refill(struct btrfs_root *root,
-                         struct btrfs_block_rsv *block_rsv,
-                         u64 min_reserved)
static inline int __btrfs_block_rsv_refill(struct btrfs_root *root,
+                                          struct btrfs_block_rsv *block_rsv,
+                                          u64 min_reserved, int flush)
  {
        u64 num_bytes = 0;
        int ret = -ENOSPC;
        if (!ret)
                return 0;
  
-       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, 1);
+       ret = reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
        if (!ret) {
                block_rsv_add_bytes(block_rsv, num_bytes, 0);
                return 0;
        return ret;
  }
  
+ int btrfs_block_rsv_refill(struct btrfs_root *root,
+                          struct btrfs_block_rsv *block_rsv,
+                          u64 min_reserved)
+ {
+       return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 1);
+ }
+ int btrfs_block_rsv_refill_noflush(struct btrfs_root *root,
+                                  struct btrfs_block_rsv *block_rsv,
+                                  u64 min_reserved)
+ {
+       return __btrfs_block_rsv_refill(root, block_rsv, min_reserved, 0);
+ }
  int btrfs_block_rsv_migrate(struct btrfs_block_rsv *src_rsv,
                            struct btrfs_block_rsv *dst_rsv,
                            u64 num_bytes)
@@@ -5265,7 -5278,7 +5279,7 @@@ alloc
                spin_lock(&block_group->free_space_ctl->tree_lock);
                if (cached &&
                    block_group->free_space_ctl->free_space <
-                   num_bytes + empty_size) {
+                   num_bytes + empty_cluster + empty_size) {
                        spin_unlock(&block_group->free_space_ctl->tree_lock);
                        goto loop;
                }
                         * people trying to start a new cluster
                         */
                        spin_lock(&last_ptr->refill_lock);
-                       if (last_ptr->block_group &&
-                           (last_ptr->block_group->ro ||
-                           !block_group_bits(last_ptr->block_group, data))) {
-                               offset = 0;
+                       if (!last_ptr->block_group ||
+                           last_ptr->block_group->ro ||
+                           !block_group_bits(last_ptr->block_group, data))
                                goto refill_cluster;
-                       }
  
                        offset = btrfs_alloc_from_cluster(block_group, last_ptr,
                                                 num_bytes, search_start);
@@@ -5342,7 -5353,7 +5354,7 @@@ refill_cluster
                        /* allocate a cluster in this block group */
                        ret = btrfs_find_space_cluster(trans, root,
                                               block_group, last_ptr,
-                                              offset, num_bytes,
+                                              search_start, num_bytes,
                                               empty_cluster + empty_size);
                        if (ret == 0) {
                                /*
diff --combined fs/btrfs/inode.c
@@@ -2318,7 -2318,7 +2318,7 @@@ static void btrfs_read_locked_inode(str
        inode_item = btrfs_item_ptr(leaf, path->slots[0],
                                    struct btrfs_inode_item);
        inode->i_mode = btrfs_inode_mode(leaf, inode_item);
 -      inode->i_nlink = btrfs_inode_nlink(leaf, inode_item);
 +      set_nlink(inode, btrfs_inode_nlink(leaf, inode_item));
        inode->i_uid = btrfs_inode_uid(leaf, inode_item);
        inode->i_gid = btrfs_inode_gid(leaf, inode_item);
        btrfs_i_size_write(inode, btrfs_inode_size(leaf, inode_item));
@@@ -3490,7 -3490,7 +3490,7 @@@ void btrfs_evict_inode(struct inode *in
         * doing the truncate.
         */
        while (1) {
-               ret = btrfs_block_rsv_refill(root, rsv, min_size);
+               ret = btrfs_block_rsv_refill_noflush(root, rsv, min_size);
  
                /*
                 * Try and steal from the global reserve since we will
@@@ -6593,7 -6593,7 +6593,7 @@@ int btrfs_create_subvol_root(struct btr
        inode->i_op = &btrfs_dir_inode_operations;
        inode->i_fop = &btrfs_dir_file_operations;
  
 -      inode->i_nlink = 1;
 +      set_nlink(inode, 1);
        btrfs_i_size_write(inode, 0);
  
        err = btrfs_update_inode(trans, new_root, inode);
diff --combined fs/btrfs/super.c
@@@ -825,9 -825,13 +825,9 @@@ static char *setup_root_args(char *args
  static struct dentry *mount_subvol(const char *subvol_name, int flags,
                                   const char *device_name, char *data)
  {
 -      struct super_block *s;
        struct dentry *root;
        struct vfsmount *mnt;
 -      struct mnt_namespace *ns_private;
        char *newargs;
 -      struct path path;
 -      int error;
  
        newargs = setup_root_args(data);
        if (!newargs)
        if (IS_ERR(mnt))
                return ERR_CAST(mnt);
  
 -      ns_private = create_mnt_ns(mnt);
 -      if (IS_ERR(ns_private)) {
 -              mntput(mnt);
 -              return ERR_CAST(ns_private);
 -      }
 +      root = mount_subtree(mnt, subvol_name);
  
 -      /*
 -       * This will trigger the automount of the subvol so we can just
 -       * drop the mnt we have here and return the dentry that we
 -       * found.
 -       */
 -      error = vfs_path_lookup(mnt->mnt_root, mnt, subvol_name,
 -                              LOOKUP_FOLLOW, &path);
 -      put_mnt_ns(ns_private);
 -      if (error)
 -              return ERR_PTR(error);
 -
 -      if (!is_subvolume_inode(path.dentry->d_inode)) {
 -              path_put(&path);
 -              mntput(mnt);
 -              error = -EINVAL;
 +      if (!IS_ERR(root) && !is_subvolume_inode(root->d_inode)) {
 +              struct super_block *s = root->d_sb;
 +              dput(root);
 +              root = ERR_PTR(-EINVAL);
 +              deactivate_locked_super(s);
                printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n",
                                subvol_name);
 -              return ERR_PTR(-EINVAL);
        }
  
 -      /* Get a ref to the sb and the dentry we found and return it */
 -      s = path.mnt->mnt_sb;
 -      atomic_inc(&s->s_active);
 -      root = dget(path.dentry);
 -      path_put(&path);
 -      down_write(&s->s_umount);
 -
        return root;
  }
  
@@@ -1057,7 -1083,7 +1057,7 @@@ static int btrfs_calc_avail_data_space(
        int i = 0, nr_devices;
        int ret;
  
-       nr_devices = fs_info->fs_devices->rw_devices;
+       nr_devices = fs_info->fs_devices->open_devices;
        BUG_ON(!nr_devices);
  
        devices_info = kmalloc(sizeof(*devices_info) * nr_devices,
        else
                min_stripe_size = BTRFS_STRIPE_LEN;
  
-       list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
-               if (!device->in_fs_metadata)
+       list_for_each_entry(device, &fs_devices->devices, dev_list) {
+               if (!device->in_fs_metadata || !device->bdev)
                        continue;
  
                avail_space = device->total_bytes - device->bytes_used;