diff options
author | Marcel Moolenaar <marcel@FreeBSD.org> | 2009-08-19 16:29:20 +0000 |
---|---|---|
committer | Marcel Moolenaar <marcel@FreeBSD.org> | 2009-08-19 16:29:20 +0000 |
commit | eb0ea23e837bc3e3993a7f84efdb868cbb49f93a (patch) | |
tree | df07874e60fb95f9707ba813108286f27b1aa52a /sbin/bsdlabel/bsdlabel.c | |
parent | fcaeaff4b6aad1829edba34184950a3b3a9a403d (diff) | |
download | src-eb0ea23e837bc3e3993a7f84efdb868cbb49f93a.tar.gz src-eb0ea23e837bc3e3993a7f84efdb868cbb49f93a.zip |
Remove the dependency on the kernel -- in particular the gctl request to
the GEOM_BSD class -- to translate the absolute offsets in the label to
relative ones. This makes bslabel(8) work correctly with GEOM_PART and
also when the BSD label is nested under arbitrary partitioning schemes.
Inspired by: Eygene Ryabinkin <rea-fbsd@codelabs.ru>
Approved by: re (kib)
Notes
Notes:
svn path=/head/; revision=196383
Diffstat (limited to 'sbin/bsdlabel/bsdlabel.c')
-rw-r--r-- | sbin/bsdlabel/bsdlabel.c | 41 |
1 files changed, 23 insertions, 18 deletions
diff --git a/sbin/bsdlabel/bsdlabel.c b/sbin/bsdlabel/bsdlabel.c index 1cb99950bbd8..9a6027c7951a 100644 --- a/sbin/bsdlabel/bsdlabel.c +++ b/sbin/bsdlabel/bsdlabel.c @@ -118,7 +118,7 @@ static int installboot; /* non-zero if we should install a boot program */ static int allfields; /* present all fields in edit */ static char const *xxboot; /* primary boot */ -static off_t mbroffset; +static uint32_t lba_offset; #ifndef LABELSECTOR #define LABELSECTOR -1 #endif @@ -403,7 +403,7 @@ writelabel(void) readboot(); for (i = 0; i < lab.d_npartitions; i++) if (lab.d_partitions[i].p_size) - lab.d_partitions[i].p_offset += mbroffset; + lab.d_partitions[i].p_offset += lba_offset; bsd_disklabel_le_enc(bootarea + labeloffset + labelsoffset * secsize, lp); if (alphacksum) { @@ -479,10 +479,9 @@ get_file_parms(int f) static int readlabel(int flag) { + uint32_t lba; int f, i; int error; - struct gctl_req *grq; - char const *errstr; f = open(specname, O_RDONLY); if (f < 0) @@ -510,22 +509,28 @@ readlabel(int flag) if (is_file) return(0); - grq = gctl_get_handle(); - gctl_ro_param(grq, "verb", -1, "read mbroffset"); - gctl_ro_param(grq, "class", -1, "BSD"); - gctl_ro_param(grq, "geom", -1, pname); - gctl_rw_param(grq, "mbroffset", sizeof(mbroffset), &mbroffset); - errstr = gctl_issue(grq); - if (errstr != NULL) { - mbroffset = 0; - gctl_free(grq); - return (error); + + /* + * Compensate for absolute block addressing by finding the + * smallest partition offset and if the offset of the 'c' + * partition is equal to that, subtract it from all offsets. + */ + lba = ~0; + for (i = 0; i < lab.d_npartitions; i++) { + if (lab.d_partitions[i].p_size) + lba = MIN(lba, lab.d_partitions[i].p_offset); } - mbroffset /= lab.d_secsize; - if (lab.d_partitions[RAW_PART].p_offset == mbroffset) - for (i = 0; i < lab.d_npartitions; i++) + if (lba != 0 && lab.d_partitions[RAW_PART].p_offset == lba) { + for (i = 0; i < lab.d_npartitions; i++) { if (lab.d_partitions[i].p_size) - lab.d_partitions[i].p_offset -= mbroffset; + lab.d_partitions[i].p_offset -= lba; + } + /* + * Save the offset so that we can write the label + * back with absolute block addresses. + */ + lba_offset = lba; + } return (error); } |