Date: Fri, 27 Oct 2000 12:30:36 -0700 (PDT) From: Matt Dillon <dillon@earth.backplane.com> To: John Baldwin <jhb@FreeBSD.ORG> Cc: hackers@FreeBSD.ORG, freebsd-stable@FreeBSD.ORG, Danny Braniss <danny@cs.huji.ac.il>, Paul Saab <paul@mu.org> Subject: Proposed patch to fix disklabel for slices. (was re: BTX halted...) Message-ID: <200010271930.e9RJUad07211@earth.backplane.com>
next in thread | raw e-mail | index | archive | help
Here is my proposal and a patch.
The patch adds a new iodctl, called DIOCGDVIRGIN. This ioctl
returns a 'virgin disklabel' for a disk or slice.
The other part of the patch is to modify the 'disklabel' program
to use the new ioctl (and to fallback to what it was doing before:
DIOCGINFO if the new ioctl fails).
With this patch you can now use 'fdisk -I da0' to create a real
dos partition, and then use 'disklabel -w -r da0s1 auto' to label it.
Without the patch it is not possible to disklabel a slice without
writing a separate program to do it (as mentioned by others in this
thread).
I am testing it now, but I believe it to be very close to correct
if not completely correct. I would appreciate comment and testing by
others and some input from Jordan in regards to possibly getting it into
the release.
-Matt
Index: sbin/disklabel/disklabel.c
===================================================================
RCS file: /home/ncvs/src/sbin/disklabel/disklabel.c,v
retrieving revision 1.28.2.3
diff -u -r1.28.2.3 disklabel.c
--- sbin/disklabel/disklabel.c 2000/07/01 06:47:46 1.28.2.3
+++ sbin/disklabel/disklabel.c 2000/10/27 19:24:00
@@ -1347,10 +1347,17 @@
warn("cannot open %s", namebuf);
return (NULL);
}
- if (ioctl(f, DIOCGDINFO, &lab) < 0) {
- warn("ioctl DIOCGDINFO");
- close(f);
- return (NULL);
+
+ /*
+ * Try to use the new get-virgin-label ioctl. If it fails,
+ * fallback to the old get-disdk-info ioctl.
+ */
+ if (ioctl(f, DIOCGDVIRGIN, &lab) < 0) {
+ if (ioctl(f, DIOCGDINFO, &lab) < 0) {
+ warn("ioctl DIOCGDINFO");
+ close(f);
+ return (NULL);
+ }
}
close(f);
lab.d_boot0 = NULL;
Index: sys/kern/kern_descrip.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v
retrieving revision 1.81.2.4
diff -u -r1.81.2.4 kern_descrip.c
--- sys/kern/kern_descrip.c 2000/10/24 19:28:26 1.81.2.4
+++ sys/kern/kern_descrip.c 2000/10/26 04:04:25
@@ -125,6 +125,9 @@
/*
* Duplicate a file descriptor to a particular value.
+ *
+ * note: keep in mind that a potential race condition exists when closing
+ * descriptors from a shared descriptor table (via rfork).
*/
#ifndef _SYS_SYSPROTO_H_
struct dup2_args {
@@ -145,8 +148,9 @@
if (old >= fdp->fd_nfiles ||
fdp->fd_ofiles[old] == NULL ||
new >= p->p_rlimit[RLIMIT_NOFILE].rlim_cur ||
- new >= maxfilesperproc)
+ new >= maxfilesperproc) {
return (EBADF);
+ }
if (old == new) {
p->p_retval[0] = new;
return (0);
@@ -157,12 +161,15 @@
if (new != i)
panic("dup2: fdalloc");
} else if (fdp->fd_ofiles[new]) {
+ struct file *fp = fdp->fd_ofiles[new];
+
if (fdp->fd_ofileflags[new] & UF_MAPPED)
(void) munmapfd(p, new);
/*
* dup2() must succeed even if the close has an error.
*/
- (void) closef(fdp->fd_ofiles[new], p);
+ fdp->fd_ofiles[new] = NULL;
+ (void) closef(fp, p);
}
return (finishdup(fdp, (int)old, (int)new, p->p_retval));
}
Index: sys/kern/subr_diskslice.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/subr_diskslice.c,v
retrieving revision 1.82
diff -u -r1.82 subr_diskslice.c
--- sys/kern/subr_diskslice.c 2000/01/28 11:51:08 1.82
+++ sys/kern/subr_diskslice.c 2000/10/27 19:23:28
@@ -366,12 +366,46 @@
int slice;
struct diskslice *sp;
struct diskslices *ssp;
+ struct partition *pp;
slice = dkslice(dev);
ssp = *sspp;
sp = &ssp->dss_slices[slice];
lp = sp->ds_label;
switch (cmd) {
+
+ case DIOCGDVIRGIN:
+ lp = (struct disklabel *)data;
+ if (ssp->dss_slices[WHOLE_DISK_SLICE].ds_label) {
+ *lp = *ssp->dss_slices[WHOLE_DISK_SLICE].ds_label;
+ } else {
+ bzero(lp, sizeof(struct disklabel));
+ }
+
+ lp->d_magic = DISKMAGIC;
+ lp->d_magic2 = DISKMAGIC;
+ pp = &lp->d_partitions[RAW_PART];
+ pp->p_offset = 0;
+ pp->p_size = sp->ds_size;
+
+ lp->d_npartitions = MAXPARTITIONS;
+ if (lp->d_interleave == 0)
+ lp->d_interleave = 1;
+ if (lp->d_rpm == 0)
+ lp->d_rpm = 3600;
+ if (lp->d_nsectors == 0)
+ lp->d_nsectors = 32;
+ if (lp->d_ntracks == 0)
+ lp->d_ntracks = 64;
+
+ lp->d_bbsize = BBSIZE;
+ lp->d_sbsize = SBSIZE;
+ lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
+ lp->d_ncylinders = sp->ds_size / lp->d_secpercyl;
+ lp->d_secperunit = sp->ds_size;
+ lp->d_checksum = 0;
+ lp->d_checksum = dkcksum(lp);
+ return (0);
case DIOCGDINFO:
if (lp == NULL)
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-stable" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200010271930.e9RJUad07211>
