From owner-svn-src-head@FreeBSD.ORG Thu May 6 19:22:50 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id CDC251065677; Thu, 6 May 2010 19:22:50 +0000 (UTC) (envelope-from kib@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [69.147.83.44]) by mx1.freebsd.org (Postfix) with ESMTP id BCED48FC0C; Thu, 6 May 2010 19:22:50 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o46JMouR067220; Thu, 6 May 2010 19:22:50 GMT (envelope-from kib@svn.freebsd.org) Received: (from kib@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o46JMoWr067215; Thu, 6 May 2010 19:22:50 GMT (envelope-from kib@svn.freebsd.org) Message-Id: <201005061922.o46JMoWr067215@svn.freebsd.org> From: Konstantin Belousov Date: Thu, 6 May 2010 19:22:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r207729 - in head/sys: fs/devfs kern sys X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 06 May 2010 19:22:50 -0000 Author: kib Date: Thu May 6 19:22:50 2010 New Revision: 207729 URL: http://svn.freebsd.org/changeset/base/207729 Log: Add MAKEDEV_NOWAIT flag to make_dev_credf(9), to create a device node in a no-sleep context. If resource allocation cannot be done without sleep, make_dev_credf() fails and returns NULL. Reviewed by: jh MFC after: 2 weeks Modified: head/sys/fs/devfs/devfs_devs.c head/sys/fs/devfs/devfs_int.h head/sys/kern/kern_conf.c head/sys/sys/conf.h Modified: head/sys/fs/devfs/devfs_devs.c ============================================================================== --- head/sys/fs/devfs/devfs_devs.c Thu May 6 18:58:32 2010 (r207728) +++ head/sys/fs/devfs/devfs_devs.c Thu May 6 19:22:50 2010 (r207729) @@ -115,17 +115,21 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, cdev 0, sizeof(struct cdev_priv), "sizeof(struct cdev_priv)"); struct cdev * -devfs_alloc(void) +devfs_alloc(int flags) { struct cdev_priv *cdp; struct cdev *cdev; struct timespec ts; - cdp = malloc(sizeof *cdp, M_CDEVP, M_USE_RESERVE | M_ZERO | M_WAITOK); + cdp = malloc(sizeof *cdp, M_CDEVP, M_USE_RESERVE | M_ZERO | + ((flags & MAKEDEV_NOWAIT) ? M_NOWAIT : M_WAITOK)); + if (cdp == NULL) + return (NULL); cdp->cdp_dirents = &cdp->cdp_dirent0; cdp->cdp_dirent0 = NULL; cdp->cdp_maxdirent = 0; + cdp->cdp_inode = 0; cdev = &cdp->cdp_c; @@ -133,6 +137,7 @@ devfs_alloc(void) LIST_INIT(&cdev->si_children); vfs_timestamp(&ts); cdev->si_atime = cdev->si_mtime = cdev->si_ctime = ts; + cdev->si_cred = NULL; return (cdev); } Modified: head/sys/fs/devfs/devfs_int.h ============================================================================== --- head/sys/fs/devfs/devfs_int.h Thu May 6 18:58:32 2010 (r207728) +++ head/sys/fs/devfs/devfs_int.h Thu May 6 19:22:50 2010 (r207729) @@ -70,7 +70,7 @@ struct cdev_priv { #define cdev2priv(c) member2struct(cdev_priv, cdp_c, c) -struct cdev *devfs_alloc(void); +struct cdev *devfs_alloc(int); void devfs_free(struct cdev *); void devfs_create(struct cdev *dev); void devfs_destroy(struct cdev *dev); Modified: head/sys/kern/kern_conf.c ============================================================================== --- head/sys/kern/kern_conf.c Thu May 6 18:58:32 2010 (r207728) +++ head/sys/kern/kern_conf.c Thu May 6 19:22:50 2010 (r207729) @@ -505,7 +505,7 @@ giant_mmap_single(struct cdev *dev, vm_o } static void -notify(struct cdev *dev, const char *ev) +notify(struct cdev *dev, const char *ev, int flags) { static const char prefix[] = "cdev="; char *data; @@ -514,7 +514,8 @@ notify(struct cdev *dev, const char *ev) if (cold) return; namelen = strlen(dev->si_name); - data = malloc(namelen + sizeof(prefix), M_TEMP, M_NOWAIT); + data = malloc(namelen + sizeof(prefix), M_TEMP, + (flags & MAKEDEV_NOWAIT) ? M_NOWAIT : M_WAITOK); if (data == NULL) return; memcpy(data, prefix, sizeof(prefix) - 1); @@ -524,17 +525,17 @@ notify(struct cdev *dev, const char *ev) } static void -notify_create(struct cdev *dev) +notify_create(struct cdev *dev, int flags) { - notify(dev, "CREATE"); + notify(dev, "CREATE", flags); } static void notify_destroy(struct cdev *dev) { - notify(dev, "DESTROY"); + notify(dev, "DESTROY", MAKEDEV_WAITOK); } static struct cdev * @@ -572,24 +573,27 @@ fini_cdevsw(struct cdevsw *devsw) devsw->d_flags &= ~D_INIT; } -static void -prep_cdevsw(struct cdevsw *devsw) +static int +prep_cdevsw(struct cdevsw *devsw, int flags) { struct cdevsw *dsw2; mtx_assert(&devmtx, MA_OWNED); if (devsw->d_flags & D_INIT) - return; + return (1); if (devsw->d_flags & D_NEEDGIANT) { dev_unlock(); - dsw2 = malloc(sizeof *dsw2, M_DEVT, M_WAITOK); + dsw2 = malloc(sizeof *dsw2, M_DEVT, + (flags & MAKEDEV_NOWAIT) ? M_NOWAIT : M_WAITOK); dev_lock(); + if (dsw2 == NULL && !(devsw->d_flags & D_INIT)) + return (0); } else dsw2 = NULL; if (devsw->d_flags & D_INIT) { if (dsw2 != NULL) cdevsw_free_devlocked(dsw2); - return; + return (1); } if (devsw->d_version != D_VERSION_03) { @@ -647,6 +651,7 @@ prep_cdevsw(struct cdevsw *devsw) if (dsw2 != NULL) cdevsw_free_devlocked(dsw2); + return (1); } static struct cdev * @@ -657,9 +662,15 @@ make_dev_credv(int flags, struct cdevsw struct cdev *dev; int i; - dev = devfs_alloc(); + dev = devfs_alloc(flags); + if (dev == NULL) + return (NULL); dev_lock(); - prep_cdevsw(devsw); + if (!prep_cdevsw(devsw, flags)) { + dev_unlock(); + devfs_free(dev); + return (NULL); + } dev = newdev(devsw, unit, dev); if (flags & MAKEDEV_REF) dev_refl(dev); @@ -686,8 +697,6 @@ make_dev_credv(int flags, struct cdevsw dev->si_flags |= SI_NAMED; if (cr != NULL) dev->si_cred = crhold(cr); - else - dev->si_cred = NULL; dev->si_uid = uid; dev->si_gid = gid; dev->si_mode = mode; @@ -696,7 +705,7 @@ make_dev_credv(int flags, struct cdevsw clean_unrhdrl(devfs_inos); dev_unlock_and_free(); - notify_create(dev); + notify_create(dev, flags); return (dev); } @@ -771,7 +780,7 @@ make_dev_alias(struct cdev *pdev, const int i; KASSERT(pdev != NULL, ("NULL pdev")); - dev = devfs_alloc(); + dev = devfs_alloc(MAKEDEV_WAITOK); dev_lock(); dev->si_flags |= SI_ALIAS; dev->si_flags |= SI_NAMED; @@ -788,7 +797,7 @@ make_dev_alias(struct cdev *pdev, const clean_unrhdrl(devfs_inos); dev_unlock(); - notify_create(dev); + notify_create(dev, MAKEDEV_WAITOK); return (dev); } @@ -973,9 +982,9 @@ clone_create(struct clonedevs **cdp, str * the end of the list. */ unit = *up; - ndev = devfs_alloc(); + ndev = devfs_alloc(MAKEDEV_WAITOK); dev_lock(); - prep_cdevsw(csw); + prep_cdevsw(csw, MAKEDEV_WAITOK); low = extra; de = dl = NULL; cd = *cdp; Modified: head/sys/sys/conf.h ============================================================================== --- head/sys/sys/conf.h Thu May 6 18:58:32 2010 (r207728) +++ head/sys/sys/conf.h Thu May 6 19:22:50 2010 (r207729) @@ -262,8 +262,10 @@ struct cdev *make_dev(struct cdevsw *_de struct cdev *make_dev_cred(struct cdevsw *_devsw, int _unit, struct ucred *_cr, uid_t _uid, gid_t _gid, int _perms, const char *_fmt, ...) __printflike(7, 8); -#define MAKEDEV_REF 0x1 -#define MAKEDEV_WHTOUT 0x2 +#define MAKEDEV_REF 0x1 +#define MAKEDEV_WHTOUT 0x2 +#define MAKEDEV_NOWAIT 0x4 +#define MAKEDEV_WAITOK 0x8 struct cdev *make_dev_credf(int _flags, struct cdevsw *_devsw, int _unit, struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode,