From a0e658617d4c374470a802deee325d66134cf714 Mon Sep 17 00:00:00 2001 From: mhitch Date: Fri, 5 Apr 1996 05:06:07 +0000 Subject: [PATCH] Add support for OFS, International FileSystems, and blocksizes > 512. Corrrect floppy rootblock calculation. Validate filesystem type. (Closes PR 2232) Filename hashing requires unsigned characters. (Closes PR 1026) Soft link path is null-terminated string, not BSTR. Use actual file header block info for hard links. Set nlink to 2 for hard linked files in adosfs_getattr(). Load allocation bitmap and set correct free space. --- sys/adosfs/adlookup.c | 9 +- sys/adosfs/adosfs.h | 34 +++++-- sys/adosfs/adutil.c | 39 ++++---- sys/adosfs/advfsops.c | 210 ++++++++++++++++++++++++++++++++++-------- sys/adosfs/advnops.c | 57 ++++++++---- 5 files changed, 266 insertions(+), 83 deletions(-) diff --git a/sys/adosfs/adlookup.c b/sys/adosfs/adlookup.c index 5ffb37550518..033a79247328 100644 --- a/sys/adosfs/adlookup.c +++ b/sys/adosfs/adlookup.c @@ -1,7 +1,8 @@ -/* $NetBSD: adlookup.c,v 1.12 1996/02/13 17:05:47 christos Exp $ */ +/* $NetBSD: adlookup.c,v 1.13 1996/04/05 05:06:07 mhitch Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps + * Copyright (c) 1996 Matthias Scheler * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -74,7 +75,7 @@ adosfs_lookup(v) struct anode *adp; /* anode of search dir */ struct ucred *ucp; /* lookup credentials */ u_long bn, plen, hval; - char *pelt; + u_char *pelt; #ifdef ADOSFS_DIAGNOSTIC advopprint(sp); @@ -90,7 +91,7 @@ adosfs_lookup(v) last = flags & ISLASTCN; lockp = flags & LOCKPARENT; wantp = flags & (LOCKPARENT | WANTPARENT); - pelt = cnp->cn_nameptr; + pelt = (u_char *)cnp->cn_nameptr; plen = cnp->cn_namelen; nocache = 0; @@ -185,7 +186,7 @@ adosfs_lookup(v) * then walk the chain. if chain has not been fully * walked before, track the count in `tabi' */ - hval = adoshash(pelt, plen, adp->ntabent); + hval = adoshash(pelt, plen, adp->ntabent, IS_INTER(adp->amp)); bn = adp->tab[hval]; i = min(adp->tabi[hval], 0); while (bn != 0) { diff --git a/sys/adosfs/adosfs.h b/sys/adosfs/adosfs.h index d92510fd2d54..553b8ad4349d 100644 --- a/sys/adosfs/adosfs.h +++ b/sys/adosfs/adosfs.h @@ -1,7 +1,8 @@ -/* $NetBSD: adosfs.h,v 1.9 1996/02/09 19:06:39 christos Exp $ */ +/* $NetBSD: adosfs.h,v 1.10 1996/04/05 05:06:08 mhitch Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps + * Copyright (c) 1996 Matthias Scheler * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -77,10 +78,10 @@ struct anode { int flags; /* misc flags */ char *slinkto; /* name of file or dir */ }; -#define VTOA(vp) ((struct anode *)(vp)->v_data) -#define ATOV(ap) ((ap)->vp) -#define ANODETABSZ(ap) (((ap)->nwords - 56) * sizeof(long)) -#define ANODETABENT(ap) ((ap)->nwords - 56) +#define VTOA(vp) ((struct anode *)(vp)->v_data) +#define ATOV(ap) ((ap)->vp) +#define ANODETABSZ(ap) (((ap)->nwords - 56) * sizeof(long)) +#define ANODETABENT(ap) ((ap)->nwords - 56) #define ANODENDATBLKENT(ap) ((ap)->nwords - 56) /* @@ -91,24 +92,34 @@ struct anode { struct adosfsmount { LIST_HEAD(anodechain, anode) anodetab[ANODEHASHSZ]; struct mount *mp; /* owner mount */ + u_long dostype; /* type of volume */ u_long rootb; /* root block number */ - u_long startb; /* start block */ - u_long endb; /* one block past last */ + u_long secsperblk; /* sectors per block */ u_long bsize; /* size of blocks */ u_long nwords; /* size of blocks in long words */ + u_long dbsize; /* data bytes per block */ uid_t uid; /* uid of mounting user */ gid_t gid; /* gid of mounting user */ u_long mask; /* mode mask */ struct vnode *devvp; /* blk device mounted on */ struct vnode *rootvp; /* out root vnode */ struct netexport export; + u_long *bitmap; /* allocation bitmap */ + u_long numblks; /* number of usable blocks */ + u_long freeblks; /* number of free blocks */ }; #define VFSTOADOSFS(mp) ((struct adosfsmount *)(mp)->mnt_data) +#define IS_FFS(amp) ((amp)->dostype & 1) +#define IS_INTER(amp) (((amp)->dostype & 7) > 1) + /* * AmigaDOS block stuff. */ +#define BBOFF (0) + #define BPT_SHORT (2) +#define BPT_DATA (8) #define BPT_LIST (16) #define BST_RDIR (1) @@ -118,12 +129,19 @@ struct adosfsmount { #define BST_FILE (-3L) #define BST_LFILE (-4L) +#define OFS_DATA_OFFSET (24) + /* * utility protos */ +#ifndef m68k long adoswordn __P((struct buf *, int)); +#else +#define adoswordn(bp,wn) (*((long *)(bp)->b_data + (wn))) +#endif + long adoscksum __P((struct buf *, long)); -int adoshash __P((const char *, int, int)); +int adoshash __P((const u_char *, int, int, int)); int adunixprot __P((int)); int adosfs_getblktype __P((struct adosfsmount *, struct buf *)); diff --git a/sys/adosfs/adutil.c b/sys/adosfs/adutil.c index 07434e322512..33757c6823c1 100644 --- a/sys/adosfs/adutil.c +++ b/sys/adosfs/adutil.c @@ -1,7 +1,8 @@ -/* $NetBSD: adutil.c,v 1.8 1996/02/09 19:06:41 christos Exp $ */ +/* $NetBSD: adutil.c,v 1.9 1996/04/05 05:06:10 mhitch Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps + * Copyright (c) 1996 Matthias Scheler * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +45,7 @@ * look for anode in the mount's hash table, return locked. */ #define AHASH(an) ((an) & (ANODEHASHSZ - 1)) -static int toupper __P((int)); +static int CapitalChar __P((int, int)); struct vnode * adosfs_ahashget(mp, an) @@ -98,7 +99,8 @@ adosfs_getblktype(amp, bp) { if (adoscksum(bp, amp->nwords)) { #ifdef DIAGNOSTIC - printf("adosfs: aget: cksum of blk %d failed\n", bp->b_blkno); + printf("adosfs: aget: cksum of blk %d failed\n", + bp->b_blkno / amp->secsperblk); #endif return (-1); } @@ -108,7 +110,8 @@ adosfs_getblktype(amp, bp) */ if (adoswordn(bp, 0) != BPT_SHORT) { #ifdef DIAGNOSTIC - printf("adosfs: aget: bad primary type blk %d\n", bp->b_blkno); + printf("adosfs: aget: bad primary type blk %d\n", + bp->b_blkno / amp->secsperblk); #endif return (-1); } @@ -135,22 +138,24 @@ adunixprot(adprot) int adprot; { if (adprot & 0xc000ee00) { - adprot = ((adprot & 0xee00) | (~adprot & 0x000e)) >> 1; - return (((adprot & 0x7) << 6) | ((adprot & 0x700) >> 5) | - (adprot >> 12)); + adprot = (adprot & 0xee0e) >> 1; + return (((adprot & 0x7) << 6) | + ((adprot & 0x700) >> 5) | + ((adprot & 0x7000) >> 12)); } else { - adprot = (~adprot >> 1) & 0x7; + adprot = (adprot >> 1) & 0x7; return((adprot << 6) | (adprot << 3) | adprot); } } static int -toupper(ch) - int ch; +CapitalChar(ch, inter) + int ch, inter; { - if (ch >= 'a' && ch <= 'z') - return(ch & ~(0x20)); + if ((ch >= 'a' && ch <= 'z') || + (inter && ch >= 0xe0 && ch <= 0xfe && ch != 0xf7)) + return(ch - ('a' - 'A')); return(ch); } @@ -170,15 +175,15 @@ adoscksum(bp, n) } int -adoshash(nam, namlen, nelt) - const char *nam; - int namlen, nelt; +adoshash(nam, namlen, nelt, inter) + const u_char *nam; + int namlen, nelt, inter; { int val; val = namlen; while (namlen--) - val = ((val * 13) + toupper(*nam++)) & 0x7ff; + val = ((val * 13) + CapitalChar(*nam++, inter)) & 0x7ff; return(val % nelt); } @@ -204,6 +209,7 @@ tvtods(tvp, dsp) } #endif +#ifndef m68k long adoswordn(bp, wn) struct buf *bp; @@ -214,3 +220,4 @@ adoswordn(bp, wn) */ return(ntohl(*((long *)bp->b_data + wn))); } +#endif diff --git a/sys/adosfs/advfsops.c b/sys/adosfs/advfsops.c index d551b1e4f87a..6a27e3da62b3 100644 --- a/sys/adosfs/advfsops.c +++ b/sys/adosfs/advfsops.c @@ -1,7 +1,8 @@ -/* $NetBSD: advfsops.c,v 1.16 1996/02/09 19:06:42 christos Exp $ */ +/* $NetBSD: advfsops.c,v 1.17 1996/04/05 05:06:12 mhitch Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps + * Copyright (c) 1996 Matthias Scheler * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -60,6 +61,7 @@ int adosfs_fhtovp __P((struct mount *, struct fid *, struct mbuf *, int adosfs_vptofh __P((struct vnode *, struct fid *)); int adosfs_mountfs __P((struct vnode *, struct mount *, struct proc *)); +int adosfs_loadbitmap __P((struct adosfsmount *)); int adosfs_mount(mp, path, data, ndp, p) @@ -154,6 +156,7 @@ adosfs_mountfs(devvp, mp, p) struct disklabel dl; struct partition *parp; struct adosfsmount *amp; + struct buf *bp; struct vnode *rvp; int error, part, i; @@ -186,13 +189,33 @@ adosfs_mountfs(devvp, mp, p) amp = malloc(sizeof(struct adosfsmount), M_ADOSFSMNT, M_WAITOK); bzero((char *)amp, (u_long)sizeof(struct adosfsmount)); amp->mp = mp; - amp->startb = parp->p_offset; - amp->endb = parp->p_offset + parp->p_size; - amp->bsize = dl.d_secsize; + if (dl.d_type == DTYPE_FLOPPY) { + amp->bsize = dl.d_secsize; + amp->secsperblk = 1; + } + else { + amp->bsize = parp->p_fsize * parp->p_frag; + amp->secsperblk = parp->p_frag; + } + amp->rootb = (parp->p_size / amp->secsperblk - 1 + parp->p_cpg) >> 1; + amp->numblks = parp->p_size / amp->secsperblk - parp->p_cpg; + + bp = NULL; + if ((error = bread(devvp, (daddr_t)BBOFF, + amp->bsize, NOCRED, &bp)) != 0) + goto fail; + + amp->dostype = adoswordn(bp, 0); + brelse(bp); + + if (amp->dostype < 0x444f5300 || amp->dostype > 0x444f5305) { + error = EINVAL; + goto fail; + } + amp->nwords = amp->bsize >> 2; + amp->dbsize = amp->bsize - (IS_FFS(amp) ? 0 : OFS_DATA_OFFSET); amp->devvp = devvp; -/* amp->rootb = (parp->p_size - 1 + 2) >> 1;*/ - amp->rootb = (parp->p_size - 1 + parp->p_cpg) >> 1; mp->mnt_data = (qaddr_t)amp; mp->mnt_stat.f_fsid.val[0] = (long)devvp->v_rdev; @@ -211,12 +234,26 @@ adosfs_mountfs(devvp, mp, p) */ if ((error = VFS_ROOT(mp, &rvp)) != 0) goto fail; + /* allocate and load bitmap, set free space */ + amp->bitmap = malloc(((amp->numblks + 31) / 32) * sizeof(*amp->bitmap), + M_ADOSFSBITMAP, M_WAITOK); + if (amp->bitmap) + adosfs_loadbitmap(amp); + if (mp->mnt_flag & MNT_RDONLY && amp->bitmap) { + /* + * Don't need the bitmap any more if it's read-only. + */ + free(amp->bitmap, M_ADOSFSBITMAP); + amp->bitmap = NULL; + } vput(rvp); return(0); fail: (void) VOP_CLOSE(devvp, FREAD, NOCRED, p); + if (amp && amp->bitmap) + free(amp->bitmap, M_ADOSFSBITMAP); if (amp) free(amp, M_ADOSFSMNT); return (error); @@ -250,6 +287,8 @@ adosfs_unmount(mp, mntflags, p) amp->devvp->v_specflags &= ~SI_MOUNTEDON; error = VOP_CLOSE(amp->devvp, FREAD, NOCRED, p); vrele(amp->devvp); + if (amp->bitmap) + free(amp->bitmap, M_ADOSFSBITMAP); free(amp, M_ADOSFSMNT); mp->mnt_data = (qaddr_t)0; mp->mnt_flag &= ~MNT_LOCAL; @@ -266,6 +305,7 @@ adosfs_root(mp, vpp) if ((error = VFS_VGET(mp, (ino_t)VFSTOADOSFS(mp)->rootb, &nvp)) != 0) return (error); + /* XXX verify it's a root block? */ *vpp = nvp; return (0); } @@ -281,10 +321,10 @@ adosfs_statfs(mp, sbp, p) amp = VFSTOADOSFS(mp); sbp->f_type = 0; sbp->f_bsize = amp->bsize; - sbp->f_iosize = amp->bsize; - sbp->f_blocks = 2; /* XXX */ - sbp->f_bfree = 0; /* none */ - sbp->f_bavail = 0; /* none */ + sbp->f_iosize = amp->dbsize; + sbp->f_blocks = amp->numblks; + sbp->f_bfree = amp->freeblks; + sbp->f_bavail = amp->freeblks; sbp->f_files = 0; /* who knows */ sbp->f_ffree = 0; /* " " */ if (sbp != &mp->mnt_stat) { @@ -310,7 +350,7 @@ adosfs_vget(mp, an, vpp) struct anode *ap; struct buf *bp; char *nam, *tmp; - int namlen, error, tmplen; + int namlen, error; error = 0; amp = VFSTOADOSFS(mp); @@ -337,7 +377,8 @@ adosfs_vget(mp, an, vpp) ap->nwords = amp->nwords; adosfs_ainshash(amp, ap); - if ((error = bread(amp->devvp, an, amp->bsize, NOCRED, &bp)) != 0) { + if ((error = bread(amp->devvp, an * amp->secsperblk, + amp->bsize, NOCRED, &bp)) != 0) { vput(vp); return (error); } @@ -357,15 +398,10 @@ adosfs_vget(mp, an, vpp) ap->created.ticks = adoswordn(bp, ap->nwords - 5); break; case ALDIR: - vp->v_type = VDIR; - break; case ADIR: vp->v_type = VDIR; break; case ALFILE: - vp->v_type = VREG; - ap->fsize = adoswordn(bp, ap->nwords - 47); - break; case AFILE: vp->v_type = VREG; ap->fsize = adoswordn(bp, ap->nwords - 47); @@ -377,9 +413,9 @@ adosfs_vget(mp, an, vpp) * from: "part:dir/file" to: "/part/dir/file" */ nam = bp->b_data + (6 * sizeof(long)); - tmplen = namlen = *(u_char *)nam++; + namlen = strlen(nam); tmp = nam; - while (tmplen-- && *tmp != ':') + while (*tmp && *tmp != ':') tmp++; if (*tmp == 0) { ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK); @@ -402,6 +438,28 @@ adosfs_vget(mp, an, vpp) vput(vp); return (EINVAL); } + + /* + * Get appropriate data from this block; hard link needs + * to get other data from the "real" block. + */ + + /* + * copy in name (from original block) + */ + nam = bp->b_data + (ap->nwords - 20) * sizeof(long); + namlen = *(u_char *)nam++; + if (namlen > 30) { +#ifdef DIAGNOSTIC + printf("adosfs: aget: name length too long blk %d\n", an); +#endif + brelse(bp); + vput(vp); + return (EINVAL); + } + bcopy(nam, ap->name, namlen); + ap->name[namlen] = 0; + /* * if dir alloc hash table and copy it in */ @@ -428,17 +486,29 @@ adosfs_vget(mp, an, vpp) * setup last indirect block cache. */ ap->lastlindblk = 0; - if (ap->type == AFILE) + if (ap->type == AFILE) { ap->lastindblk = ap->block; - else if (ap->type == ALFILE) + if (adoswordn(bp, ap->nwords - 10)) + ap->linkto = ap->block; + } else if (ap->type == ALFILE) { ap->lastindblk = ap->linkto; + brelse(bp); + bp = NULL; + error = bread(amp->devvp, ap->linkto * amp->secsperblk, + amp->bsize, NOCRED, &bp); + ap->fsize = adoswordn(bp, ap->nwords - 47); + /* + * Should ap->block be set to the real file header block? + */ + ap->block = ap->linkto; + } if (ap->type == AROOT) { - ap->adprot = 0; + ap->adprot = 15; ap->uid = amp->uid; ap->gid = amp->gid; } else { - ap->adprot = adoswordn(bp, ap->nwords - 48); + ap->adprot = adoswordn(bp, ap->nwords - 48) ^ 15; /* * Get uid/gid from extensions in file header * (really need to know if this is a muFS partition) @@ -465,27 +535,89 @@ adosfs_vget(mp, an, vpp) ap->mtime.mins = adoswordn(bp, ap->nwords - 22); ap->mtime.ticks = adoswordn(bp, ap->nwords - 21); - /* - * copy in name - */ - nam = bp->b_data + (ap->nwords - 20) * sizeof(long); - namlen = *(u_char *)nam++; - if (namlen > 30) { -#ifdef DIAGNOSTIC - printf("adosfs: aget: name length too long blk %d\n", an); -#endif - brelse(bp); - vput(vp); - return (EINVAL); - } - bcopy(nam, ap->name, namlen); - ap->name[namlen] = 0; - *vpp = vp; /* return vp */ brelse(bp); /* release buffer */ return (0); } +/* + * Load the bitmap into memory, and count the number of available + * blocks. + * The bitmap will be released if the filesystem is read-only; it's + * only needed to find the free space. + */ +int +adosfs_loadbitmap(amp) + struct adosfsmount *amp; +{ + struct buf *bp, *mapbp; + u_long bn; + int blkix, endix, mapix; + int bmsize; + int error; + + bp = mapbp = NULL; + bn = amp->rootb; + if ((error = bread(amp->devvp, bn * amp->secsperblk, amp->bsize, + NOCRED, &bp)) != 0) + return (error); + blkix = amp->nwords - 49; + endix = amp->nwords - 24; + mapix = 0; + bmsize = (amp->numblks + 31) / 32; + while (mapix < bmsize) { + int n; + u_long bits; + + if (adoswordn(bp, blkix) == 0) + break; + if (mapbp != NULL) + brelse(mapbp); + if ((error = bread(amp->devvp, + adoswordn(bp, blkix) * amp->secsperblk, amp->bsize, + NOCRED, &mapbp)) != 0) + break; + if (adoscksum(mapbp, amp->nwords)) { +#ifdef DIAGNOSTIC + printf("adosfs: loadbitmap - cksum of blk %d failed\n", + adoswordn(bp, blkix)); +#endif + /* XXX Force read-only? Set free space 0? */ + break; + } + n = 1; + while (n < amp->nwords && mapix < bmsize) { + amp->bitmap[mapix++] = bits = adoswordn(mapbp, n); + ++n; + if (mapix == bmsize && amp->numblks & 31) + bits &= ~(0xffffffff << (amp->numblks & 31)); + while (bits) { + if (bits & 1) + ++amp->freeblks; + bits >>= 1; + } + } + ++blkix; + if (mapix < bmsize && blkix == endix) { + bn = adoswordn(bp, blkix); + brelse(bp); + if ((error = bread(amp->devvp, bn * amp->secsperblk, + amp->bsize, NOCRED, &bp)) != 0) + break; + /* + * Why is there no checksum on these blocks? + */ + blkix = 0; + endix = amp->nwords - 1; + } + } + if (bp) + brelse(bp); + if (mapbp) + brelse(mapbp); + return (error); +} + /* * File handle to vnode diff --git a/sys/adosfs/advnops.c b/sys/adosfs/advnops.c index 98fb8a332893..bbcd42512175 100644 --- a/sys/adosfs/advnops.c +++ b/sys/adosfs/advnops.c @@ -1,7 +1,8 @@ -/* $NetBSD: advnops.c,v 1.26 1996/02/10 00:44:18 christos Exp $ */ +/* $NetBSD: advnops.c,v 1.27 1996/04/05 05:06:13 mhitch Exp $ */ /* * Copyright (c) 1994 Christian E. Hopps + * Copyright (c) 1996 Matthias Scheler * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -206,18 +207,20 @@ adosfs_getattr(v) /* * XXX actually we can track this if we were to walk the list * of links if it exists. + * XXX for now, just set nlink to 2 if this is a hard link + * to a file, or a file with a hard link. */ - vap->va_nlink = 1; + vap->va_nlink = 1 + (ap->linkto != 0); /* * round up to nearest blocks add number of file list * blocks needed and mutiply by number of bytes per block. */ - fblks = howmany(ap->fsize, amp->bsize); + fblks = howmany(ap->fsize, amp->dbsize); fblks += howmany(fblks, ANODENDATBLKENT(ap)); - vap->va_bytes = fblks * amp->bsize; + vap->va_bytes = fblks * amp->dbsize; vap->va_size = ap->fsize; - vap->va_blocksize = amp->bsize; + vap->va_blocksize = amp->dbsize; } #ifdef ADOSFS_DIAGNOSTIC printf(" 0)"); @@ -280,9 +283,9 @@ adosfs_read(v) do { /* * we are only supporting ADosFFS currently - * (which have data blocks of 512 bytes) + * (which have data blocks without headers) */ - size = amp->bsize; + size = amp->dbsize; lbn = uio->uio_offset / size; on = uio->uio_offset % size; n = min((u_int)(size - on), uio->uio_resid); @@ -299,9 +302,29 @@ adosfs_read(v) * but not much as ados makes little attempt to * make things contigous */ - error = bread(sp->a_vp, lbn, size, NOCRED, &bp); + error = bread(sp->a_vp, lbn * amp->secsperblk, + amp->bsize, NOCRED, &bp); sp->a_vp->v_lastr = lbn; - n = min(n, (u_int)size - bp->b_resid); + + if (!IS_FFS(amp)) { + if (bp->b_resid > 0) + error = EIO; /* OFS needs the complete block */ + else if (adoswordn(bp, 0) != BPT_DATA) { +#ifdef DIAGNOSTIC + printf("adosfs: bad primary type blk %d\n", + bp->b_blkno / amp->secsperblk); +#endif + error=EINVAL; + } + else if ( adoscksum(bp, ap->nwords)) { +#ifdef DIAGNOSTIC + printf("adosfs: blk %d failed cksum.\n", + bp->b_blkno / amp->secsperblk); +#endif + error=EINVAL; + } + } + if (error) { brelse(bp); goto reterr; @@ -309,7 +332,9 @@ adosfs_read(v) #ifdef ADOSFS_DIAGNOSTIC printf(" %d+%d-%d+%d", lbn, on, lbn, n); #endif - error = uiomove(bp->b_un.b_addr + on, (int)n, uio); + n = min(n, (u_int)size - bp->b_resid); + error = uiomove(bp->b_un.b_addr + on + + amp->bsize - amp->dbsize, (int)n, uio); brelse(bp); } while (error == 0 && uio->uio_resid > 0 && n != 0); reterr: @@ -568,10 +593,10 @@ adosfs_bmap(v) #ifdef ADOSFS_DIAGNOSTIC advopprint(sp); #endif - bn = sp->a_bn; + ap = VTOA(sp->a_vp); + bn = sp->a_bn / ap->amp->secsperblk; bnp = sp->a_bnp; error = 0; - ap = VTOA(sp->a_vp); if (sp->a_vpp != NULL) *sp->a_vpp = ap->amp->devvp; @@ -622,8 +647,8 @@ adosfs_bmap(v) error = EINVAL; goto reterr; } - error = bread(ap->amp->devvp, nb, ap->amp->bsize, - NOCRED, &flbp); + error = bread(ap->amp->devvp, nb * ap->amp->secsperblk, + ap->amp->bsize, NOCRED, &flbp); if (error) goto reterr; if (adoscksum(flbp, ap->nwords)) { @@ -651,11 +676,11 @@ adosfs_bmap(v) flblkoff = bn % ANODENDATBLKENT(ap); if (flblkoff < adoswordn(flbp, 2 /* ADBI_NBLKTABENT */)) { flblkoff = (ap->nwords - 51) - flblkoff; - *bnp = adoswordn(flbp, flblkoff); + *bnp = adoswordn(flbp, flblkoff) * ap->amp->secsperblk; } else { #ifdef DIAGNOSTIC printf("flblk offset %d too large in lblk %d blk %d\n", - flblkoff, bn, flbp->b_blkno); + flblkoff, bn / ap->amp->secsperblk , flbp->b_blkno); #endif error = EINVAL; }