Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/dkwedge Handle read-only parent devices.
details: https://anonhg.NetBSD.org/src/rev/6141cf208d50
branches: trunk
changeset: 379238:6141cf208d50
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sat May 22 13:43:50 2021 +0000
description:
Handle read-only parent devices.
Currently this only affects xbd(4). Other disk drivers succeed opening
read-only disks as read-write and only fail subsequent write requests.
diffstat:
sys/dev/dkwedge/dk.c | 25 +++++++++++++++++++++----
1 files changed, 21 insertions(+), 4 deletions(-)
diffs (72 lines):
diff -r 1138b827d350 -r 6141cf208d50 sys/dev/dkwedge/dk.c
--- a/sys/dev/dkwedge/dk.c Sat May 22 01:24:27 2021 +0000
+++ b/sys/dev/dkwedge/dk.c Sat May 22 13:43:50 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dk.c,v 1.102 2020/10/06 15:05:54 mlelstv Exp $ */
+/* $NetBSD: dk.c,v 1.103 2021/05/22 13:43:50 mlelstv Exp $ */
/*-
* Copyright (c) 2004, 2005, 2006, 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.102 2020/10/06 15:05:54 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: dk.c,v 1.103 2021/05/22 13:43:50 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "opt_dkwedge.h"
@@ -90,6 +90,7 @@ struct dkwedge_softc {
kcondvar_t sc_dkdrn;
u_int sc_iopend; /* I/Os pending */
int sc_flags; /* flags (sc_iolock) */
+ int sc_mode; /* parent open mode */
};
#define DK_F_WAIT_DRAIN 0x0001 /* waiting for I/O to drain */
@@ -1138,6 +1139,7 @@ dkopen(dev_t dev, int flags, int fmt, st
struct dkwedge_softc *sc = dkwedge_lookup(dev);
struct vnode *vp;
int error = 0;
+ int mode;
if (sc == NULL)
return (ENODEV);
@@ -1155,12 +1157,27 @@ dkopen(dev_t dev, int flags, int fmt, st
if (sc->sc_dk.dk_openmask == 0) {
if (sc->sc_parent->dk_rawopens == 0) {
KASSERT(sc->sc_parent->dk_rawvp == NULL);
- error = dk_open_parent(sc->sc_pdev, FREAD | FWRITE, &vp);
+ /*
+ * Try open read-write. If this fails for EROFS
+ * and wedge is read-only, retry to open read-only.
+ */
+ mode = FREAD | FWRITE;
+ error = dk_open_parent(sc->sc_pdev, mode, &vp);
+ if (error == EROFS && (flags & FWRITE) == 0) {
+ mode &= ~FWRITE;
+ error = dk_open_parent(sc->sc_pdev, mode, &vp);
+ }
if (error)
goto popen_fail;
+ /* remember open mode */
+ sc->sc_mode = mode;
sc->sc_parent->dk_rawvp = vp;
}
sc->sc_parent->dk_rawopens++;
+ } else if (flags & ~sc->sc_mode & FWRITE) {
+ /* parent is opened read-only, cannot open read-write */
+ error = EROFS;
+ goto popen_fail;
}
if (fmt == S_IFCHR)
sc->sc_dk.dk_copenmask |= 1;
@@ -1197,7 +1214,7 @@ dklastclose(struct dkwedge_softc *sc)
mutex_exit(&sc->sc_dk.dk_openlock);
if (vp) {
- dk_close_parent(vp, FREAD | FWRITE);
+ dk_close_parent(vp, sc->sc_mode);
}
return error;
Home |
Main Index |
Thread Index |
Old Index