Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 Jun 2010 13:22:39 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r209106 - in head/sys: kern sys
Message-ID:  <201006121322.o5CDMd57010715@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Sat Jun 12 13:22:39 2010
New Revision: 209106
URL: http://svn.freebsd.org/changeset/base/209106

Log:
  Add another variation of make_dev(9), make_dev_p(9), that is allowed
  to fail and can return useful error code.
  
  Requested by:	jh
  Reviewed by:	imp, jh
  MFC after:	3 weeks

Modified:
  head/sys/kern/kern_conf.c
  head/sys/sys/conf.h

Modified: head/sys/kern/kern_conf.c
==============================================================================
--- head/sys/kern/kern_conf.c	Sat Jun 12 13:21:25 2010	(r209105)
+++ head/sys/kern/kern_conf.c	Sat Jun 12 13:22:39 2010	(r209106)
@@ -55,9 +55,8 @@ struct mtx devmtx;
 static void destroy_devl(struct cdev *dev);
 static int destroy_dev_sched_cbl(struct cdev *dev,
     void (*cb)(void *), void *arg);
-static struct cdev *make_dev_credv(int flags,
-    struct cdevsw *devsw, int unit,
-    struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
+static int make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw,
+    int unit, struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
     va_list ap);
 
 static struct cdev_priv_list cdevp_free_list =
