Return to BSD News archive
Path: sserve!manuel.anu.edu.au!munnari.oz.au!spool.mu.edu!umn.edu!The-Star.honeywell.com!sol.ctr.columbia.edu!caen!uunet!charon.amdahl.com!amdahl!paulp From: paulp@uts.amdahl.com (Paul Popelka) Newsgroups: comp.unix.bsd Subject: [386bsd] patches for pcfs to support hard disk filesystems Message-ID: <6a0K03lubdIH00@amdahl.uts.amdahl.com> Date: 23 Nov 92 17:35:09 GMT Organization: Amdahl Corporation, Sunnyvale CA Lines: 309 Hi, Here are some patches to make pcfs work with dos filesystems on hard disks. Don't use an unpatched pcfs on hard disks. To mount a hard disk dos filesystem: - use disklabel to define a 386bsd partition that covers the area occupied by the dos filesystem. Set this partition's type to MSDOS with disklabel. When you use disklabel in this way it will write a 386bsd bootblock on the first block of the disk. This wipes out the dos partition table. I don't know of a way to prevent it from doing this. So, I just used dd to save a copy of the dos bootblock, and restored it after disklabel was done. - Then, mount the filesystem. Example: mount -t pcfs /dev/sd0b /mnt Don't put a dos filesystem in partition "a" of your hard disk. This will corrupt that dos filesystem. This is because the kernel thinks partition "a" covers the disk label and attempts to write in the area where the label is thought to be are disallowed. Unfortunately the first block of the fat in a hard disk dos filesystem lives in this spot where the label might be. There is a problem with moving directories in pcfs. It does NOT corrupt your filesystem. Here's a description of how to see the problem. Assume there are 3 directories on the filesystem. One called abc and under it is one called def. Under def is one called 123. mount -t pcfs /dev/fd0a /mnt cd /mnt mv abc/def def cd def/123 pwd /mnt/def/123 cd /mnt mv def abc cd abc/def pwd At this pointed the diagnostic "pwd: No such file or directory" will appear. At this point we are(?) in directory /mnt/abc/def. cd .. pwd /mnt So, the cd .. moved us up 2 levels to def's old parent. Once the vnode cache is flushed of the related vnodes this works ok. I'm looking at this problem. Paul --------------------------cut here----------------------------------- *** 0.0/pcfs_fat.c Sun Nov 22 20:14:33 1992 --- pcfs_fat.c Fri Nov 20 20:06:05 1992 *************** *** 204,211 **** if (bn != bp0_bn) { if (bp0) brelse(bp0); ! if (error = bread(pmp->pm_devvp, bn, ! pmp->pm_BytesPerSec, NOCRED, &bp0)) { brelse(bp0); return error; } --- 204,212 ---- if (bn != bp0_bn) { if (bp0) brelse(bp0); ! error = bread(pmp->pm_devvp, bn, ! pmp->pm_BytesPerSec, NOCRED, &bp0); ! if (error) { brelse(bp0); return error; } *************** *** 571,577 **** whichbyte)); } if (function & FAT_SET) { ! *(u_short *)(bp0->b_un.b_addr+whichbyte) = newcontents; updateotherfats(pmp, bp0, 0, whichblk); if (pmp->pm_waitonfat) bwrite(bp0); /* write out blk from the 1st fat */ --- 572,578 ---- whichbyte)); } if (function & FAT_SET) { ! *((u_short *)(bp0->b_un.b_addr+whichbyte)) = newcontents; updateotherfats(pmp, bp0, 0, whichblk); if (pmp->pm_waitonfat) bwrite(bp0); /* write out blk from the 1st fat */ *** 0.0/pcfs_lookup.c Sun Nov 22 20:14:24 1992 --- pcfs_lookup.c Sat Nov 21 20:49:24 1992 *************** *** 488,494 **** */ if (ndp->ni_pcfs.pcfs_cluster == PCFSROOT) { bn = pmp->pm_rootdirblk + ! (ndp->ni_pcfs.pcfs_offset / pmp->pm_depclust); theoff = ndp->ni_pcfs.pcfs_offset % pmp->pm_depclust; } else { bn = cntobn(pmp, ndp->ni_pcfs.pcfs_cluster); --- 488,495 ---- */ if (ndp->ni_pcfs.pcfs_cluster == PCFSROOT) { bn = pmp->pm_rootdirblk + ! ((ndp->ni_pcfs.pcfs_offset / pmp->pm_depclust) * ! pmp->pm_SectPerClust); theoff = ndp->ni_pcfs.pcfs_offset % pmp->pm_depclust; } else { bn = cntobn(pmp, ndp->ni_pcfs.pcfs_cluster); *************** *** 534,540 **** struct buf *bp; if (dirclust == PCFSROOT) { ! bn = pmp->pm_rootdirblk + (diroffset / pmp->pm_depclust); offset = diroffset % pmp->pm_depclust; } else { bn = cntobn(pmp, dirclust); --- 535,542 ---- struct buf *bp; if (dirclust == PCFSROOT) { ! bn = pmp->pm_rootdirblk + ((diroffset / pmp->pm_depclust) * ! pmp->pm_SectPerClust); offset = diroffset % pmp->pm_depclust; } else { bn = cntobn(pmp, dirclust); *************** *** 753,759 **** if (dep->de_dirclust == PCFSROOT) { bn = pmp->pm_rootdirblk + ! (dep->de_diroffset / pmp->pm_depclust); theoff = dep->de_diroffset % pmp->pm_depclust; } else { bn = cntobn(pmp, dep->de_dirclust); --- 755,762 ---- if (dep->de_dirclust == PCFSROOT) { bn = pmp->pm_rootdirblk + ! ((dep->de_diroffset / pmp->pm_depclust) * ! pmp->pm_SectPerClust); theoff = dep->de_diroffset % pmp->pm_depclust; } else { bn = cntobn(pmp, dep->de_dirclust); *** 0.0/pcfs_vnops.c Wed Nov 18 21:46:28 1992 --- pcfs_vnops.c Sat Nov 21 20:18:45 1992 *************** *** 991,996 **** --- 991,997 ---- * tdep is unlocked and unreferenced */ } else { + unsigned long dirsize; /* * If the source and destination are in different * directories, then mark the entry in the source *************** *** 1000,1009 **** * the filesystem. And, if we moved a directory, * then update its .. entry to point to the new * parent directory. */ DELOCK(fdep); bcopy(toname, fdep->de_Name, 11); /* update denode */ ! if (error = createde(fdep, tndp, (struct denode **)0)) { /* should put back filename */ DEUNLOCK(fdep); goto bad; --- 1001,1021 ---- * the filesystem. And, if we moved a directory, * then update its .. entry to point to the new * parent directory. + * If we moved a directory will also insure that + * the directory entry on disk has a filesize of + * zero. */ DELOCK(fdep); bcopy(toname, fdep->de_Name, 11); /* update denode */ ! if (fdep->de_Attributes & ATTR_DIRECTORY) { ! dirsize = fdep->de_FileSize; ! fdep->de_FileSize = 0; ! } ! error = createde(fdep, tndp, (struct denode **)0); ! if (fdep->de_Attributes & ATTR_DIRECTORY) { ! fdep->de_FileSize = dirsize; ! } ! if (error) { /* should put back filename */ DEUNLOCK(fdep); goto bad; *************** *** 1294,1299 **** --- 1306,1312 ---- { int error = 0; int diff; + char pushout; long n; long on; long lost; *************** *** 1380,1389 **** /* * code to convert from dos directory entries to ufs directory entries */ ! dentp = (struct direntry *)bp->b_un.b_addr + on; prev = 0; crnt = (struct dirent *)dirbuf; ! while ((char *)dentp < bp->b_un.b_addr + n) { /*printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n", dentp, prev, crnt, dentp->deName[0], dentp->deAttributes);*/ /* --- 1393,1403 ---- /* * code to convert from dos directory entries to ufs directory entries */ ! pushout = 0; ! dentp = (struct direntry *)(bp->b_un.b_addr + on); prev = 0; crnt = (struct dirent *)dirbuf; ! while ((char *)dentp < bp->b_un.b_addr + on + n) { /*printf("rd: dentp %08x prev %08x crnt %08x deName %02x attr %02x\n", dentp, prev, crnt, dentp->deName[0], dentp->deAttributes);*/ /* *************** *** 1392,1401 **** * space onto the end of the previous entry or, * manufacture an empty entry if there is no previous * entry. - * If the entry is empty then set a flag saying finish - * out the block but signal an end of file since empty - * slots mean there are no further entries of interest - * in the directory. */ if (dentp->deName[0] == SLOT_EMPTY || dentp->deName[0] == SLOT_DELETED || --- 1406,1411 ---- *************** *** 1432,1437 **** --- 1442,1448 ---- prev = crnt; } crnt = (struct dirent *)((char *)crnt + sizeof(struct direntry)); + pushout = 1; /* * If our intermediate buffer is full then copy *************** *** 1443,1449 **** * the buffer before brelse()'ing it. */ if ((unsigned char *)crnt >= &dirbuf[sizeof dirbuf]) { ! error = uiomove(dirbuf, n, uio); if (error) break; prev = 0; --- 1454,1461 ---- * the buffer before brelse()'ing it. */ if ((unsigned char *)crnt >= &dirbuf[sizeof dirbuf]) { ! pushout = 0; ! error = uiomove(dirbuf, sizeof(dirbuf), uio); if (error) break; prev = 0; *************** *** 1451,1456 **** --- 1463,1473 ---- } dentp++; } + if (pushout) { + pushout = 0; + error = uiomove(dirbuf, (char *)crnt - (char *)dirbuf, + uio); + } /* * If we have read everything from this block or *************** *** 1572,1580 **** * holes, so we shouldn't ever see this. */ if (bp->b_blkno == bp->b_lblkno) { ! if (error = pcbmap(dep, ! bp->b_lblkno << (pmp->pm_cnshift - pmp->pm_bnshift), ! &bp->b_blkno, 0)) return error; if ((long)bp->b_blkno == -1) clrbuf(bp); --- 1589,1595 ---- * holes, so we shouldn't ever see this. */ if (bp->b_blkno == bp->b_lblkno) { ! if (error = pcbmap(dep, bp->b_lblkno, &bp->b_blkno, 0)) return error; if ((long)bp->b_blkno == -1) clrbuf(bp); --------------------------you've got the complete patch---------------------