+ /*
+ * No need to update segment usage if there was no former inode address
+ * or if the last inode address is in the current partial segment.
+ */
+ if (daddr != LFS_UNUSED_DADDR &&
+ !(daddr >= fs->lfs_lastpseg && daddr <= bp->b_blkno)) {
+ LFS_SEGENTRY(sup, fs, datosn(fs, daddr), bp);
+#ifdef DIAGNOSTIC
+ if (sup->su_nbytes < sizeof(struct dinode)) {
+ /* XXX -- Change to a panic. */
+ printf("lfs: negative bytes (segment %d)\n",
+ datosn(fs, daddr));
+ panic("negative bytes");
+ }
+#endif
+ sup->su_nbytes -= sizeof(struct dinode);
+ redo_ifile =
+ (ino == LFS_IFILE_INUM && !(bp->b_flags & B_GATHERED));
+ error = VOP_BWRITE(bp);
+ }
+ return (redo_ifile);
+}
+
+int
+lfs_gatherblock(sp, bp, sptr)
+ struct segment *sp;
+ struct buf *bp;
+ int *sptr;
+{
+ struct lfs *fs;
+ int version;
+
+ /*
+ * If full, finish this segment. We may be doing I/O, so
+ * release and reacquire the splbio().
+ */
+#ifdef DIAGNOSTIC
+ if (sp->vp == NULL)
+ panic ("lfs_gatherblock: Null vp in segment");
+#endif
+ fs = sp->fs;
+ if (sp->sum_bytes_left < sizeof(daddr_t) ||
+ sp->seg_bytes_left < fs->lfs_bsize) {
+ if (sptr)
+ splx(*sptr);
+ lfs_updatemeta(sp);
+
+ version = sp->fip->fi_version;
+ (void) lfs_writeseg(fs, sp);
+
+ sp->fip->fi_version = version;
+ sp->fip->fi_ino = VTOI(sp->vp)->i_number;
+ /* Add the current file to the segment summary. */
+ ++((SEGSUM *)(sp->segsum))->ss_nfinfo;
+ sp->sum_bytes_left -=
+ sizeof(struct finfo) - sizeof(daddr_t);
+
+ if (sptr)
+ *sptr = splbio();
+ return(1);
+ }
+
+ /* Insert into the buffer list, update the FINFO block. */
+ bp->b_flags |= B_GATHERED;
+ *sp->cbpp++ = bp;
+ sp->fip->fi_blocks[sp->fip->fi_nblocks++] = bp->b_lblkno;
+
+ sp->sum_bytes_left -= sizeof(daddr_t);
+ sp->seg_bytes_left -= fs->lfs_bsize;
+ return(0);