@@ -580,20 +579,20 @@ prep_cdevsw(struct cdevsw *devsw, int fl
 
 	mtx_assert(&devmtx, MA_OWNED);
 	if (devsw->d_flags & D_INIT)
-		return (1);
+		return (0);
 	if (devsw->d_flags & D_NEEDGIANT) {
 		dev_unlock();
 		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);
+			return (ENOMEM);
 	} else
 		dsw2 = NULL;
 	if (devsw->d_flags & D_INIT) {
 		if (dsw2 != NULL)
 			cdevsw_free_devlocked(dsw2);
-		return (1);
+		return (0);
 	}
 
 	if (devsw->d_version != D_VERSION_03) {
@@ -651,25 +650,28 @@ prep_cdevsw(struct cdevsw *devsw, int fl
 
 	if (dsw2 != NULL)
 		cdevsw_free_devlocked(dsw2);
-	return (1);
+	return (0);
 }
 
-static struct cdev *
-make_dev_credv(int flags, struct cdevsw *devsw, int unit,
-    struct ucred *cr, uid_t uid,
-    gid_t gid, int mode, const char *fmt, va_list ap)
+static int
+make_dev_credv(int flags, struct cdev **dres, struct cdevsw *devsw, int unit,
+    struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt,
+    va_list ap)
 {
 	struct cdev *dev;
-	int i;
+	int i, res;
 
+	KASSERT((flags & MAKEDEV_WAITOK) == 0 || (flags & MAKEDEV_NOWAIT) == 0,
+	    ("make_dev_credv: both WAITOK and NOWAIT specified"));
 	dev = devfs_alloc(flags);
 	if (dev == NULL)
-		return (NULL);
+		return (ENOMEM);
 	dev_lock();
-	if (!prep_cdevsw(devsw, flags)) {
+	res = prep_cdevsw(devsw, flags);
+	if (res != 0) {
 		dev_unlock();
 		devfs_free(dev);
-		return (NULL);
+		return (res);
 	}
 	dev = newdev(devsw, unit, dev);
 	if (flags & MAKEDEV_REF)
@@ -682,7 +684,8 @@ make_dev_credv(int flags, struct cdevsw 
 		 * XXX: still ??
 		 */
 		dev_unlock_and_free();
-		return (dev);
+		*dres = dev;
+		return (0);
 	}
 	KASSERT(!(dev->si_flags & SI_NAMED),
 	    ("make_dev() by driver %s on pre-existing device (min=%x, name=%s)",
@@ -707,7 +710,8 @@ make_dev_credv(int flags, struct cdevsw 
 
 	notify_create(dev, flags);
 
-	return (dev);
+	*dres = dev;
+	return (0);
 }
 
 struct cdev *
@@ -716,10 +720,13 @@ make_dev(struct cdevsw *devsw, int unit,
 {
 	struct cdev *dev;
 	va_list ap;
+	int res;
 
 	va_start(ap, fmt);
-	dev = make_dev_credv(0, devsw, unit, NULL, uid, gid, mode, fmt, ap);
+	res = make_dev_credv(0, &dev, devsw, unit, NULL, uid, gid, mode, fmt,
+	    ap);
 	va_end(ap);
+	KASSERT(res == 0 && dev != NULL, ("make_dev: failed make_dev_credv"));
 	return (dev);
 }
 
@@ -729,28 +736,50 @@ make_dev_cred(struct cdevsw *devsw, int 
 {
 	struct cdev *dev;
 	va_list ap;
+	int res;
 
 	va_start(ap, fmt);
-	dev = make_dev_credv(0, devsw, unit, cr, uid, gid, mode, fmt, ap);
+	res = make_dev_credv(0, &dev, devsw, unit, cr, uid, gid, mode, fmt, ap);
 	va_end(ap);
 
+	KASSERT(res == 0 && dev != NULL,
+	    ("make_dev_cred: failed make_dev_credv"));
 	return (dev);
 }
 
 struct cdev *
-make_dev_credf(int flags, struct cdevsw *devsw, int unit,
-    struct ucred *cr, uid_t uid,
-    gid_t gid, int mode, const char *fmt, ...)
+make_dev_credf(int flags, struct cdevsw *devsw, int unit, struct ucred *cr,
+    uid_t uid, gid_t gid, int mode, const char *fmt, ...)
 {
 	struct cdev *dev;
 	va_list ap;
+	int res;
 
 	va_start(ap, fmt);
-	dev = make_dev_credv(flags, devsw, unit, cr, uid, gid, mode,
+	res = make_dev_credv(flags, &dev, devsw, unit, cr, uid, gid, mode,
 	    fmt, ap);
 	va_end(ap);
 
-	return (dev);
+	KASSERT((flags & MAKEDEV_NOWAIT) != 0 || res == 0,
+	    ("make_dev_credf: failed make_dev_credv"));
+	return (res == 0 ? dev : NULL);
+}
+
+int
+make_dev_p(int flags, struct cdev **cdev, struct cdevsw *devsw, int unit,
+    struct ucred *cr, uid_t uid, gid_t gid, int mode, const char *fmt, ...)
+{
+	va_list ap;
+	int res;
+
+	va_start(ap, fmt);
+	res = make_dev_credv(flags, cdev, devsw, unit, cr, uid, gid, mode,
+	    fmt, ap);
+	va_end(ap);
+
+	KASSERT((flags & MAKEDEV_NOWAIT) != 0 || res == 0,
+	    ("make_dev_credf: failed make_dev_credv"));
+	return (res);
 }
 
 static void

Modified: head/sys/sys/conf.h
==============================================================================
--- head/sys/sys/conf.h	Sat Jun 12 13:21:25 2010	(r209105)
+++ head/sys/sys/conf.h	Sat Jun 12 13:22:39 2010	(r209106)
@@ -270,7 +270,11 @@ struct cdev *make_dev_credf(int _flags,
 		struct cdevsw *_devsw, int _unit,
 		struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode,
 		const char *_fmt, ...) __printflike(8, 9);
-struct cdev *make_dev_alias(struct cdev *_pdev, const char *_fmt, ...) __printflike(2, 3);
+int	make_dev_p(int _flags, struct cdev **_cdev, struct cdevsw *_devsw,
+		int _unit, struct ucred *_cr, uid_t _uid, gid_t _gid, int _mode,
+		const char *_fmt, ...) __printflike(9, 10);
+struct cdev *make_dev_alias(struct cdev *_pdev, const char *_fmt, ...)
+		__printflike(2, 3);
 void	dev_lock(void);
 void	dev_unlock(void);
 void	setconf(void);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201006121322.o5CDMd57010715>