[linux] 08/08: nbd: Create size change events for userspace (Closes: #812487)

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Wed Apr 13 22:26:30 UTC 2016


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch master
in repository linux.

commit a8c2d3c6996d24a0b4e610a859d33746bc3e066d
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Wed Apr 13 23:23:32 2016 +0100

    nbd: Create size change events for userspace (Closes: #812487)
---
 debian/changelog                                   |   1 +
 ...d-create-size-change-events-for-userspace.patch | 163 +++++++++++++++++++++
 debian/patches/series                              |   1 +
 3 files changed, 165 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index a70e6ae..1ad8b02 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -247,6 +247,7 @@ linux (4.5.1-1) UNRELEASED; urgency=medium
   * [armhf] Add support for octa-core big.LITTLE systems including Exynos
     (Closes: #819379)
   * [armhf] watchdog: Enable S3C2410_WATCHDOG as module (Closes: #819377)
+  * nbd: Create size change events for userspace (Closes: #812487)
 
   [ Aurelien Jarno ]
   * [mipsel/mips/config.loongson-2f] Disable VIDEO_CX23885, VIDEO_IVTV,
diff --git a/debian/patches/features/all/nbd-create-size-change-events-for-userspace.patch b/debian/patches/features/all/nbd-create-size-change-events-for-userspace.patch
new file mode 100644
index 0000000..0e6ef99
--- /dev/null
+++ b/debian/patches/features/all/nbd-create-size-change-events-for-userspace.patch
@@ -0,0 +1,163 @@
+From: Markus Pargmann <mpa at pengutronix.de>
+Date: Mon, 27 Jul 2015 07:36:49 +0200
+Subject: nbd: Create size change events for userspace
+Origin: https://git.kernel.org/linus/37091fdd831f28a6509008542174ed324dd645bc
+Bug-Debian: https://bugs.debian.org/812487
+
+The userspace needs to know when nbd devices are ready for use.
+Currently no events are created for the userspace which doesn't work for
+systemd.
+
+See the discussion here: https://github.com/systemd/systemd/pull/358
+
+This patch uses a central point to setup the nbd-internal sizes. A ioctl
+to set a size does not lead to a visible size change. The size of the
+block device will be kept at 0 until nbd is connected. As soon as it
+connects, the size will be changed to the real value and a uevent is
+created. When disconnecting, the blockdevice is set to 0 size and
+another uevent is generated.
+
+Signed-off-by: Markus Pargmann <mpa at pengutronix.de>
+---
+ drivers/block/nbd.c | 79 +++++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 58 insertions(+), 21 deletions(-)
+
+--- a/drivers/block/nbd.c
++++ b/drivers/block/nbd.c
+@@ -98,6 +98,11 @@ static inline struct device *nbd_to_dev(
+ 	return disk_to_dev(nbd->disk);
+ }
+ 
++static bool nbd_is_connected(struct nbd_device *nbd)
++{
++	return !!nbd->task_recv;
++}
++
+ static const char *nbdcmd_to_ascii(int cmd)
+ {
+ 	switch (cmd) {
+@@ -110,6 +115,42 @@ static const char *nbdcmd_to_ascii(int c
+ 	return "invalid";
+ }
+ 
++static int nbd_size_clear(struct nbd_device *nbd, struct block_device *bdev)
++{
++	bdev->bd_inode->i_size = 0;
++	set_capacity(nbd->disk, 0);
++	kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
++
++	return 0;
++}
++
++static void nbd_size_update(struct nbd_device *nbd, struct block_device *bdev)
++{
++	if (!nbd_is_connected(nbd))
++		return;
++
++	bdev->bd_inode->i_size = nbd->bytesize;
++	set_capacity(nbd->disk, nbd->bytesize >> 9);
++	kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE);
++}
++
++static int nbd_size_set(struct nbd_device *nbd, struct block_device *bdev,
++			int blocksize, int nr_blocks)
++{
++	int ret;
++
++	ret = set_blocksize(bdev, blocksize);
++	if (ret)
++		return ret;
++
++	nbd->blksize = blocksize;
++	nbd->bytesize = (loff_t)blocksize * (loff_t)nr_blocks;
++
++	nbd_size_update(nbd, bdev);
++
++	return 0;
++}
++
+ static void nbd_end_request(struct nbd_device *nbd, struct request *req)
+ {
+ 	int error = req->errors ? -EIO : 0;
+@@ -402,7 +443,7 @@ static struct device_attribute pid_attr
+ 	.show = pid_show,
+ };
+ 
+-static int nbd_thread_recv(struct nbd_device *nbd)
++static int nbd_thread_recv(struct nbd_device *nbd, struct block_device *bdev)
+ {
+ 	struct request *req;
+ 	int ret;
+@@ -427,6 +468,8 @@ static int nbd_thread_recv(struct nbd_de
+ 		return ret;
+ 	}
+ 
++	nbd_size_update(nbd, bdev);
++
+ 	while (1) {
+ 		req = nbd_read_stat(nbd);
+ 		if (IS_ERR(req)) {
+@@ -437,6 +480,8 @@ static int nbd_thread_recv(struct nbd_de
+ 		nbd_end_request(nbd, req);
+ 	}
+ 
++	nbd_size_clear(nbd, bdev);
++
+ 	device_remove_file(disk_to_dev(nbd->disk), &pid_attr);
+ 
+ 	spin_lock_irqsave(&nbd->tasks_lock, flags);
+@@ -696,20 +741,19 @@ static int __nbd_ioctl(struct block_devi
+ 		return -EINVAL;
+ 	}
+ 
+-	case NBD_SET_BLKSIZE:
+-		nbd->blksize = arg;
+-		nbd->bytesize &= ~(nbd->blksize-1);
+-		bdev->bd_inode->i_size = nbd->bytesize;
+-		set_blocksize(bdev, nbd->blksize);
+-		set_capacity(nbd->disk, nbd->bytesize >> 9);
+-		return 0;
++	case NBD_SET_BLKSIZE: {
++		loff_t bsize = nbd->bytesize;
++		do_div(bsize, arg);
++
++		return nbd_size_set(nbd, bdev, arg, bsize);
++	}
+ 
+ 	case NBD_SET_SIZE:
+-		nbd->bytesize = arg & ~(nbd->blksize-1);
+-		bdev->bd_inode->i_size = nbd->bytesize;
+-		set_blocksize(bdev, nbd->blksize);
+-		set_capacity(nbd->disk, nbd->bytesize >> 9);
+-		return 0;
++		return nbd_size_set(nbd, bdev, nbd->blksize,
++				    arg / nbd->blksize);
++
++	case NBD_SET_SIZE_BLOCKS:
++		return nbd_size_set(nbd, bdev, nbd->blksize, arg);
+ 
+ 	case NBD_SET_TIMEOUT:
+ 		nbd->xmit_timeout = arg * HZ;
+@@ -725,13 +769,6 @@ static int __nbd_ioctl(struct block_devi
+ 		nbd->flags = arg;
+ 		return 0;
+ 
+-	case NBD_SET_SIZE_BLOCKS:
+-		nbd->bytesize = ((u64) arg) * nbd->blksize;
+-		bdev->bd_inode->i_size = nbd->bytesize;
+-		set_blocksize(bdev, nbd->blksize);
+-		set_capacity(nbd->disk, nbd->bytesize >> 9);
+-		return 0;
+-
+ 	case NBD_DO_IT: {
+ 		struct task_struct *thread;
+ 		struct socket *sock;
+@@ -762,7 +799,7 @@ static int __nbd_ioctl(struct block_devi
+ 		}
+ 
+ 		nbd_dev_dbg_init(nbd);
+-		error = nbd_thread_recv(nbd);
++		error = nbd_thread_recv(nbd, bdev);
+ 		nbd_dev_dbg_close(nbd);
+ 		kthread_stop(thread);
+ 
diff --git a/debian/patches/series b/debian/patches/series
index 26ee80d..7bea7d9 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -144,3 +144,4 @@ bugfix/all/ipv4-don-t-do-expensive-useless-work-during-inetdev-.patch
 bugfix/x86/x86-mm-32-enable-full-randomization-on-i386-and-x86_.patch
 bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch
 bugfix/x86/acpi-processor-request-native-thermal-interrupt-hand.patch
+features/all/nbd-create-size-change-events-for-userspace.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list