Skip site navigation (1)Skip section navigation (2)
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-hackers" 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>