Merge branch 'bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs...
[pandora-kernel.git] / fs / btrfs / super.c
index 5f56213..65b62da 100644 (file)
@@ -638,7 +638,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
        if (IS_ERR(root)) {
                error = PTR_ERR(root);
                deactivate_locked_super(s);
-               goto error;
+               goto error_free_subvol_name;
        }
        /* if they gave us a subvolume name bind mount into that */
        if (strcmp(subvol_name, ".")) {
@@ -652,14 +652,14 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
                        deactivate_locked_super(s);
                        error = PTR_ERR(new_root);
                        dput(root);
-                       goto error_close_devices;
+                       goto error_free_subvol_name;
                }
                if (!new_root->d_inode) {
                        dput(root);
                        dput(new_root);
                        deactivate_locked_super(s);
                        error = -ENXIO;
-                       goto error_close_devices;
+                       goto error_free_subvol_name;
                }
                dput(root);
                root = new_root;
@@ -677,7 +677,6 @@ error_close_devices:
        btrfs_close_devices(fs_devices);
 error_free_subvol_name:
        kfree(subvol_name);
-error:
        return error;
 }
 
@@ -725,18 +724,25 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
        struct list_head *head = &root->fs_info->space_info;
        struct btrfs_space_info *found;
        u64 total_used = 0;
+       u64 total_used_data = 0;
        int bits = dentry->d_sb->s_blocksize_bits;
        __be32 *fsid = (__be32 *)root->fs_info->fsid;
 
        rcu_read_lock();
-       list_for_each_entry_rcu(found, head, list)
+       list_for_each_entry_rcu(found, head, list) {
+               if (found->flags & (BTRFS_BLOCK_GROUP_METADATA |
+                                   BTRFS_BLOCK_GROUP_SYSTEM))
+                       total_used_data += found->disk_total;
+               else
+                       total_used_data += found->disk_used;
                total_used += found->disk_used;
+       }
        rcu_read_unlock();
 
        buf->f_namelen = BTRFS_NAME_LEN;
        buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
        buf->f_bfree = buf->f_blocks - (total_used >> bits);
-       buf->f_bavail = buf->f_bfree;
+       buf->f_bavail = buf->f_blocks - (total_used_data >> bits);
        buf->f_bsize = dentry->d_sb->s_blocksize;
        buf->f_type = BTRFS_SUPER_MAGIC;