-static daddr_t
-lfs_nextseg(fs)
- LFS *fs;
-{
- int segnum, sn;
-
- segnum = sn = datosn(fs, fs->lfs_nextseg);
- while ((sn = seginc(fs, sn)) != segnum &&
- fs->lfs_segtab[sn].su_flags & SEGUSE_DIRTY);
-
- if (sn == segnum)
- panic("lfs_nextseg: file system full"); /* XXX */
- return (sntoda(fs, sn));
-}
-
-/*
- * Update the metadata that points to the blocks listed in the FINFO
- * array.
- */
-static void
-lfs_updatemeta(fs, sp, ip, lbp, bpp, nblocks)
- LFS *fs;
- SEGMENT *sp;
- INODE *ip;
- daddr_t *lbp;
- BUF **bpp;
- int nblocks;
-{
- SEGUSE *segup;
- BUF **lbpp, *bp;
- daddr_t daddr, iblkno;
- int db_per_fsb, error, i;
- long lbn;
-
- if (nblocks == 0)
- return;
-
- /* Sort the blocks and add disk addresses */
- shellsort(bpp, lbp, nblocks);
-
- db_per_fsb = 1 << fs->lfs_fsbtodb;
- for (lbpp = bpp, i = 0; i < nblocks; ++i, ++lbpp) {
- (*lbpp)->b_blkno = sp->saddr;
- sp->saddr += db_per_fsb;
- }
-
- for (lbpp = bpp, i = 0; i < nblocks; ++i, ++lbpp) {
- lbn = lbp[i];
- if (error = lfs_bmap(ip, lbn, &daddr))
- panic("lfs_updatemeta: lfs_bmap");
-
- /* Update in-core copy of old segment usage information. */
- if (daddr != UNASSIGNED) {
- segup = fs->lfs_segtab + datosn(fs, daddr);
- segup->su_lastmod = time.tv_sec;
-#ifdef DIAGNOSTIC
- if (segup->su_nbytes < fs->lfs_bsize)
- panic("lfs: negative bytes (segment %d)\n",
- segup - fs->lfs_segtab);
-#endif
- segup->su_nbytes -= fs->lfs_bsize;
- }
-
- /*
- * Now change whomever points to lbn. We could start with the
- * smallest (most negative) block number in these if clauses,
- * but we assume that indirect blocks are least common, and
- * handle them separately. The test for < 0 is correct and
- * minimizes the path in the common case.
- */
-#define BREAD(bno) \
- if (error = bread(ITOV(ip), (bno), fs->lfs_bsize, NOCRED, &bp)) \
- panic("lfs_updatemeta: bread");
-
- if (lbn < 0)
- if (lbn < -NIADDR) {
-#ifdef META
- printf("meta: update indirect block %d\n",
- D_INDIR);
-#endif
- BREAD(D_INDIR);
- bp->b_un.b_daddr[-lbn % NINDIR(fs)] =
- (*lbpp)->b_blkno;
- lfs_bwrite(bp);
- } else {
- ip->i_ib[-lbn-1] = (*lbpp)->b_blkno;
- } else if (lbn < NDADDR) {
- ip->i_db[lbn] = (*lbpp)->b_blkno;
- } else if ((lbn -= NDADDR) < NINDIR(fs)) {
-#ifdef META
- printf("meta: update indirect block %d\n", S_INDIR);
-#endif
- BREAD(S_INDIR);
- bp->b_un.b_daddr[lbn] = (*lbpp)->b_blkno;
- lfs_bwrite(bp);
- } else if ((lbn =
- (lbn - NINDIR(fs)) / NINDIR(fs)) < NINDIR(fs)) {
- iblkno = -(lbn + NIADDR + 1);
-#ifdef META
- printf("meta: update indirect block %d\n", iblkno);
-#endif
- BREAD(iblkno);
- bp->b_un.b_daddr[lbn % NINDIR(fs)] = (*lbpp)->b_blkno;
- lfs_bwrite(bp);
- } else
- panic("lfs_updatemeta: logical block number too large");
- }
-}
-
-static SEGMENT *
-lfs_writeckp(fs, sp)
- LFS *fs;
- SEGMENT *sp;