- ip = VTOI(fs->lfs_ivnode);
- fip = sp->fip;
- lbp = &fip->fi_blocks[fip->fi_nblocks];
- for (xp = fs->lfs_segtab, i = 0; i < fs->lfs_segtabsz;
- xp += fs->lfs_bsize, ++i, ++lbp) {
- *sp->cbpp++ = bp = lfs_newbuf(fs, sp->saddr, fs->lfs_bsize);
- bp->b_flags |= B_CALL;
- bcopy(xp, bp->b_un.b_addr, fs->lfs_bsize);
- ip->i_db[i] = sp->saddr;
- sp->saddr += (1 << fs->lfs_fsbtodb);
- *lbp = i;
- ++fip->fi_nblocks;
- }
- return (lfs_writeinode(fs, sp, VTOI(fs->lfs_ivnode)));
-}
-
-/*
- * Write the dirty blocks associated with a vnode.
- */
-static SEGMENT *
-lfs_writefile(fs, sp, vp, do_ckp)
- LFS *fs;
- SEGMENT *sp;
- VNODE *vp;
- int do_ckp;
-{
- FINFO *fip;
- ino_t inum;
-
- inum = VTOI(vp)->i_number;
- printf("lfs_writefile: node %d\n", inum);
-
- if (vp->v_dirtyblkhd != NULL) {
- if (sp->seg_bytes_left < fs->lfs_bsize) {
- lfs_writeseg(fs, sp);
- sp = lfs_newseg(fs);
- } else if (sp->sum_bytes_left < sizeof(FINFO))
- sp = lfs_newsum(fs, sp);
- sp->sum_bytes_left -= sizeof(FINFO) - sizeof(daddr_t);
-
- fip = sp->fip;
- fip->fi_nblocks = 0;
- fip->fi_version =
- inum == LFS_IFILE_INUM ? 1 : lfs_getversion(fs, inum);
- fip->fi_ino = inum;
-
- sp = lfs_gather(fs, sp, vp, match_data);
- if (do_ckp) {
- sp = lfs_gather(fs, sp, vp, match_indir);
- sp = lfs_gather(fs, sp, vp, match_dindir);
- }
-
- fip = sp->fip;
- printf("lfs_writefile: adding %d blocks\n", fip->fi_nblocks);
-
- /*
- * If this is the ifile, always update the file count as we'll
- * be adding the segment usage information even if we didn't
- * write any blocks. Also, don't update the FINFO pointer for
- * the ifile as the segment usage information hasn't yet been
- * added.
- */
- if (inum == LFS_IFILE_INUM)
- ++((SEGSUM *)(sp->segsum))->ss_nfinfo;
- else if (fip->fi_nblocks != 0) {
- ++((SEGSUM *)(sp->segsum))->ss_nfinfo;
- sp->fip = (FINFO *)((caddr_t)fip + sizeof(FINFO) +
- sizeof(daddr_t) * (fip->fi_nblocks - 1));
- }
- }
-
- /* If this isn't the ifile, update the inode. */
- if (inum != LFS_IFILE_INUM)
- sp = lfs_writeinode(fs, sp, VTOI(vp));
- return (sp);
-}
-
-static SEGMENT *
-lfs_writeinode(fs, sp, ip)
- LFS *fs;
- SEGMENT *sp;
- INODE *ip;
-{
- BUF *bp;
- daddr_t next_addr;
- int nblocks;
-
-printf("lfs_writeinode\n");
- /* Allocate a new inode block if necessary. */
- if (sp->ibp == NULL) {
- /* Allocate a new segment if necessary. */
- if (sp->seg_bytes_left < fs->lfs_bsize) {
- lfs_writeseg(fs, sp);
- sp = lfs_newseg(fs);
- }
-
- /* Get next inode block. */
- next_addr = next(fs, sp, &nblocks);
-
- /*
- * Get a new buffer and enter into the buffer list from
- * the top of the list.
- */
- sp->ibp = sp->bpp[fs->lfs_ssize - (nblocks + 1)] =
- lfs_newbuf(fs, next_addr, fs->lfs_bsize);
- sp->ibp->b_flags |= B_CALL;
-
- /* Set remaining space counter. */
- sp->seg_bytes_left -= fs->lfs_bsize;
-
- printf("alloc inode: bp %x, lblkno %x, bp index %d\n",
- sp->sbp, sp->sbp->b_lblkno, fs->lfs_ssize - nblocks);
+ LFS_SEGENTRY(sup, fs, datosn(fs, fs->lfs_curseg), bp);
+ sup->su_flags &= ~SEGUSE_ACTIVE;
+ LFS_UBWRITE(bp);
+
+ LFS_SEGENTRY(sup, fs, datosn(fs, fs->lfs_nextseg), bp);
+ sup->su_flags |= SEGUSE_ACTIVE | SEGUSE_DIRTY;
+ LFS_UBWRITE(bp);
+
+ LFS_CLEANERINFO(cip, fs, bp);
+ --cip->clean;
+ ++cip->dirty;
+ LFS_UBWRITE(bp);
+
+ fs->lfs_lastseg = fs->lfs_curseg;
+ fs->lfs_curseg = fs->lfs_nextseg;
+ for (sn = curseg = datosn(fs, fs->lfs_curseg);;) {
+ sn = (sn + 1) % fs->lfs_nseg;
+ if (sn == curseg)
+ panic("lfs_nextseg: no clean segments");
+ LFS_SEGENTRY(sup, fs, sn, bp);
+ isdirty = sup->su_flags & SEGUSE_DIRTY;
+ brelse(bp);
+ if (!isdirty)
+ break;