|
@@ -7025,36 +7025,35 @@ btrfs_lock_cluster(struct btrfs_block_group_cache *block_group,
|
|
|
int delalloc)
|
|
|
{
|
|
|
struct btrfs_block_group_cache *used_bg = NULL;
|
|
|
- bool locked = false;
|
|
|
-again:
|
|
|
+
|
|
|
spin_lock(&cluster->refill_lock);
|
|
|
- if (locked) {
|
|
|
- if (used_bg == cluster->block_group)
|
|
|
+ while (1) {
|
|
|
+ used_bg = cluster->block_group;
|
|
|
+ if (!used_bg)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ if (used_bg == block_group)
|
|
|
return used_bg;
|
|
|
|
|
|
- up_read(&used_bg->data_rwsem);
|
|
|
- btrfs_put_block_group(used_bg);
|
|
|
- }
|
|
|
+ btrfs_get_block_group(used_bg);
|
|
|
|
|
|
- used_bg = cluster->block_group;
|
|
|
- if (!used_bg)
|
|
|
- return NULL;
|
|
|
+ if (!delalloc)
|
|
|
+ return used_bg;
|
|
|
|
|
|
- if (used_bg == block_group)
|
|
|
- return used_bg;
|
|
|
+ if (down_read_trylock(&used_bg->data_rwsem))
|
|
|
+ return used_bg;
|
|
|
|
|
|
- btrfs_get_block_group(used_bg);
|
|
|
+ spin_unlock(&cluster->refill_lock);
|
|
|
|
|
|
- if (!delalloc)
|
|
|
- return used_bg;
|
|
|
+ down_read(&used_bg->data_rwsem);
|
|
|
|
|
|
- if (down_read_trylock(&used_bg->data_rwsem))
|
|
|
- return used_bg;
|
|
|
+ spin_lock(&cluster->refill_lock);
|
|
|
+ if (used_bg == cluster->block_group)
|
|
|
+ return used_bg;
|
|
|
|
|
|
- spin_unlock(&cluster->refill_lock);
|
|
|
- down_read(&used_bg->data_rwsem);
|
|
|
- locked = true;
|
|
|
- goto again;
|
|
|
+ up_read(&used_bg->data_rwsem);
|
|
|
+ btrfs_put_block_group(used_bg);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static inline void
|