aboutsummaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorBruce Evans <bde@FreeBSD.org>1998-12-24 09:45:10 +0000
committerBruce Evans <bde@FreeBSD.org>1998-12-24 09:45:10 +0000
commitd26105a9ceae32edefdb94ee7b183533b67a5b55 (patch)
treef8a5465ca3105ebc1ee085840066ce4ef9f1e687 /sys/ufs
parent082a22b108ccd7de407210f87e88f92c974d9fd5 (diff)
downloadsrc-d26105a9ceae32edefdb94ee7b183533b67a5b55.tar.gz
src-d26105a9ceae32edefdb94ee7b183533b67a5b55.zip
Fixed null pointer panics which I introduced in rev.1.86. Vnodes
may be revoked, so vnop routines must be careful about accessing the vnode if they may have blocked. Fixed marking for update after successfully reading or writing 0 bytes. In this case, POSIX.1 specifies marking if and only if the requested count is nonzero, but rev.1.86 never marked.
Notes
Notes: svn path=/head/; revision=42042
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ufs/ufs_vnops.c26
1 files changed, 19 insertions, 7 deletions
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index 47578d0ee2a6..a0f0a53e413a 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* @(#)ufs_vnops.c 8.27 (Berkeley) 5/27/95
- * $Id: ufs_vnops.c,v 1.101 1998/12/09 02:06:27 eivind Exp $
+ * $Id: ufs_vnops.c,v 1.102 1998/12/20 12:36:01 dfr Exp $
*/
#include "opt_quota.h"
@@ -1810,13 +1810,19 @@ ufsspec_read(ap)
} */ *ap;
{
int error, resid;
+ struct inode *ip;
struct uio *uio;
uio = ap->a_uio;
resid = uio->uio_resid;
error = VOCALL(spec_vnodeop_p, VOFFSET(vop_read), ap);
- if (uio->uio_resid != resid)
- VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
+ /*
+ * The inode may have been revoked during the call, so it must not
+ * be accessed blindly here or in the other wrapper functions.
+ */
+ ip = VTOI(ap->a_vp);
+ if (ip != NULL && (uio->uio_resid != resid || error == 0 && resid != 0))
+ ip->i_flag |= IN_ACCESS;
return (error);
}
@@ -1833,12 +1839,14 @@ ufsspec_write(ap)
} */ *ap;
{
int error, resid;
+ struct inode *ip;
struct uio *uio;
uio = ap->a_uio;
resid = uio->uio_resid;
error = VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap);
- if (uio->uio_resid != resid)
+ ip = VTOI(ap->a_vp);
+ if (ip != NULL && (uio->uio_resid != resid || error == 0 && resid != 0))
VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
return (error);
}
@@ -1879,13 +1887,15 @@ ufsfifo_read(ap)
} */ *ap;
{
int error, resid;
+ struct inode *ip;
struct uio *uio;
uio = ap->a_uio;
resid = uio->uio_resid;
error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), ap);
- if (uio->uio_resid != resid &&
- (ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0)
+ ip = VTOI(ap->a_vp);
+ if ((ap->a_vp->v_mount->mnt_flag & MNT_NOATIME) == 0 && ip != NULL &&
+ (uio->uio_resid != resid || error == 0 && resid != 0))
VTOI(ap->a_vp)->i_flag |= IN_ACCESS;
return (error);
}
@@ -1903,12 +1913,14 @@ ufsfifo_write(ap)
} */ *ap;
{
int error, resid;
+ struct inode *ip;
struct uio *uio;
uio = ap->a_uio;
resid = uio->uio_resid;
error = VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), ap);
- if (uio->uio_resid != resid)
+ ip = VTOI(ap->a_vp);
+ if (ip != NULL && (uio->uio_resid != resid || error == 0 && resid != 0))
VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE;
return (error);
}