btrfs: open code btrfs_dev_replace_clear_lock_blocking
[sfrench/cifs-2.6.git] / fs / btrfs / volumes.c
index b39e4bd6457ff33bc05441f9cffb7eca4404ede3..f435d397019eae589f4e9daf88c954229537a60e 100644 (file)
@@ -1613,7 +1613,7 @@ static u64 find_next_chunk(struct btrfs_fs_info *fs_info)
 
        em_tree = &fs_info->mapping_tree.map_tree;
        read_lock(&em_tree->lock);
-       n = rb_last(&em_tree->map);
+       n = rb_last(&em_tree->map.rb_root);
        if (n) {
                em = rb_entry(n, struct extent_map, rb_node);
                ret = em->start + em->len;
@@ -1889,10 +1889,16 @@ int btrfs_rm_device(struct btrfs_fs_info *fs_info, const char *device_path,
        if (ret)
                goto out;
 
-       ret = btrfs_find_device_by_devspec(fs_info, devid, device_path,
-                                          &device);
-       if (ret)
+       device = btrfs_find_device_by_devspec(fs_info, devid, device_path);
+
+       if (IS_ERR(device)) {
+               if (PTR_ERR(device) == -ENOENT &&
+                   strcmp(device_path, "missing") == 0)
+                       ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
+               else
+                       ret = PTR_ERR(device);
                goto out;
+       }
 
        if (test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state)) {
                ret = BTRFS_ERROR_DEV_TGT_REPLACE;
@@ -2163,30 +2169,21 @@ static struct btrfs_device *btrfs_find_device_missing_or_by_path(
 /*
  * Lookup a device given by device id, or the path if the id is 0.
  */
-int btrfs_find_device_by_devspec(struct btrfs_fs_info *fs_info, u64 devid,
-                                const char *devpath,
-                                struct btrfs_device **device)
+struct btrfs_device *btrfs_find_device_by_devspec(
+               struct btrfs_fs_info *fs_info, u64 devid, const char *devpath)
 {
-       int ret = 0;
+       struct btrfs_device *device;
 
        if (devid) {
-               *device = btrfs_find_device(fs_info, devid, NULL, NULL);
-               if (!*device)
-                       ret = -ENOENT;
+               device = btrfs_find_device(fs_info, devid, NULL, NULL);
+               if (!device)
+                       return ERR_PTR(-ENOENT);
        } else {
                if (!devpath || !devpath[0])
-                       return -EINVAL;
-
-               *device = btrfs_find_device_missing_or_by_path(fs_info, devpath);
-               if (IS_ERR(*device)) {
-                       if (PTR_ERR(*device) == -ENOENT &&
-                           strcmp(devpath, "missing") == 0)
-                               ret = BTRFS_ERROR_DEV_MISSING_NOT_FOUND;
-                       else
-                               ret = PTR_ERR(*device);
-               }
+                       return ERR_PTR(-EINVAL);
+               device = btrfs_find_device_missing_or_by_path(fs_info, devpath);
        }
-       return ret;
+       return device;
 }
 
 /*
@@ -3694,7 +3691,7 @@ static int alloc_profile_is_valid(u64 flags, int extended)
                return !extended; /* "0" is valid for usual profiles */
 
        /* true if exactly one bit set */
-       return (flags & (flags - 1)) == 0;
+       return is_power_of_2(flags);
 }
 
 static inline int balance_need_close(struct btrfs_fs_info *fs_info)
@@ -5907,7 +5904,11 @@ static int __btrfs_map_block(struct btrfs_fs_info *fs_info,
        }
 out:
        if (dev_replace_is_ongoing) {
-               btrfs_dev_replace_clear_lock_blocking(dev_replace);
+               ASSERT(atomic_read(&dev_replace->blocking_readers) > 0);
+               btrfs_dev_replace_read_lock(dev_replace);
+               /* Barrier implied by atomic_dec_and_test */
+               if (atomic_dec_and_test(&dev_replace->blocking_readers))
+                       cond_wake_up_nomb(&dev_replace->read_lock_wq);
                btrfs_dev_replace_read_unlock(dev_replace);
        }
        free_extent_map(em);
@@ -7448,7 +7449,7 @@ static int verify_chunk_dev_extent_mapping(struct btrfs_fs_info *fs_info)
        int ret = 0;
 
        read_lock(&em_tree->lock);
-       for (node = rb_first(&em_tree->map); node; node = rb_next(node)) {
+       for (node = rb_first_cached(&em_tree->map); node; node = rb_next(node)) {
                em = rb_entry(node, struct extent_map, rb_node);
                if (em->map_lookup->num_stripes !=
                    em->map_lookup->verified_stripes) {