btrfs: Drop fs_info parameter from btrfs_qgroup_account_extents
[sfrench/cifs-2.6.git] / fs / btrfs / volumes.c
index b2d05c6b1c5672a638ba8752333c10508e366885..dcc2b486b2c5e2ec43d025f5ae3dd82d3006a1ca 100644 (file)
@@ -27,6 +27,7 @@
 #include <linux/raid/pq.h>
 #include <linux/semaphore.h>
 #include <linux/uuid.h>
+#include <linux/list_sort.h>
 #include <asm/div64.h>
 #include "ctree.h"
 #include "extent_map.h"
@@ -278,7 +279,7 @@ static void btrfs_kobject_uevent(struct block_device *bdev,
                        &disk_to_dev(bdev->bd_disk)->kobj);
 }
 
-void btrfs_cleanup_fs_uuids(void)
+void __exit btrfs_cleanup_fs_uuids(void)
 {
        struct btrfs_fs_devices *fs_devices;
 
@@ -708,7 +709,7 @@ static int btrfs_open_one_device(struct btrfs_fs_devices *fs_devices,
        if (test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) &&
            device->devid != BTRFS_DEV_REPLACE_DEVID) {
                fs_devices->rw_devices++;
-               list_add(&device->dev_alloc_list, &fs_devices->alloc_list);
+               list_add_tail(&device->dev_alloc_list, &fs_devices->alloc_list);
        }
        brelse(bh);
 
@@ -895,7 +896,11 @@ error:
        return ERR_PTR(-ENOMEM);
 }
 
-void btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices, int step)
+/*
+ * After we have read the system tree and know devids belonging to
+ * this filesystem, remove the device which does not belong there.
+ */
+void btrfs_free_extra_devids(struct btrfs_fs_devices *fs_devices, int step)
 {
        struct btrfs_device *device, *next;
        struct btrfs_device *latest_dev = NULL;
@@ -1103,6 +1108,20 @@ out:
        return ret;
 }
 
+static int devid_cmp(void *priv, struct list_head *a, struct list_head *b)
+{
+       struct btrfs_device *dev1, *dev2;
+
+       dev1 = list_entry(a, struct btrfs_device, dev_list);
+       dev2 = list_entry(b, struct btrfs_device, dev_list);
+
+       if (dev1->devid < dev2->devid)
+               return -1;
+       else if (dev1->devid > dev2->devid)
+               return 1;
+       return 0;
+}
+
 int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                       fmode_t flags, void *holder)
 {
@@ -1113,6 +1132,7 @@ int btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
                fs_devices->opened++;
                ret = 0;
        } else {
+               list_sort(NULL, &fs_devices->devices, devid_cmp);
                ret = __btrfs_open_devices(fs_devices, flags, holder);
        }
        mutex_unlock(&uuid_mutex);
@@ -2642,7 +2662,6 @@ int btrfs_init_dev_replace_tgtdev(struct btrfs_fs_info *fs_info,
        device->total_bytes = btrfs_device_get_total_bytes(srcdev);
        device->disk_total_bytes = btrfs_device_get_disk_total_bytes(srcdev);
        device->bytes_used = btrfs_device_get_bytes_used(srcdev);
-       ASSERT(list_empty(&srcdev->resized_list));
        device->commit_total_bytes = srcdev->commit_total_bytes;
        device->commit_bytes_used = device->bytes_used;
        device->fs_info = fs_info;
@@ -2666,19 +2685,6 @@ error:
        return ret;
 }
 
-void btrfs_init_dev_replace_tgtdev_for_resume(struct btrfs_fs_info *fs_info,
-                                             struct btrfs_device *tgtdev)
-{
-       u32 sectorsize = fs_info->sectorsize;
-
-       WARN_ON(fs_info->fs_devices->rw_devices == 0);
-       tgtdev->io_width = sectorsize;
-       tgtdev->io_align = sectorsize;
-       tgtdev->sector_size = sectorsize;
-       tgtdev->fs_info = fs_info;
-       set_bit(BTRFS_DEV_STATE_IN_FS_METADATA, &tgtdev->dev_state);
-}
-
 static noinline int btrfs_update_device(struct btrfs_trans_handle *trans,
                                        struct btrfs_device *device)
 {
@@ -4202,7 +4208,8 @@ static int btrfs_uuid_scan_kthread(void *data)
        key.offset = 0;
 
        while (1) {
-               ret = btrfs_search_forward(root, &key, path, 0);
+               ret = btrfs_search_forward(root, &key, path,
+                               BTRFS_OLDEST_GENERATION);
                if (ret) {
                        if (ret > 0)
                                ret = 0;
@@ -4672,7 +4679,7 @@ static void check_raid56_incompat_flag(struct btrfs_fs_info *info, u64 type)
        btrfs_set_fs_incompat(info, RAID56);
 }
 
-#define BTRFS_MAX_DEVS(r) ((BTRFS_MAX_ITEM_SIZE(r->fs_info)            \
+#define BTRFS_MAX_DEVS(info) ((BTRFS_MAX_ITEM_SIZE(info)       \
                        - sizeof(struct btrfs_chunk))           \
                        / sizeof(struct btrfs_stripe) + 1)
 
