Date: Mon, 16 Feb 2015 09:53:44 +0000 (UTC) From: Roger Pau Monné <royger@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r278844 - head/sys/dev/xen/xenstore Message-ID: <201502160953.t1G9rijI028299@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: royger Date: Mon Feb 16 09:53:43 2015 New Revision: 278844 URL: https://svnweb.freebsd.org/changeset/base/278844 Log: xen: fix xenstore dev Xenstore user-space device has two problems currently: - It does not correctly handle concurrent clients, because it's storing each client data in dev->si_drv1. - It does not correctly free this data when the client closes the device. In order to solve both of this issues store the per-client data using cdevpriv, which also comes with a hook in order to perform the necessary cleanup on device close. While there also make the device eternal. Sponsored by: Citrix Systems R&D Reported and Tested by: thompsa MFC after: 2 weeks Modified: head/sys/dev/xen/xenstore/xenstore_dev.c Modified: head/sys/dev/xen/xenstore/xenstore_dev.c ============================================================================== --- head/sys/dev/xen/xenstore/xenstore_dev.c Mon Feb 16 07:01:02 2015 (r278843) +++ head/sys/dev/xen/xenstore/xenstore_dev.c Mon Feb 16 09:53:43 2015 (r278844) @@ -77,7 +77,11 @@ static int xs_dev_read(struct cdev *dev, struct uio *uio, int ioflag) { int error; - struct xs_dev_data *u = dev->si_drv1; + struct xs_dev_data *u; + + error = devfs_get_cdevpriv((void **)&u); + if (error != 0) + return (error); while (u->read_prod == u->read_cons) { error = tsleep(u, PCATCH, "xsdread", hz/10); @@ -115,11 +119,15 @@ static int xs_dev_write(struct cdev *dev, struct uio *uio, int ioflag) { int error; - struct xs_dev_data *u = dev->si_drv1; + struct xs_dev_data *u; struct xs_dev_transaction *trans; void *reply; int len = uio->uio_resid; + error = devfs_get_cdevpriv((void **)&u); + if (error != 0) + return (error); + if ((len + u->len) > sizeof(u->u.buffer)) return (EINVAL); @@ -177,25 +185,10 @@ xs_dev_write(struct cdev *dev, struct ui return (error); } -static int -xs_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) -{ - struct xs_dev_data *u; - -#if 0 /* XXX figure out if equiv needed */ - nonseekable_open(inode, filp); -#endif - u = malloc(sizeof(*u), M_XENSTORE, M_WAITOK|M_ZERO); - LIST_INIT(&u->transactions); - dev->si_drv1 = u; - - return (0); -} - -static int -xs_dev_close(struct cdev *dev, int fflag, int devtype, struct thread *td) +static void +xs_dev_dtor(void *arg) { - struct xs_dev_data *u = dev->si_drv1; + struct xs_dev_data *u = arg; struct xs_dev_transaction *trans, *tmp; LIST_FOREACH_SAFE(trans, &u->transactions, list, tmp) { @@ -205,7 +198,21 @@ xs_dev_close(struct cdev *dev, int fflag } free(u, M_XENSTORE); - return (0); +} + +static int +xs_dev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + struct xs_dev_data *u; + int error; + + u = malloc(sizeof(*u), M_XENSTORE, M_WAITOK|M_ZERO); + LIST_INIT(&u->transactions); + error = devfs_set_cdevpriv(u, xs_dev_dtor); + if (error != 0) + free(u, M_XENSTORE); + + return (error); } static struct cdevsw xs_dev_cdevsw = { @@ -213,7 +220,6 @@ static struct cdevsw xs_dev_cdevsw = { .d_read = xs_dev_read, .d_write = xs_dev_write, .d_open = xs_dev_open, - .d_close = xs_dev_close, .d_name = "xs_dev", }; @@ -262,8 +268,8 @@ xs_dev_attach(device_t dev) { struct cdev *xs_cdev; - xs_cdev = make_dev(&xs_dev_cdevsw, 0, UID_ROOT, GID_WHEEL, 0400, - "xen/xenstore"); + xs_cdev = make_dev_credf(MAKEDEV_ETERNAL, &xs_dev_cdevsw, 0, NULL, + UID_ROOT, GID_WHEEL, 0400, "xen/xenstore"); if (xs_cdev == NULL) return (EINVAL);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201502160953.t1G9rijI028299>