summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2018-04-05 02:29:24 +0300
committerDavid Sterba <dsterba@suse.com>2018-12-17 16:51:44 +0300
commit129827e3001fd1e6892a0629b48f9c7c91cbb8b6 (patch)
tree2a99d8de69cd3d439d96a384d41da62ac083e6c1
parentceb21a8db48559fd0809e03c4df9eb37743d9170 (diff)
downloadlinux-129827e3001fd1e6892a0629b48f9c7c91cbb8b6.tar.xz
btrfs: dev-replace: swich locking to rw semaphore
This is the first part of removing the custom locking and waiting scheme used for device replace. It was probably copied from extent buffer locking, but there's nothing that would require more than is provided by the common locking primitives. The rw spinlock protects waiting tasks counter in case of incompatible locks and the waitqueue. Same as rw semaphore. This patch only switches the locking primitive, for better bisectability. There should be no functional change other than the overhead of the locking and potential sleeping instead of spinning when the lock is contended. Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/ctree.h2
-rw-r--r--fs/btrfs/dev-replace.c12
-rw-r--r--fs/btrfs/disk-io.c2
3 files changed, 8 insertions, 8 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 81cbbb24678e..b4f97120aecd 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -378,7 +378,7 @@ struct btrfs_dev_replace {
struct btrfs_device *tgtdev;
struct mutex lock_finishing_cancel_unmount;
- rwlock_t lock;
+ struct rw_semaphore rwsem;
atomic_t blocking_readers;
wait_queue_head_t read_lock_wq;
diff --git a/fs/btrfs/dev-replace.c b/fs/btrfs/dev-replace.c
index 3b272ff60fea..316a29278306 100644
--- a/fs/btrfs/dev-replace.c
+++ b/fs/btrfs/dev-replace.c
@@ -1002,12 +1002,12 @@ int btrfs_dev_replace_is_ongoing(struct btrfs_dev_replace *dev_replace)
void btrfs_dev_replace_read_lock(struct btrfs_dev_replace *dev_replace)
{
- read_lock(&dev_replace->lock);
+ down_read(&dev_replace->rwsem);
}
void btrfs_dev_replace_read_unlock(struct btrfs_dev_replace *dev_replace)
{
- read_unlock(&dev_replace->lock);
+ up_read(&dev_replace->rwsem);
}
void btrfs_dev_replace_write_lock(struct btrfs_dev_replace *dev_replace)
@@ -1015,16 +1015,16 @@ void btrfs_dev_replace_write_lock(struct btrfs_dev_replace *dev_replace)
again:
wait_event(dev_replace->read_lock_wq,
atomic_read(&dev_replace->blocking_readers) == 0);
- write_lock(&dev_replace->lock);
+ down_write(&dev_replace->rwsem);
if (atomic_read(&dev_replace->blocking_readers)) {
- write_unlock(&dev_replace->lock);
+ up_write(&dev_replace->rwsem);
goto again;
}
}
void btrfs_dev_replace_write_unlock(struct btrfs_dev_replace *dev_replace)
{
- write_unlock(&dev_replace->lock);
+ up_write(&dev_replace->rwsem);
}
/* inc blocking cnt and release read lock */
@@ -1033,7 +1033,7 @@ void btrfs_dev_replace_set_lock_blocking(
{
/* only set blocking for read lock */
atomic_inc(&dev_replace->blocking_readers);
- read_unlock(&dev_replace->lock);
+ up_read(&dev_replace->rwsem);
}
void btrfs_bio_counter_inc_noblocked(struct btrfs_fs_info *fs_info)
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 14d355d0cb7a..eca66ac52c7a 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2141,7 +2141,7 @@ static void btrfs_init_btree_inode(struct btrfs_fs_info *fs_info)
static void btrfs_init_dev_replace_locks(struct btrfs_fs_info *fs_info)
{
mutex_init(&fs_info->dev_replace.lock_finishing_cancel_unmount);
- rwlock_init(&fs_info->dev_replace.lock);
+ init_rwsem(&fs_info->dev_replace.rwsem);
atomic_set(&fs_info->dev_replace.blocking_readers, 0);
init_waitqueue_head(&fs_info->dev_replace.replace_wait);
init_waitqueue_head(&fs_info->dev_replace.read_lock_wq);