If the main process of `erofsmount_nbd()` encounters an error after the
nbd device has been successfully set up, it fails to disconnect it
before exiting, resulting in the subprocess not being cleaned up and
keeping its connection with NBD device.

This patch resolves the issue by disconnecting NBD device before exiting
on error.

Signed-off-by: Yifan Zhao <[email protected]>
---
Note:
- I believe directly killing the child process is unsafe, as it may leave
in-flight NBD requests from the kernel unhandled, causing soft lockup.
- And I believe using nbdpath here is safe, as the child process maintains
the NBD device connection throughout, preventing concurrent access by other
actors.

 mount/main.c | 17 +++++++++++++++--
 1 file changed, 15 insertions(+), 2 deletions(-)

diff --git a/mount/main.c b/mount/main.c
index 2a21979..d2d4815 100644
--- a/mount/main.c
+++ b/mount/main.c
@@ -1287,10 +1287,23 @@ static int erofsmount_nbd(struct erofs_nbd_source 
*source,
 
        if (!err) {
                err = mount(nbdpath, mountpoint, fstype, flags, options);
-               if (err < 0)
+               if (err < 0) {
                        err = -errno;
+                       if (msg.is_netlink) {
+                               erofs_nbd_nl_disconnect(msg.nbdnum);
+                       } else {
+                               int nbdfd;
+
+                               nbdfd = open(nbdpath, O_RDWR);
+                               if (nbdfd > 0) {
+                                       erofs_nbd_disconnect(nbdfd);
+                                       close(nbdfd);
+                               }
+                       }
+                       return err;
+               }
 
-               if (!err && msg.is_netlink) {
+               if (msg.is_netlink) {
                        id = erofs_nbd_get_identifier(msg.nbdnum);
 
                        err = IS_ERR(id) ? PTR_ERR(id) :
-- 
2.43.0


Reply via email to