+ /*
+ * Determine the number of levels of indirection.
+ */
+ sh = 1;
+ bn -= NDADDR;
+ for (j = NIADDR; j > 0; j--) {
+ sh *= NINDIR(fs);
+ if (bn < sh)
+ break;
+ bn -= sh;
+ }
+ if (j == 0)
+ return (EFBIG);
+ /*
+ * Fetch through the indirect blocks.
+ */
+ nb = ip->i_ib[NIADDR - j];
+ if (nb == 0) {
+ *bnp = (daddr_t)-1;
+ return (0);
+ }
+ for (; j <= NIADDR; j++) {
+ if (error = bread(ip->i_devvp, fsbtodb(fs, nb),
+ (int)fs->fs_bsize, NOCRED, &bp)) {
+ brelse(bp);
+ return (error);
+ }
+ bap = bp->b_un.b_daddr;
+ sh /= NINDIR(fs);
+ i = (bn / sh) % NINDIR(fs);
+ nb = bap[i];
+ if (nb == 0) {
+ *bnp = (daddr_t)-1;
+ brelse(bp);
+ return (0);
+ }
+ brelse(bp);
+ }
+ *bnp = fsbtodb(fs, nb);
+ return (0);
+}
+
+/*
+ * Balloc defines the structure of file system storage
+ * by allocating the physical blocks on a device given
+ * the inode and the logical block number in a file.
+ */
+balloc(ip, bn, size, bpp, flags)
+ register struct inode *ip;
+ register daddr_t bn;
+ int size;
+ struct buf **bpp;
+ int flags;
+{
+ register struct fs *fs;
+ register daddr_t nb;
+ struct buf *bp, *nbp;
+ struct vnode *vp = ITOV(ip);
+ int osize, nsize, i, j, sh, error;
+ daddr_t newb, lbn, *bap, pref, blkpref();
+
+ *bpp = (struct buf *)0;
+ if (bn < 0)
+ return (EFBIG);