(void) uvm_vnp_uncache(ITOV(ip));
ffs_realloccg(ip, lbprev, bpref, osize, nsize, cred, bpp, blknop)	register struct inode *ip;	daddr_t lbprev;	daddr_t bpref;	int osize, nsize;	struct ucred *cred;	struct buf **bpp;	ufs_daddr_t *blknop;{	struct fs *fs;	struct buf *bp = NULL;	ufs_daddr_t quota_updated = 0;	int cg, request, error;	daddr_t bprev, bno;	if (bpp != NULL)		*bpp = NULL;	fs = ip->i_fs;#ifdef DIAGNOSTIC	if ((u_int)osize > fs->fs_bsize || fragoff(fs, osize) != 0 ||	    (u_int)nsize > fs->fs_bsize || fragoff(fs, nsize) != 0) {		printf(		    "dev = 0x%x, bsize = %d, osize = %d, nsize = %d, fs = %s\n",		    ip->i_dev, fs->fs_bsize, osize, nsize, fs->fs_fsmnt);		panic("ffs_realloccg: bad size");	}	if (cred == NOCRED)		panic("ffs_realloccg: missing credential");#endif /* DIAGNOSTIC */	if (cred->cr_uid != 0 && freespace(fs, fs->fs_minfree) <= 0)		goto nospace;	if ((bprev = ip->i_ffs_db[lbprev]) == 0) {		printf("dev = 0x%x, bsize = %d, bprev = %d, fs = %s\n",		    ip->i_dev, fs->fs_bsize, bprev, fs->fs_fsmnt);		panic("ffs_realloccg: bad bprev");	}	/*	 * Allocate the extra space in the buffer.	 */	if (bpp != NULL &&	    (error = bread(ITOV(ip), lbprev, osize, NOCRED, &bp)) != 0)		goto error;	if ((error = ufs_quota_alloc_blocks(ip, btodb(nsize - osize), cred))	    != 0)		goto error;	quota_updated = btodb(nsize - osize);	/*	 * Check for extension in the existing location.	 */	cg = dtog(fs, bprev);	if ((bno = ffs_fragextend(ip, cg, (long)bprev, osize, nsize)) != 0) {		ip->i_ffs_blocks += btodb(nsize - osize);		ip->i_flag |= IN_CHANGE | IN_UPDATE;		if (bpp != NULL) {			if (bp->b_blkno != fsbtodb(fs, bno))				panic("ffs_realloccg: bad blockno");			allocbuf(bp, nsize);			bp->b_flags |= B_DONE;			bzero((char *)bp->b_data + osize, (u_int)nsize - osize);			*bpp = bp;		}		if (blknop != NULL) {			*blknop = bno;		}		return (0);	}	/*	 * Allocate a new disk location.	 */	if (bpref >= fs->fs_size)		bpref = 0;	switch ((int)fs->fs_optim) {	case FS_OPTSPACE:		/*		 * Allocate an exact sized fragment. Although this makes		 * best use of space, we will waste time relocating it if		 * the file continues to grow. If the fragmentation is		 * less than half of the minimum free reserve, we choose		 * to begin optimizing for time.		 */		request = nsize;		if (fs->fs_minfree < 5 ||		    fs->fs_cstotal.cs_nffree >		    fs->fs_dsize * fs->fs_minfree / (2 * 100))			break;		log(LOG_NOTICE, "%s: optimization changed from SPACE to TIME\n",			fs->fs_fsmnt);		fs->fs_optim = FS_OPTTIME;		break;	case FS_OPTTIME:		/*		 * At this point we have discovered a file that is trying to		 * grow a small fragment to a larger fragment. To save time,		 * we allocate a full sized block, then free the unused portion.		 * If the file continues to grow, the `ffs_fragextend' call		 * above will be able to grow it in place without further		 * copying. If aberrant programs cause disk fragmentation to		 * grow within 2% of the free reserve, we choose to begin		 * optimizing for space.		 */		request = fs->fs_bsize;		if (fs->fs_cstotal.cs_nffree <		    fs->fs_dsize * (fs->fs_minfree - 2) / 100)			break;		log(LOG_NOTICE, "%s: optimization changed from TIME to SPACE\n",			fs->fs_fsmnt);		fs->fs_optim = FS_OPTSPACE;		break;	default:		printf("dev = 0x%x, optim = %d, fs = %s\n",		    ip->i_dev, fs->fs_optim, fs->fs_fsmnt);		panic("ffs_realloccg: bad optim");		/* NOTREACHED */	}	bno = (daddr_t)ffs_hashalloc(ip, cg, (long)bpref, request,	    			     ffs_alloccg);	if (bno <= 0) 		goto nospace;	if (!DOINGSOFTDEP(ITOV(ip)))		ffs_blkfree(ip, bprev, (long)osize);	if (nsize < request)		ffs_blkfree(ip, bno + numfrags(fs, nsize),		    (long)(request - nsize));	ip->i_ffs_blocks += btodb(nsize - osize);	ip->i_flag |= IN_CHANGE | IN_UPDATE;	if (bpp != NULL) {		bp->b_blkno = fsbtodb(fs, bno);		allocbuf(bp, nsize);		bp->b_flags |= B_DONE;		bzero((char *)bp->b_data + osize, (u_int)nsize - osize);		*bpp = bp;	}	if (blknop != NULL) {		*blknop = bno;	}	return (0);nospace:	/*	 * no space available	 */	ffs_fserr(fs, cred->cr_uid, "file system full");	uprintf("\n%s: write failed, file system is full\n", fs->fs_fsmnt);	error = ENOSPC;error:	if (bp != NULL) {		brelse(bp);		bp = NULL;	} 	/*	 * Restore user's disk quota because allocation failed.	 */	if (quota_updated != 0)		(void)ufs_quota_free_blocks(ip, quota_updated, cred);			return error;}