[PATCH] erofs-utils: mount: enable autoclear for NBD devices
Gao Xiang
hsiangkao at linux.alibaba.com
Wed Sep 3 18:23:41 AEST 2025
Enable NBD_CFLAG_DISCONNECT_ON_CLOSE to allow `umount(2)` to unmount
the filesystem and disconnect NBD devices in a single operation.
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
lib/backends/nbd.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
lib/liberofs_nbd.h | 2 ++
mount/main.c | 16 +++++++++++++++-
3 files changed, 63 insertions(+), 1 deletion(-)
diff --git a/lib/backends/nbd.c b/lib/backends/nbd.c
index 682fc7b..b9535dc 100644
--- a/lib/backends/nbd.c
+++ b/lib/backends/nbd.c
@@ -466,6 +466,46 @@ err_out:
close(sv[1]);
return err;
}
+
+int erofs_nbd_nl_reconfigure(int index, const char *identifier,
+ bool autoclear)
+{
+ struct nl_sock *socket;
+ struct nl_msg *msg;
+ int err, driver_id;
+ unsigned int cflags;
+
+ socket = erofs_nbd_get_nl_sock(&driver_id);
+ if (IS_ERR(socket))
+ return PTR_ERR(socket);
+
+ msg = nlmsg_alloc();
+ if (!msg) {
+ erofs_err("Couldn't allocate netlink message");
+ err = -ENOMEM;
+ goto err_nls_free;
+ }
+
+ err = -EINVAL;
+ genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, driver_id, 0, 0,
+ NBD_CMD_RECONFIGURE, 0);
+ NLA_PUT_U32(msg, NBD_ATTR_INDEX, index);
+ if (identifier)
+ NLA_PUT_STRING(msg, NBD_ATTR_BACKEND_IDENTIFIER, identifier);
+
+ cflags = (autoclear ? NBD_CFLAG_DISCONNECT_ON_CLOSE : 0);
+ NLA_PUT_U64(msg, NBD_ATTR_CLIENT_FLAGS, cflags);
+
+ err = nl_send_sync(socket, msg);
+ nl_socket_free(socket);
+ return err;
+
+nla_put_failure:
+ nlmsg_free(msg);
+err_nls_free:
+ nl_socket_free(socket);
+ return err;
+}
#else
int erofs_nbd_nl_connect(int *index, int blkbits, u64 blocks,
const char *identifier)
@@ -477,6 +517,12 @@ int erofs_nbd_nl_reconnect(int index, const char *identifier)
{
return -EOPNOTSUPP;
}
+
+int erofs_nbd_nl_reconfigure(int index, const char *identifier,
+ bool autoclear)
+{
+ return -EOPNOTSUPP;
+}
#endif
int erofs_nbd_do_it(int nbdfd)
diff --git a/lib/liberofs_nbd.h b/lib/liberofs_nbd.h
index 049c318..260605a 100644
--- a/lib/liberofs_nbd.h
+++ b/lib/liberofs_nbd.h
@@ -47,4 +47,6 @@ int erofs_nbd_disconnect(int nbdfd);
int erofs_nbd_nl_connect(int *index, int blkbits, u64 blocks,
const char *identifier);
int erofs_nbd_nl_reconnect(int index, const char *identifier);
+int erofs_nbd_nl_reconfigure(int index, const char *identifier,
+ bool autoclear);
#endif
diff --git a/mount/main.c b/mount/main.c
index 139b532..a270f0a 100644
--- a/mount/main.c
+++ b/mount/main.c
@@ -544,7 +544,8 @@ static int erofsmount_nbd(const char *source, const char *mountpoint,
const char *fstype, int flags,
const char *options)
{
- char nbdpath[32];
+ bool is_netlink = false;
+ char nbdpath[32], *id;
int num, nbdfd;
pid_t pid = 0;
long err;
@@ -575,6 +576,7 @@ static int erofsmount_nbd(const char *source, const char *mountpoint,
} else {
num = err;
(void)snprintf(nbdpath, sizeof(nbdpath), "/dev/nbd%d", num);
+ is_netlink = true;
}
while (1) {
@@ -591,6 +593,18 @@ static int erofsmount_nbd(const char *source, const char *mountpoint,
err = mount(nbdpath, mountpoint, fstype, flags, options);
if (err < 0)
err = -errno;
+
+ if (!err && is_netlink) {
+ id = erofs_nbd_get_identifier(num);
+ if (id == ERR_PTR(-ENOENT))
+ id = NULL;
+
+ err = IS_ERR(id) ? PTR_ERR(id) :
+ erofs_nbd_nl_reconfigure(num, id, true);
+ if (err)
+ erofs_warn("failed to turn on autoclear for nbd%d: %s",
+ num, erofs_strerror(err));
+ }
}
return err;
}
--
2.43.5
More information about the Linux-erofs
mailing list