From cc7ac0f551d1d50b7532008afdeb3e5919a09a7e Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 23 Jul 2024 11:41:02 +0200 Subject: [PATCH 1/2] Close block devices in a synchronous manner fput() doesn't wait for all references on the disk to be unclaimed but instead it only schedules a worker that is supposed to cleanup resources once the device is released. During cache initialization we open device at least twice - to check its properties and then to actually use it as cache. But since we use the async fput() after the probe, the device might still be in use once we try to open it for the second time (the second open returns -EBUSY). Using synchronous __fput_sync() to close the device fixes the issue __fput_sync() exists in the kernel API longer than bdev_file_open_by_path() and the presence of the latter is the condition to use the synchronous put so it is perfectly safe to get rid of fput() from the configure framework Signed-off-by: Michal Mielewczyk --- configure.d/1_bdev_release.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.d/1_bdev_release.conf b/configure.d/1_bdev_release.conf index 1425ebf53..8a1a64348 100644 --- a/configure.d/1_bdev_release.conf +++ b/configure.d/1_bdev_release.conf @@ -41,7 +41,7 @@ apply() { bdev_release(handle)" ;; "4") add_define "cas_bdev_release(handle, mode, holder) \\ - fput(handle)" ;; + __fput_sync(handle)" ;; *) exit 1 esac From 0836101b85ccb7de471c0f94d0ce4abba8c9d12b Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 25 Jul 2024 14:26:43 +0200 Subject: [PATCH 2/2] configure: refactor bdev_{close|open}() API Signed-off-by: Michal Mielewczyk --- configure.d/1_bdev_open_by_path.conf | 40 +++++++++++++++++----- configure.d/1_bdev_release.conf | 50 ---------------------------- 2 files changed, 32 insertions(+), 58 deletions(-) delete mode 100644 configure.d/1_bdev_release.conf diff --git a/configure.d/1_bdev_open_by_path.conf b/configure.d/1_bdev_open_by_path.conf index 6c5dd6cac..4782fa06b 100644 --- a/configure.d/1_bdev_open_by_path.conf +++ b/configure.d/1_bdev_open_by_path.conf @@ -14,15 +14,18 @@ check() { if compile_module $cur_name "blkdev_get_by_path(NULL, 0, NULL);" "linux/blkdev.h" then echo $cur_name 1 >> $config_file_path - elif compile_module $cur_name "blkdev_get_by_path(NULL, 0, NULL, NULL);" "linux/blkdev.h" + elif compile_module $cur_name "blkdev_get_by_path(NULL, 0, NULL, NULL);blkdev_put(NULL, FMODE_READ);" "linux/blkdev.h" then echo $cur_name 2 >> $config_file_path - elif compile_module $cur_name "bdev_open_by_path(NULL, 0, NULL, NULL);" "linux/blkdev.h" + elif compile_module $cur_name "blkdev_get_by_path(NULL, 0, NULL, NULL);blkdev_put(NULL, NULL);" "linux/blkdev.h" then echo $cur_name 3 >> $config_file_path - elif compile_module $cur_name "bdev_file_open_by_path(NULL, 0, NULL, NULL);" "linux/blkdev.h" + elif compile_module $cur_name "bdev_open_by_path(NULL, 0, NULL, NULL);" "linux/blkdev.h" then echo $cur_name 4 >> $config_file_path + elif compile_module $cur_name "bdev_file_open_by_path(NULL, 0, NULL, NULL);" "linux/blkdev.h" + then + echo $cur_name 5 >> $config_file_path else echo $cur_name X >> $config_file_path fi @@ -31,29 +34,50 @@ check() { apply() { case "$1" in "1") + # Related kernel commit 0718afd47f70cf46877c39c25d06b786e1a3f36c add_typedef "struct block_device *cas_bdev_handle_t;" add_define "cas_bdev_open_by_path(path, mode, holder) \\ blkdev_get_by_path(path, mode, holder)" add_define "cas_bdev_get_from_handle(handle) \\ - ((struct block_device *)handle)" ;; + ((struct block_device *)handle)" + add_define "cas_bdev_release(handle, mode, holder) \\ + blkdev_put((struct block_device *)handle, mode)" ;; "2") + # Before kernel commit 2736e8eeb0ccdc71d1f4256c9c9a28f58cc43307 add_typedef "struct block_device *cas_bdev_handle_t;" add_define "cas_bdev_open_by_path(path, mode, holder) \\ blkdev_get_by_path(path, mode, holder, NULL)" add_define "cas_bdev_get_from_handle(handle) \\ - ((struct block_device *)handle)" ;; + ((struct block_device *)handle)" + add_define "cas_bdev_release(handle, mode, holder) \\ + blkdev_put((struct block_device *)handle, mode)" ;; "3") + # From kernel commit 2736e8eeb0ccdc71d1f4256c9c9a28f58cc43307 + add_typedef "struct block_device *cas_bdev_handle_t;" + add_define "cas_bdev_open_by_path(path, mode, holder) \\ + blkdev_get_by_path(path, mode, holder, NULL)" + add_define "cas_bdev_get_from_handle(handle) \\ + ((struct block_device *)handle)" + add_define "cas_bdev_release(handle, mode, holder) \\ + blkdev_put((struct block_device *)handle, holder)" ;; + "4") + # From kernel commit e719b4d156749f02eafed31a3c515f2aa9dcc72a add_typedef "struct bdev_handle *cas_bdev_handle_t;" add_define "cas_bdev_open_by_path(path, mode, holder) \\ bdev_open_by_path(path, mode, holder, NULL)" add_define "cas_bdev_get_from_handle(handle) \\ - (handle->bdev)" ;; - "4") + (handle->bdev)" + add_define "cas_bdev_release(handle, mode, holder) \\ + bdev_release(handle)" ;; + "5") + # From kernel commit e97d06a46526d9392cbdbd7eda193091e1af2723 add_typedef "struct file *cas_bdev_handle_t;" add_define "cas_bdev_open_by_path(path, mode, holder) \\ bdev_file_open_by_path(path, mode, holder, NULL)" add_define "cas_bdev_get_from_handle(handle) \\ - file_bdev(handle)" ;; + file_bdev(handle)" + add_define "cas_bdev_release(handle, mode, holder) \\ + __fput_sync(handle)" ;; *) exit 1 esac diff --git a/configure.d/1_bdev_release.conf b/configure.d/1_bdev_release.conf deleted file mode 100644 index 8a1a64348..000000000 --- a/configure.d/1_bdev_release.conf +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/bash -# -# Copyright(c) 2012-2022 Intel Corporation -# Copyright(c) 2024 Huawei Technologies -# SPDX-License-Identifier: BSD-3-Clause -# - -. $(dirname $3)/conf_framework.sh - - -check() { - cur_name=$(basename $2) - config_file_path=$1 - if compile_module $cur_name "blkdev_put(NULL, FMODE_READ);" "linux/blkdev.h" - then - echo $cur_name 1 >> $config_file_path - elif compile_module $cur_name "blkdev_put(NULL, NULL);" "linux/blkdev.h" - then - echo $cur_name 2 >> $config_file_path - elif compile_module $cur_name "bdev_release(NULL);" "linux/blkdev.h" - then - echo $cur_name 3 >> $config_file_path - elif compile_module $cur_name "bdev_file_open_by_path(NULL, 0, NULL, NULL);" "linux/blkdev.h" - then - echo $cur_name 4 >> $config_file_path - else - echo $cur_name X >> $config_file_path - fi -} - -apply() { - case "$1" in - "1") - add_define "cas_bdev_release(handle, mode, holder) \\ - blkdev_put((struct block_device *)handle, mode)" ;; - "2") - add_define "cas_bdev_release(handle, mode, holder) \\ - blkdev_put((struct block_device *)handle, holder)" ;; - "3") - add_define "cas_bdev_release(handle, mode, holder) \\ - bdev_release(handle)" ;; - "4") - add_define "cas_bdev_release(handle, mode, holder) \\ - __fput_sync(handle)" ;; - *) - exit 1 - esac -} - -conf_run $@