Use make_dev_s() instead of make_dev() to avoid race setting

"si_drv1". Convert panic() into regular error while at it.

Suggested by:	jhb @
MFC after:	1 week
Sponsored by:	Mellanox Technologies
This commit is contained in:
Hans Petter Selasky 2016-05-24 07:06:04 +00:00
parent b28956a456
commit 5a6748b2cf

View file

@ -2,7 +2,7 @@
* Copyright (c) 2010 Isilon Systems, Inc.
* Copyright (c) 2010 iX Systems, Inc.
* Copyright (c) 2010 Panasas, Inc.
* Copyright (c) 2013, 2014 Mellanox Technologies, Ltd.
* Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -80,12 +80,27 @@ cdev_put(struct linux_cdev *p)
static inline int
cdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count)
{
struct make_dev_args args;
int error;
if (count != 1)
panic("cdev_add: Unsupported count: %d", count);
cdev->cdev = make_dev(&linuxcdevsw, MINOR(dev), 0, 0, 0700,
"%s", kobject_name(&cdev->kobj));
return (-EINVAL);
cdev->dev = dev;
cdev->cdev->si_drv1 = cdev;
/* Setup arguments for make_dev_s() */
make_dev_args_init(&args);
args.mda_devsw = &linuxcdevsw;
args.mda_uid = 0;
args.mda_gid = 0;
args.mda_mode = 0700;
args.mda_si_drv1 = cdev;
args.mda_unit = MINOR(dev);
error = make_dev_s(&args, &cdev->cdev, "%s",
kobject_name(&cdev->kobj));
if (error)
return (-error);
kobject_get(cdev->kobj.parent);
return (0);
@ -94,10 +109,24 @@ cdev_add(struct linux_cdev *cdev, dev_t dev, unsigned count)
static inline int
cdev_add_ext(struct linux_cdev *cdev, dev_t dev, uid_t uid, gid_t gid, int mode)
{
cdev->cdev = make_dev(&linuxcdevsw, MINOR(dev), uid, gid, mode,
"%s/%d", kobject_name(&cdev->kobj), MINOR(dev));
struct make_dev_args args;
int error;
cdev->dev = dev;
cdev->cdev->si_drv1 = cdev;
/* Setup arguments for make_dev_s() */
make_dev_args_init(&args);
args.mda_devsw = &linuxcdevsw;
args.mda_uid = uid;
args.mda_gid = gid;
args.mda_mode = mode;
args.mda_si_drv1 = cdev;
args.mda_unit = MINOR(dev);
error = make_dev_s(&args, &cdev->cdev, "%s/%d",
kobject_name(&cdev->kobj), MINOR(dev));
if (error)
return (-error);
kobject_get(cdev->kobj.parent);
return (0);