Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

nbd: correct disconnect behavior

Currently, when a disconnect is requested by the user (via NBD_DISCONNECT
ioctl) the return from NBD_DO_IT is undefined (it is usually one of
several error codes). This means that nbd-client does not know if a
manual disconnect was performed or whether a network error occurred.
Because of this, nbd-client's persist mode (which tries to reconnect after
error, but not after manual disconnect) does not always work correctly.

This change fixes this by causing NBD_DO_IT to always return 0 if a user
requests a disconnect. This means that nbd-client can correctly either
persist the connection (if an error occurred) or disconnect (if the user
requested it).

Signed-off-by: Paul Clements <paul.clements@steeleye.com>
Acked-by: Rob Landley <rob@landley.net>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Paul Clements and committed by
Linus Torvalds
c378f70a 9532f149

+7 -1
+6 -1
drivers/block/nbd.c
··· 623 623 if (!nbd->sock) 624 624 return -EINVAL; 625 625 626 + nbd->disconnect = 1; 627 + 626 628 nbd_send_req(nbd, &sreq); 627 - return 0; 629 + return 0; 628 630 } 629 631 630 632 case NBD_CLEAR_SOCK: { ··· 656 654 nbd->sock = SOCKET_I(inode); 657 655 if (max_part > 0) 658 656 bdev->bd_invalidated = 1; 657 + nbd->disconnect = 0; /* we're connected now */ 659 658 return 0; 660 659 } else { 661 660 fput(file); ··· 746 743 set_capacity(nbd->disk, 0); 747 744 if (max_part > 0) 748 745 ioctl_by_bdev(bdev, BLKRRPART, 0); 746 + if (nbd->disconnect) /* user requested, ignore socket errors */ 747 + return 0; 749 748 return nbd->harderror; 750 749 } 751 750
+1
include/linux/nbd.h
··· 41 41 u64 bytesize; 42 42 pid_t pid; /* pid of nbd-client, if attached */ 43 43 int xmit_timeout; 44 + int disconnect; /* a disconnect has been requested by user */ 44 45 }; 45 46 46 47 #endif