bp = softdep_setup_pagecache(ip, lbn, newsize);
panic("softdep_setup_allocdirect: Bonk art in the head\n");
softdep_setup_allocdirect(ip, lbn, newblkno, oldblkno, newsize, oldsize, bp)	struct inode *ip;	/* inode to which block is being added */	ufs_lbn_t lbn;		/* block pointer within inode */	ufs_daddr_t newblkno;	/* disk block number being added */	ufs_daddr_t oldblkno;	/* previous block number, 0 unless frag */	long newsize;		/* size of new block */	long oldsize;		/* size of new block */	struct buf *bp;		/* bp for allocated block */{	struct allocdirect *adp, *oldadp;	struct allocdirectlst *adphead;	struct bmsafemap *bmsafemap;	struct inodedep *inodedep;	struct pagedep *pagedep;	struct newblk *newblk;	MALLOC(adp, struct allocdirect *, sizeof(struct allocdirect),		M_ALLOCDIRECT, M_SOFTDEP_FLAGS);	bzero(adp, sizeof(struct allocdirect));	adp->ad_list.wk_type = D_ALLOCDIRECT;	adp->ad_lbn = lbn;	adp->ad_newblkno = newblkno;	adp->ad_oldblkno = oldblkno;	adp->ad_newsize = newsize;	adp->ad_oldsize = oldsize;	adp->ad_state = ATTACHED;	if (newblkno == oldblkno)		adp->ad_freefrag = NULL;	else		adp->ad_freefrag = newfreefrag(ip, oldblkno, oldsize);	if (newblk_lookup(ip->i_fs, newblkno, 0, &newblk) == 0)		panic("softdep_setup_allocdirect: lost block");	ACQUIRE_LOCK(&lk);	inodedep_lookup(ip->i_fs, ip->i_number, DEPALLOC | NODELAY, &inodedep);	adp->ad_inodedep = inodedep;	if (newblk->nb_state == DEPCOMPLETE) {		adp->ad_state |= DEPCOMPLETE;		adp->ad_buf = NULL;	} else {		bmsafemap = newblk->nb_bmsafemap;		adp->ad_buf = bmsafemap->sm_buf;		LIST_REMOVE(newblk, nb_deps);		LIST_INSERT_HEAD(&bmsafemap->sm_allocdirecthd, adp, ad_deps);	}	LIST_REMOVE(newblk, nb_hash);	FREE(newblk, M_NEWBLK);	/*	 * If we were not passed a bp to attach the dep to,	 * then this must be for a regular file.	 * Allocate a buffer to represent the page cache pages	 * that are the real dependency.  The pages themselves	 * cannot refer to the dependency since we don't want to	 * add a field to struct vm_page for this.	 */	if (bp == NULL) {		bp = softdep_setup_pagecache(ip, lbn, newsize);	}	WORKLIST_INSERT(&bp->b_dep, &adp->ad_list);	if (lbn >= NDADDR) {		/* allocating an indirect block */		if (oldblkno != 0) {			FREE_LOCK(&lk);			panic("softdep_setup_allocdirect: non-zero indir");		}	} else {		/*		 * Allocating a direct block.		 *		 * If we are allocating a directory block, then we must		 * allocate an associated pagedep to track additions and		 * deletions.		 */		if ((ip->i_ffs_mode & IFMT) == IFDIR &&		    pagedep_lookup(ip, lbn, DEPALLOC, &pagedep) == 0)			WORKLIST_INSERT(&bp->b_dep, &pagedep->pd_list);	}	/*	 * The list of allocdirects must be kept in sorted and ascending	 * order so that the rollback routines can quickly determine the	 * first uncommitted block (the size of the file stored on disk	 * ends at the end of the lowest committed fragment, or if there	 * are no fragments, at the end of the highest committed block).	 * Since files generally grow, the typical case is that the new	 * block is to be added at the end of the list. We speed this	 * special case by checking against the last allocdirect in the	 * list before laboriously traversing the list looking for the	 * insertion point.	 */	adphead = &inodedep->id_newinoupdt;	oldadp = TAILQ_LAST(adphead, allocdirectlst);	if (oldadp == NULL || oldadp->ad_lbn <= lbn) {		/* insert at end of list */		TAILQ_INSERT_TAIL(adphead, adp, ad_next);		if (oldadp != NULL && oldadp->ad_lbn == lbn)			allocdirect_merge(adphead, adp, oldadp);		FREE_LOCK(&lk);		return;	}	TAILQ_FOREACH(oldadp, adphead, ad_next) {		if (oldadp->ad_lbn >= lbn)			break;	}	if (oldadp == NULL) {		FREE_LOCK(&lk);		panic("softdep_setup_allocdirect: lost entry");	}	/* insert in middle of list */	TAILQ_INSERT_BEFORE(oldadp, adp, ad_next);	if (oldadp->ad_lbn == lbn)		allocdirect_merge(adphead, adp, oldadp);	FREE_LOCK(&lk);}