On 30.01.20 г. 14:59 ч., Nikolay Borisov wrote:
> A (D)ouble (R)eader (W)riter lock is a locking primitive that allows
> to have multiple readers or multiple writers but not multiple readers
> and writers holding it concurrently. The code is factored out from
> the existing open-coded locking scheme used to exclude pending
> snapshots from nocow writers and vice-versa. Current implementation
> actually favors Readers (that is snapshot creaters) to writers (nocow
> writers of the filesystem).
>
> Signed-off-by: Nikolay Borisov <nborisov@xxxxxxxx>
> ---
> fs/btrfs/ctree.h | 1 +
> fs/btrfs/locking.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++
> fs/btrfs/locking.h | 21 +++++++++++
> 3 files changed, 109 insertions(+)
>
> diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
> index f90b82050d2d..908430f563fa 100644
> --- a/fs/btrfs/ctree.h
> +++ b/fs/btrfs/ctree.h
> @@ -33,6 +33,7 @@
> #include "extent_map.h"
> #include "async-thread.h"
> #include "block-rsv.h"
> +#include "locking.h"
>
> struct btrfs_trans_handle;
> struct btrfs_transaction;
> diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c
> index 571c4826c428..66d7d1279535 100644
> --- a/fs/btrfs/locking.c
> +++ b/fs/btrfs/locking.c
> @@ -523,3 +523,90 @@ void btrfs_unlock_up_safe(struct btrfs_path *path, int level)
> path->locks[i] = 0;
> }
> }
> +
> +int btrfs_drw_lock_init(struct btrfs_drw_lock *lock)
> +{
> + int ret;
> +
> + ret = percpu_counter_init(&lock->writers, 0, GFP_KERNEL);
> + if (ret)
> + return ret;
> +
> + atomic_set(&lock->readers, 0);
> + init_waitqueue_head(&lock->pending_readers);
> + init_waitqueue_head(&lock->pending_writers);
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(btrfs_drw_lock_init);
I have the functions EXPORT_SYMBOL since I have an internal patch which
is hooking this code to locktorture. SO they can be removed.