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