if (1 || doreallocblks == 0)
if (doreallocblks == 0)
ffs_reallocblks(v)	void *v;{	struct vop_reallocblks_args /* {		struct vnode *a_vp;		struct cluster_save *a_buflist;	} */ *ap = v;	struct fs *fs;	struct inode *ip;	struct vnode *vp;	struct buf *sbp, *ebp;	daddr_t *bap, *sbap, *ebap = NULL;	struct cluster_save *buflist;	daddr_t start_lbn, end_lbn, soff, newblk, blkno;	struct indir start_ap[NIADDR + 1], end_ap[NIADDR + 1], *idp;	int i, len, start_lvl, end_lvl, pref, ssize;	/* XXXUBC - don't reallocblks for now */	if (1 || doreallocblks == 0)		return (ENOSPC);	vp = ap->a_vp;	ip = VTOI(vp);	fs = ip->i_fs;	if (fs->fs_contigsumsize <= 0)		return (ENOSPC);	buflist = ap->a_buflist;	len = buflist->bs_nchildren;	start_lbn = buflist->bs_children[0]->b_lblkno;	end_lbn = start_lbn + len - 1;#ifdef DIAGNOSTIC	for (i = 0; i < len; i++)		if (!ffs_checkblk(ip,		   dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))			panic("ffs_reallocblks: unallocated block 1");			for (i = 1; i < len; i++)		if (buflist->bs_children[i]->b_lblkno != start_lbn + i)			panic("ffs_reallocblks: non-logical cluster");	blkno = buflist->bs_children[0]->b_blkno;	ssize = fsbtodb(fs, fs->fs_frag);	for (i = 1; i < len - 1; i++)		if (buflist->bs_children[i]->b_blkno != blkno + (i * ssize))			panic("ffs_reallocblks: non-physical cluster %d", i);#endif	/*	 * If the latest allocation is in a new cylinder group, assume that	 * the filesystem has decided to move and do not force it back to	 * the previous cylinder group.	 */	if (dtog(fs, dbtofsb(fs, buflist->bs_children[0]->b_blkno)) !=	    dtog(fs, dbtofsb(fs, buflist->bs_children[len - 1]->b_blkno)))		return (ENOSPC);	if (ufs_getlbns(vp, start_lbn, start_ap, &start_lvl) ||	    ufs_getlbns(vp, end_lbn, end_ap, &end_lvl))		return (ENOSPC);	/*	 * Get the starting offset and block map for the first block.	 */	if (start_lvl == 0) {		sbap = &ip->i_ffs_db[0];		soff = start_lbn;	} else {		idp = &start_ap[start_lvl - 1];		if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &sbp)) {			brelse(sbp);			return (ENOSPC);		}		sbap = (daddr_t *)sbp->b_data;		soff = idp->in_off;	}	/*	 * Find the preferred location for the cluster.	 */	pref = ffs_blkpref(ip, start_lbn, soff, sbap);	/*	 * If the block range spans two block maps, get the second map.	 */	if (end_lvl == 0 || (idp = &end_ap[end_lvl - 1])->in_off + 1 >= len) {		ssize = len;	} else {#ifdef DIAGNOSTIC		if (start_lvl > 1 &&		    start_ap[start_lvl-1].in_lbn == idp->in_lbn)			panic("ffs_reallocblk: start == end");#endif		ssize = len - (idp->in_off + 1);		if (bread(vp, idp->in_lbn, (int)fs->fs_bsize, NOCRED, &ebp))			goto fail;		ebap = (daddr_t *)ebp->b_data;	}	/*	 * Search the block map looking for an allocation of the desired size.	 */	if ((newblk = (daddr_t)ffs_hashalloc(ip, dtog(fs, pref), (long)pref,	    len, ffs_clusteralloc)) == 0)		goto fail;	/*	 * We have found a new contiguous block.	 *	 * First we have to replace the old block pointers with the new	 * block pointers in the inode and indirect blocks associated	 * with the file.	 */#ifdef DEBUG	if (prtrealloc)		printf("realloc: ino %d, lbns %d-%d\n\told:", ip->i_number,		    start_lbn, end_lbn);#endif	blkno = newblk;	for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) {		if (i == ssize) {			bap = ebap;			soff = -i;		}#ifdef DIAGNOSTIC		if (!ffs_checkblk(ip,		   dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))			panic("ffs_reallocblks: unallocated block 2");		if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != *bap)			panic("ffs_reallocblks: alloc mismatch");#endif#ifdef DEBUG		if (prtrealloc)			printf(" %d,", *bap);#endif		if (DOINGSOFTDEP(vp)) {			if (sbap == &ip->i_ffs_db[0] && i < ssize)				softdep_setup_allocdirect(ip, start_lbn + i,				    blkno, *bap, fs->fs_bsize, fs->fs_bsize,				    buflist->bs_children[i]);			else				softdep_setup_allocindir_page(ip, start_lbn + i,				    i < ssize ? sbp : ebp, soff + i, blkno,				    *bap, buflist->bs_children[i]);		}		*bap++ = blkno;	}	/*	 * Next we must write out the modified inode and indirect blocks.	 * For strict correctness, the writes should be synchronous since	 * the old block values may have been written to disk. In practise	 * they are almost never written, but if we are concerned about	 * strict correctness, the `doasyncfree' flag should be set to zero.	 *	 * The test on `doasyncfree' should be changed to test a flag	 * that shows whether the associated buffers and inodes have	 * been written. The flag should be set when the cluster is	 * started and cleared whenever the buffer or inode is flushed.	 * We can then check below to see if it is set, and do the	 * synchronous write only when it has been cleared.	 */	if (sbap != &ip->i_ffs_db[0]) {		if (doasyncfree)			bdwrite(sbp);		else			bwrite(sbp);	} else {		ip->i_flag |= IN_CHANGE | IN_UPDATE;		if (!doasyncfree) {			UFS_UPDATE(ip, MNT_WAIT);		}	}	if (ssize < len) {		if (doasyncfree)			bdwrite(ebp);		else			bwrite(ebp);	}	/*	 * Last, free the old blocks and assign the new blocks to the buffers.	 */#ifdef DEBUG	if (prtrealloc)		printf("\n\tnew:");#endif	for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {		if (!DOINGSOFTDEP(vp))			ffs_blkfree(ip,			    dbtofsb(fs, buflist->bs_children[i]->b_blkno),			    fs->fs_bsize);		buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);#ifdef DIAGNOSTIC		if (!ffs_checkblk(ip,		   dbtofsb(fs, buflist->bs_children[i]->b_blkno), fs->fs_bsize))			panic("ffs_reallocblks: unallocated block 3");		if (prtrealloc)			printf(" %d,", blkno);#endif	}#ifdef DEBUG	if (prtrealloc) {		prtrealloc--;		printf("\n");	}#endif	return (0);fail:	if (ssize < len)		brelse(ebp);	if (sbap != &ip->i_ffs_db[0])		brelse(sbp);	return (ENOSPC);}