+++ /dev/null
-From 1587253bfd3c2e90d8659abd8093396881f622fc Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:46 -0700
-Subject: btrfs: add macros for annotating wait events with lockdep
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit ab9a323f9ab576000795285dd7ac6afeedf29e32 ]
-
-Introduce four macros that are used to annotate wait events in btrfs code
-with lockdep;
-
- 1) the btrfs_lockdep_init_map
- 2) the btrfs_lockdep_acquire,
- 3) the btrfs_lockdep_release
- 4) the btrfs_might_wait_for_event macros.
-
-The btrfs_lockdep_init_map macro is used to initialize a lockdep map.
-
-The btrfs_lockdep_<acquire,release> macros are used by threads to take
-the lockdep map as readers (shared lock) and release it, respectively.
-
-The btrfs_might_wait_for_event macro is used by threads to take the
-lockdep map as writers (exclusive lock) and release it.
-
-In general, the lockdep annotation for wait events work as follows:
-
-The condition for a wait event can be modified and signaled at the same
-time by multiple threads. These threads hold the lockdep map as readers
-when they enter a context in which blocking would prevent signaling the
-condition. Frequently, this occurs when a thread violates a condition
-(lockdep map acquire), before restoring it and signaling it at a later
-point (lockdep map release).
-
-The threads that block on the wait event take the lockdep map as writers
-(exclusive lock). These threads have to block until all the threads that
-hold the lockdep map as readers signal the condition for the wait event
-and release the lockdep map.
-
-The lockdep annotation is used to warn about potential deadlock scenarios
-that involve the threads that modify and signal the wait event condition
-and threads that block on the wait event. A simple example is illustrated
-below:
-
-Without lockdep:
-
-TA TB
-cond = false
- lock(A)
- wait_event(w, cond)
- unlock(A)
-lock(A)
-cond = true
-signal(w)
-unlock(A)
-
-With lockdep:
-
-TA TB
-rwsem_acquire_read(lockdep_map)
-cond = false
- lock(A)
- rwsem_acquire(lockdep_map)
- rwsem_release(lockdep_map)
- wait_event(w, cond)
- unlock(A)
-lock(A)
-cond = true
-signal(w)
-unlock(A)
-rwsem_release(lockdep_map)
-
-In the second case, with the lockdep annotation, lockdep would warn about
-an ABBA deadlock, while the first case would just deadlock at some point.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 45 insertions(+)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index 02d3ee6c7d9b..3ab1219db32e 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1108,6 +1108,51 @@ enum {
- BTRFS_ROOT_RESET_LOCKDEP_CLASS,
- };
-
-+/*
-+ * Lockdep annotation for wait events.
-+ *
-+ * @owner: The struct where the lockdep map is defined
-+ * @lock: The lockdep map corresponding to a wait event
-+ *
-+ * This macro is used to annotate a wait event. In this case a thread acquires
-+ * the lockdep map as writer (exclusive lock) because it has to block until all
-+ * the threads that hold the lock as readers signal the condition for the wait
-+ * event and release their locks.
-+ */
-+#define btrfs_might_wait_for_event(owner, lock) \
-+ do { \
-+ rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_); \
-+ rwsem_release(&owner->lock##_map, _THIS_IP_); \
-+ } while (0)
-+
-+/*
-+ * Protection for the resource/condition of a wait event.
-+ *
-+ * @owner: The struct where the lockdep map is defined
-+ * @lock: The lockdep map corresponding to a wait event
-+ *
-+ * Many threads can modify the condition for the wait event at the same time
-+ * and signal the threads that block on the wait event. The threads that modify
-+ * the condition and do the signaling acquire the lock as readers (shared
-+ * lock).
-+ */
-+#define btrfs_lockdep_acquire(owner, lock) \
-+ rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_)
-+
-+/*
-+ * Used after signaling the condition for a wait event to release the lockdep
-+ * map held by a reader thread.
-+ */
-+#define btrfs_lockdep_release(owner, lock) \
-+ rwsem_release(&owner->lock##_map, _THIS_IP_)
-+
-+/* Initialization of the lockdep map */
-+#define btrfs_lockdep_init_map(owner, lock) \
-+ do { \
-+ static struct lock_class_key lock##_key; \
-+ lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \
-+ } while (0)
-+
- static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
- {
- clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
---
-2.35.1
-
+++ /dev/null
-From 28946141bf21e5e533d472b762e7a4dac31be136 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:57 -0700
-Subject: btrfs: change the lockdep class of free space inode's invalidate_lock
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 9d7464c87b159bbf763c24faeb7a2dcaac96e4a1 ]
-
-Reinitialize the class of the lockdep map for struct inode's
-mapping->invalidate_lock in load_free_space_cache() function in
-fs/btrfs/free-space-cache.c. This will prevent lockdep from producing
-false positives related to execution paths that make use of free space
-inodes and paths that make use of normal inodes.
-
-Specifically, with this change lockdep will create separate lock
-dependencies that include the invalidate_lock, in the case that free
-space inodes are used and in the case that normal inodes are used.
-
-The lockdep class for this lock was first initialized in
-inode_init_always() in fs/inode.c.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/free-space-cache.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
-index 529907ea3825..456da08feccd 100644
---- a/fs/btrfs/free-space-cache.c
-+++ b/fs/btrfs/free-space-cache.c
-@@ -899,6 +899,8 @@ static int copy_free_space_cache(struct btrfs_block_group *block_group,
- return ret;
- }
-
-+static struct lock_class_key btrfs_free_space_inode_key;
-+
- int load_free_space_cache(struct btrfs_block_group *block_group)
- {
- struct btrfs_fs_info *fs_info = block_group->fs_info;
-@@ -968,6 +970,14 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
- }
- spin_unlock(&block_group->lock);
-
-+ /*
-+ * Reinitialize the class of struct inode's mapping->invalidate_lock for
-+ * free space inodes to prevent false positives related to locks for normal
-+ * inodes.
-+ */
-+ lockdep_set_class(&(&inode->i_data)->invalidate_lock,
-+ &btrfs_free_space_inode_key);
-+
- ret = __load_free_space_cache(fs_info->tree_root, inode, &tmp_ctl,
- path, block_group->start);
- btrfs_free_path(path);
---
-2.35.1
-
arm64-dts-imx8mq-librem5-add-bq25895-as-max17055-s-p.patch
arm-orion-fix-include-path.patch
btrfs-dump-extra-info-if-one-free-space-cache-has-mo.patch
-btrfs-add-macros-for-annotating-wait-events-with-loc.patch
-btrfs-change-the-lockdep-class-of-free-space-inode-s.patch
btrfs-scrub-try-to-fix-super-block-errors.patch
btrfs-don-t-print-information-about-space-cache-or-t.patch
arm64-dts-uniphier-add-usb-device-support-for-pxs3-r.patch
+++ /dev/null
-From e444bea4707bcdad792b420041dfd32f9201d1d6 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:46 -0700
-Subject: btrfs: add macros for annotating wait events with lockdep
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit ab9a323f9ab576000795285dd7ac6afeedf29e32 ]
-
-Introduce four macros that are used to annotate wait events in btrfs code
-with lockdep;
-
- 1) the btrfs_lockdep_init_map
- 2) the btrfs_lockdep_acquire,
- 3) the btrfs_lockdep_release
- 4) the btrfs_might_wait_for_event macros.
-
-The btrfs_lockdep_init_map macro is used to initialize a lockdep map.
-
-The btrfs_lockdep_<acquire,release> macros are used by threads to take
-the lockdep map as readers (shared lock) and release it, respectively.
-
-The btrfs_might_wait_for_event macro is used by threads to take the
-lockdep map as writers (exclusive lock) and release it.
-
-In general, the lockdep annotation for wait events work as follows:
-
-The condition for a wait event can be modified and signaled at the same
-time by multiple threads. These threads hold the lockdep map as readers
-when they enter a context in which blocking would prevent signaling the
-condition. Frequently, this occurs when a thread violates a condition
-(lockdep map acquire), before restoring it and signaling it at a later
-point (lockdep map release).
-
-The threads that block on the wait event take the lockdep map as writers
-(exclusive lock). These threads have to block until all the threads that
-hold the lockdep map as readers signal the condition for the wait event
-and release the lockdep map.
-
-The lockdep annotation is used to warn about potential deadlock scenarios
-that involve the threads that modify and signal the wait event condition
-and threads that block on the wait event. A simple example is illustrated
-below:
-
-Without lockdep:
-
-TA TB
-cond = false
- lock(A)
- wait_event(w, cond)
- unlock(A)
-lock(A)
-cond = true
-signal(w)
-unlock(A)
-
-With lockdep:
-
-TA TB
-rwsem_acquire_read(lockdep_map)
-cond = false
- lock(A)
- rwsem_acquire(lockdep_map)
- rwsem_release(lockdep_map)
- wait_event(w, cond)
- unlock(A)
-lock(A)
-cond = true
-signal(w)
-unlock(A)
-rwsem_release(lockdep_map)
-
-In the second case, with the lockdep annotation, lockdep would warn about
-an ABBA deadlock, while the first case would just deadlock at some point.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 45 insertions(+)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index 1bbc810574f2..8d35db5b2b62 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1148,6 +1148,51 @@ enum {
- BTRFS_ROOT_RESET_LOCKDEP_CLASS,
- };
-
-+/*
-+ * Lockdep annotation for wait events.
-+ *
-+ * @owner: The struct where the lockdep map is defined
-+ * @lock: The lockdep map corresponding to a wait event
-+ *
-+ * This macro is used to annotate a wait event. In this case a thread acquires
-+ * the lockdep map as writer (exclusive lock) because it has to block until all
-+ * the threads that hold the lock as readers signal the condition for the wait
-+ * event and release their locks.
-+ */
-+#define btrfs_might_wait_for_event(owner, lock) \
-+ do { \
-+ rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_); \
-+ rwsem_release(&owner->lock##_map, _THIS_IP_); \
-+ } while (0)
-+
-+/*
-+ * Protection for the resource/condition of a wait event.
-+ *
-+ * @owner: The struct where the lockdep map is defined
-+ * @lock: The lockdep map corresponding to a wait event
-+ *
-+ * Many threads can modify the condition for the wait event at the same time
-+ * and signal the threads that block on the wait event. The threads that modify
-+ * the condition and do the signaling acquire the lock as readers (shared
-+ * lock).
-+ */
-+#define btrfs_lockdep_acquire(owner, lock) \
-+ rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_)
-+
-+/*
-+ * Used after signaling the condition for a wait event to release the lockdep
-+ * map held by a reader thread.
-+ */
-+#define btrfs_lockdep_release(owner, lock) \
-+ rwsem_release(&owner->lock##_map, _THIS_IP_)
-+
-+/* Initialization of the lockdep map */
-+#define btrfs_lockdep_init_map(owner, lock) \
-+ do { \
-+ static struct lock_class_key lock##_key; \
-+ lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \
-+ } while (0)
-+
- static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
- {
- clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
---
-2.35.1
-
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++--------------
+ fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 20 deletions(-)
-diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
-index d9577f822ba5..19e58e553fa1 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
-@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
+@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btr
struct btrfs_free_space *info, u64 offset,
u64 bytes, bool update_stats);
static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
struct btrfs_path *path,
u64 offset)
-@@ -881,7 +900,14 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
+@@ -881,7 +900,14 @@ out:
return ret;
free_cache:
io_ctl_drop_pages(&io_ctl);
goto out;
}
-@@ -1017,7 +1043,13 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+@@ -1007,7 +1033,13 @@ int load_free_space_cache(struct btrfs_b
if (ret == 0)
ret = 1;
} else {
btrfs_warn(fs_info,
"block group %llu has wrong amount of free space",
block_group->start);
-@@ -2980,25 +3012,6 @@ static void __btrfs_return_cluster_to_free_space(
+@@ -2970,25 +3002,6 @@ static void __btrfs_return_cluster_to_fr
btrfs_put_block_group(block_group);
}
void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
{
spin_lock(&ctl->tree_lock);
---
-2.35.1
-
+++ /dev/null
-From 64796875b3d6eef72b90481ed83ae4db55ce12c8 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:57 -0700
-Subject: btrfs: change the lockdep class of free space inode's invalidate_lock
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 9d7464c87b159bbf763c24faeb7a2dcaac96e4a1 ]
-
-Reinitialize the class of the lockdep map for struct inode's
-mapping->invalidate_lock in load_free_space_cache() function in
-fs/btrfs/free-space-cache.c. This will prevent lockdep from producing
-false positives related to execution paths that make use of free space
-inodes and paths that make use of normal inodes.
-
-Specifically, with this change lockdep will create separate lock
-dependencies that include the invalidate_lock, in the case that free
-space inodes are used and in the case that normal inodes are used.
-
-The lockdep class for this lock was first initialized in
-inode_init_always() in fs/inode.c.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/free-space-cache.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
-index 16710d4571da..d9577f822ba5 100644
---- a/fs/btrfs/free-space-cache.c
-+++ b/fs/btrfs/free-space-cache.c
-@@ -920,6 +920,8 @@ static int copy_free_space_cache(struct btrfs_block_group *block_group,
- return ret;
- }
-
-+static struct lock_class_key btrfs_free_space_inode_key;
-+
- int load_free_space_cache(struct btrfs_block_group *block_group)
- {
- struct btrfs_fs_info *fs_info = block_group->fs_info;
-@@ -989,6 +991,14 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
- }
- spin_unlock(&block_group->lock);
-
-+ /*
-+ * Reinitialize the class of struct inode's mapping->invalidate_lock for
-+ * free space inodes to prevent false positives related to locks for normal
-+ * inodes.
-+ */
-+ lockdep_set_class(&(&inode->i_data)->invalidate_lock,
-+ &btrfs_free_space_inode_key);
-+
- ret = __load_free_space_cache(fs_info->tree_root, inode, &tmp_ctl,
- path, block_group->start);
- btrfs_free_path(path);
---
-2.35.1
-
arm64-dts-imx8mq-librem5-add-bq25895-as-max17055-s-p.patch
arm-orion-fix-include-path.patch
btrfs-dump-extra-info-if-one-free-space-cache-has-mo.patch
-btrfs-add-macros-for-annotating-wait-events-with-loc.patch
-btrfs-change-the-lockdep-class-of-free-space-inode-s.patch
btrfs-scrub-properly-report-super-block-errors-in-sy.patch
btrfs-scrub-try-to-fix-super-block-errors.patch
btrfs-don-t-print-information-about-space-cache-or-t.patch
+++ /dev/null
-From cfca5f04b3bb29b3a74ff00154aacebe440602ed Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:50 -0700
-Subject: btrfs: add lockdep annotations for num_extwriters wait event
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 5a9ba6709f13313984900d635b4c73c9eb7d644e ]
-
-Similarly to the num_writers wait event in fs/btrfs/transaction.c add a
-lockdep annotation for the num_extwriters wait event.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 1 +
- fs/btrfs/disk-io.c | 1 +
- fs/btrfs/transaction.c | 13 +++++++++++++
- 3 files changed, 15 insertions(+)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index 707e644bab92..e886cf639c0f 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1097,6 +1097,7 @@ struct btrfs_fs_info {
- * compiled without lockdep).
- */
- struct lockdep_map btrfs_trans_num_writers_map;
-+ struct lockdep_map btrfs_trans_num_extwriters_map;
-
- #ifdef CONFIG_BTRFS_FS_REF_VERIFY
- spinlock_t ref_verify_lock;
-diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
-index a04b32f7df9d..811d743e26e6 100644
---- a/fs/btrfs/disk-io.c
-+++ b/fs/btrfs/disk-io.c
-@@ -2991,6 +2991,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
- seqlock_init(&fs_info->profiles_lock);
-
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers);
-+ btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters);
-
- INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
- INIT_LIST_HEAD(&fs_info->space_info);
-diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
-index b3cb54d852f8..44e47db4c8e8 100644
---- a/fs/btrfs/transaction.c
-+++ b/fs/btrfs/transaction.c
-@@ -314,6 +314,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
- extwriter_counter_inc(cur_trans, type);
- spin_unlock(&fs_info->trans_lock);
- btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers);
-+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_extwriters);
- return 0;
- }
- spin_unlock(&fs_info->trans_lock);
-@@ -336,6 +337,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
- return -ENOMEM;
-
- btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers);
-+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_extwriters);
-
- spin_lock(&fs_info->trans_lock);
- if (fs_info->running_transaction) {
-@@ -343,11 +345,13 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
- * someone started a transaction after we unlocked. Make sure
- * to redo the checks above
- */
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
- btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- kfree(cur_trans);
- goto loop;
- } else if (BTRFS_FS_ERROR(fs_info)) {
- spin_unlock(&fs_info->trans_lock);
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
- btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- kfree(cur_trans);
- return -EROFS;
-@@ -1028,6 +1032,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
-
- cond_wake_up(&cur_trans->writer_wait);
-
-+ btrfs_lockdep_release(info, btrfs_trans_num_extwriters);
- btrfs_lockdep_release(info, btrfs_trans_num_writers);
-
- btrfs_put_transaction(cur_trans);
-@@ -2270,6 +2275,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- if (ret)
- goto lockdep_release;
-
-+ /*
-+ * The thread has started/joined the transaction thus it holds the
-+ * lockdep map as a reader. It has to release it before acquiring the
-+ * lockdep map as a writer.
-+ */
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
-+ btrfs_might_wait_for_event(fs_info, btrfs_trans_num_extwriters);
- wait_event(cur_trans->writer_wait,
- extwriter_counter_read(cur_trans) == 0);
-
-@@ -2541,6 +2553,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- return ret;
-
- lockdep_release:
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
- btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- goto cleanup_transaction;
- }
---
-2.35.1
-
+++ /dev/null
-From 4c3eac5e35f1d4118988475c65fddc92b7dced27 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:48 -0700
-Subject: btrfs: add lockdep annotations for num_writers wait event
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit e1489b4fe6045a79a5e9c658eed65311977e230a ]
-
-Annotate the num_writers wait event in fs/btrfs/transaction.c with
-lockdep in order to catch deadlocks involving this wait event.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 6 ++++++
- fs/btrfs/disk-io.c | 2 ++
- fs/btrfs/transaction.c | 38 +++++++++++++++++++++++++++++++++-----
- 3 files changed, 41 insertions(+), 5 deletions(-)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index dfeb7174219e..707e644bab92 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1092,6 +1092,12 @@ struct btrfs_fs_info {
- /* Updates are not protected by any lock */
- struct btrfs_commit_stats commit_stats;
-
-+ /*
-+ * Annotations for transaction events (structures are empty when
-+ * compiled without lockdep).
-+ */
-+ struct lockdep_map btrfs_trans_num_writers_map;
-+
- #ifdef CONFIG_BTRFS_FS_REF_VERIFY
- spinlock_t ref_verify_lock;
- struct rb_root block_tree;
-diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
-index 2633137c3e9f..a04b32f7df9d 100644
---- a/fs/btrfs/disk-io.c
-+++ b/fs/btrfs/disk-io.c
-@@ -2990,6 +2990,8 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
- mutex_init(&fs_info->zoned_data_reloc_io_lock);
- seqlock_init(&fs_info->profiles_lock);
-
-+ btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers);
-+
- INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
- INIT_LIST_HEAD(&fs_info->space_info);
- INIT_LIST_HEAD(&fs_info->tree_mod_seq_list);
-diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
-index 0bec10740ad3..b3cb54d852f8 100644
---- a/fs/btrfs/transaction.c
-+++ b/fs/btrfs/transaction.c
-@@ -313,6 +313,7 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
- atomic_inc(&cur_trans->num_writers);
- extwriter_counter_inc(cur_trans, type);
- spin_unlock(&fs_info->trans_lock);
-+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers);
- return 0;
- }
- spin_unlock(&fs_info->trans_lock);
-@@ -334,16 +335,20 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
- if (!cur_trans)
- return -ENOMEM;
-
-+ btrfs_lockdep_acquire(fs_info, btrfs_trans_num_writers);
-+
- spin_lock(&fs_info->trans_lock);
- if (fs_info->running_transaction) {
- /*
- * someone started a transaction after we unlocked. Make sure
- * to redo the checks above
- */
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- kfree(cur_trans);
- goto loop;
- } else if (BTRFS_FS_ERROR(fs_info)) {
- spin_unlock(&fs_info->trans_lock);
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- kfree(cur_trans);
- return -EROFS;
- }
-@@ -1022,6 +1027,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
- extwriter_counter_dec(cur_trans, trans->type);
-
- cond_wake_up(&cur_trans->writer_wait);
-+
-+ btrfs_lockdep_release(info, btrfs_trans_num_writers);
-+
- btrfs_put_transaction(cur_trans);
-
- if (current->journal_info == trans)
-@@ -1994,6 +2002,12 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
- if (cur_trans == fs_info->running_transaction) {
- cur_trans->state = TRANS_STATE_COMMIT_DOING;
- spin_unlock(&fs_info->trans_lock);
-+
-+ /*
-+ * The thread has already released the lockdep map as reader
-+ * already in btrfs_commit_transaction().
-+ */
-+ btrfs_might_wait_for_event(fs_info, btrfs_trans_num_writers);
- wait_event(cur_trans->writer_wait,
- atomic_read(&cur_trans->num_writers) == 1);
-
-@@ -2222,7 +2236,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- btrfs_put_transaction(prev_trans);
- if (ret)
-- goto cleanup_transaction;
-+ goto lockdep_release;
- } else {
- spin_unlock(&fs_info->trans_lock);
- }
-@@ -2236,7 +2250,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- */
- if (BTRFS_FS_ERROR(fs_info)) {
- ret = -EROFS;
-- goto cleanup_transaction;
-+ goto lockdep_release;
- }
- }
-
-@@ -2250,19 +2264,21 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- ret = btrfs_start_delalloc_flush(fs_info);
- if (ret)
-- goto cleanup_transaction;
-+ goto lockdep_release;
-
- ret = btrfs_run_delayed_items(trans);
- if (ret)
-- goto cleanup_transaction;
-+ goto lockdep_release;
-
- wait_event(cur_trans->writer_wait,
- extwriter_counter_read(cur_trans) == 0);
-
- /* some pending stuffs might be added after the previous flush. */
- ret = btrfs_run_delayed_items(trans);
-- if (ret)
-+ if (ret) {
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- goto cleanup_transaction;
-+ }
-
- btrfs_wait_delalloc_flush(fs_info);
-
-@@ -2284,6 +2300,14 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- add_pending_snapshot(trans);
- cur_trans->state = TRANS_STATE_COMMIT_DOING;
- spin_unlock(&fs_info->trans_lock);
-+
-+ /*
-+ * The thread has started/joined the transaction thus it holds the
-+ * lockdep map as a reader. It has to release it before acquiring the
-+ * lockdep map as a writer.
-+ */
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
-+ btrfs_might_wait_for_event(fs_info, btrfs_trans_num_writers);
- wait_event(cur_trans->writer_wait,
- atomic_read(&cur_trans->num_writers) == 1);
-
-@@ -2515,6 +2539,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- cleanup_transaction(trans, ret);
-
- return ret;
-+
-+lockdep_release:
-+ btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
-+ goto cleanup_transaction;
- }
-
- /*
---
-2.35.1
-
+++ /dev/null
-From 5898b5a0ae847ba581045a1ebfa11348731daa5d Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:54 -0700
-Subject: btrfs: add lockdep annotations for pending_ordered wait event
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 8b53779eaa98b55f4cccadd4d12b3233e9633140 ]
-
-In contrast to the num_writers and num_extwriters wait events, the
-condition for the pending ordered wait event is signaled in a different
-context from the wait event itself. The condition signaling occurs in
-btrfs_remove_ordered_extent() in fs/btrfs/ordered-data.c while the wait
-event is implemented in btrfs_commit_transaction() in
-fs/btrfs/transaction.c
-
-Thus the thread signaling the condition has to acquire the lockdep map
-as a reader at the start of btrfs_remove_ordered_extent() and release it
-after it has signaled the condition. In this case some dependencies
-might be left out due to the placement of the annotation, but it is
-better than no annotation at all.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 1 +
- fs/btrfs/disk-io.c | 1 +
- fs/btrfs/ordered-data.c | 3 +++
- fs/btrfs/transaction.c | 1 +
- 4 files changed, 6 insertions(+)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index f8172e269f03..8bd9a6d5ade6 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1099,6 +1099,7 @@ struct btrfs_fs_info {
- struct lockdep_map btrfs_trans_num_writers_map;
- struct lockdep_map btrfs_trans_num_extwriters_map;
- struct lockdep_map btrfs_state_change_map[4];
-+ struct lockdep_map btrfs_trans_pending_ordered_map;
-
- #ifdef CONFIG_BTRFS_FS_REF_VERIFY
- spinlock_t ref_verify_lock;
-diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
-index 68c6cb4e9283..393553fdfed6 100644
---- a/fs/btrfs/disk-io.c
-+++ b/fs/btrfs/disk-io.c
-@@ -2992,6 +2992,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
-
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers);
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters);
-+ btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered);
- btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start,
- BTRFS_LOCKDEP_TRANS_COMMIT_START);
- btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked,
-diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
-index 1952ac85222c..2a4cb6db42d1 100644
---- a/fs/btrfs/ordered-data.c
-+++ b/fs/btrfs/ordered-data.c
-@@ -525,6 +525,7 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode,
- struct rb_node *node;
- bool pending;
-
-+ btrfs_lockdep_acquire(fs_info, btrfs_trans_pending_ordered);
- /* This is paired with btrfs_add_ordered_extent. */
- spin_lock(&btrfs_inode->lock);
- btrfs_mod_outstanding_extents(btrfs_inode, -1);
-@@ -580,6 +581,8 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode,
- }
- }
-
-+ btrfs_lockdep_release(fs_info, btrfs_trans_pending_ordered);
-+
- spin_lock(&root->ordered_extent_lock);
- list_del_init(&entry->root_extent_list);
- root->nr_ordered_extents--;
-diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
-index d3576f84020d..6e3b2cb6a04a 100644
---- a/fs/btrfs/transaction.c
-+++ b/fs/btrfs/transaction.c
-@@ -2310,6 +2310,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- * transaction. Otherwise if this transaction commits before the ordered
- * extents complete we lose logged data after a power failure.
- */
-+ btrfs_might_wait_for_event(fs_info, btrfs_trans_pending_ordered);
- wait_event(cur_trans->pending_wait,
- atomic_read(&cur_trans->pending_ordered) == 0);
-
---
-2.35.1
-
+++ /dev/null
-From dbaab36298dc01beea6a2d8ffe12e7d7180f2b30 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:59 -0700
-Subject: btrfs: add lockdep annotations for the ordered extents wait event
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 5f4403e10f9b75b081bcc763b98d73e29de8c248 ]
-
-This wait event is very similar to the pending ordered wait event in the
-sense that it occurs in a different context than the condition signaling
-for the event. The signaling occurs in btrfs_remove_ordered_extent()
-while the wait event is implemented in btrfs_start_ordered_extent() in
-fs/btrfs/ordered-data.c
-
-However, in this case a thread must not acquire the lockdep map for the
-ordered extents wait event when the ordered extent is related to a free
-space inode. That is because lockdep creates dependencies between locks
-acquired both in execution paths related to normal inodes and paths
-related to free space inodes, thus leading to false positives.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 1 +
- fs/btrfs/disk-io.c | 1 +
- fs/btrfs/inode.c | 13 +++++++++++++
- fs/btrfs/ordered-data.c | 18 ++++++++++++++++++
- 4 files changed, 33 insertions(+)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index 8bd9a6d5ade6..804962f97452 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1100,6 +1100,7 @@ struct btrfs_fs_info {
- struct lockdep_map btrfs_trans_num_extwriters_map;
- struct lockdep_map btrfs_state_change_map[4];
- struct lockdep_map btrfs_trans_pending_ordered_map;
-+ struct lockdep_map btrfs_ordered_extent_map;
-
- #ifdef CONFIG_BTRFS_FS_REF_VERIFY
- spinlock_t ref_verify_lock;
-diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
-index 393553fdfed6..e0e1730e67d7 100644
---- a/fs/btrfs/disk-io.c
-+++ b/fs/btrfs/disk-io.c
-@@ -2993,6 +2993,7 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers);
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters);
- btrfs_lockdep_init_map(fs_info, btrfs_trans_pending_ordered);
-+ btrfs_lockdep_init_map(fs_info, btrfs_ordered_extent);
- btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start,
- BTRFS_LOCKDEP_TRANS_COMMIT_START);
- btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked,
-diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
-index 1372210869b1..b06955727055 100644
---- a/fs/btrfs/inode.c
-+++ b/fs/btrfs/inode.c
-@@ -3225,6 +3225,8 @@ int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent)
- clear_bits |= EXTENT_DELALLOC_NEW;
-
- freespace_inode = btrfs_is_free_space_inode(inode);
-+ if (!freespace_inode)
-+ btrfs_lockdep_acquire(fs_info, btrfs_ordered_extent);
-
- if (test_bit(BTRFS_ORDERED_IOERR, &ordered_extent->flags)) {
- ret = -EIO;
-@@ -8959,6 +8961,7 @@ void btrfs_destroy_inode(struct inode *vfs_inode)
- struct btrfs_ordered_extent *ordered;
- struct btrfs_inode *inode = BTRFS_I(vfs_inode);
- struct btrfs_root *root = inode->root;
-+ bool freespace_inode;
-
- WARN_ON(!hlist_empty(&vfs_inode->i_dentry));
- WARN_ON(vfs_inode->i_data.nrpages);
-@@ -8980,6 +8983,12 @@ void btrfs_destroy_inode(struct inode *vfs_inode)
- if (!root)
- return;
-
-+ /*
-+ * If this is a free space inode do not take the ordered extents lockdep
-+ * map.
-+ */
-+ freespace_inode = btrfs_is_free_space_inode(inode);
-+
- while (1) {
- ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1);
- if (!ordered)
-@@ -8988,6 +8997,10 @@ void btrfs_destroy_inode(struct inode *vfs_inode)
- btrfs_err(root->fs_info,
- "found ordered extent %llu %llu on inode cleanup",
- ordered->file_offset, ordered->num_bytes);
-+
-+ if (!freespace_inode)
-+ btrfs_lockdep_acquire(root->fs_info, btrfs_ordered_extent);
-+
- btrfs_remove_ordered_extent(inode, ordered);
- btrfs_put_ordered_extent(ordered);
- btrfs_put_ordered_extent(ordered);
-diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
-index 2a4cb6db42d1..eb24a6d20ff8 100644
---- a/fs/btrfs/ordered-data.c
-+++ b/fs/btrfs/ordered-data.c
-@@ -524,6 +524,13 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode,
- struct btrfs_fs_info *fs_info = root->fs_info;
- struct rb_node *node;
- bool pending;
-+ bool freespace_inode;
-+
-+ /*
-+ * If this is a free space inode the thread has not acquired the ordered
-+ * extents lockdep map.
-+ */
-+ freespace_inode = btrfs_is_free_space_inode(btrfs_inode);
-
- btrfs_lockdep_acquire(fs_info, btrfs_trans_pending_ordered);
- /* This is paired with btrfs_add_ordered_extent. */
-@@ -597,6 +604,8 @@ void btrfs_remove_ordered_extent(struct btrfs_inode *btrfs_inode,
- }
- spin_unlock(&root->ordered_extent_lock);
- wake_up(&entry->wait);
-+ if (!freespace_inode)
-+ btrfs_lockdep_release(fs_info, btrfs_ordered_extent);
- }
-
- static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
-@@ -715,9 +724,16 @@ void btrfs_start_ordered_extent(struct btrfs_ordered_extent *entry, int wait)
- u64 start = entry->file_offset;
- u64 end = start + entry->num_bytes - 1;
- struct btrfs_inode *inode = BTRFS_I(entry->inode);
-+ bool freespace_inode;
-
- trace_btrfs_ordered_extent_start(inode, entry);
-
-+ /*
-+ * If this is a free space inode do not take the ordered extents lockdep
-+ * map.
-+ */
-+ freespace_inode = btrfs_is_free_space_inode(inode);
-+
- /*
- * pages in the range can be dirty, clean or writeback. We
- * start IO on any dirty ones so the wait doesn't stall waiting
-@@ -726,6 +742,8 @@ void btrfs_start_ordered_extent(struct btrfs_ordered_extent *entry, int wait)
- if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags))
- filemap_fdatawrite_range(inode->vfs_inode.i_mapping, start, end);
- if (wait) {
-+ if (!freespace_inode)
-+ btrfs_might_wait_for_event(inode->root->fs_info, btrfs_ordered_extent);
- wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE,
- &entry->flags));
- }
---
-2.35.1
-
+++ /dev/null
-From 3c196fc7745196ba3f6358ce334e0512366c86f6 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:52 -0700
-Subject: btrfs: add lockdep annotations for transaction states wait events
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 3e738c531aad8caa7f3d20ab878a8a0d3574e730 ]
-
-Add lockdep annotations for the transaction states that have wait
-events;
-
- 1) TRANS_STATE_COMMIT_START
- 2) TRANS_STATE_UNBLOCKED
- 3) TRANS_STATE_SUPER_COMMITTED
- 4) TRANS_STATE_COMPLETED
-
-The new macros introduced here to annotate the transaction states wait
-events have the same effect as the generic lockdep annotation macros.
-
-With the exception of the lockdep annotation for TRANS_STATE_COMMIT_START
-the transaction thread has to acquire the lockdep maps for the
-transaction states as reader after the lockdep map for num_writers is
-released so that lockdep does not complain.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 32 +++++++++++++++++++++++++
- fs/btrfs/disk-io.c | 8 +++++++
- fs/btrfs/transaction.c | 53 ++++++++++++++++++++++++++++++++++--------
- 3 files changed, 83 insertions(+), 10 deletions(-)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index e886cf639c0f..f8172e269f03 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1098,6 +1098,7 @@ struct btrfs_fs_info {
- */
- struct lockdep_map btrfs_trans_num_writers_map;
- struct lockdep_map btrfs_trans_num_extwriters_map;
-+ struct lockdep_map btrfs_state_change_map[4];
-
- #ifdef CONFIG_BTRFS_FS_REF_VERIFY
- spinlock_t ref_verify_lock;
-@@ -1181,6 +1182,13 @@ enum {
- BTRFS_ROOT_RESET_LOCKDEP_CLASS,
- };
-
-+enum btrfs_lockdep_trans_states {
-+ BTRFS_LOCKDEP_TRANS_COMMIT_START,
-+ BTRFS_LOCKDEP_TRANS_UNBLOCKED,
-+ BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED,
-+ BTRFS_LOCKDEP_TRANS_COMPLETED,
-+};
-+
- /*
- * Lockdep annotation for wait events.
- *
-@@ -1219,6 +1227,22 @@ enum {
- #define btrfs_lockdep_release(owner, lock) \
- rwsem_release(&owner->lock##_map, _THIS_IP_)
-
-+/*
-+ * Macros for the transaction states wait events, similar to the generic wait
-+ * event macros.
-+ */
-+#define btrfs_might_wait_for_state(owner, i) \
-+ do { \
-+ rwsem_acquire(&owner->btrfs_state_change_map[i], 0, 0, _THIS_IP_); \
-+ rwsem_release(&owner->btrfs_state_change_map[i], _THIS_IP_); \
-+ } while (0)
-+
-+#define btrfs_trans_state_lockdep_acquire(owner, i) \
-+ rwsem_acquire_read(&owner->btrfs_state_change_map[i], 0, 0, _THIS_IP_)
-+
-+#define btrfs_trans_state_lockdep_release(owner, i) \
-+ rwsem_release(&owner->btrfs_state_change_map[i], _THIS_IP_)
-+
- /* Initialization of the lockdep map */
- #define btrfs_lockdep_init_map(owner, lock) \
- do { \
-@@ -1226,6 +1250,14 @@ enum {
- lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \
- } while (0)
-
-+/* Initialization of the transaction states lockdep maps. */
-+#define btrfs_state_lockdep_init_map(owner, lock, state) \
-+ do { \
-+ static struct lock_class_key lock##_key; \
-+ lockdep_init_map(&owner->btrfs_state_change_map[state], #lock, \
-+ &lock##_key, 0); \
-+ } while (0)
-+
- static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
- {
- clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
-diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
-index 811d743e26e6..68c6cb4e9283 100644
---- a/fs/btrfs/disk-io.c
-+++ b/fs/btrfs/disk-io.c
-@@ -2992,6 +2992,14 @@ void btrfs_init_fs_info(struct btrfs_fs_info *fs_info)
-
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_writers);
- btrfs_lockdep_init_map(fs_info, btrfs_trans_num_extwriters);
-+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_commit_start,
-+ BTRFS_LOCKDEP_TRANS_COMMIT_START);
-+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_unblocked,
-+ BTRFS_LOCKDEP_TRANS_UNBLOCKED);
-+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_super_committed,
-+ BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
-+ btrfs_state_lockdep_init_map(fs_info, btrfs_trans_completed,
-+ BTRFS_LOCKDEP_TRANS_COMPLETED);
-
- INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
- INIT_LIST_HEAD(&fs_info->space_info);
-diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
-index 44e47db4c8e8..d3576f84020d 100644
---- a/fs/btrfs/transaction.c
-+++ b/fs/btrfs/transaction.c
-@@ -550,6 +550,7 @@ static void wait_current_trans(struct btrfs_fs_info *fs_info)
- refcount_inc(&cur_trans->use_count);
- spin_unlock(&fs_info->trans_lock);
-
-+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED);
- wait_event(fs_info->transaction_wait,
- cur_trans->state >= TRANS_STATE_UNBLOCKED ||
- TRANS_ABORTED(cur_trans));
-@@ -868,6 +869,15 @@ static noinline void wait_for_commit(struct btrfs_transaction *commit,
- u64 transid = commit->transid;
- bool put = false;
-
-+ /*
-+ * At the moment this function is called with min_state either being
-+ * TRANS_STATE_COMPLETED or TRANS_STATE_SUPER_COMMITTED.
-+ */
-+ if (min_state == TRANS_STATE_COMPLETED)
-+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED);
-+ else
-+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
-+
- while (1) {
- wait_event(commit->commit_wait, commit->state >= min_state);
- if (put)
-@@ -1980,6 +1990,7 @@ void btrfs_commit_transaction_async(struct btrfs_trans_handle *trans)
- * Wait for the current transaction commit to start and block
- * subsequent transaction joins
- */
-+ btrfs_might_wait_for_state(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START);
- wait_event(fs_info->transaction_blocked_wait,
- cur_trans->state >= TRANS_STATE_COMMIT_START ||
- TRANS_ABORTED(cur_trans));
-@@ -2137,12 +2148,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- ktime_t interval;
-
- ASSERT(refcount_read(&trans->use_count) == 1);
-+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START);
-
- /* Stop the commit early if ->aborted is set */
- if (TRANS_ABORTED(cur_trans)) {
- ret = cur_trans->aborted;
-- btrfs_end_transaction(trans);
-- return ret;
-+ goto lockdep_trans_commit_start_release;
- }
-
- btrfs_trans_release_metadata(trans);
-@@ -2159,10 +2170,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- * Any running threads may add more while we are here.
- */
- ret = btrfs_run_delayed_refs(trans, 0);
-- if (ret) {
-- btrfs_end_transaction(trans);
-- return ret;
-- }
-+ if (ret)
-+ goto lockdep_trans_commit_start_release;
- }
-
- btrfs_create_pending_block_groups(trans);
-@@ -2191,10 +2200,8 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- if (run_it) {
- ret = btrfs_start_dirty_block_groups(trans);
-- if (ret) {
-- btrfs_end_transaction(trans);
-- return ret;
-- }
-+ if (ret)
-+ goto lockdep_trans_commit_start_release;
- }
- }
-
-@@ -2209,6 +2216,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- if (trans->in_fsync)
- want_state = TRANS_STATE_SUPER_COMMITTED;
-+
-+ btrfs_trans_state_lockdep_release(fs_info,
-+ BTRFS_LOCKDEP_TRANS_COMMIT_START);
- ret = btrfs_end_transaction(trans);
- wait_for_commit(cur_trans, want_state);
-
-@@ -2222,6 +2232,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- cur_trans->state = TRANS_STATE_COMMIT_START;
- wake_up(&fs_info->transaction_blocked_wait);
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START);
-
- if (cur_trans->list.prev != &fs_info->trans_list) {
- enum btrfs_trans_state want_state = TRANS_STATE_COMPLETED;
-@@ -2323,6 +2334,16 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- wait_event(cur_trans->writer_wait,
- atomic_read(&cur_trans->num_writers) == 1);
-
-+ /*
-+ * Make lockdep happy by acquiring the state locks after
-+ * btrfs_trans_num_writers is released. If we acquired the state locks
-+ * before releasing the btrfs_trans_num_writers lock then lockdep would
-+ * complain because we did not follow the reverse order unlocking rule.
-+ */
-+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED);
-+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
-+ btrfs_trans_state_lockdep_acquire(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED);
-+
- /*
- * We've started the commit, clear the flag in case we were triggered to
- * do an async commit but somebody else started before the transaction
-@@ -2332,6 +2353,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- if (TRANS_ABORTED(cur_trans)) {
- ret = cur_trans->aborted;
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED);
- goto scrub_continue;
- }
- /*
-@@ -2466,6 +2488,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- mutex_unlock(&fs_info->reloc_mutex);
-
- wake_up(&fs_info->transaction_wait);
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED);
-
- ret = btrfs_write_and_wait_transaction(trans);
- if (ret) {
-@@ -2497,6 +2520,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- */
- cur_trans->state = TRANS_STATE_SUPER_COMMITTED;
- wake_up(&cur_trans->commit_wait);
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
-
- btrfs_finish_extent_commit(trans);
-
-@@ -2510,6 +2534,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- */
- cur_trans->state = TRANS_STATE_COMPLETED;
- wake_up(&cur_trans->commit_wait);
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED);
-
- spin_lock(&fs_info->trans_lock);
- list_del_init(&cur_trans->list);
-@@ -2538,7 +2563,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
-
- unlock_reloc:
- mutex_unlock(&fs_info->reloc_mutex);
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_UNBLOCKED);
- scrub_continue:
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_SUPER_COMMITTED);
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMPLETED);
- btrfs_scrub_continue(fs_info);
- cleanup_transaction:
- btrfs_trans_release_metadata(trans);
-@@ -2556,6 +2584,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
- btrfs_lockdep_release(fs_info, btrfs_trans_num_extwriters);
- btrfs_lockdep_release(fs_info, btrfs_trans_num_writers);
- goto cleanup_transaction;
-+
-+lockdep_trans_commit_start_release:
-+ btrfs_trans_state_lockdep_release(fs_info, BTRFS_LOCKDEP_TRANS_COMMIT_START);
-+ btrfs_end_transaction(trans);
-+ return ret;
- }
-
- /*
---
-2.35.1
-
+++ /dev/null
-From 9b390e7dfd1a0faeff4012513dc4864e9df58bab Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:46 -0700
-Subject: btrfs: add macros for annotating wait events with lockdep
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit ab9a323f9ab576000795285dd7ac6afeedf29e32 ]
-
-Introduce four macros that are used to annotate wait events in btrfs code
-with lockdep;
-
- 1) the btrfs_lockdep_init_map
- 2) the btrfs_lockdep_acquire,
- 3) the btrfs_lockdep_release
- 4) the btrfs_might_wait_for_event macros.
-
-The btrfs_lockdep_init_map macro is used to initialize a lockdep map.
-
-The btrfs_lockdep_<acquire,release> macros are used by threads to take
-the lockdep map as readers (shared lock) and release it, respectively.
-
-The btrfs_might_wait_for_event macro is used by threads to take the
-lockdep map as writers (exclusive lock) and release it.
-
-In general, the lockdep annotation for wait events work as follows:
-
-The condition for a wait event can be modified and signaled at the same
-time by multiple threads. These threads hold the lockdep map as readers
-when they enter a context in which blocking would prevent signaling the
-condition. Frequently, this occurs when a thread violates a condition
-(lockdep map acquire), before restoring it and signaling it at a later
-point (lockdep map release).
-
-The threads that block on the wait event take the lockdep map as writers
-(exclusive lock). These threads have to block until all the threads that
-hold the lockdep map as readers signal the condition for the wait event
-and release the lockdep map.
-
-The lockdep annotation is used to warn about potential deadlock scenarios
-that involve the threads that modify and signal the wait event condition
-and threads that block on the wait event. A simple example is illustrated
-below:
-
-Without lockdep:
-
-TA TB
-cond = false
- lock(A)
- wait_event(w, cond)
- unlock(A)
-lock(A)
-cond = true
-signal(w)
-unlock(A)
-
-With lockdep:
-
-TA TB
-rwsem_acquire_read(lockdep_map)
-cond = false
- lock(A)
- rwsem_acquire(lockdep_map)
- rwsem_release(lockdep_map)
- wait_event(w, cond)
- unlock(A)
-lock(A)
-cond = true
-signal(w)
-unlock(A)
-rwsem_release(lockdep_map)
-
-In the second case, with the lockdep annotation, lockdep would warn about
-an ABBA deadlock, while the first case would just deadlock at some point.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Reviewed-by: David Sterba <dsterba@suse.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/ctree.h | 45 +++++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 45 insertions(+)
-
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index df8c99c99df9..dfeb7174219e 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1174,6 +1174,51 @@ enum {
- BTRFS_ROOT_RESET_LOCKDEP_CLASS,
- };
-
-+/*
-+ * Lockdep annotation for wait events.
-+ *
-+ * @owner: The struct where the lockdep map is defined
-+ * @lock: The lockdep map corresponding to a wait event
-+ *
-+ * This macro is used to annotate a wait event. In this case a thread acquires
-+ * the lockdep map as writer (exclusive lock) because it has to block until all
-+ * the threads that hold the lock as readers signal the condition for the wait
-+ * event and release their locks.
-+ */
-+#define btrfs_might_wait_for_event(owner, lock) \
-+ do { \
-+ rwsem_acquire(&owner->lock##_map, 0, 0, _THIS_IP_); \
-+ rwsem_release(&owner->lock##_map, _THIS_IP_); \
-+ } while (0)
-+
-+/*
-+ * Protection for the resource/condition of a wait event.
-+ *
-+ * @owner: The struct where the lockdep map is defined
-+ * @lock: The lockdep map corresponding to a wait event
-+ *
-+ * Many threads can modify the condition for the wait event at the same time
-+ * and signal the threads that block on the wait event. The threads that modify
-+ * the condition and do the signaling acquire the lock as readers (shared
-+ * lock).
-+ */
-+#define btrfs_lockdep_acquire(owner, lock) \
-+ rwsem_acquire_read(&owner->lock##_map, 0, 0, _THIS_IP_)
-+
-+/*
-+ * Used after signaling the condition for a wait event to release the lockdep
-+ * map held by a reader thread.
-+ */
-+#define btrfs_lockdep_release(owner, lock) \
-+ rwsem_release(&owner->lock##_map, _THIS_IP_)
-+
-+/* Initialization of the lockdep map */
-+#define btrfs_lockdep_init_map(owner, lock) \
-+ do { \
-+ static struct lock_class_key lock##_key; \
-+ lockdep_init_map(&owner->lock##_map, #lock, &lock##_key, 0); \
-+ } while (0)
-+
- static inline void btrfs_wake_unfinished_drop(struct btrfs_fs_info *fs_info)
- {
- clear_and_wake_up_bit(BTRFS_FS_UNFINISHED_DROPS, &fs_info->flags);
---
-2.35.1
-
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
- fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++--------------
+ fs/btrfs/free-space-cache.c | 53 +++++++++++++++++++++++++++-----------------
1 file changed, 33 insertions(+), 20 deletions(-)
-diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
-index 835071fa39a9..2f88053cfc5e 100644
--- a/fs/btrfs/free-space-cache.c
+++ b/fs/btrfs/free-space-cache.c
-@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl,
+@@ -48,6 +48,25 @@ static void bitmap_clear_bits(struct btr
struct btrfs_free_space *info, u64 offset,
u64 bytes, bool update_stats);
static struct inode *__lookup_free_space_inode(struct btrfs_root *root,
struct btrfs_path *path,
u64 offset)
-@@ -881,7 +900,14 @@ static int __load_free_space_cache(struct btrfs_root *root, struct inode *inode,
+@@ -881,7 +900,14 @@ out:
return ret;
free_cache:
io_ctl_drop_pages(&io_ctl);
goto out;
}
-@@ -1017,7 +1043,13 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
+@@ -1007,7 +1033,13 @@ int load_free_space_cache(struct btrfs_b
if (ret == 0)
ret = 1;
} else {
btrfs_warn(fs_info,
"block group %llu has wrong amount of free space",
block_group->start);
-@@ -2980,25 +3012,6 @@ static void __btrfs_return_cluster_to_free_space(
+@@ -2970,25 +3002,6 @@ static void __btrfs_return_cluster_to_fr
btrfs_put_block_group(block_group);
}
void __btrfs_remove_free_space_cache(struct btrfs_free_space_ctl *ctl)
{
spin_lock(&ctl->tree_lock);
---
-2.35.1
-
+++ /dev/null
-From a029bfa12be1da1c419fa9f774fbb645899d2832 Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Mon, 25 Jul 2022 15:11:57 -0700
-Subject: btrfs: change the lockdep class of free space inode's invalidate_lock
-
-From: Ioannis Angelakopoulos <iangelak@fb.com>
-
-[ Upstream commit 9d7464c87b159bbf763c24faeb7a2dcaac96e4a1 ]
-
-Reinitialize the class of the lockdep map for struct inode's
-mapping->invalidate_lock in load_free_space_cache() function in
-fs/btrfs/free-space-cache.c. This will prevent lockdep from producing
-false positives related to execution paths that make use of free space
-inodes and paths that make use of normal inodes.
-
-Specifically, with this change lockdep will create separate lock
-dependencies that include the invalidate_lock, in the case that free
-space inodes are used and in the case that normal inodes are used.
-
-The lockdep class for this lock was first initialized in
-inode_init_always() in fs/inode.c.
-
-Reviewed-by: Josef Bacik <josef@toxicpanda.com>
-Signed-off-by: Ioannis Angelakopoulos <iangelak@fb.com>
-Signed-off-by: David Sterba <dsterba@suse.com>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/btrfs/free-space-cache.c | 10 ++++++++++
- 1 file changed, 10 insertions(+)
-
-diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c
-index 85404c62a1c2..835071fa39a9 100644
---- a/fs/btrfs/free-space-cache.c
-+++ b/fs/btrfs/free-space-cache.c
-@@ -920,6 +920,8 @@ static int copy_free_space_cache(struct btrfs_block_group *block_group,
- return ret;
- }
-
-+static struct lock_class_key btrfs_free_space_inode_key;
-+
- int load_free_space_cache(struct btrfs_block_group *block_group)
- {
- struct btrfs_fs_info *fs_info = block_group->fs_info;
-@@ -989,6 +991,14 @@ int load_free_space_cache(struct btrfs_block_group *block_group)
- }
- spin_unlock(&block_group->lock);
-
-+ /*
-+ * Reinitialize the class of struct inode's mapping->invalidate_lock for
-+ * free space inodes to prevent false positives related to locks for normal
-+ * inodes.
-+ */
-+ lockdep_set_class(&(&inode->i_data)->invalidate_lock,
-+ &btrfs_free_space_inode_key);
-+
- ret = __load_free_space_cache(fs_info->tree_root, inode, &tmp_ctl,
- path, block_group->start);
- btrfs_free_path(path);
---
-2.35.1
-
arm64-dts-imx8mq-librem5-add-bq25895-as-max17055-s-p.patch
arm-orion-fix-include-path.patch
btrfs-dump-extra-info-if-one-free-space-cache-has-mo.patch
-btrfs-add-macros-for-annotating-wait-events-with-loc.patch
-btrfs-add-lockdep-annotations-for-num_writers-wait-e.patch
-btrfs-add-lockdep-annotations-for-num_extwriters-wai.patch
-btrfs-add-lockdep-annotations-for-transaction-states.patch
-btrfs-add-lockdep-annotations-for-pending_ordered-wa.patch
-btrfs-change-the-lockdep-class-of-free-space-inode-s.patch
-btrfs-add-lockdep-annotations-for-the-ordered-extent.patch
btrfs-scrub-properly-report-super-block-errors-in-sy.patch
btrfs-scrub-try-to-fix-super-block-errors.patch
btrfs-don-t-print-information-about-space-cache-or-t.patch