nbd: Create size change events for userspace (Closes: #812487)
This commit is contained in:
parent
e3395a2405
commit
a8c2d3c699
|
@ -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,
|
||||
|
|
163
debian/patches/features/all/nbd-create-size-change-events-for-userspace.patch
vendored
Normal file
163
debian/patches/features/all/nbd-create-size-change-events-for-userspace.patch
vendored
Normal file
|
@ -0,0 +1,163 @@
|
|||
From: Markus Pargmann <mpa@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@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);
|
||||
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue