[PATCH v3 02/12] block/bdev: Annotate the blk_holder_ops callback invocations

Bart Van Assche
2026-04-02T18:40:13Z

The four callback functions in blk_holder_ops all release the
bd_holder_lock. Add __release() annotations where appropriate to prepare
for enabling thread-safety analysis. Explicit __release() annotations have
been added since Clang does not support adding a __releases() annotation
to a function pointer.

Signed-off-by: Bart Van Assche <bvanassche@acm.org>
---
block/bdev.c | 10 ++++++++--
block/ioctl.c | 6 ++++--
2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/block/bdev.c b/block/bdev.c
index ed022f8c48c7..bab8f23ec7ec 100644
--- a/block/bdev.c
+++ b/block/bdev.c
@@ -312,7 +312,9 @@ int bdev_freeze(struct block_device *bdev)
mutex_lock(&bdev->bd_holder_lock);
if (bdev->bd_holder_ops && bdev->bd_holder_ops->freeze) {
error = bdev->bd_holder_ops->freeze(bdev);
+ /* bdev->bd_holder_ops->freeze() releases bd_holder_lock */
lockdep_assert_not_held(&bdev->bd_holder_lock);
+ __release(&bdev->bd_holder_lock);
} else {
mutex_unlock(&bdev->bd_holder_lock);
error = sync_blockdev(bdev);
@@ -355,7 +357,9 @@ int bdev_thaw(struct block_device *bdev)
mutex_lock(&bdev->bd_holder_lock);
if (bdev->bd_holder_ops && bdev->bd_holder_ops->thaw) {
error = bdev->bd_holder_ops->thaw(bdev);
+ /* bdev->bd_holder_ops->thaw() releases bd_holder_lock */
lockdep_assert_not_held(&bdev->bd_holder_lock);
+ __release(&bdev->bd_holder_lock);
} else {
mutex_unlock(&bdev->bd_holder_lock);
}
@@ -1254,9 +1258,11 @@ EXPORT_SYMBOL(lookup_bdev);
void bdev_mark_dead(struct block_device *bdev, bool surprise)
{
mutex_lock(&bdev->bd_holder_lock);
- if (bdev->bd_holder_ops && bdev->bd_holder_ops->mark_dead)
+ if (bdev->bd_holder_ops && bdev->bd_holder_ops->mark_dead) {
bdev->bd_holder_ops->mark_dead(bdev, surprise);
- else {
+ /* bdev->bd_holder_ops->mark_dead() releases bd_holder_lock */
+ __release(&bdev->bd_holder_lock);
+ } else {
mutex_unlock(&bdev->bd_holder_lock);
sync_blockdev(bdev);
}
diff --git a/block/ioctl.c b/block/ioctl.c
index 0b04661ac809..57c69ef0f2cd 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -523,9 +523,11 @@ static int blkdev_flushbuf(struct block_device *bdev, unsigned cmd,
return -EACCES;

mutex_lock(&bdev->bd_holder_lock);
- if (bdev->bd_holder_ops && bdev->bd_holder_ops->sync)
+ if (bdev->bd_holder_ops && bdev->bd_holder_ops->sync) {
bdev->bd_holder_ops->sync(bdev);
- else {
+ /* bdev->bd_holder_ops->sync() releases bd_holder_lock */
+ __release(&bdev->bd_holder_lock);
+ } else {
mutex_unlock(&bdev->bd_holder_lock);
sync_blockdev(bdev);
}