MFC r207729:

Add MAKEDEV_NOWAIT flag for make_dev_credf(9).
This commit is contained in:
Konstantin Belousov 2010-05-20 09:38:15 +00:00
parent f950c14263
commit c67c645d9d
4 changed files with 40 additions and 24 deletions

View File

@ -112,17 +112,21 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, cdev_priv, CTLFLAG_RD,
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;
@ -130,6 +134,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);
}

View File

@ -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);

View File

@ -508,7 +508,7 @@ giant_mmap_single(struct cdev *dev, vm_ooffset_t *offset, vm_size_t size,
}
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;
@ -517,7 +517,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);
@ -527,17 +528,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 *
@ -575,24 +576,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_01 &&
@ -653,6 +657,7 @@ prep_cdevsw(struct cdevsw *devsw)
if (dsw2 != NULL)
cdevsw_free_devlocked(dsw2);
return (1);
}
static struct cdev *
@ -663,9 +668,15 @@ make_dev_credv(int flags, struct cdevsw *devsw, int unit,
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);
@ -692,8 +703,6 @@ make_dev_credv(int flags, struct cdevsw *devsw, int unit,
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;
@ -702,7 +711,7 @@ make_dev_credv(int flags, struct cdevsw *devsw, int unit,
clean_unrhdrl(devfs_inos);
dev_unlock_and_free();
notify_create(dev);
notify_create(dev, flags);
return (dev);
}
@ -777,7 +786,7 @@ make_dev_alias(struct cdev *pdev, const char *fmt, ...)
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;
@ -794,7 +803,7 @@ make_dev_alias(struct cdev *pdev, const char *fmt, ...)
clean_unrhdrl(devfs_inos);
dev_unlock();
notify_create(dev);
notify_create(dev, MAKEDEV_WAITOK);
return (dev);
}
@ -979,9 +988,9 @@ clone_create(struct clonedevs **cdp, struct cdevsw *csw, int *up,
* 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;

View File

@ -271,8 +271,10 @@ struct cdev *make_dev(struct cdevsw *_devsw, int _unit, uid_t _uid, gid_t _gid,
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,