Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src For devices, sockets and fifos ignore setting the file size ...
details: https://anonhg.NetBSD.org/src/rev/134a67e0e428
branches: trunk
changeset: 768164:134a67e0e428
user: hannken <hannken%NetBSD.org@localhost>
date: Wed Aug 10 06:27:02 2011 +0000
description:
For devices, sockets and fifos ignore setting the file size to zero to make
open(..., O_TRUNC) happy and allow them to write through the lower layer.
Fixes PR #43560 (writing to null device in unionfs fails)
diffstat:
sys/fs/union/union_vnops.c | 55 ++++++++++++++++++++++++++++++++++++---------
tests/fs/union/t_pr.c | 24 +++++++++----------
2 files changed, 55 insertions(+), 24 deletions(-)
diffs (166 lines):
diff -r bdc230317911 -r 134a67e0e428 sys/fs/union/union_vnops.c
--- a/sys/fs/union/union_vnops.c Wed Aug 10 06:19:54 2011 +0000
+++ b/sys/fs/union/union_vnops.c Wed Aug 10 06:27:02 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: union_vnops.c,v 1.42 2011/08/07 06:01:51 hannken Exp $ */
+/* $NetBSD: union_vnops.c,v 1.43 2011/08/10 06:27:02 hannken Exp $ */
/*
* Copyright (c) 1992, 1993, 1994, 1995
@@ -72,7 +72,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.42 2011/08/07 06:01:51 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: union_vnops.c,v 1.43 2011/08/10 06:27:02 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -888,12 +888,14 @@
struct vattr *vap = ap->a_vap;
struct vnode *vp = ap->a_vp;
struct union_node *un = VTOUNION(vp);
+ bool size_only; /* All but va_size are VNOVAL. */
int error;
- if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
- vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
- vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
- (vp->v_mount->mnt_flag & MNT_RDONLY))
+ size_only = (vap->va_flags == VNOVAL && vap->va_uid == (uid_t)VNOVAL &&
+ vap->va_gid == (gid_t)VNOVAL && vap->va_atime.tv_sec == VNOVAL &&
+ vap->va_mtime.tv_sec == VNOVAL && vap->va_mode == (mode_t)VNOVAL);
+
+ if (!size_only && (vp->v_mount->mnt_flag & MNT_RDONLY))
return (EROFS);
if (vap->va_size != VNOVAL) {
switch (vp->v_type) {
@@ -931,8 +933,9 @@
}
/*
- * Try to set attributes in upper layer,
- * otherwise return read-only filesystem error.
+ * Try to set attributes in upper layer, ignore size change to zero
+ * for devices to handle O_TRUNC and return read-only filesystem error
+ * otherwise.
*/
if (un->un_uppervp != NULLVP) {
FIXUP(un);
@@ -940,7 +943,22 @@
if ((error == 0) && (vap->va_size != VNOVAL))
union_newsize(ap->a_vp, vap->va_size, VNOVAL);
} else {
- error = EROFS;
+ KASSERT(un->un_lowervp != NULLVP);
+ switch (un->un_lowervp->v_type) {
+ case VCHR:
+ case VBLK:
+ case VSOCK:
+ case VFIFO:
+ if (size_only &&
+ (vap->va_size == 0 || vap->va_size == VNOVAL))
+ error = 0;
+ else
+ error = EROFS;
+ break;
+ default:
+ error = EROFS;
+ break;
+ }
}
return (error);
@@ -1003,8 +1021,23 @@
struct union_node *un = VTOUNION(ap->a_vp);
vp = UPPERVP(ap->a_vp);
- if (vp == NULLVP)
- panic("union: missing upper layer in write");
+ if (vp == NULLVP) {
+ vp = LOWERVP(ap->a_vp);
+ KASSERT(vp != NULL);
+ switch (vp->v_type) {
+ case VBLK:
+ case VCHR:
+ case VSOCK:
+ case VFIFO:
+ vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
+ error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag,
+ ap->a_cred);
+ VOP_UNLOCK(vp);
+ return error;
+ default:
+ panic("union: missing upper layer in write");
+ }
+ }
FIXUP(un);
error = VOP_WRITE(vp, ap->a_uio, ap->a_ioflag, ap->a_cred);
diff -r bdc230317911 -r 134a67e0e428 tests/fs/union/t_pr.c
--- a/tests/fs/union/t_pr.c Wed Aug 10 06:19:54 2011 +0000
+++ b/tests/fs/union/t_pr.c Wed Aug 10 06:27:02 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_pr.c,v 1.7 2010/07/03 13:37:22 pooka Exp $ */
+/* $NetBSD: t_pr.c,v 1.8 2011/08/10 06:27:02 hannken Exp $ */
#include <sys/types.h>
#include <sys/mount.h>
@@ -50,7 +50,6 @@
unionargs.target = __UNCONST("/Tunion2/B");
unionargs.mntflags = UNMNT_BELOW;
- /* atf_tc_expect_signal(-1, "PR kern/23986"); */
rump_sys_mount(MOUNT_UNION, "/Tunion", 0,&unionargs,sizeof(unionargs));
}
@@ -64,7 +63,7 @@
ATF_TC_BODY(devnull1, tc)
{
struct union_args unionargs;
- int fd;
+ int fd, res;
rump_init();
@@ -80,14 +79,12 @@
fd = rump_sys_open("/mp/null", O_WRONLY | O_CREAT | O_TRUNC);
- atf_tc_expect_fail("PR kern/43560");
- if (fd == -1 && errno == EROFS) {
- atf_tc_fail("open returned EROFS");
- } else if (fd == -1) {
- atf_tc_expect_pass();
- atf_tc_fail_errno("open fail");
- }
+ if (fd == -1)
+ atf_tc_fail_errno("open");
+ res = rump_sys_write(fd, &fd, sizeof(fd));
+ if (res != sizeof(fd))
+ atf_tc_fail("write");
}
ATF_TC(devnull2);
@@ -100,7 +97,7 @@
ATF_TC_BODY(devnull2, tc)
{
struct union_args unionargs;
- int fd;
+ int fd, res;
rump_init();
@@ -118,8 +115,9 @@
if (fd == -1)
atf_tc_fail_errno("open");
- atf_tc_expect_signal(-1, "PR kern/43560");
- rump_sys_write(fd, &fd, sizeof(fd));
+ res = rump_sys_write(fd, &fd, sizeof(fd));
+ if (res != sizeof(fd))
+ atf_tc_fail("write");
}
ATF_TP_ADD_TCS(tp)
Home |
Main Index |
Thread Index |
Old Index