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>