Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Fix ioctl locking. Add dkdriver.
details: https://anonhg.NetBSD.org/src/rev/0a79805e5465
branches: trunk
changeset: 1014921:0a79805e5465
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Tue Oct 06 18:45:23 2020 +0000
description:
Fix ioctl locking. Add dkdriver.
diffstat:
sys/dev/ccd.c | 222 +++++++++++++++++++++++++++++++--------------------------
1 files changed, 122 insertions(+), 100 deletions(-)
diffs (truncated from 303 to 300 lines):
diff -r 6b870ad942a5 -r 0a79805e5465 sys/dev/ccd.c
--- a/sys/dev/ccd.c Tue Oct 06 16:39:23 2020 +0000
+++ b/sys/dev/ccd.c Tue Oct 06 18:45:23 2020 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ccd.c,v 1.184 2020/06/11 19:20:46 ad Exp $ */
+/* $NetBSD: ccd.c,v 1.185 2020/10/06 18:45:23 mlelstv Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998, 1999, 2007, 2009 The NetBSD Foundation, Inc.
@@ -88,7 +88,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.184 2020/06/11 19:20:46 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ccd.c,v 1.185 2020/10/06 18:45:23 mlelstv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -209,6 +209,11 @@
.d_flag = D_DISK | D_MPSAFE
};
+static const struct dkdriver ccddkdriver = {
+ .d_strategy = ccdstrategy,
+ .d_minphys = minphys
+};
+
#ifdef DEBUG
static void printiinfo(struct ccdiinfo *);
#endif
@@ -229,7 +234,7 @@
sc->sc_iolock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
cv_init(&sc->sc_stop, "ccdstop");
cv_init(&sc->sc_push, "ccdthr");
- disk_init(&sc->sc_dkdev, sc->sc_xname, NULL); /* XXX */
+ disk_init(&sc->sc_dkdev, sc->sc_xname, &ccddkdriver);
return sc;
}
@@ -1134,8 +1139,6 @@
return (EBADF);
}
- mutex_enter(&cs->sc_dvlock);
-
/* Must be initialized for these... */
switch (cmd) {
case CCDIOCCLR:
@@ -1159,15 +1162,102 @@
case ODIOCWDINFO:
case ODIOCGDEFLABEL:
#endif
- if ((cs->sc_flags & CCDF_INITED) == 0) {
- error = ENXIO;
- goto out;
- }
+ if ((cs->sc_flags & CCDF_INITED) == 0)
+ return ENXIO;
}
error = disk_ioctl(&cs->sc_dkdev, dev, cmd, data, flag, l);
if (error != EPASSTHROUGH)
- goto out;
+ return error;
+
+ switch (cmd) {
+ case DIOCGSTRATEGY:
+ {
+ struct disk_strategy *dks = (void *)data;
+
+ mutex_enter(cs->sc_iolock);
+ if (cs->sc_bufq != NULL)
+ strlcpy(dks->dks_name,
+ bufq_getstrategyname(cs->sc_bufq),
+ sizeof(dks->dks_name));
+ else
+ error = EINVAL;
+ mutex_exit(cs->sc_iolock);
+ dks->dks_paramlen = 0;
+ break;
+ }
+
+ case DIOCWDINFO:
+ case DIOCSDINFO:
+#ifdef __HAVE_OLD_DISKLABEL
+ case ODIOCWDINFO:
+ case ODIOCSDINFO:
+#endif
+ {
+ struct disklabel *lp;
+#ifdef __HAVE_OLD_DISKLABEL
+ if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
+ memset(&newlabel, 0, sizeof newlabel);
+ memcpy(&newlabel, data, sizeof (struct olddisklabel));
+ lp = &newlabel;
+ } else
+#endif
+ lp = (struct disklabel *)data;
+
+ cs->sc_flags |= CCDF_LABELLING;
+
+ error = setdisklabel(cs->sc_dkdev.dk_label,
+ lp, 0, cs->sc_dkdev.dk_cpulabel);
+ if (error == 0) {
+ if (cmd == DIOCWDINFO
+#ifdef __HAVE_OLD_DISKLABEL
+ || cmd == ODIOCWDINFO
+#endif
+ )
+ error = writedisklabel(CCDLABELDEV(dev),
+ ccdstrategy, cs->sc_dkdev.dk_label,
+ cs->sc_dkdev.dk_cpulabel);
+ }
+
+ cs->sc_flags &= ~CCDF_LABELLING;
+ break;
+ }
+
+ case DIOCKLABEL:
+ if (*(int *)data != 0)
+ cs->sc_flags |= CCDF_KLABEL;
+ else
+ cs->sc_flags &= ~CCDF_KLABEL;
+ break;
+
+ case DIOCWLABEL:
+ if (*(int *)data != 0)
+ cs->sc_flags |= CCDF_WLABEL;
+ else
+ cs->sc_flags &= ~CCDF_WLABEL;
+ break;
+
+ case DIOCGDEFLABEL:
+ ccdgetdefaultlabel(cs, (struct disklabel *)data);
+ break;
+
+#ifdef __HAVE_OLD_DISKLABEL
+ case ODIOCGDEFLABEL:
+ ccdgetdefaultlabel(cs, &newlabel);
+ if (newlabel.d_npartitions > OLDMAXPARTITIONS)
+ return ENOTTY;
+ memcpy(data, &newlabel, sizeof (struct olddisklabel));
+ break;
+#endif
+ default:
+ error = ENOTTY;
+ break;
+ }
+
+ if (error != ENOTTY)
+ return error;
+
+ mutex_enter(&cs->sc_dvlock);
error = 0;
switch (cmd) {
@@ -1233,6 +1323,12 @@
sizeof(*vpp));
kmem_free(cpp, ccio->ccio_ndisks *
sizeof(*cpp));
+
+ /*
+ * No component data is allocated,
+ * nothing is to be freed.
+ */
+ cs->sc_nccdisks = 0;
goto out;
}
++lookedup;
@@ -1332,43 +1428,31 @@
cs->sc_cinfo[i].ci_pathlen);
}
- /* Free interleave index. */
- for (i = 0; cs->sc_itable[i].ii_ndisk; ++i) {
- kmem_free(cs->sc_itable[i].ii_index,
- cs->sc_itable[i].ii_indexsz);
+ if (cs->sc_nccdisks != 0) {
+ /* Free interleave index. */
+ for (i = 0; cs->sc_itable[i].ii_ndisk; ++i) {
+ kmem_free(cs->sc_itable[i].ii_index,
+ cs->sc_itable[i].ii_indexsz);
+ }
+ /* Free component info and interleave table. */
+ kmem_free(cs->sc_cinfo, cs->sc_nccdisks *
+ sizeof(struct ccdcinfo));
+ kmem_free(cs->sc_itable, (cs->sc_nccdisks + 1) *
+ sizeof(struct ccdiinfo));
}
- /* Free component info and interleave table. */
- kmem_free(cs->sc_cinfo, cs->sc_nccdisks *
- sizeof(struct ccdcinfo));
- kmem_free(cs->sc_itable, (cs->sc_nccdisks + 1) *
- sizeof(struct ccdiinfo));
-
aprint_normal("%s: detached\n", cs->sc_xname);
/* Detach the disk. */
disk_detach(&cs->sc_dkdev);
bufq_free(cs->sc_bufq);
+
+ /* also releases dv_lock */
ccdput(cs);
+
/* Don't break, otherwise cs is read again. */
return 0;
- case DIOCGSTRATEGY:
- {
- struct disk_strategy *dks = (void *)data;
-
- mutex_enter(cs->sc_iolock);
- if (cs->sc_bufq != NULL)
- strlcpy(dks->dks_name,
- bufq_getstrategyname(cs->sc_bufq),
- sizeof(dks->dks_name));
- else
- error = EINVAL;
- mutex_exit(cs->sc_iolock);
- dks->dks_paramlen = 0;
- break;
- }
-
case DIOCGCACHE:
{
int dkcache = 0;
@@ -1410,73 +1494,11 @@
}
break;
- case DIOCWDINFO:
- case DIOCSDINFO:
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCWDINFO:
- case ODIOCSDINFO:
-#endif
- {
- struct disklabel *lp;
-#ifdef __HAVE_OLD_DISKLABEL
- if (cmd == ODIOCSDINFO || cmd == ODIOCWDINFO) {
- memset(&newlabel, 0, sizeof newlabel);
- memcpy(&newlabel, data, sizeof (struct olddisklabel));
- lp = &newlabel;
- } else
-#endif
- lp = (struct disklabel *)data;
-
- cs->sc_flags |= CCDF_LABELLING;
-
- error = setdisklabel(cs->sc_dkdev.dk_label,
- lp, 0, cs->sc_dkdev.dk_cpulabel);
- if (error == 0) {
- if (cmd == DIOCWDINFO
-#ifdef __HAVE_OLD_DISKLABEL
- || cmd == ODIOCWDINFO
-#endif
- )
- error = writedisklabel(CCDLABELDEV(dev),
- ccdstrategy, cs->sc_dkdev.dk_label,
- cs->sc_dkdev.dk_cpulabel);
- }
-
- cs->sc_flags &= ~CCDF_LABELLING;
+default:
+ error = ENOTTY;
break;
}
- case DIOCKLABEL:
- if (*(int *)data != 0)
- cs->sc_flags |= CCDF_KLABEL;
- else
- cs->sc_flags &= ~CCDF_KLABEL;
- break;
-
- case DIOCWLABEL:
- if (*(int *)data != 0)
- cs->sc_flags |= CCDF_WLABEL;
- else
- cs->sc_flags &= ~CCDF_WLABEL;
- break;
-
- case DIOCGDEFLABEL:
- ccdgetdefaultlabel(cs, (struct disklabel *)data);
- break;
-
-#ifdef __HAVE_OLD_DISKLABEL
- case ODIOCGDEFLABEL:
- ccdgetdefaultlabel(cs, &newlabel);
- if (newlabel.d_npartitions > OLDMAXPARTITIONS)
- return ENOTTY;
- memcpy(data, &newlabel, sizeof (struct olddisklabel));
- break;
-#endif
-
- default:
- error = ENOTTY;
- }
-
Home |
Main Index |
Thread Index |
Old Index