Thu Aug 29 06:43:13 2019 UTC ()
Add missing operation VOP_GETPAGES() returning EFAULT.

Without this operation posix_fadvise(..., POSIX_FADV_WILLNEED)
would leave the v_interlock held.

Observed by maxv@


(hannken)
diff -r1.160 -r1.161 src/sys/miscfs/kernfs/kernfs_vnops.c
diff -r1.206 -r1.207 src/sys/miscfs/procfs/procfs_vnops.c

cvs diff -r1.160 -r1.161 src/sys/miscfs/kernfs/kernfs_vnops.c (expand / switch to unified diff)

--- src/sys/miscfs/kernfs/kernfs_vnops.c 2018/09/03 16:29:35 1.160
+++ src/sys/miscfs/kernfs/kernfs_vnops.c 2019/08/29 06:43:13 1.161
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kernfs_vnops.c,v 1.160 2018/09/03 16:29:35 riastradh Exp $ */ 1/* $NetBSD: kernfs_vnops.c,v 1.161 2019/08/29 06:43:13 hannken Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1992, 1993 4 * Copyright (c) 1992, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software donated to Berkeley by 7 * This code is derived from software donated to Berkeley by
8 * Jan-Simon Pendry. 8 * Jan-Simon Pendry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -29,27 +29,27 @@ @@ -29,27 +29,27 @@
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE. 32 * SUCH DAMAGE.
33 * 33 *
34 * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95 34 * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95
35 */ 35 */
36 36
37/* 37/*
38 * Kernel parameter filesystem (/kern) 38 * Kernel parameter filesystem (/kern)
39 */ 39 */
40 40
41#include <sys/cdefs.h> 41#include <sys/cdefs.h>
42__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.160 2018/09/03 16:29:35 riastradh Exp $"); 42__KERNEL_RCSID(0, "$NetBSD: kernfs_vnops.c,v 1.161 2019/08/29 06:43:13 hannken Exp $");
43 43
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/systm.h> 45#include <sys/systm.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/vmmeter.h> 47#include <sys/vmmeter.h>
48#include <sys/time.h> 48#include <sys/time.h>
49#include <sys/proc.h> 49#include <sys/proc.h>
50#include <sys/vnode.h> 50#include <sys/vnode.h>
51#include <sys/malloc.h> 51#include <sys/malloc.h>
52#include <sys/file.h> 52#include <sys/file.h>
53#include <sys/stat.h> 53#include <sys/stat.h>
54#include <sys/mount.h> 54#include <sys/mount.h>
55#include <sys/namei.h> 55#include <sys/namei.h>
@@ -162,26 +162,27 @@ int kernfs_readdir(void *); @@ -162,26 +162,27 @@ int kernfs_readdir(void *);
162#define kernfs_readlink genfs_eopnotsupp 162#define kernfs_readlink genfs_eopnotsupp
163#define kernfs_abortop genfs_abortop 163#define kernfs_abortop genfs_abortop
164int kernfs_inactive(void *); 164int kernfs_inactive(void *);
165int kernfs_reclaim(void *); 165int kernfs_reclaim(void *);
166#define kernfs_lock genfs_lock 166#define kernfs_lock genfs_lock
167#define kernfs_unlock genfs_unlock 167#define kernfs_unlock genfs_unlock
168#define kernfs_bmap genfs_badop 168#define kernfs_bmap genfs_badop
169#define kernfs_strategy genfs_badop 169#define kernfs_strategy genfs_badop
170int kernfs_print(void *); 170int kernfs_print(void *);
171#define kernfs_islocked genfs_islocked 171#define kernfs_islocked genfs_islocked
172int kernfs_pathconf(void *); 172int kernfs_pathconf(void *);
173#define kernfs_advlock genfs_einval 173#define kernfs_advlock genfs_einval
174#define kernfs_bwrite genfs_eopnotsupp 174#define kernfs_bwrite genfs_eopnotsupp
 175int kernfs_getpages(void *);
