*BSD News Article 14172


Return to BSD News archive

Newsgroups: comp.os.386bsd.development
Path: sserve!newshost.anu.edu.au!munnari.oz.au!constellation!osuunx.ucc.okstate.edu!moe.ksu.ksu.edu!zaphod.mps.ohio-state.edu!cs.utexas.edu!uunet!mcsun!sun4nl!eur.nl!pk
From: pk@cs.few.eur.nl (Paul Kranenburg)
Subject: truncate(2) can only truncate
Message-ID: <1993Apr7.162556.18882@cs.few.eur.nl>
Sender: news@cs.few.eur.nl
Reply-To: pk@cs.few.eur.nl
Organization: Erasmus University Rotterdam
Date: Wed, 7 Apr 1993 16:25:56 GMT
Lines: 67

I found that [f]truncate(2) applied to file on a UFS filesystem can not
be used to extend that file, as in:

	# cp /dev/null xxx
	# ls -ls xxx
		0 -rw-r--r--    1 root            0 Apr  7 18:16 xxx
	# <compile> "main(){truncate("xxx", 10000);}"
	# ./a.out
	# ls -ls xxx
		4 -rw-r--r--    1 root        10000 Apr  7 18:17 xxx


The manual page does not exactly say that it should. However, it works
on NFS mounted file systems (the NFS server clearly cooperates).
The following patch allows the same thing on a local UFS file system.

Comments anyone?

-pk

-----------------------------------------------------------------------

------- ufs_inode.c -------
*** /tmp/da18439	Wed Apr  7 18:24:48 1993
--- ufs_inode.c	Wed Apr  7 15:31:15 1993
***************
*** 407,415 ****
--- 407,445 ----
  
  	vnode_pager_setsize(ITOV(oip), length);
  	if (oip->i_size <= length) {
+ 
+ 		if (oip->i_size < length) {
+ 			daddr_t lbn;
+ 			int on;
+ 			struct buf *bp;
+ 
+ 			fs = oip->i_fs;
+ 			lbn = lblkno(fs, length - 1);
+ 			on = blkoff(fs, length - 1);
+ 			flags |= B_CLRBUF;
+ 			if (error = balloc(oip, lbn, (int)(on), &bp, flags))
+ 				return (error);
+ 
+ 			oip->i_size = length;
+ 
+ #if 1
+ 			brelse(bp);
+ 
+ #else			/* Would this be necessary ? */
+ 			if (ioflag & IO_SYNC)
+ 				(void) bwrite(bp);
+ 			else if (n + on == fs->fs_bsize) {
+ 				bp->b_flags |= B_AGE;
+ 				bawrite(bp);
+ 			} else
+ 				bdwrite(bp);
+ #endif
+ 		}
+ 
  		oip->i_flag |= ICHG|IUPD;
  		error = iupdat(oip, &time, &time, 1);
  		return (error);
+ 
  	}
  	/*
  	 * Calculate index into inode's block list of