summaryrefslogtreecommitdiffstats
path: root/sys/kern/subr_diskslice.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/kern/subr_diskslice.c')
-rw-r--r--sys/kern/subr_diskslice.c53
1 files changed, 45 insertions, 8 deletions
diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c
index 0362851..0b6bf03 100644
--- a/sys/kern/subr_diskslice.c
+++ b/sys/kern/subr_diskslice.c
@@ -43,7 +43,7 @@
* from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $
* from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91
* from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
- * $Id: subr_diskslice.c,v 1.10 1995/04/24 17:06:59 bde Exp $
+ * $Id: subr_diskslice.c,v 1.11 1995/04/30 15:16:02 bde Exp $
*/
#include <sys/param.h>
@@ -385,20 +385,28 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
*sspp = NULL;
lp = malloc(sizeof *lp, M_DEVBUF, M_WAITOK);
*lp = *ssp->dss_slices[WHOLE_DISK_SLICE].ds_label;
- error = dsopen(dname, dev, S_IFCHR, sspp, lp, strat, setgeom);
+ error = dsopen(dname, dev,
+ ssp->dss_slices[WHOLE_DISK_SLICE].ds_copenmask
+ & (1 << RAW_PART) ? S_IFCHR : S_IFBLK,
+ sspp, lp, strat, setgeom);
if (error != 0) {
free(lp, M_DEVBUF);
*sspp = ssp;
return (error);
}
+ /*
+ * Reopen everything. This is a no-op except in the "force"
+ * case and when the raw bdev and cdev are both open. Abort
+ * if anything fails.
+ */
for (slice = 0; slice < ssp->dss_nslices; slice++) {
u_char openmask;
int part;
- openmask = ssp->dss_slices[slice].ds_bopenmask;
- for (part = 0; part < ssp->dss_nslices; part++) {
- if (!(openmask & (1 << part)))
+ for (openmask = ssp->dss_slices[slice].ds_bopenmask,
+ part = 0; openmask; openmask >>= 1, part++) {
+ if (!(openmask & 1))
continue;
error = dsopen(dname,
dkmodslice(dkmodpart(dev, part),
@@ -411,9 +419,9 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
return (EBUSY);
}
}
- openmask = ssp->dss_slices[slice].ds_copenmask;
- for (part = 0; part < ssp->dss_nslices; part++) {
- if (!(openmask & (1 << part)))
+ for (openmask = ssp->dss_slices[slice].ds_copenmask,
+ part = 0; openmask; openmask >>= 1, part++) {
+ if (!(openmask & 1))
continue;
error = dsopen(dname,
dkmodslice(dkmodpart(dev, part),
@@ -427,6 +435,7 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom)
}
}
}
+
free(lp, M_DEVBUF);
dsgone(&ssp);
return (0);
@@ -678,6 +687,34 @@ out:
return (0);
}
+int
+dssize(dev, sspp, dopen, dclose)
+ dev_t dev;
+ struct diskslices **sspp;
+ d_open_t dopen;
+ d_close_t dclose;
+{
+ struct disklabel *lp;
+ int part;
+ int slice;
+ struct diskslices *ssp;
+
+ slice = dkslice(dev);
+ part = dkpart(dev);
+ ssp = *sspp;
+ if (ssp == NULL || slice >= ssp->dss_nslices
+ || !(ssp->dss_slices[slice].ds_bopenmask & (1 << part))) {
+ if (dopen(dev, FREAD, S_IFBLK, (struct proc *)NULL) != 0)
+ return (-1);
+ dclose(dev, FREAD, S_IFBLK, (struct proc *)NULL);
+ ssp = *sspp;
+ }
+ lp = ssp->dss_slices[slice].ds_label;
+ if (lp == NULL)
+ return (-1);
+ return ((int)lp->d_partitions[part].p_size);
+}
+
static char *
fixlabel(sname, sp, lp, writeflag)
char *sname;
OpenPOWER on IntegriCloud