lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1462954726-11825-19-git-send-email-pranjas@gmail.com>
Date:	Wed, 11 May 2016 11:18:46 +0300
From:	"Pranay Kr. Srivastava" <pranjas@...il.com>
To:	mpa@...gutronix.de, nbd-general@...ts.sourceforge.net,
	linux-kernel@...r.kernel.org, gregkh@...uxfoundation.org
Cc:	"Pranay Kr. Srivastava" <pranjas@...il.com>
Subject: [PATCH v4 18/18] make nbd device wait for its users in case of timeout

When a timeout occurs or a recv fails, then
instead of abruplty killing nbd block device
wait for it's users to finish.

This is more required when filesystem(s) like
ext2 or ext3 don't expect their buffer heads to
disappear while the filesystem is mounted.

The change is described below:
a) Add a users count to nbd_device structure.
b) Add a bit flag to nbd_device structure of unsigned long.

If the current user count is not 1 then make nbd-client wait
for the in_use bit to be cleared.

Signed-off-by: Pranay Kr. Srivastava <pranjas@...il.com>
---
 drivers/block/nbd.c      | 40 ++++++++++++++++++++++++++++++++++++++++
 include/uapi/linux/nbd.h |  1 +
 2 files changed, 41 insertions(+)

diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 482a3c0..9b024d8 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -59,6 +59,7 @@ struct nbd_device {
 	int xmit_timeout;
 	atomic_t timedout;
 	bool disconnect; /* a disconnect has been requested by user */
+	u32 users;
 
 	struct timer_list timeout_timer;
 	/* protects initialization and shutdown of the socket */
@@ -69,6 +70,7 @@ struct nbd_device {
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 	struct dentry *dbg_dir;
 #endif
+	unsigned long bflags;	/* word size bit flags for use. */
 };
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
@@ -822,6 +824,15 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
 		sock_shutdown(nbd);
 		mutex_lock(&nbd->tx_lock);
 		nbd_clear_que(nbd);
+		/*
+		 * Wait for any users currently using
+		 * this block device.
+		 */
+		mutex_unlock(&nbd->tx_lock);
+		pr_info("Waiting for users to release device %s ...\n",
+						bdev->bd_disk->disk_name);
+		wait_on_bit(&nbd->bflags, NBD_BFLAG_INUSE_BIT, TASK_INTERRUPTIBLE);
+		mutex_lock(&nbd->tx_lock);
 		kill_bdev(bdev);
 		nbd_bdev_reset(bdev);
 
@@ -870,10 +881,39 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
 	return error;
 }
 
+static int nbd_open(struct block_device *bdev, fmode_t mode)
+{
+	struct nbd_device *nbd_dev = bdev->bd_disk->private_data;
+	nbd_dev->users++;
+	pr_debug("Opening nbd_dev %s. Active users = %u\n",
+			bdev->bd_disk->disk_name, nbd_dev->users);
+	if (nbd_dev->users > 1)
+	{
+		set_bit(NBD_BFLAG_INUSE_BIT, &nbd_dev->bflags);
+	}
+	return 0;
+}
+
+static void nbd_release(struct gendisk *disk, fmode_t mode)
+{
+	struct nbd_device *nbd_dev = disk->private_data;
+	nbd_dev->users--;
+	pr_debug("Closing nbd_dev %s. Active users = %u\n",
+			disk->disk_name, nbd_dev->users);
+	if (nbd_dev->users == 1)
+	{
+		clear_bit(NBD_BFLAG_INUSE_BIT, &nbd_dev->bflags);
+		smp_mb();
+		wake_up_bit(&nbd_dev->bflags, NBD_BFLAG_INUSE_BIT);
+	}
+}
+
 static const struct block_device_operations nbd_fops = {
 	.owner =	THIS_MODULE,
 	.ioctl =	nbd_ioctl,
 	.compat_ioctl =	nbd_ioctl,
+	.open = 	nbd_open,
+	.release = 	nbd_release
 };
 
 #if IS_ENABLED(CONFIG_DEBUG_FS)
diff --git a/include/uapi/linux/nbd.h b/include/uapi/linux/nbd.h
index e08e413..8f3d3f0 100644
--- a/include/uapi/linux/nbd.h
+++ b/include/uapi/linux/nbd.h
@@ -44,6 +44,7 @@ enum {
 /* there is a gap here to match userspace */
 #define NBD_FLAG_SEND_TRIM    (1 << 5) /* send trim/discard */
 
+#define NBD_BFLAG_INUSE_BIT	(1) /* bit number for bflags */
 /* userspace doesn't need the nbd_device structure */
 
 /* These are sent over the network in the request/reply magic fields */
-- 
2.6.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