diff options
author | alc <alc@FreeBSD.org> | 2012-01-16 00:26:49 +0000 |
---|---|---|
committer | alc <alc@FreeBSD.org> | 2012-01-16 00:26:49 +0000 |
commit | 213db2103e6330ef8205522e5abb4dc9481c6c3d (patch) | |
tree | ead83f2a8c9c0d57d631896299abc8a488aa7e10 /sys/fs | |
parent | 83920bc18511f0c34df0d3888ba7ebe90c39d3d8 (diff) | |
download | FreeBSD-src-213db2103e6330ef8205522e5abb4dc9481c6c3d.zip FreeBSD-src-213db2103e6330ef8205522e5abb4dc9481c6c3d.tar.gz |
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
Diffstat (limited to 'sys/fs')
-rw-r--r-- | sys/fs/tmpfs/tmpfs.h | 2 | ||||
-rw-r--r-- | sys/fs/tmpfs/tmpfs_subr.c | 12 | ||||
-rw-r--r-- | 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 fe00fea..efa7c6d 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 94bc0bf..d2b2245 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 f0dfe36..3f1482e 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)); |