Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c =================================================================== --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c (wersja 200158) +++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c (kopia robocza) @@ -102,7 +102,7 @@ } static struct g_consumer * -vdev_geom_attach(struct g_provider *pp, int write) +vdev_geom_attach(struct g_provider *pp) { struct g_geom *gp; struct g_consumer *cp; @@ -126,7 +126,7 @@ g_wither_geom(gp, ENXIO); return (NULL); } - if (g_access(cp, 1, write, 1) != 0) { + if (g_access(cp, 1, 0, 1) != 0) { g_wither_geom(gp, ENXIO); return (NULL); } @@ -145,14 +145,14 @@ g_destroy_consumer(cp); return (NULL); } - if (g_access(cp, 1, write, 1) != 0) { + if (g_access(cp, 1, 0, 1) != 0) { g_detach(cp); g_destroy_consumer(cp); return (NULL); } ZFS_LOG(1, "Created consumer for %s.", pp->name); } else { - if (g_access(cp, 1, cp->acw > 0 ? 0 : write, 1) != 0) + if (g_access(cp, 1, 0, 1) != 0) return (NULL); ZFS_LOG(1, "Used existing consumer for %s.", pp->name); } @@ -342,7 +342,6 @@ struct vdev_geom_find { uint64_t guid; - int write; struct g_consumer *cp; }; @@ -394,10 +393,10 @@ g_detach(zcp); if (guid != ap->guid) continue; - ap->cp = vdev_geom_attach(pp, ap->write); + ap->cp = vdev_geom_attach(pp); if (ap->cp == NULL) { - printf("ZFS WARNING: Cannot open %s " - "for writting.\n", pp->name); + printf("ZFS WARNING: Unable to attach to %s.", + pp->name); continue; } goto end; @@ -411,14 +410,13 @@ } static struct g_consumer * -vdev_geom_attach_by_guid(uint64_t guid, int write) +vdev_geom_attach_by_guid(uint64_t guid) { struct vdev_geom_find *ap; struct g_consumer *cp; ap = kmem_zalloc(sizeof(*ap), KM_SLEEP); ap->guid = guid; - ap->write = write; g_waitfor_event(vdev_geom_attach_by_guid_event, ap, M_WAITOK, NULL); cp = ap->cp; kmem_free(ap, sizeof(*ap)); @@ -433,7 +431,7 @@ size_t len; ZFS_LOG(1, "Searching by guid [%ju].", (uintmax_t)vd->vdev_guid); - cp = vdev_geom_attach_by_guid(vd->vdev_guid, !!(spa_mode & FWRITE)); + cp = vdev_geom_attach_by_guid(vd->vdev_guid); if (cp != NULL) { len = strlen(cp->provider->name) + strlen("/dev/") + 1; buf = kmem_alloc(len, KM_SLEEP); @@ -464,7 +462,7 @@ pp = g_provider_by_name(vd->vdev_path + sizeof("/dev/") - 1); if (pp != NULL) { ZFS_LOG(1, "Found provider by name %s.", vd->vdev_path); - cp = vdev_geom_attach(pp, !!(spa_mode & FWRITE)); + cp = vdev_geom_attach(pp); if (cp != NULL && check_guid) { g_topology_unlock(); guid = vdev_geom_read_guid(cp); @@ -492,7 +490,7 @@ vdev_geom_ctx_t *ctx; struct g_provider *pp; struct g_consumer *cp; - int owned; + int error, owned; /* * We must have a pathname, and it must be absolute. @@ -506,6 +504,7 @@ if ((owned = mtx_owned(&Giant))) mtx_unlock(&Giant); + error = 0; cp = vdev_geom_open_by_path(vd, 1); if (cp == NULL) { /* @@ -519,13 +518,24 @@ cp = vdev_geom_open_by_path(vd, 0); if (cp == NULL) { ZFS_LOG(1, "Provider %s not found.", vd->vdev_path); - vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; - if (owned) - mtx_lock(&Giant); - return (EACCES); + error = ENOENT; + } else if (cp->acw == 0 && (spa_mode & FWRITE) != 0) { + g_topology_lock(); + error = g_access(cp, 0, 1, 0); + if (error != 0) { + printf("ZFS WARNING: Unable to open %s for writing (error=%d).", + vd->vdev_path, error); + vdev_geom_detach(cp, 0); + cp = NULL; + } + g_topology_unlock(); } if (owned) mtx_lock(&Giant); + if (cp == NULL) { + vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; + return (error); + } cp->private = vd;