From 213db2103e6330ef8205522e5abb4dc9481c6c3d Mon Sep 17 00:00:00 2001 From: alc Date: Mon, 16 Jan 2012 00:26:49 +0000 Subject: [PATCH] When tmpfs_write() resets an extended file to its original size after an error, we want tmpfs_reg_resize() to ignore I/O errors and unconditionally update the file's size. Reviewed by: kib MFC after: 3 weeks --- sys/fs/tmpfs/tmpfs.h | 2 +- sys/fs/tmpfs/tmpfs_subr.c | 12 ++++++++---- sys/fs/tmpfs/tmpfs_vnops.c | 5 +++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h index fe00fea0c91c..efa7c6d41a23 100644 --- a/sys/fs/tmpfs/tmpfs.h +++ b/sys/fs/tmpfs/tmpfs.h @@ -436,7 +436,7 @@ struct tmpfs_dirent * tmpfs_dir_lookupbycookie(struct tmpfs_node *, off_t); int tmpfs_dir_getdents(struct tmpfs_node *, struct uio *, off_t *); int tmpfs_dir_whiteout_add(struct vnode *, struct componentname *); void tmpfs_dir_whiteout_remove(struct vnode *, struct componentname *); -int tmpfs_reg_resize(struct vnode *, off_t); +int tmpfs_reg_resize(struct vnode *, off_t, boolean_t); int tmpfs_chflags(struct vnode *, int, struct ucred *, struct thread *); int tmpfs_chmod(struct vnode *, mode_t, struct ucred *, struct thread *); int tmpfs_chown(struct vnode *, uid_t, gid_t, struct ucred *, diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index 94bc0bfa1987..d2b22454e793 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -882,7 +882,7 @@ tmpfs_dir_whiteout_remove(struct vnode *dvp, struct componentname *cnp) * Returns zero on success or an appropriate error code on failure. */ int -tmpfs_reg_resize(struct vnode *vp, off_t newsize) +tmpfs_reg_resize(struct vnode *vp, off_t newsize, boolean_t ignerr) { struct tmpfs_mount *tmp; struct tmpfs_node *node; @@ -952,8 +952,12 @@ retry: } else { vm_page_free(m); vm_page_unlock(m); - VM_OBJECT_UNLOCK(uobj); - return (EIO); + if (ignerr) + m = NULL; + else { + VM_OBJECT_UNLOCK(uobj); + return (EIO); + } } } if (m != NULL) { @@ -1351,7 +1355,7 @@ tmpfs_truncate(struct vnode *vp, off_t length) if (length > VFS_TO_TMPFS(vp->v_mount)->tm_maxfilesize) return (EFBIG); - error = tmpfs_reg_resize(vp, length); + error = tmpfs_reg_resize(vp, length, FALSE); if (error == 0) { node->tn_status |= TMPFS_NODE_CHANGED | TMPFS_NODE_MODIFIED; } diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index f0dfe36c3774..3f1482e6566b 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -747,7 +747,8 @@ tmpfs_write(struct vop_write_args *v) extended = uio->uio_offset + uio->uio_resid > node->tn_size; if (extended) { - error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid); + error = tmpfs_reg_resize(vp, uio->uio_offset + uio->uio_resid, + FALSE); if (error != 0) goto out; } @@ -773,7 +774,7 @@ tmpfs_write(struct vop_write_args *v) } if (error != 0) - (void)tmpfs_reg_resize(vp, oldsize); + (void)tmpfs_reg_resize(vp, oldsize, TRUE); out: MPASS(IMPLIES(error == 0, uio->uio_resid == 0));