@@ -4713,10 +4720,13 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
 
        BUG_ON(!alloc_profile_is_valid(type, 0));
 
-       if (list_empty(&fs_devices->alloc_list))
+       if (list_empty(&fs_devices->alloc_list)) {
+               if (btrfs_test_opt(info, ENOSPC_DEBUG))
+                       btrfs_debug(info, "%s: no writable device", __func__);
                return -ENOSPC;
+       }
 
-       index = __get_raid_index(type);
+       index = btrfs_bg_flags_to_raid_index(type);
 
        sub_stripes = btrfs_raid_array[index].sub_stripes;
        dev_stripes = btrfs_raid_array[index].dev_stripes;
@@ -4729,7 +4739,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                max_stripe_size = SZ_1G;
                max_chunk_size = 10 * max_stripe_size;
                if (!devs_max)
-                       devs_max = BTRFS_MAX_DEVS(info->chunk_root);
+                       devs_max = BTRFS_MAX_DEVS(info);
        } else if (type & BTRFS_BLOCK_GROUP_METADATA) {
                /* for larger filesystems, use larger metadata chunks */
                if (fs_devices->total_rw_bytes > 50ULL * SZ_1G)
@@ -4738,7 +4748,7 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                        max_stripe_size = SZ_256M;
                max_chunk_size = max_stripe_size;
                if (!devs_max)
-                       devs_max = BTRFS_MAX_DEVS(info->chunk_root);
+                       devs_max = BTRFS_MAX_DEVS(info);
        } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) {
                max_stripe_size = SZ_32M;
                max_chunk_size = 2 * max_stripe_size;
@@ -4797,8 +4807,14 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                if (ret == 0)
                        max_avail = max_stripe_size * dev_stripes;
 
-               if (max_avail < BTRFS_STRIPE_LEN * dev_stripes)
+               if (max_avail < BTRFS_STRIPE_LEN * dev_stripes) {
+                       if (btrfs_test_opt(info, ENOSPC_DEBUG))
+                               btrfs_debug(info,
+                       "%s: devid %llu has no free space, have=%llu want=%u",
+                                           __func__, device->devid, max_avail,
+                                           BTRFS_STRIPE_LEN * dev_stripes);
                        continue;
+               }
 
                if (ndevs == fs_devices->rw_devices) {
                        WARN(1, "%s: found more than %llu devices\n",
@@ -4821,8 +4837,13 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
        /* round down to number of usable stripes */
        ndevs = round_down(ndevs, devs_increment);
 
-       if (ndevs < devs_increment * sub_stripes || ndevs < devs_min) {
+       if (ndevs < devs_min) {
                ret = -ENOSPC;
+               if (btrfs_test_opt(info, ENOSPC_DEBUG)) {
+                       btrfs_debug(info,
+       "%s: not enough devices with free space: have=%d minimum required=%d",
+                                   __func__, ndevs, devs_min);
+               }
                goto error;
        }
 
@@ -4856,18 +4877,17 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
         * and compare that answer with the max chunk size
         */
        if (stripe_size * data_stripes > max_chunk_size) {
-               u64 mask = (1ULL << 24) - 1;
-
                stripe_size = div_u64(max_chunk_size, data_stripes);
 
                /* bump the answer up to a 16MB boundary */
-               stripe_size = (stripe_size + mask) & ~mask;
+               stripe_size = round_up(stripe_size, SZ_16M);
 
-               /* but don't go higher than the limits we found
-                * while searching for free extents
+               /*
+                * But don't go higher than the limits we found while searching
+                * for free extents
                 */
-               if (stripe_size > devices_info[ndevs-1].max_avail)
-                       stripe_size = devices_info[ndevs-1].max_avail;
+               stripe_size = min(devices_info[ndevs - 1].max_avail,
+                                 stripe_size);
        }
 
        /* align to BTRFS_STRIPE_LEN */
@@ -7358,20 +7378,20 @@ void btrfs_update_commit_device_size(struct btrfs_fs_info *fs_info)
 }
 
 /* Must be invoked during the transaction commit */
-void btrfs_update_commit_device_bytes_used(struct btrfs_fs_info *fs_info,
-                                       struct btrfs_transaction *transaction)
+void btrfs_update_commit_device_bytes_used(struct btrfs_transaction *trans)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct extent_map *em;
        struct map_lookup *map;
        struct btrfs_device *dev;
        int i;
 
-       if (list_empty(&transaction->pending_chunks))
+       if (list_empty(&trans->pending_chunks))
                return;
 
        /* In order to kick the device replace finish process */
        mutex_lock(&fs_info->chunk_mutex);
-       list_for_each_entry(em, &transaction->pending_chunks, list) {
+       list_for_each_entry(em, &trans->pending_chunks, list) {
                map = em->map_lookup;
 
                for (i = 0; i < map->num_stripes; i++) {