NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: kern/49310: random errno values from truncate



The following reply was made to PR kern/49310; it has been noted by GNATS.

From: Martin Husemann <martin%duskware.de@localhost>
To: gnats-bugs%NetBSD.org@localhost
Cc: 
Subject: Re: kern/49310: random errno values from truncate
Date: Tue, 28 Oct 2014 14:57:29 +0100

 This is caused by uninitialized use of the automatic variable "error",
 and has been there since we got wapbl. The changes in stack usage
 only exposed it.
 
 Besides, there was a minor glitch with kauth credentials not being passed
 in the call from ufs_setattr(), plus some additional size checks from
 Joerg. Additionally we moved one check into ufs_wapbl_truncate().
 
 The below patch fixes the issue for me, doing a full test run now.
 
 Martin
 
 
 Index: ufs_extern.h
 ===================================================================
 RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extern.h,v
 retrieving revision 1.76
 diff -u -p -r1.76 ufs_extern.h
 --- ufs_extern.h	21 Oct 2014 10:39:26 -0000	1.76
 +++ ufs_extern.h	28 Oct 2014 13:53:14 -0000
 @@ -111,7 +111,7 @@ int	ufs_getlbns(struct vnode *, daddr_t,
  /* ufs_inode.c */
  int	ufs_reclaim(struct vnode *);
  int	ufs_balloc_range(struct vnode *, off_t, off_t, kauth_cred_t, int);
 -int	ufs_wapbl_truncate(struct vnode *, uint64_t, uint64_t, uint64_t);
 +int	ufs_wapbl_truncate(struct vnode *, uint64_t, uint64_t, uint64_t, kauth_cred_t);
  
  /* ufs_lookup.c */
  void	ufs_dirbad(struct inode *, doff_t, const char *);
 Index: ufs_inode.c
 ===================================================================
 RCS file: /cvsroot/src/sys/ufs/ufs/ufs_inode.c,v
 retrieving revision 1.91
 diff -u -p -r1.91 ufs_inode.c
 --- ufs_inode.c	21 Oct 2014 10:39:26 -0000	1.91
 +++ ufs_inode.c	28 Oct 2014 13:53:14 -0000
 @@ -111,8 +111,9 @@ ufs_inactive(void *v)
  			 * When journaling, only truncate one indirect block
  			 * at a time
  			 */
 -			if (vp->v_mount->mnt_wapbl && ip->i_size > base + incr) {
 -				error = ufs_wapbl_truncate(vp, incr, base, 0);
 +			if (vp->v_mount->mnt_wapbl) {
 +				error = ufs_wapbl_truncate(vp, incr, base, 0,
 +				    NOCRED);
  			}
  			if (!error) {
  				error = UFS_WAPBL_BEGIN(vp->v_mount);
 @@ -297,23 +298,28 @@ ufs_balloc_range(struct vnode *vp, off_t
  
  int
  ufs_wapbl_truncate(struct vnode *vp, uint64_t incr, uint64_t base,
 -    uint64_t newsize)
 +    uint64_t newsize, kauth_cred_t cred)
  {
  	struct inode *ip = VTOI(vp);
  	int error;
  
 +	if (newsize < base)
 +		newsize = base;
 +	if (ip->i_size <= newsize + incr)
 +		return 0;	/* Short enough */
 +
  	error = UFS_WAPBL_BEGIN(vp->v_mount);
  	if (error)
  		return error;
  
 -	while (ip->i_size > base + incr) {
 +	while (ip->i_size > newsize + incr) {
  		/*
  		 * round down to next full indirect
  		 * block boundary.
  		 */
  		uint64_t nsize =
  		    base + ((ip->i_size - base - 1) & ~(incr - 1));
 -		error = UFS_TRUNCATE(vp, nsize, 0, NOCRED);
 +		error = UFS_TRUNCATE(vp, nsize, 0, cred);
  		if (error)
  			break;
  		UFS_WAPBL_END(vp->v_mount);
 Index: ufs_vnops.c
 ===================================================================
 RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v
 retrieving revision 1.223
 diff -u -p -r1.223 ufs_vnops.c
 --- ufs_vnops.c	21 Oct 2014 10:39:26 -0000	1.223
 +++ ufs_vnops.c	28 Oct 2014 13:53:14 -0000
 @@ -589,9 +589,10 @@ ufs_setattr(void *v)
  			 * When journaling, only truncate one indirect block
  			 * at a time.
  			 */
 -			if (vp->v_mount->mnt_wapbl && ip->i_size > base + incr) {
 +			error = 0;
 +			if (vp->v_mount->mnt_wapbl) {
  				error = ufs_wapbl_truncate(vp, incr, base,
 -				    vap->va_size);
 +				    vap->va_size, cred);
  			}
  			if (!error) {
  				error = UFS_WAPBL_BEGIN(vp->v_mount);
 


Home | Main Index | Thread Index | Old Index