Thu Mar 30 09:09:26 2017 UTC ()
Protect tmpfs_getpages() against reclaiming vnodes.


(hannken)
diff -r1.129 -r1.130 src/sys/fs/tmpfs/tmpfs_vnops.c

cvs diff -r1.129 -r1.130 src/sys/fs/tmpfs/tmpfs_vnops.c (expand / switch to unified diff)

--- src/sys/fs/tmpfs/tmpfs_vnops.c 2017/01/11 12:12:32 1.129
+++ src/sys/fs/tmpfs/tmpfs_vnops.c 2017/03/30 09:09:26 1.130
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: tmpfs_vnops.c,v 1.129 2017/01/11 12:12:32 joerg Exp $ */ 1/* $NetBSD: tmpfs_vnops.c,v 1.130 2017/03/30 09:09:26 hannken Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code 8 * by Julio M. Merino Vidal, developed as part of Google's Summer of Code
9 * 2005 program. 9 * 2005 program.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -25,27 +25,27 @@ @@ -25,27 +25,27 @@
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33/* 33/*
34 * tmpfs vnode interface. 34 * tmpfs vnode interface.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.129 2017/01/11 12:12:32 joerg Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: tmpfs_vnops.c,v 1.130 2017/03/30 09:09:26 hannken Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/dirent.h> 41#include <sys/dirent.h>
42#include <sys/fcntl.h> 42#include <sys/fcntl.h>
43#include <sys/event.h> 43#include <sys/event.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
45#include <sys/namei.h> 45#include <sys/namei.h>
46#include <sys/stat.h> 46#include <sys/stat.h>
47#include <sys/uio.h> 47#include <sys/uio.h>
48#include <sys/unistd.h> 48#include <sys/unistd.h>
49#include <sys/vnode.h> 49#include <sys/vnode.h>
50#include <sys/lockf.h> 50#include <sys/lockf.h>
51#include <sys/kauth.h> 51#include <sys/kauth.h>
@@ -1155,45 +1155,48 @@ tmpfs_getpages(void *v) @@ -1155,45 +1155,48 @@ tmpfs_getpages(void *v)
1155 const voff_t offset = ap->a_offset; 1155 const voff_t offset = ap->a_offset;
1156 struct vm_page **pgs = ap->a_m; 1156 struct vm_page **pgs = ap->a_m;
1157 const int centeridx = ap->a_centeridx; 1157 const int centeridx = ap->a_centeridx;
1158 const vm_prot_t access_type = ap->a_access_type; 1158 const vm_prot_t access_type = ap->a_access_type;
1159 const int advice = ap->a_advice; 1159 const int advice = ap->a_advice;
1160 const int flags = ap->a_flags; 1160 const int flags = ap->a_flags;
1161 int error, npages = *ap->a_count; 1161 int error, npages = *ap->a_count;
1162 tmpfs_node_t *node; 1162 tmpfs_node_t *node;
1163 struct uvm_object *uobj; 1163 struct uvm_object *uobj;
1164 1164
1165 KASSERT(vp->v_type == VREG); 1165 KASSERT(vp->v_type == VREG);
1166 KASSERT(mutex_owned(vp->v_interlock)); 1166 KASSERT(mutex_owned(vp->v_interlock));
1167 1167
1168 node = VP_TO_TMPFS_NODE(vp); 
1169 uobj = node->tn_spec.tn_reg.tn_aobj; 
1170 
1171 /* 1168 /*
1172 * Currently, PGO_PASTEOF is not supported. 1169 * Currently, PGO_PASTEOF is not supported.
1173 */ 1170 */
1174 if (vp->v_size <= offset + (centeridx << PAGE_SHIFT)) { 1171 if (vp->v_size <= offset + (centeridx << PAGE_SHIFT)) {
1175 if ((flags & PGO_LOCKED) == 0) 1172 if ((flags & PGO_LOCKED) == 0)
1176 mutex_exit(vp->v_interlock); 1173 mutex_exit(vp->v_interlock);
1177 return EINVAL; 1174 return EINVAL;
1178 } 1175 }
1179 1176
1180 if (vp->v_size < offset + (npages << PAGE_SHIFT)) { 1177 if (vp->v_size < offset + (npages << PAGE_SHIFT)) {
1181 npages = (round_page(vp->v_size) - offset) >> PAGE_SHIFT; 1178 npages = (round_page(vp->v_size) - offset) >> PAGE_SHIFT;
1182 } 1179 }
1183 1180
1184 if ((flags & PGO_LOCKED) != 0) 1181 if ((flags & PGO_LOCKED) != 0)
1185 return EBUSY; 1182 return EBUSY;
1186 1183
 1184 if (vdead_check(vp, VDEAD_NOWAIT) != 0)
 1185 return ENOENT;
 1186
 1187 node = VP_TO_TMPFS_NODE(vp);
 1188 uobj = node->tn_spec.tn_reg.tn_aobj;
 1189
1187 if ((flags & PGO_NOTIMESTAMP) == 0) { 1190 if ((flags & PGO_NOTIMESTAMP) == 0) {
1188 u_int tflags = 0; 1191 u_int tflags = 0;
1189 1192
1190 if ((vp->v_mount->mnt_flag & MNT_NOATIME) == 0) 1193 if ((vp->v_mount->mnt_flag & MNT_NOATIME) == 0)
1191 tflags |= TMPFS_UPDATE_ATIME; 1194 tflags |= TMPFS_UPDATE_ATIME;
1192 1195
1193 if ((access_type & VM_PROT_WRITE) != 0) { 1196 if ((access_type & VM_PROT_WRITE) != 0) {
1194 tflags |= TMPFS_UPDATE_MTIME; 1197 tflags |= TMPFS_UPDATE_MTIME;
1195 if (vp->v_mount->mnt_flag & MNT_RELATIME) 1198 if (vp->v_mount->mnt_flag & MNT_RELATIME)
1196 tflags |= TMPFS_UPDATE_ATIME; 1199 tflags |= TMPFS_UPDATE_ATIME;
1197 } 1200 }
1198 tmpfs_update(vp, tflags); 1201 tmpfs_update(vp, tflags);
1199 } 1202 }