From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753618AbbG0JjL (ORCPT ); Mon, 27 Jul 2015 05:39:11 -0400 Received: from metis.ext.pengutronix.de ([92.198.50.35]:50655 "EHLO metis.ext.pengutronix.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752750AbbG0JjJ (ORCPT ); Mon, 27 Jul 2015 05:39:09 -0400 Date: Mon, 27 Jul 2015 11:39:07 +0200 From: Markus Pargmann To: nbd-general@lists.sourceforge.net Cc: linux-kernel@vger.kernel.org, kernel@pengutronix.de Subject: Re: [PATCH 10/10] nbd: Create size change events for userspace Message-ID: <20150727093907.GK1749@pengutronix.de> References: <1437981176-21061-1-git-send-email-mpa@pengutronix.de> <1437981176-21061-11-git-send-email-mpa@pengutronix.de> MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="bWEb1MG/o7IKOlQF" Content-Disposition: inline In-Reply-To: <1437981176-21061-11-git-send-email-mpa@pengutronix.de> X-Sent-From: Pengutronix Hildesheim X-URL: http://www.pengutronix.de/ X-IRC: #ptxdist @freenode X-Accept-Language: de,en X-Accept-Content-Type: text/plain X-Uptime: 11:37:32 up 3 days, 15:46, 99 users, load average: 8.63, 7.64, 12.12 User-Agent: Mutt/1.5.23 (2014-03-12) X-SA-Exim-Connect-IP: 2001:67c:670:100:1d::7 X-SA-Exim-Mail-From: mpa@pengutronix.de X-SA-Exim-Scanned: No (on metis.ext.pengutronix.de); SAEximRunCond expanded to false X-PTX-Original-Recipient: linux-kernel@vger.kernel.org Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org --bWEb1MG/o7IKOlQF Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Mon, Jul 27, 2015 at 09:12:56AM +0200, Markus Pargmann wrote: > 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. >=20 > See the discussion here: https://github.com/systemd/systemd/pull/358 >=20 > 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. >=20 > Signed-off-by: Markus Pargmann > --- > drivers/block/nbd.c | 74 ++++++++++++++++++++++++++++++++++++++---------= ------ > 1 file changed, 54 insertions(+), 20 deletions(-) >=20 > diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c > index 1176a3b27a7e..95eb2904c324 100644 > --- a/drivers/block/nbd.c > +++ b/drivers/block/nbd.c > @@ -97,6 +97,11 @@ static inline struct device *nbd_to_dev(struct nbd_dev= ice *nbd) > return disk_to_dev(nbd->disk); > } > =20 > +static bool nbd_is_connected(struct nbd_device *nbd) > +{ > + return !!nbd->task_recv; > +} > + > static const char *nbdcmd_to_ascii(int cmd) > { > switch (cmd) { > @@ -109,6 +114,43 @@ static const char *nbdcmd_to_ascii(int cmd) > return "invalid"; > } > =20 > +static int nbd_size_clear(struct nbd_device *nbd, struct block_device *b= dev) > +{ > + bdev->bd_inode->i_size =3D 0; > + set_blocksize(bdev, 0); > + set_capacity(nbd->disk, 0); > + kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); > + > + return 0; > +} > + > +static int nbd_size_update(struct nbd_device *nbd, struct block_device *= bdev) > +{ > + int ret; > + > + if (!nbd_is_connected(nbd)) > + return 0; > + > + ret =3D set_blocksize(bdev, nbd->blksize); > + if (ret) > + return ret; > + > + bdev->bd_inode->i_size =3D nbd->bytesize; > + set_capacity(nbd->disk, nbd->bytesize >> 9); > + kobject_uevent(&nbd_to_dev(nbd)->kobj, KOBJ_CHANGE); > + > + return 0; > +} > + > +static int nbd_size_set(struct nbd_device *nbd, struct block_device *bde= v, > + int blocksize, int nr_blocks) > +{ > + nbd->blksize =3D blocksize; > + nbd->bytesize =3D blocksize * nr_blocks; > + > + return nbd_size_update(nbd, bdev); > +} > + > static void nbd_end_request(struct nbd_device *nbd, struct request *req) > { > int error =3D req->errors ? -EIO : 0; > @@ -399,7 +441,7 @@ static struct device_attribute pid_attr =3D { > .show =3D pid_show, > }; > =20 > -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; > @@ -417,6 +459,8 @@ static int nbd_thread_recv(struct nbd_device *nbd) > return ret; > } > =20 > + nbd_size_update(nbd, bdev); > + > while (1) { > req =3D nbd_read_stat(nbd); > if (IS_ERR(req)) { > @@ -427,6 +471,8 @@ static int nbd_thread_recv(struct nbd_device *nbd) > nbd_end_request(nbd, req); > } > =20 > + nbd_size_clear(nbd, bdev); > + > device_remove_file(disk_to_dev(nbd->disk), &pid_attr); > =20 > nbd->task_recv =3D NULL; > @@ -681,19 +727,14 @@ static int __nbd_ioctl(struct block_device *bdev, s= truct nbd_device *nbd, > } > =20 > case NBD_SET_BLKSIZE: > - nbd->blksize =3D arg; > - nbd->bytesize &=3D ~(nbd->blksize-1); > - bdev->bd_inode->i_size =3D nbd->bytesize; > - set_blocksize(bdev, nbd->blksize); > - set_capacity(nbd->disk, nbd->bytesize >> 9); > - return 0; > + return nbd_size_set(nbd, bdev, arg, nbd->bytesize / arg); This does not work for 32bit systems. Have to use do_div() for this. Will fix that for the next version. Best regards, Markus > =20 > case NBD_SET_SIZE: > - nbd->bytesize =3D arg & ~(nbd->blksize-1); > - bdev->bd_inode->i_size =3D 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); > =20 > case NBD_SET_TIMEOUT: > nbd->xmit_timeout =3D arg * HZ; > @@ -709,13 +750,6 @@ static int __nbd_ioctl(struct block_device *bdev, st= ruct nbd_device *nbd, > nbd->flags =3D arg; > return 0; > =20 > - case NBD_SET_SIZE_BLOCKS: > - nbd->bytesize =3D ((u64) arg) * nbd->blksize; > - bdev->bd_inode->i_size =3D 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; > @@ -746,7 +780,7 @@ static int __nbd_ioctl(struct block_device *bdev, str= uct nbd_device *nbd, > } > =20 > nbd_dev_dbg_init(nbd); > - error =3D nbd_thread_recv(nbd); > + error =3D nbd_thread_recv(nbd, bdev); > nbd_dev_dbg_close(nbd); > kthread_stop(thread); > =20 > --=20 > 2.1.4 >=20 >=20 --=20 Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | --bWEb1MG/o7IKOlQF Content-Type: application/pgp-signature; name="signature.asc" Content-Description: Digital signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBAgAGBQJVtfw6AAoJEEpcgKtcEGQQuccP/RxyfgR+2LiqPMbknQwYl8RB PfGlE7RQPrHFwYGUSGKZThrd/sVraT2PN+bMjzD2BaLjNNp3PWetBejq6/XiK12+ 5LA5T/5tRccde/1BfHPn2aQBUGs1Bvd04Ke/mRigmwB2KMMMztmy1Zd2mogYZCkW 8sHY4uYIAa8scWqxYFPeVeKPMI4ix2eCfRFVrF5XiR9uUKi8rix2IYtiIyjl0u1B htcDdB7j7MqIJLmgbR6T1AyyV+9Hsbdr6seaFeFvqT77yhmBtxym0GzWf6GyVp7A cRFMubEwH5DwhmsplAA7qwwTnLgdOYkUa4I+xSHMBawtk4dw+magKkwcTAxzMP+i gOUGvmyJ84MC5a6bG6QMEy08IqA2DVcUZNJ6DFlo4a3+GiUK9JXdgJcFl5dM4j3D KUiw9KB7N2K7gLM3ng+yFwyItYPrB3X5FbJk5VW4WoC+5l9N3PClWuAZh+OkmbV7 8yYWj0govBq9SgOZC8PLbRjgJRp8o3iXmvvSRPxM/xxDd5SRYIEM1tIiwprz2k8w /hrHBeQ0AKXCzdxkuWt7ilZOl04265nZDOjYAMVA9+pwHNtR3dKcDm+IwhL6bMyq XofZDAVO2yrJM7WzKqvYOdMvHDOV8wuxWOPA7o03XMW0NyGi+NzAXhb0EooZEsAM W142iyiRp33XctyAnUnX =kbv1 -----END PGP SIGNATURE----- --bWEb1MG/o7IKOlQF--