summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormav <mav@FreeBSD.org>2013-08-13 07:56:40 +0000
committermav <mav@FreeBSD.org>2013-08-13 07:56:40 +0000
commiteba4a485b224ae259700b960fe63abf2463a33aa (patch)
tree21db4ff3b5ea40848ed69e4ff8547e8266d7123c /sys/geom
parent9b26a416432eed29bc60e0a89a4db1554a89142a (diff)
downloadFreeBSD-src-eba4a485b224ae259700b960fe63abf2463a33aa.zip
FreeBSD-src-eba4a485b224ae259700b960fe63abf2463a33aa.tar.gz
Return error when opening read-only volumes (like RAID4/5/...) for writing.
Previously opens succeeded, but actual write operations returned errors. Requested by: peter MFC after: 2 weeks
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/raid/g_raid.c5
-rw-r--r--sys/geom/raid/g_raid.h1
-rw-r--r--sys/geom/raid/tr_raid5.c3
3 files changed, 8 insertions, 1 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c
index fd6d69c..41a1f96 100644
--- a/sys/geom/raid/g_raid.c
+++ b/sys/geom/raid/g_raid.c
@@ -1863,6 +1863,11 @@ g_raid_access(struct g_provider *pp, int acr, int acw, int ace)
error = ENXIO;
goto out;
}
+ /* Deny write opens for read-only volumes. */
+ if (vol->v_read_only && acw > 0) {
+ error = EROFS;
+ goto out;
+ }
if (dcw == 0)
g_raid_clean(vol, dcw);
vol->v_provider_open += acr + acw + ace;
diff --git a/sys/geom/raid/g_raid.h b/sys/geom/raid/g_raid.h
index 183edff6..993b100 100644
--- a/sys/geom/raid/g_raid.h
+++ b/sys/geom/raid/g_raid.h
@@ -306,6 +306,7 @@ struct g_raid_volume {
int v_stopping; /* Volume is stopping */
int v_provider_open; /* Number of opens. */
int v_global_id; /* Global volume ID (rX). */
+ int v_read_only; /* Volume is read-only. */
TAILQ_ENTRY(g_raid_volume) v_next; /* List of volumes entry. */
LIST_ENTRY(g_raid_volume) v_global_next; /* Global list entry. */
};
diff --git a/sys/geom/raid/tr_raid5.c b/sys/geom/raid/tr_raid5.c
index 989343b..6e54d16 100644
--- a/sys/geom/raid/tr_raid5.c
+++ b/sys/geom/raid/tr_raid5.c
@@ -185,8 +185,9 @@ g_raid_tr_start_raid5(struct g_raid_tr_object *tr)
struct g_raid_volume *vol;
trs = (struct g_raid_tr_raid5_object *)tr;
- vol = tr->tro_volume;
trs->trso_starting = 0;
+ vol = tr->tro_volume;
+ vol->v_read_only = 1;
g_raid_tr_update_state_raid5(vol, NULL);
return (0);
}
OpenPOWER on IntegriCloud