175#define kernfs_putpages genfs_putpages 176#define kernfs_putpages genfs_putpages
176 177
177static int kernfs_xread(struct kernfs_node *, int, char **, 178static int kernfs_xread(struct kernfs_node *, int, char **,
178 size_t, size_t *); 179 size_t, size_t *);
179static int kernfs_xwrite(const struct kernfs_node *, char *, size_t); 180static int kernfs_xwrite(const struct kernfs_node *, char *, size_t);
180 181
181int (**kernfs_vnodeop_p)(void *); 182int (**kernfs_vnodeop_p)(void *);
182const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = { 183const struct vnodeopv_entry_desc kernfs_vnodeop_entries[] = {
183 { &vop_default_desc, vn_default_error }, 184 { &vop_default_desc, vn_default_error },
184 { &vop_lookup_desc, kernfs_lookup }, /* lookup */ 185 { &vop_lookup_desc, kernfs_lookup }, /* lookup */
185 { &vop_create_desc, kernfs_create }, /* create */ 186 { &vop_create_desc, kernfs_create }, /* create */
186 { &vop_mknod_desc, kernfs_mknod }, /* mknod */ 187 { &vop_mknod_desc, kernfs_mknod }, /* mknod */
187 { &vop_open_desc, kernfs_open }, /* open */ 188 { &vop_open_desc, kernfs_open }, /* open */
@@ -209,26 +210,27 @@ const struct vnodeopv_entry_desc kernfs_ @@ -209,26 +210,27 @@ const struct vnodeopv_entry_desc kernfs_
209 { &vop_readlink_desc, kernfs_readlink }, /* readlink */ 210 { &vop_readlink_desc, kernfs_readlink }, /* readlink */
210 { &vop_abortop_desc, kernfs_abortop }, /* abortop */ 211 { &vop_abortop_desc, kernfs_abortop }, /* abortop */
211 { &vop_inactive_desc, kernfs_inactive }, /* inactive */ 212 { &vop_inactive_desc, kernfs_inactive }, /* inactive */
212 { &vop_reclaim_desc, kernfs_reclaim }, /* reclaim */ 213 { &vop_reclaim_desc, kernfs_reclaim }, /* reclaim */
213 { &vop_lock_desc, kernfs_lock }, /* lock */ 214 { &vop_lock_desc, kernfs_lock }, /* lock */
214 { &vop_unlock_desc, kernfs_unlock }, /* unlock */ 215 { &vop_unlock_desc, kernfs_unlock }, /* unlock */
215 { &vop_bmap_desc, kernfs_bmap }, /* bmap */ 216 { &vop_bmap_desc, kernfs_bmap }, /* bmap */
216 { &vop_strategy_desc, kernfs_strategy }, /* strategy */ 217 { &vop_strategy_desc, kernfs_strategy }, /* strategy */
217 { &vop_print_desc, kernfs_print }, /* print */ 218 { &vop_print_desc, kernfs_print }, /* print */
218 { &vop_islocked_desc, kernfs_islocked }, /* islocked */ 219 { &vop_islocked_desc, kernfs_islocked }, /* islocked */
219 { &vop_pathconf_desc, kernfs_pathconf }, /* pathconf */ 220 { &vop_pathconf_desc, kernfs_pathconf }, /* pathconf */
220 { &vop_advlock_desc, kernfs_advlock }, /* advlock */ 221 { &vop_advlock_desc, kernfs_advlock }, /* advlock */
221 { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */ 222 { &vop_bwrite_desc, kernfs_bwrite }, /* bwrite */
 223 { &vop_getpages_desc, kernfs_getpages }, /* getpages */
222 { &vop_putpages_desc, kernfs_putpages }, /* putpages */ 224 { &vop_putpages_desc, kernfs_putpages }, /* putpages */
223 { NULL, NULL } 225 { NULL, NULL }
224}; 226};
225const struct vnodeopv_desc kernfs_vnodeop_opv_desc = 227const struct vnodeopv_desc kernfs_vnodeop_opv_desc =
226 { &kernfs_vnodeop_p, kernfs_vnodeop_entries }; 228 { &kernfs_vnodeop_p, kernfs_vnodeop_entries };
227 229
228static inline int 230static inline int
229kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b) 231kernfs_fileop_compare(struct kernfs_fileop *a, struct kernfs_fileop *b)
230{ 232{
231 if (a->kf_type < b->kf_type) 233 if (a->kf_type < b->kf_type)
232 return -1; 234 return -1;
233 if (a->kf_type > b->kf_type) 235 if (a->kf_type > b->kf_type)
234 return 1; 236 return 1;
@@ -1159,13 +1161,33 @@ int @@ -1159,13 +1161,33 @@ int
1159kernfs_symlink(void *v) 1161kernfs_symlink(void *v)
1160{ 1162{
1161 struct vop_symlink_v3_args /* { 1163 struct vop_symlink_v3_args /* {
1162 struct vnode *a_dvp; 1164 struct vnode *a_dvp;
1163 struct vnode **a_vpp; 1165 struct vnode **a_vpp;
1164 struct componentname *a_cnp; 1166 struct componentname *a_cnp;
1165 struct vattr *a_vap; 1167 struct vattr *a_vap;
1166 char *a_target; 1168 char *a_target;
1167 } */ *ap = v; 1169 } */ *ap = v;
1168 1170
1169 VOP_ABORTOP(ap->a_dvp, ap->a_cnp); 1171 VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
1170 return (EROFS); 1172 return (EROFS);
1171} 1173}
 1174
 1175int
 1176kernfs_getpages(void *v)
 1177{
 1178 struct vop_getpages_args /* {
 1179 struct vnode *a_vp;
 1180 voff_t a_offset;
 1181 struct vm_page **a_m;
 1182 int *a_count;
 1183 int a_centeridx;
 1184 vm_prot_t a_access_type;
 1185 int a_advice;
 1186 int a_flags;
 1187 } */ *ap = v;
 1188
 1189 if ((ap->a_flags & PGO_LOCKED) == 0)
 1190 mutex_exit(ap->a_vp->v_interlock);
 1191
 1192 return (EFAULT);
 1193}

cvs diff -r1.206 -r1.207 src/sys/miscfs/procfs/procfs_vnops.c (expand / switch to unified diff)

--- src/sys/miscfs/procfs/procfs_vnops.c 2019/03/30 23:28:30 1.206
+++ src/sys/miscfs/procfs/procfs_vnops.c 2019/08/29 06:43:13 1.207
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: procfs_vnops.c,v 1.206 2019/03/30 23:28:30 christos Exp $ */ 1/* $NetBSD: procfs_vnops.c,v 1.207 2019/08/29 06:43:13 hannken Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2006, 2007, 2008 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 Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -95,27 +95,27 @@ @@ -95,27 +95,27 @@
95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98 * SUCH DAMAGE. 98 * SUCH DAMAGE.
99 * 99 *
100 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 100 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
101 */ 101 */
102 102
103/* 103/*
104 * procfs vnode interface 104 * procfs vnode interface
105 */ 105 */
106 106
107#include <sys/cdefs.h> 107#include <sys/cdefs.h>
108__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.206 2019/03/30 23:28:30 christos Exp $"); 108__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.207 2019/08/29 06:43:13 hannken Exp $");
109 109
110#include <sys/param.h> 110#include <sys/param.h>
111#include <sys/systm.h> 111#include <sys/systm.h>
112#include <sys/time.h> 112#include <sys/time.h>
113#include <sys/kernel.h> 113#include <sys/kernel.h>
114#include <sys/file.h> 114#include <sys/file.h>
115#include <sys/filedesc.h> 115#include <sys/filedesc.h>
116#include <sys/proc.h> 116#include <sys/proc.h>
117#include <sys/vnode.h> 117#include <sys/vnode.h>
118#include <sys/namei.h> 118#include <sys/namei.h>
119#include <sys/malloc.h> 119#include <sys/malloc.h>
120#include <sys/mount.h> 120#include <sys/mount.h>
121#include <sys/dirent.h> 121#include <sys/dirent.h>
@@ -233,26 +233,27 @@ int procfs_readdir(void *); @@ -233,26 +233,27 @@ int procfs_readdir(void *);
233int procfs_readlink(void *); 233int procfs_readlink(void *);
234#define procfs_abortop genfs_abortop 234#define procfs_abortop genfs_abortop
235int procfs_inactive(void *); 235int procfs_inactive(void *);
236int procfs_reclaim(void *); 236int procfs_reclaim(void *);
237#define procfs_lock genfs_lock 237#define procfs_lock genfs_lock
238#define procfs_unlock genfs_unlock 238#define procfs_unlock genfs_unlock
239#define procfs_bmap genfs_badop 239#define procfs_bmap genfs_badop
240#define procfs_strategy genfs_badop 240#define procfs_strategy genfs_badop
241int procfs_print(void *); 241int procfs_print(void *);
242int procfs_pathconf(void *); 242int procfs_pathconf(void *);
243#define procfs_islocked genfs_islocked 243#define procfs_islocked genfs_islocked
244#define procfs_advlock genfs_einval 244#define procfs_advlock genfs_einval
245#define procfs_bwrite genfs_eopnotsupp 245#define procfs_bwrite genfs_eopnotsupp
 246int procfs_getpages(void *);
