[PATCH 05/13] block: add blockdevice_unregister_removed()
Sascha Hauer
s.hauer at pengutronix.de
Mon Aug 31 06:20:12 PDT 2026
Removing a block device whose medium is gone is not the same as removing
one that is merely no longer wanted. The medium is not coming back, so
the filesystems mounted from it have become useless, and keeping them
around only means the device cannot be removed at all: the open cdevs
make it busy.
Add a variant of blockdevice_unregister() for that case which unmounts
the filesystems on the device and on its partitions first. Removable
media are the ones that need it - a USB stick that has been unplugged, an
SD card that has been ejected - so this is not something the block layer
can decide on its own, the driver knows.
The error case is still reported so a caller that cannot get rid of the
device knows it must not free it.
Signed-off-by: Sascha Hauer <s.hauer at pengutronix.de>
Assisted-by: Claude:claude-opus-5
---
common/block.c | 26 ++++++++++++++++++++++++++
include/block.h | 1 +
2 files changed, 27 insertions(+)
diff --git a/common/block.c b/common/block.c
index 141604eb87..5441c7ca18 100644
--- a/common/block.c
+++ b/common/block.c
@@ -7,6 +7,7 @@
#include <common.h>
#include <block.h>
#include <disks.h>
+#include <fs.h>
#include <malloc.h>
#include <linux/err.h>
#include <linux/list.h>
@@ -546,6 +547,31 @@ int blockdevice_unregister(struct block_device *blk)
return 0;
}
+/**
+ * blockdevice_unregister_removed - remove a block device whose medium is gone
+ * @blk: the block device
+ *
+ * For media that can disappear while barebox is running: a USB stick that
+ * has been unplugged, an SD card that has been ejected. The filesystems
+ * mounted from the device or from one of its partitions cannot be used
+ * anymore, and would only keep the device from going away, so drop them.
+ *
+ * Use blockdevice_unregister() instead when the device is still there and
+ * the removal is not forced upon us. That one leaves the mounts alone and
+ * fails when the device is in use.
+ *
+ * Return: 0 when the device has been removed, a negative error code when
+ * something still holds it open. In the latter case the caller
+ * must not free the block device: the cdevs are still registered
+ * and refer to it.
+ */
+int blockdevice_unregister_removed(struct block_device *blk)
+{
+ cdev_umount_all(&blk->cdev);
+
+ return blockdevice_unregister(blk);
+}
+
int block_read(struct block_device *blk, void *buf, sector_t block, blkcnt_t num_blocks)
{
int ret;
diff --git a/include/block.h b/include/block.h
index 9a0102db15..065ae81358 100644
--- a/include/block.h
+++ b/include/block.h
@@ -97,6 +97,7 @@ extern struct list_head block_device_list;
int blockdevice_register(struct block_device *blk);
int blockdevice_unregister(struct block_device *blk);
+int blockdevice_unregister_removed(struct block_device *blk);
int block_read(struct block_device *blk, void *buf, sector_t block, blkcnt_t num_blocks);
int block_write(struct block_device *blk, void *buf, sector_t block, blkcnt_t num_blocks);
--
2.47.3
More information about the barebox
mailing list