- nb = lblkno(fs, ip->i_size);
- if (rwflg == B_WRITE && nb < NDADDR && nb < bn) {
- osize = blksize(fs, ip, nb);
- if (osize < fs->fs_bsize && osize > 0) {
- bp = realloccg(ip, ip->i_db[nb],
- blkpref(ip, nb, (int)nb, &ip->i_db[0]),
- osize, (int)fs->fs_bsize);
- if (bp == NULL)
- return ((daddr_t)-1);
- ip->i_size = (nb + 1) * fs->fs_bsize;
- ip->i_db[nb] = dbtofsb(fs, bp->b_blkno);
- ip->i_flag |= IUPD|ICHG;
- bdwrite(bp);
- }
+ if (ap->a_vpp != NULL)
+ *ap->a_vpp = VTOI(ap->a_vp)->i_devvp;
+ if (ap->a_bnp == NULL)
+ return (0);
+
+ return (lfs_bmaparray(ap->a_vp, ap->a_bn, ap->a_bnp, NULL, NULL));
+}
+
+/*
+ * LFS has a different version of bmap from FFS because of a naming conflict.
+ * In FFS, meta blocks are given real disk addresses at allocation time, and
+ * are linked into the device vnode, using a logical block number which is
+ * the same as the physical block number. This can't be done by LFS because
+ * blocks aren't given disk addresses until they're written, so there's no
+ * way to distinguish the meta-data blocks for one file from any other file.
+ * This means that meta-data blocks have to be on the vnode for the file so
+ * they can be found, and have to have "names" different from the standard
+ * data blocks. To do this, we divide the name space into positive and
+ * negative block numbers, and give the meta-data blocks negative logical
+ * numbers. Indirect blocks are addressed by the negative address of the
+ * first data block to which they point. Double indirect blocks are addressed
+ * by one less than the address of the first indirect block to which they
+ * point. Triple indirect blocks are addressed by one less than the address
+ * of the first double indirect block to which they point.
+ */
+int
+lfs_bmaparray(vp, bn, bnp, ap, nump)
+ struct vnode *vp;
+ register daddr_t bn;
+ daddr_t *bnp;
+ INDIR *ap;
+ int *nump;
+{
+ register struct inode *ip;
+ struct buf *bp;
+ struct lfs *fs;
+ struct vnode *devvp;
+ INDIR a[NIADDR], *xap;
+ daddr_t *bap, daddr;
+ long metalbn;
+ int error, num, off;
+ struct vop_strategy_args vop_strategy_a;
+
+ ip = VTOI(vp);
+#ifdef DIAGNOSTIC
+ if (ap != NULL && nump == NULL || ap == NULL && nump != NULL)
+ panic("lfs_bmaparray: invalid arguments");
+#endif
+
+ xap = ap == NULL ? a : ap;
+ if (!nump)
+ nump = #
+ if (error = lfs_getlbns(vp, bn, xap, nump))
+ return (error);
+
+ num = *nump;
+ if (num == 0) {
+ *bnp = ip->i_db[bn];
+ if (*bnp == 0)
+ *bnp = UNASSIGNED;
+ return (0);