246#define procfs_putpages genfs_null_putpages 247#define procfs_putpages genfs_null_putpages
247 248
248static int atoi(const char *, size_t); 249static int atoi(const char *, size_t);
249 250
250/* 251/*
251 * procfs vnode operations. 252 * procfs vnode operations.
252 */ 253 */
253int (**procfs_vnodeop_p)(void *); 254int (**procfs_vnodeop_p)(void *);
254const struct vnodeopv_entry_desc procfs_vnodeop_entries[] = { 255const struct vnodeopv_entry_desc procfs_vnodeop_entries[] = {
255 { &vop_default_desc, vn_default_error }, 256 { &vop_default_desc, vn_default_error },
256 { &vop_lookup_desc, procfs_lookup }, /* lookup */ 257 { &vop_lookup_desc, procfs_lookup }, /* lookup */
257 { &vop_create_desc, procfs_create }, /* create */ 258 { &vop_create_desc, procfs_create }, /* create */
258 { &vop_mknod_desc, procfs_mknod }, /* mknod */ 259 { &vop_mknod_desc, procfs_mknod }, /* mknod */
@@ -281,26 +282,27 @@ const struct vnodeopv_entry_desc procfs_ @@ -281,26 +282,27 @@ const struct vnodeopv_entry_desc procfs_
281 { &vop_readdir_desc, procfs_readdir }, /* readdir */ 282 { &vop_readdir_desc, procfs_readdir }, /* readdir */
282 { &vop_readlink_desc, procfs_readlink }, /* readlink */ 283 { &vop_readlink_desc, procfs_readlink }, /* readlink */
283 { &vop_abortop_desc, procfs_abortop }, /* abortop */ 284 { &vop_abortop_desc, procfs_abortop }, /* abortop */
284 { &vop_inactive_desc, procfs_inactive }, /* inactive */ 285 { &vop_inactive_desc, procfs_inactive }, /* inactive */
285 { &vop_reclaim_desc, procfs_reclaim }, /* reclaim */ 286 { &vop_reclaim_desc, procfs_reclaim }, /* reclaim */
286 { &vop_lock_desc, procfs_lock }, /* lock */ 287 { &vop_lock_desc, procfs_lock }, /* lock */
287 { &vop_unlock_desc, procfs_unlock }, /* unlock */ 288 { &vop_unlock_desc, procfs_unlock }, /* unlock */
288 { &vop_bmap_desc, procfs_bmap }, /* bmap */ 289 { &vop_bmap_desc, procfs_bmap }, /* bmap */
289 { &vop_strategy_desc, procfs_strategy }, /* strategy */ 290 { &vop_strategy_desc, procfs_strategy }, /* strategy */
290 { &vop_print_desc, procfs_print }, /* print */ 291 { &vop_print_desc, procfs_print }, /* print */
291 { &vop_islocked_desc, procfs_islocked }, /* islocked */ 292 { &vop_islocked_desc, procfs_islocked }, /* islocked */
292 { &vop_pathconf_desc, procfs_pathconf }, /* pathconf */ 293 { &vop_pathconf_desc, procfs_pathconf }, /* pathconf */
293 { &vop_advlock_desc, procfs_advlock }, /* advlock */ 294 { &vop_advlock_desc, procfs_advlock }, /* advlock */
 295 { &vop_getpages_desc, procfs_getpages }, /* getpages */
294 { &vop_putpages_desc, procfs_putpages }, /* putpages */ 296 { &vop_putpages_desc, procfs_putpages }, /* putpages */
295 { NULL, NULL } 297 { NULL, NULL }
296}; 298};
297const struct vnodeopv_desc procfs_vnodeop_opv_desc = 299const struct vnodeopv_desc procfs_vnodeop_opv_desc =
298 { &procfs_vnodeop_p, procfs_vnodeop_entries }; 300 { &procfs_vnodeop_p, procfs_vnodeop_entries };
299/* 301/*
300 * set things up for doing i/o on 302 * set things up for doing i/o on
301 * the pfsnode (vp). (vp) is locked 303 * the pfsnode (vp). (vp) is locked
302 * on entry, and should be left locked 304 * on entry, and should be left locked
303 * on exit. 305 * on exit.
304 * 306 *
305 * for procfs we don't need to do anything 307 * for procfs we don't need to do anything
306 * in particular for i/o. all that is done 308 * in particular for i/o. all that is done
@@ -1709,26 +1711,46 @@ procfs_readlink(void *v) @@ -1709,26 +1711,46 @@ procfs_readlink(void *v)
1709 }  1711 }
1710 closef(fp); 1712 closef(fp);
1711 } 1713 }
1712 1714
1713 if (error == 0) 1715 if (error == 0)
1714 error = uiomove(bp, len, ap->a_uio); 1716 error = uiomove(bp, len, ap->a_uio);
1715 if (pown) 1717 if (pown)
1716 procfs_proc_unlock(pown); 1718 procfs_proc_unlock(pown);
1717 if (path) 1719 if (path)
1718 free(path, M_TEMP); 1720 free(path, M_TEMP);
1719 return error; 1721 return error;
1720} 1722}
1721 1723
 1724int
 1725procfs_getpages(void *v)
 1726{
 1727 struct vop_getpages_args /* {
 1728 struct vnode *a_vp;
 1729 voff_t a_offset;
 1730 struct vm_page **a_m;
 1731 int *a_count;
 1732 int a_centeridx;
 1733 vm_prot_t a_access_type;
 1734 int a_advice;
 1735 int a_flags;
 1736 } */ *ap = v;
 1737
 1738 if ((ap->a_flags & PGO_LOCKED) == 0)
 1739 mutex_exit(ap->a_vp->v_interlock);
 1740
 1741 return (EFAULT);
 1742}
 1743
1722/* 1744/*
1723 * convert decimal ascii to int 1745 * convert decimal ascii to int
1724 */ 1746 */
1725static int 1747static int
1726atoi(const char *b, size_t len) 1748atoi(const char *b, size_t len)
1727{ 1749{
1728 int p = 0; 1750 int p = 0;
1729 1751
1730 while (len--) { 1752 while (len--) {
1731 char c = *b++; 1753 char c = *b++;
1732 if (c < '0' || c > '9') 1754 if (c < '0' || c > '9')
1733 return -1; 1755 return -1;
1734 p = 10 * p + (c - '0'); 1756 p = 10 * p + (c - '0');