*BSD News Article 4204


Return to BSD News archive

Path: sserve!manuel!munnari.oz.au!spool.mu.edu!wupost!uunet!mcsun!sunic!ugle.unit.no!lise.unit.no!arnej
From: arnej@Lise.Unit.NO (Arne Henrik Juul)
Newsgroups: comp.unix.bsd
Subject: [386bsd] FIX: Truncating when appending over NFS
Message-ID: <1992Aug28.024229.22985@ugle.unit.no>
Date: 28 Aug 92 02:42:29 GMT
Article-I.D.: ugle.1992Aug28.024229.22985
Sender: news@ugle.unit.no (NetNews Administrator)
Reply-To: arnej@lise.unit.no
Followup-To: comp.unix.bsd
Organization: Norwegian Institute of Technology
Lines: 89

Thanks to Ian Donaldson, I found - and fixed - the bug
which causes files to be truncated when opened for append via
NFS in certain configurations.

He said (some articles ago):
 > 
 > I fixed this exact bug in an ancient NFS port a few days ago (on a
 > SVR3.2 machine actually).  The problem was that the NFS server wasn't
 > interpreting the sattr information provided in the "NFS create" call
 > properly.
 > 
 > One field of sattr is the file size.  When you do creat() of the above
 > form, SunOS sends the file size attribute as -1 over the wire which
 > should mean to the server "don't change the file size".  The server is
 > probably ignoring this field and truncating the file unconditionally
 > (at least thats what the server I worked on did).
 > 
 > The fix was trivial... just recognize the size attribute and if -1,
 > leave the file size alone, otherwise truncate to the specified value.
 > 
 > Ian D

And this was exactly what was wrong. The file was always truncated if
it existed. The reason why it only happens when used from certain
NFS clients, is that some clients does not do a NFS create request at
all if the file already exists.

So everybody who are just waiting to run their 386bsd machines as file
servers, this is your patch :-)

*** nfs_serv.c.orig	Fri Aug 28 04:34:35 1992
--- nfs_serv.c	Fri Aug 28 04:40:29 1992
***************
*** 550,556 ****
  
  /*
   * nfs create service
!  * now does a truncate to 0 length via. setattr if it already exists
   */
  nfsrv_create(mrep, md, dpos, cred, xid, mrq, repstat, p)
  	struct mbuf *mrep, *md, **mrq;
--- 550,557 ----
  
  /*
   * nfs create service
!  * if it already exists, just set length
!  * do NOT truncate unconditionally !
   */
  nfsrv_create(mrep, md, dpos, cred, xid, mrq, repstat, p)
  	struct mbuf *mrep, *md, **mrq;
***************
*** 588,595 ****
  	VATTR_NULL(vap);
  	nfsm_disect(tl, u_long *, NFSX_SATTR);
  	/*
! 	 * Iff doesn't exist, create it
! 	 * otherwise just truncate to 0 length
  	 *   should I set the mode too ??
  	 */
  	if (nd.ni_vp == NULL) {
--- 589,596 ----
  	VATTR_NULL(vap);
  	nfsm_disect(tl, u_long *, NFSX_SATTR);
  	/*
! 	 * If it doesn't exist, create it
! 	 * otherwise just set length from attributes
  	 *   should I set the mode too ??
  	 */
  	if (nd.ni_vp == NULL) {
***************
*** 654,660 ****
  		else
  			vput(nd.ni_dvp);
  		VOP_ABORTOP(&nd);
! 		vap->va_size = 0;
  		if (error = VOP_SETATTR(vp, vap, cred, p)) {
  			vput(vp);
  			nfsm_reply(0);
--- 655,661 ----
  		else
  			vput(nd.ni_dvp);
  		VOP_ABORTOP(&nd);
! 		vap->va_size = fxdr_unsigned(long, *(tl+3));
  		if (error = VOP_SETATTR(vp, vap, cred, p)) {
  			vput(vp);
  			nfsm_reply(0);

--
Arne H. Juul  --  arnej@lise.unit.no  --  University of Trondheim, Norway