Mon Jul 19 01:30:25 2021 UTC ()
Abolish all the silly indirection macros for initializing vnode ops tables.

These are things of the form #define foofs_op genfs_op, or #define
foofs_op genfs_eopnotsupp, or similar. They serve no purpose besides
obfuscation, and have gotten cutpasted all over everywhere.

Part 2; cvs randomly didn't commit these changes before, and then hid
them from me until I touched the files to force it to rethink. Dunno
what happened.

There's probably more of these, going to have to scan the tree the
hard way.


(dholland)
diff -r1.60 -r1.61 src/sys/fs/cd9660/cd9660_vnops.c
diff -r1.220 -r1.221 src/sys/fs/puffs/puffs_vnops.c
diff -r1.14 -r1.15 src/sys/fs/tmpfs/tmpfs_fifoops.c
diff -r1.15 -r1.16 src/sys/fs/tmpfs/tmpfs_specops.c

cvs diff -r1.60 -r1.61 src/sys/fs/cd9660/cd9660_vnops.c (switch to unified diff)

--- src/sys/fs/cd9660/cd9660_vnops.c 2021/07/18 23:56:13 1.60
+++ src/sys/fs/cd9660/cd9660_vnops.c 2021/07/19 01:30:24 1.61
@@ -1,952 +1,937 @@ @@ -1,952 +1,937 @@
1/* $NetBSD: cd9660_vnops.c,v 1.60 2021/07/18 23:56:13 dholland Exp $ */ 1/* $NetBSD: cd9660_vnops.c,v 1.61 2021/07/19 01:30:24 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1994 4 * Copyright (c) 1994
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 contributed to Berkeley 7 * This code is derived from software contributed to Berkeley
8 * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension 8 * by Pace Willisson (pace@blitz.com). The Rock Ridge Extension
9 * Support code is derived from software contributed to Berkeley 9 * Support code is derived from software contributed to Berkeley
10 * by Atsushi Murai (amurai@spec.co.jp). 10 * by Atsushi Murai (amurai@spec.co.jp).
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
15 * 1. Redistributions of source code must retain the above copyright 15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer. 16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright 17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the 18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution. 19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors 20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software 21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission. 22 * without specific prior written permission.
23 * 23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE. 34 * SUCH DAMAGE.
35 * 35 *
36 * @(#)cd9660_vnops.c 8.15 (Berkeley) 5/27/95 36 * @(#)cd9660_vnops.c 8.15 (Berkeley) 5/27/95
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.60 2021/07/18 23:56:13 dholland Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: cd9660_vnops.c,v 1.61 2021/07/19 01:30:24 dholland Exp $");
41 41
42#include <sys/param.h> 42#include <sys/param.h>
43#include <sys/systm.h> 43#include <sys/systm.h>
44#include <sys/namei.h> 44#include <sys/namei.h>
45#include <sys/resourcevar.h> 45#include <sys/resourcevar.h>
46#include <sys/kernel.h> 46#include <sys/kernel.h>
47#include <sys/file.h> 47#include <sys/file.h>
48#include <sys/stat.h> 48#include <sys/stat.h>
49#include <sys/buf.h> 49#include <sys/buf.h>
50#include <sys/proc.h> 50#include <sys/proc.h>
51#include <sys/mount.h> 51#include <sys/mount.h>
52#include <sys/vnode.h> 52#include <sys/vnode.h>
53#include <sys/malloc.h> 53#include <sys/malloc.h>
54#include <sys/dirent.h> 54#include <sys/dirent.h>
55#include <sys/kauth.h> 55#include <sys/kauth.h>
56 56
57#include <miscfs/fifofs/fifo.h> 57#include <miscfs/fifofs/fifo.h>
58#include <miscfs/genfs/genfs.h> 58#include <miscfs/genfs/genfs.h>
59#include <miscfs/specfs/specdev.h> 59#include <miscfs/specfs/specdev.h>
60 60
61#include <fs/cd9660/iso.h> 61#include <fs/cd9660/iso.h>
62#include <fs/cd9660/cd9660_extern.h> 62#include <fs/cd9660/cd9660_extern.h>
63#include <fs/cd9660/cd9660_node.h> 63#include <fs/cd9660/cd9660_node.h>
64#include <fs/cd9660/iso_rrip.h> 64#include <fs/cd9660/iso_rrip.h>
65#include <fs/cd9660/cd9660_mount.h> 65#include <fs/cd9660/cd9660_mount.h>
66 66
67/* 67/*
68 * Structure for reading directories 68 * Structure for reading directories
69 */ 69 */
70struct isoreaddir { 70struct isoreaddir {
71 struct dirent saveent; 71 struct dirent saveent;
72 struct dirent assocent; 72 struct dirent assocent;
73 struct dirent current; 73 struct dirent current;
74 off_t saveoff; 74 off_t saveoff;
75 off_t assocoff; 75 off_t assocoff;
76 off_t curroff; 76 off_t curroff;
77 struct uio *uio; 77 struct uio *uio;
78 off_t uio_off; 78 off_t uio_off;
79 int eofflag; 79 int eofflag;
80 off_t *cookies; 80 off_t *cookies;
81 int ncookies; 81 int ncookies;
82}; 82};
83 83
84int iso_uiodir(struct isoreaddir *, struct dirent *, off_t); 84int iso_uiodir(struct isoreaddir *, struct dirent *, off_t);
85int iso_shipdir(struct isoreaddir *); 85int iso_shipdir(struct isoreaddir *);
86 86
87static int 87static int
88cd9660_check_possible(struct vnode *vp, struct iso_node *ip, accmode_t accmode) 88cd9660_check_possible(struct vnode *vp, struct iso_node *ip, accmode_t accmode)
89{ 89{
90 90
91 /* 91 /*
92 * Disallow write attempts unless the file is a socket, 92 * Disallow write attempts unless the file is a socket,
93 * fifo, or a block or character device resident on the 93 * fifo, or a block or character device resident on the
94 * file system. 94 * file system.
95 */ 95 */
96 if (accmode & VWRITE) { 96 if (accmode & VWRITE) {
97 switch (vp->v_type) { 97 switch (vp->v_type) {
98 case VDIR: 98 case VDIR:
99 case VLNK: 99 case VLNK:
100 case VREG: 100 case VREG:
101 return (EROFS); 101 return (EROFS);
102 default: 102 default:
103 break; 103 break;
104 } 104 }
105 } 105 }
106 106
107 return 0; 107 return 0;
108} 108}
109 109
110/* 110/*
111 * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC. 111 * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
112 * The mode is shifted to select the owner/group/other fields. The 112 * The mode is shifted to select the owner/group/other fields. The
113 * super user is granted all permissions. 113 * super user is granted all permissions.
114 */ 114 */
115static int 115static int
116cd9660_check_permitted(struct vnode *vp, struct iso_node *ip, accmode_t accmode, 116cd9660_check_permitted(struct vnode *vp, struct iso_node *ip, accmode_t accmode,
117 kauth_cred_t cred) 117 kauth_cred_t cred)
118{ 118{
119 119
120 return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(accmode, 120 return kauth_authorize_vnode(cred, KAUTH_ACCESS_ACTION(accmode,
121 vp->v_type, ip->inode.iso_mode & ALLPERMS), vp, NULL, 121 vp->v_type, ip->inode.iso_mode & ALLPERMS), vp, NULL,
122 genfs_can_access(vp, cred, ip->inode.iso_uid, ip->inode.iso_gid, 122 genfs_can_access(vp, cred, ip->inode.iso_uid, ip->inode.iso_gid,
123 ip->inode.iso_mode & ALLPERMS, NULL, accmode)); 123 ip->inode.iso_mode & ALLPERMS, NULL, accmode));
124} 124}
125 125
126int 126int
127cd9660_access(void *v) 127cd9660_access(void *v)
128{ 128{
129 struct vop_access_args /* { 129 struct vop_access_args /* {
130 struct vnode *a_vp; 130 struct vnode *a_vp;
131 accmode_t a_accmode; 131 accmode_t a_accmode;
132 kauth_cred_t a_cred; 132 kauth_cred_t a_cred;
133 } */ *ap = v; 133 } */ *ap = v;
134 struct vnode *vp = ap->a_vp; 134 struct vnode *vp = ap->a_vp;
135 struct iso_node *ip = VTOI(vp); 135 struct iso_node *ip = VTOI(vp);
136 int error; 136 int error;
137 137
138 error = cd9660_check_possible(vp, ip, ap->a_accmode); 138 error = cd9660_check_possible(vp, ip, ap->a_accmode);
139 if (error) 139 if (error)
140 return error; 140 return error;
141 141
142 error = cd9660_check_permitted(vp, ip, ap->a_accmode, ap->a_cred); 142 error = cd9660_check_permitted(vp, ip, ap->a_accmode, ap->a_cred);
143 143
144 return error; 144 return error;
145} 145}
146 146
147int 147int
148cd9660_getattr(void *v) 148cd9660_getattr(void *v)
149{ 149{
150 struct vop_getattr_args /* { 150 struct vop_getattr_args /* {
151 struct vnode *a_vp; 151 struct vnode *a_vp;
152 struct vattr *a_vap; 152 struct vattr *a_vap;
153 kauth_cred_t a_cred; 153 kauth_cred_t a_cred;
154 } */ *ap = v; 154 } */ *ap = v;
155 struct vnode *vp = ap->a_vp; 155 struct vnode *vp = ap->a_vp;
156 struct iso_node *ip = VTOI(vp); 156 struct iso_node *ip = VTOI(vp);
157 struct vattr *vap = ap->a_vap; 157 struct vattr *vap = ap->a_vap;
158 158
159 vap->va_fsid = ip->i_dev; 159 vap->va_fsid = ip->i_dev;
160 vap->va_fileid = ip->i_number; 160 vap->va_fileid = ip->i_number;
161 161
162 vap->va_mode = ip->inode.iso_mode & ALLPERMS; 162 vap->va_mode = ip->inode.iso_mode & ALLPERMS;
163 vap->va_nlink = ip->inode.iso_links; 163 vap->va_nlink = ip->inode.iso_links;
164 vap->va_uid = ip->inode.iso_uid; 164 vap->va_uid = ip->inode.iso_uid;
165 vap->va_gid = ip->inode.iso_gid; 165 vap->va_gid = ip->inode.iso_gid;
166 vap->va_atime = ip->inode.iso_atime; 166 vap->va_atime = ip->inode.iso_atime;
167 vap->va_mtime = ip->inode.iso_mtime; 167 vap->va_mtime = ip->inode.iso_mtime;
168 vap->va_ctime = ip->inode.iso_ctime; 168 vap->va_ctime = ip->inode.iso_ctime;
169 vap->va_rdev = ip->inode.iso_rdev; 169 vap->va_rdev = ip->inode.iso_rdev;
170 170
171 vap->va_size = (u_quad_t) ip->i_size; 171 vap->va_size = (u_quad_t) ip->i_size;
172 if (ip->i_size == 0 && vp->v_type == VLNK) { 172 if (ip->i_size == 0 && vp->v_type == VLNK) {
173 struct vop_readlink_args rdlnk; 173 struct vop_readlink_args rdlnk;
174 struct iovec aiov; 174 struct iovec aiov;
175 struct uio auio; 175 struct uio auio;
176 char *cp; 176 char *cp;
177 177
178 cp = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK); 178 cp = (char *)malloc(MAXPATHLEN, M_TEMP, M_WAITOK);
179 aiov.iov_base = cp; 179 aiov.iov_base = cp;
180 aiov.iov_len = MAXPATHLEN; 180 aiov.iov_len = MAXPATHLEN;
181 auio.uio_iov = &aiov; 181 auio.uio_iov = &aiov;
182 auio.uio_iovcnt = 1; 182 auio.uio_iovcnt = 1;
183 auio.uio_offset = 0; 183 auio.uio_offset = 0;
184 auio.uio_rw = UIO_READ; 184 auio.uio_rw = UIO_READ;
185 auio.uio_resid = MAXPATHLEN; 185 auio.uio_resid = MAXPATHLEN;
186 UIO_SETUP_SYSSPACE(&auio); 186 UIO_SETUP_SYSSPACE(&auio);
187 rdlnk.a_uio = &auio; 187 rdlnk.a_uio = &auio;
188 rdlnk.a_vp = ap->a_vp; 188 rdlnk.a_vp = ap->a_vp;
189 rdlnk.a_cred = ap->a_cred; 189 rdlnk.a_cred = ap->a_cred;
190 if (cd9660_readlink(&rdlnk) == 0) 190 if (cd9660_readlink(&rdlnk) == 0)
191 vap->va_size = MAXPATHLEN - auio.uio_resid; 191 vap->va_size = MAXPATHLEN - auio.uio_resid;
192 free(cp, M_TEMP); 192 free(cp, M_TEMP);
193 } 193 }
194 vap->va_flags = 0; 194 vap->va_flags = 0;
195 vap->va_gen = 1; 195 vap->va_gen = 1;
196 vap->va_blocksize = ip->i_mnt->logical_block_size; 196 vap->va_blocksize = ip->i_mnt->logical_block_size;
197 vap->va_bytes = (u_quad_t) ip->i_size; 197 vap->va_bytes = (u_quad_t) ip->i_size;
198 vap->va_type = vp->v_type; 198 vap->va_type = vp->v_type;
199 return (0); 199 return (0);
200} 200}
201 201
202/* 202/*
203 * Vnode op for reading. 203 * Vnode op for reading.
204 */ 204 */
205int 205int
206cd9660_read(void *v) 206cd9660_read(void *v)
207{ 207{
208 struct vop_read_args /* { 208 struct vop_read_args /* {
209 struct vnode *a_vp; 209 struct vnode *a_vp;
210 struct uio *a_uio; 210 struct uio *a_uio;
211 int a_ioflag; 211 int a_ioflag;
212 kauth_cred_t a_cred; 212 kauth_cred_t a_cred;
213 } */ *ap = v; 213 } */ *ap = v;
214 struct vnode *vp = ap->a_vp; 214 struct vnode *vp = ap->a_vp;
215 struct uio *uio = ap->a_uio; 215 struct uio *uio = ap->a_uio;
216 struct iso_node *ip = VTOI(vp); 216 struct iso_node *ip = VTOI(vp);
217 struct iso_mnt *imp; 217 struct iso_mnt *imp;
218 struct buf *bp; 218 struct buf *bp;
219 daddr_t lbn, rablock; 219 daddr_t lbn, rablock;
220 off_t diff; 220 off_t diff;
221 int rasize, error = 0; 221 int rasize, error = 0;
222 long size, n, on; 222 long size, n, on;
223 223
224 if (uio->uio_resid == 0) 224 if (uio->uio_resid == 0)
225 return (0); 225 return (0);
226 if (uio->uio_offset < 0) 226 if (uio->uio_offset < 0)
227 return (EINVAL); 227 return (EINVAL);
228 if (uio->uio_offset >= ip->i_size) 228 if (uio->uio_offset >= ip->i_size)
229 return 0; 229 return 0;
230 ip->i_flag |= IN_ACCESS; 230 ip->i_flag |= IN_ACCESS;
231 imp = ip->i_mnt; 231 imp = ip->i_mnt;
232 232
233 if (vp->v_type == VREG) { 233 if (vp->v_type == VREG) {
234 const int advice = IO_ADV_DECODE(ap->a_ioflag); 234 const int advice = IO_ADV_DECODE(ap->a_ioflag);
235 error = 0; 235 error = 0;
236 236
237 while (uio->uio_resid > 0) { 237 while (uio->uio_resid > 0) {
238 vsize_t bytelen = MIN(ip->i_size - uio->uio_offset, 238 vsize_t bytelen = MIN(ip->i_size - uio->uio_offset,
239 uio->uio_resid); 239 uio->uio_resid);
240 240
241 if (bytelen == 0) 241 if (bytelen == 0)
242 break; 242 break;
243 error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice, 243 error = ubc_uiomove(&vp->v_uobj, uio, bytelen, advice,
244 UBC_READ | UBC_PARTIALOK | UBC_VNODE_FLAGS(vp)); 244 UBC_READ | UBC_PARTIALOK | UBC_VNODE_FLAGS(vp));
245 if (error) 245 if (error)
246 break; 246 break;
247 } 247 }
248 goto out; 248 goto out;
249 } 249 }
250 250
251 do { 251 do {
252 lbn = cd9660_lblkno(imp, uio->uio_offset); 252 lbn = cd9660_lblkno(imp, uio->uio_offset);
253 on = cd9660_blkoff(imp, uio->uio_offset); 253 on = cd9660_blkoff(imp, uio->uio_offset);
254 n = MIN(imp->logical_block_size - on, uio->uio_resid); 254 n = MIN(imp->logical_block_size - on, uio->uio_resid);
255 diff = (off_t)ip->i_size - uio->uio_offset; 255 diff = (off_t)ip->i_size - uio->uio_offset;
256 if (diff <= 0) 256 if (diff <= 0)
257 return (0); 257 return (0);
258 if (diff < n) 258 if (diff < n)
259 n = diff; 259 n = diff;
260 size = cd9660_blksize(imp, ip, lbn); 260 size = cd9660_blksize(imp, ip, lbn);
261 rablock = lbn + 1; 261 rablock = lbn + 1;
262 if (cd9660_lblktosize(imp, rablock) < ip->i_size) { 262 if (cd9660_lblktosize(imp, rablock) < ip->i_size) {
263 rasize = cd9660_blksize(imp, ip, rablock); 263 rasize = cd9660_blksize(imp, ip, rablock);
264 error = breadn(vp, lbn, size, &rablock, 264 error = breadn(vp, lbn, size, &rablock,
265 &rasize, 1, 0, &bp); 265 &rasize, 1, 0, &bp);
266 } else { 266 } else {
267 error = bread(vp, lbn, size, 0, &bp); 267 error = bread(vp, lbn, size, 0, &bp);
268 } 268 }
269 if (error) { 269 if (error) {
270 return (error); 270 return (error);
271 } 271 }
272 n = MIN(n, size - bp->b_resid); 272 n = MIN(n, size - bp->b_resid);
273 273
274 error = uiomove((char *)bp->b_data + on, (int)n, uio); 274 error = uiomove((char *)bp->b_data + on, (int)n, uio);
275 brelse(bp, 0); 275 brelse(bp, 0);
276 } while (error == 0 && uio->uio_resid > 0 && n != 0); 276 } while (error == 0 && uio->uio_resid > 0 && n != 0);
277 277
278out: 278out:
279 return (error); 279 return (error);
280} 280}
281 281
282int 282int
283iso_uiodir(struct isoreaddir *idp, struct dirent *dp, off_t off) 283iso_uiodir(struct isoreaddir *idp, struct dirent *dp, off_t off)
284{ 284{
285 int error; 285 int error;
286 286
287 dp->d_name[dp->d_namlen] = 0; 287 dp->d_name[dp->d_namlen] = 0;
288 dp->d_reclen = _DIRENT_SIZE(dp); 288 dp->d_reclen = _DIRENT_SIZE(dp);
289 289
290 if (idp->uio->uio_resid < dp->d_reclen) { 290 if (idp->uio->uio_resid < dp->d_reclen) {
291 idp->eofflag = 0; 291 idp->eofflag = 0;
292 return (-1); 292 return (-1);
293 } 293 }
294 294
295 if (idp->cookies) { 295 if (idp->cookies) {
296 if (idp->ncookies <= 0) { 296 if (idp->ncookies <= 0) {
297 idp->eofflag = 0; 297 idp->eofflag = 0;
298 return (-1); 298 return (-1);
299 } 299 }
300 300
301 *idp->cookies++ = off; 301 *idp->cookies++ = off;
302 --idp->ncookies; 302 --idp->ncookies;
303 } 303 }
304 304
305 if ((error = uiomove(dp, dp->d_reclen, idp->uio)) != 0) 305 if ((error = uiomove(dp, dp->d_reclen, idp->uio)) != 0)
306 return (error); 306 return (error);
307 idp->uio_off = off; 307 idp->uio_off = off;
308 return (0); 308 return (0);
309} 309}
310 310
311int 311int
312iso_shipdir(struct isoreaddir *idp) 312iso_shipdir(struct isoreaddir *idp)
313{ 313{
314 struct dirent *dp; 314 struct dirent *dp;
315 int cl, sl, assoc; 315 int cl, sl, assoc;
316 int error; 316 int error;
317 char *cname, *sname; 317 char *cname, *sname;
318 318
319 cl = idp->current.d_namlen; 319 cl = idp->current.d_namlen;
320 cname = idp->current.d_name; 320 cname = idp->current.d_name;
321 321
322 assoc = (cl > 1) && (*cname == ASSOCCHAR); 322 assoc = (cl > 1) && (*cname == ASSOCCHAR);
323 if (assoc) { 323 if (assoc) {
324 cl--; 324 cl--;
325 cname++; 325 cname++;
326 } 326 }
327 327
328 dp = &idp->saveent; 328 dp = &idp->saveent;
329 sname = dp->d_name; 329 sname = dp->d_name;
330 if (!(sl = dp->d_namlen)) { 330 if (!(sl = dp->d_namlen)) {
331 dp = &idp->assocent; 331 dp = &idp->assocent;
332 sname = dp->d_name + 1; 332 sname = dp->d_name + 1;
333 sl = dp->d_namlen - 1; 333 sl = dp->d_namlen - 1;
334 } 334 }
335 if (sl > 0) { 335 if (sl > 0) {
336 if (sl != cl 336 if (sl != cl
337 || memcmp(sname, cname, sl)) { 337 || memcmp(sname, cname, sl)) {
338 if (idp->assocent.d_namlen) { 338 if (idp->assocent.d_namlen) {
339 error = iso_uiodir(idp, &idp->assocent, 339 error = iso_uiodir(idp, &idp->assocent,
340 idp->assocoff); 340 idp->assocoff);
341 if (error) 341 if (error)
342 return (error); 342 return (error);
343 idp->assocent.d_namlen = 0; 343 idp->assocent.d_namlen = 0;
344 } 344 }
345 if (idp->saveent.d_namlen) { 345 if (idp->saveent.d_namlen) {
346 error = iso_uiodir(idp, &idp->saveent, 346 error = iso_uiodir(idp, &idp->saveent,
347 idp->saveoff); 347 idp->saveoff);
348 if (error) 348 if (error)
349 return (error); 349 return (error);
350 idp->saveent.d_namlen = 0; 350 idp->saveent.d_namlen = 0;
351 } 351 }
352 } 352 }
353 } 353 }
354 idp->current.d_reclen = _DIRENT_SIZE(&idp->current); 354 idp->current.d_reclen = _DIRENT_SIZE(&idp->current);
355 if (assoc) { 355 if (assoc) {
356 idp->assocoff = idp->curroff; 356 idp->assocoff = idp->curroff;
357 memcpy(&idp->assocent, &idp->current, idp->current.d_reclen); 357 memcpy(&idp->assocent, &idp->current, idp->current.d_reclen);
358 } else { 358 } else {
359 idp->saveoff = idp->curroff; 359 idp->saveoff = idp->curroff;
360 memcpy(&idp->saveent, &idp->current, idp->current.d_reclen); 360 memcpy(&idp->saveent, &idp->current, idp->current.d_reclen);
361 } 361 }
362 return (0); 362 return (0);
363} 363}
364 364
365/* 365/*
366 * Vnode op for readdir 366 * Vnode op for readdir
367 */ 367 */
368int 368int
369cd9660_readdir(void *v) 369cd9660_readdir(void *v)
370{ 370{
371 struct vop_readdir_args /* { 371 struct vop_readdir_args /* {
372 struct vnode *a_vp; 372 struct vnode *a_vp;
373 struct uio *a_uio; 373 struct uio *a_uio;
374 kauth_cred_t a_cred; 374 kauth_cred_t a_cred;
375 int *a_eofflag; 375 int *a_eofflag;
376 off_t **a_cookies; 376 off_t **a_cookies;
377 int *a_ncookies; 377 int *a_ncookies;
378 } */ *ap = v; 378 } */ *ap = v;
379 struct uio *uio = ap->a_uio; 379 struct uio *uio = ap->a_uio;
380 struct isoreaddir *idp; 380 struct isoreaddir *idp;
381 struct vnode *vdp = ap->a_vp; 381 struct vnode *vdp = ap->a_vp;
382 struct iso_node *dp; 382 struct iso_node *dp;
383 struct iso_mnt *imp; 383 struct iso_mnt *imp;
384 struct buf *bp = NULL; 384 struct buf *bp = NULL;
385 struct iso_directory_record *ep; 385 struct iso_directory_record *ep;
386 int entryoffsetinblock; 386 int entryoffsetinblock;
387 doff_t endsearch; 387 doff_t endsearch;
388 u_long bmask; 388 u_long bmask;
389 int error = 0; 389 int error = 0;
390 int reclen; 390 int reclen;
391 u_short namelen; 391 u_short namelen;
392 off_t *cookies = NULL; 392 off_t *cookies = NULL;
393 int ncookies = 0; 393 int ncookies = 0;
394 394
395 if (vdp->v_type != VDIR) 395 if (vdp->v_type != VDIR)
396 return (ENOTDIR); 396 return (ENOTDIR);
397 397
398 dp = VTOI(vdp); 398 dp = VTOI(vdp);
399 imp = dp->i_mnt; 399 imp = dp->i_mnt;
400 bmask = imp->im_bmask; 400 bmask = imp->im_bmask;
401 401
402 idp = malloc(sizeof(*idp), M_TEMP, M_WAITOK | M_ZERO); 402 idp = malloc(sizeof(*idp), M_TEMP, M_WAITOK | M_ZERO);
403 idp->saveent.d_namlen = idp->assocent.d_namlen = 0; 403 idp->saveent.d_namlen = idp->assocent.d_namlen = 0;
404 /* 404 /*
405 * XXX 405 * XXX
406 * Is it worth trying to figure out the type? 406 * Is it worth trying to figure out the type?
407 */ 407 */
408 idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type = 408 idp->saveent.d_type = idp->assocent.d_type = idp->current.d_type =
409 DT_UNKNOWN; 409 DT_UNKNOWN;
410 idp->uio = uio; 410 idp->uio = uio;
411 if (ap->a_ncookies == NULL) 411 if (ap->a_ncookies == NULL)
412 idp->cookies = NULL; 412 idp->cookies = NULL;
413 else { 413 else {
414 ncookies = uio->uio_resid / _DIRENT_MINSIZE((struct dirent *)0); 414 ncookies = uio->uio_resid / _DIRENT_MINSIZE((struct dirent *)0);
415 cookies = malloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK); 415 cookies = malloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK);
416 idp->cookies = cookies; 416 idp->cookies = cookies;
417 idp->ncookies = ncookies; 417 idp->ncookies = ncookies;
418 } 418 }
419 idp->eofflag = 1; 419 idp->eofflag = 1;
420 idp->curroff = uio->uio_offset; 420 idp->curroff = uio->uio_offset;
421 421
422 if ((entryoffsetinblock = idp->curroff & bmask) && 422 if ((entryoffsetinblock = idp->curroff & bmask) &&
423 (error = cd9660_blkatoff(vdp, (off_t)idp->curroff, NULL, &bp))) { 423 (error = cd9660_blkatoff(vdp, (off_t)idp->curroff, NULL, &bp))) {
424 free(idp, M_TEMP); 424 free(idp, M_TEMP);
425 return (error); 425 return (error);
426 } 426 }
427 endsearch = dp->i_size; 427 endsearch = dp->i_size;
428 428
429 while (idp->curroff < endsearch) { 429 while (idp->curroff < endsearch) {
430 /* 430 /*
431 * If offset is on a block boundary, 431 * If offset is on a block boundary,
432 * read the next directory block. 432 * read the next directory block.
433 * Release previous if it exists. 433 * Release previous if it exists.
434 */ 434 */
435 if ((idp->curroff & bmask) == 0) { 435 if ((idp->curroff & bmask) == 0) {
436 if (bp != NULL) 436 if (bp != NULL)
437 brelse(bp, 0); 437 brelse(bp, 0);
438 error = cd9660_blkatoff(vdp, (off_t)idp->curroff, 438 error = cd9660_blkatoff(vdp, (off_t)idp->curroff,
439 NULL, &bp); 439 NULL, &bp);
440 if (error) 440 if (error)
441 break; 441 break;
442 entryoffsetinblock = 0; 442 entryoffsetinblock = 0;
443 } 443 }
444 /* 444 /*
445 * Get pointer to next entry. 445 * Get pointer to next entry.
446 */ 446 */
447 KASSERT(bp != NULL); 447 KASSERT(bp != NULL);
448 ep = (struct iso_directory_record *) 448 ep = (struct iso_directory_record *)
449 ((char *)bp->b_data + entryoffsetinblock); 449 ((char *)bp->b_data + entryoffsetinblock);
450 450
451 reclen = isonum_711(ep->length); 451 reclen = isonum_711(ep->length);
452 if (reclen == 0) { 452 if (reclen == 0) {
453 /* skip to next block, if any */ 453 /* skip to next block, if any */
454 idp->curroff = 454 idp->curroff =
455 (idp->curroff & ~bmask) + imp->logical_block_size; 455 (idp->curroff & ~bmask) + imp->logical_block_size;
456 continue; 456 continue;
457 } 457 }
458 458
459 if (reclen < ISO_DIRECTORY_RECORD_SIZE) { 459 if (reclen < ISO_DIRECTORY_RECORD_SIZE) {
460 error = EINVAL; 460 error = EINVAL;
461 /* illegal entry, stop */ 461 /* illegal entry, stop */
462 break; 462 break;
463 } 463 }
464 464
465 if (entryoffsetinblock + reclen > imp->logical_block_size) { 465 if (entryoffsetinblock + reclen > imp->logical_block_size) {
466 error = EINVAL; 466 error = EINVAL;
467 /* illegal directory, so stop looking */ 467 /* illegal directory, so stop looking */
468 break; 468 break;
469 } 469 }
470 470
471 idp->current.d_namlen = isonum_711(ep->name_len); 471 idp->current.d_namlen = isonum_711(ep->name_len);
472 472
473 if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) { 473 if (reclen < ISO_DIRECTORY_RECORD_SIZE + idp->current.d_namlen) {
474 error = EINVAL; 474 error = EINVAL;
475 /* illegal entry, stop */ 475 /* illegal entry, stop */
476 break; 476 break;
477 } 477 }
478 478
479 if (isonum_711(ep->flags)&2) 479 if (isonum_711(ep->flags)&2)
480 idp->current.d_fileno = isodirino(ep, imp); 480 idp->current.d_fileno = isodirino(ep, imp);
481 else 481 else
482 idp->current.d_fileno = dbtob(bp->b_blkno) + 482 idp->current.d_fileno = dbtob(bp->b_blkno) +
483 entryoffsetinblock; 483 entryoffsetinblock;
484 484
485 idp->curroff += reclen; 485 idp->curroff += reclen;
486 486
487 switch (imp->iso_ftype) { 487 switch (imp->iso_ftype) {
488 case ISO_FTYPE_RRIP: 488 case ISO_FTYPE_RRIP:
489 cd9660_rrip_getname(ep, idp->current.d_name, &namelen, 489 cd9660_rrip_getname(ep, idp->current.d_name, &namelen,
490 &idp->current.d_fileno, imp); 490 &idp->current.d_fileno, imp);
491 idp->current.d_namlen = (u_char)namelen; 491 idp->current.d_namlen = (u_char)namelen;
492 if (idp->current.d_namlen) 492 if (idp->current.d_namlen)
493 error = iso_uiodir(idp, &idp->current, 493 error = iso_uiodir(idp, &idp->current,
494 idp->curroff); 494 idp->curroff);
495 break; 495 break;
496 default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */ 496 default: /* ISO_FTYPE_DEFAULT || ISO_FTYPE_9660 */
497 isofntrans(ep->name, idp->current.d_namlen, 497 isofntrans(ep->name, idp->current.d_namlen,
498 idp->current.d_name, &namelen, 498 idp->current.d_name, &namelen,
499 imp->iso_ftype == ISO_FTYPE_9660, 499 imp->iso_ftype == ISO_FTYPE_9660,
500 (imp->im_flags & ISOFSMNT_NOCASETRANS) == 0, 500 (imp->im_flags & ISOFSMNT_NOCASETRANS) == 0,
501 isonum_711(ep->flags)&4, 501 isonum_711(ep->flags)&4,
502 imp->im_joliet_level); 502 imp->im_joliet_level);
503 switch (idp->current.d_name[0]) { 503 switch (idp->current.d_name[0]) {
504 case 0: 504 case 0:
505 idp->current.d_name[0] = '.'; 505 idp->current.d_name[0] = '.';
506 idp->current.d_namlen = 1; 506 idp->current.d_namlen = 1;
507 error = iso_uiodir(idp, &idp->current, 507 error = iso_uiodir(idp, &idp->current,
508 idp->curroff); 508 idp->curroff);
509 break; 509 break;
510 case 1: 510 case 1:
511 strlcpy(idp->current.d_name, "..", 511 strlcpy(idp->current.d_name, "..",
512 sizeof(idp->current.d_name)); 512 sizeof(idp->current.d_name));
513 idp->current.d_namlen = 2; 513 idp->current.d_namlen = 2;
514 error = iso_uiodir(idp, &idp->current, 514 error = iso_uiodir(idp, &idp->current,
515 idp->curroff); 515 idp->curroff);
516 break; 516 break;
517 default: 517 default:
518 idp->current.d_namlen = (u_char)namelen; 518 idp->current.d_namlen = (u_char)namelen;
519 if (imp->iso_ftype == ISO_FTYPE_DEFAULT) 519 if (imp->iso_ftype == ISO_FTYPE_DEFAULT)
520 error = iso_shipdir(idp); 520 error = iso_shipdir(idp);
521 else 521 else
522 error = iso_uiodir(idp, &idp->current, 522 error = iso_uiodir(idp, &idp->current,
523 idp->curroff); 523 idp->curroff);
524 break; 524 break;
525 } 525 }
526 } 526 }
527 if (error) 527 if (error)
528 break; 528 break;
529 529
530 entryoffsetinblock += reclen; 530 entryoffsetinblock += reclen;
531 } 531 }
532 532
533 if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) { 533 if (!error && imp->iso_ftype == ISO_FTYPE_DEFAULT) {
534 idp->current.d_namlen = 0; 534 idp->current.d_namlen = 0;
535 error = iso_shipdir(idp); 535 error = iso_shipdir(idp);
536 } 536 }
537 if (error < 0) 537 if (error < 0)
538 error = 0; 538 error = 0;
539 539
540 if (ap->a_ncookies != NULL) { 540 if (ap->a_ncookies != NULL) {
541 if (error) 541 if (error)
542 free(cookies, M_TEMP); 542 free(cookies, M_TEMP);
543 else { 543 else {
544 /* 544 /*
545 * Work out the number of cookies actually used. 545 * Work out the number of cookies actually used.
546 */ 546 */
547 *ap->a_ncookies = ncookies - idp->ncookies; 547 *ap->a_ncookies = ncookies - idp->ncookies;
548 *ap->a_cookies = cookies; 548 *ap->a_cookies = cookies;
549 } 549 }
550 } 550 }
551 551
552 if (bp) 552 if (bp)
553 brelse(bp, 0); 553 brelse(bp, 0);
554 554
555 uio->uio_offset = idp->uio_off; 555 uio->uio_offset = idp->uio_off;
556 *ap->a_eofflag = idp->eofflag; 556 *ap->a_eofflag = idp->eofflag;
557 557
558 free(idp, M_TEMP); 558 free(idp, M_TEMP);
559 559
560 return (error); 560 return (error);
561} 561}
562 562
563/* 563/*
564 * Return target name of a symbolic link 564 * Return target name of a symbolic link
565 * Shouldn't we get the parent vnode and read the data from there? 565 * Shouldn't we get the parent vnode and read the data from there?
566 * This could eventually result in deadlocks in cd9660_lookup. 566 * This could eventually result in deadlocks in cd9660_lookup.
567 * But otherwise the block read here is in the block buffer two times. 567 * But otherwise the block read here is in the block buffer two times.
568 */ 568 */
569typedef struct iso_directory_record ISODIR; 569typedef struct iso_directory_record ISODIR;
570typedef struct iso_node ISONODE; 570typedef struct iso_node ISONODE;
571typedef struct iso_mnt ISOMNT; 571typedef struct iso_mnt ISOMNT;
572 572
573int 573int
574cd9660_readlink(void *v) 574cd9660_readlink(void *v)
575{ 575{
576 struct vop_readlink_args /* { 576 struct vop_readlink_args /* {
577 struct vnode *a_vp; 577 struct vnode *a_vp;
578 struct uio *a_uio; 578 struct uio *a_uio;
579 kauth_cred_t a_cred; 579 kauth_cred_t a_cred;
580 } */ *ap = v; 580 } */ *ap = v;
581 ISONODE *ip; 581 ISONODE *ip;
582 ISODIR *dirp; 582 ISODIR *dirp;
583 ISOMNT *imp; 583 ISOMNT *imp;
584 struct buf *bp; 584 struct buf *bp;
585 struct uio *uio; 585 struct uio *uio;
586 u_short symlen; 586 u_short symlen;
587 int error; 587 int error;
588 char *symname; 588 char *symname;
589 bool use_pnbuf; 589 bool use_pnbuf;
590 590
591 ip = VTOI(ap->a_vp); 591 ip = VTOI(ap->a_vp);
592 imp = ip->i_mnt; 592 imp = ip->i_mnt;
593 uio = ap->a_uio; 593 uio = ap->a_uio;
594 594
595 if (imp->iso_ftype != ISO_FTYPE_RRIP) 595 if (imp->iso_ftype != ISO_FTYPE_RRIP)
596 return (EINVAL); 596 return (EINVAL);
597 597
598 /* 598 /*
599 * Get parents directory record block that this inode included. 599 * Get parents directory record block that this inode included.
600 */ 600 */
601 error = bread(imp->im_devvp, 601 error = bread(imp->im_devvp,
602 (ip->i_number >> imp->im_bshift) << 602 (ip->i_number >> imp->im_bshift) <<
603 (imp->im_bshift - DEV_BSHIFT), 603 (imp->im_bshift - DEV_BSHIFT),
604 imp->logical_block_size, 0, &bp); 604 imp->logical_block_size, 0, &bp);
605 if (error) { 605 if (error) {
606 return (EINVAL); 606 return (EINVAL);
607 } 607 }
608 608
609 /* 609 /*
610 * Setup the directory pointer for this inode 610 * Setup the directory pointer for this inode
611 */ 611 */
612 dirp = (ISODIR *)((char *)bp->b_data + (ip->i_number & imp->im_bmask)); 612 dirp = (ISODIR *)((char *)bp->b_data + (ip->i_number & imp->im_bmask));
613 613
614 /* 614 /*
615 * Just make sure, we have a right one.... 615 * Just make sure, we have a right one....
616 * 1: Check not cross boundary on block 616 * 1: Check not cross boundary on block
617 */ 617 */
618 if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length) 618 if ((ip->i_number & imp->im_bmask) + isonum_711(dirp->length)
619 > imp->logical_block_size) { 619 > imp->logical_block_size) {
620 brelse(bp, 0); 620 brelse(bp, 0);
621 return (EINVAL); 621 return (EINVAL);
622 } 622 }
623 623
624 /* 624 /*
625 * Now get a buffer 625 * Now get a buffer
626 * Abuse a namei buffer for now. 626 * Abuse a namei buffer for now.
627 */ 627 */
628 use_pnbuf = !VMSPACE_IS_KERNEL_P(uio->uio_vmspace) || 628 use_pnbuf = !VMSPACE_IS_KERNEL_P(uio->uio_vmspace) ||
629 uio->uio_iov->iov_len < MAXPATHLEN; 629 uio->uio_iov->iov_len < MAXPATHLEN;
630 if (use_pnbuf) { 630 if (use_pnbuf) {
631 symname = PNBUF_GET(); 631 symname = PNBUF_GET();
632 } else { 632 } else {
633 symname = uio->uio_iov->iov_base; 633 symname = uio->uio_iov->iov_base;
634 } 634 }
635 635
636 /* 636 /*
637 * Ok, we just gathering a symbolic name in SL record. 637 * Ok, we just gathering a symbolic name in SL record.
638 */ 638 */
639 if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) { 639 if (cd9660_rrip_getsymname(dirp, symname, &symlen, imp) == 0) {
640 if (use_pnbuf) { 640 if (use_pnbuf) {
641 PNBUF_PUT(symname); 641 PNBUF_PUT(symname);
642 } 642 }
643 brelse(bp, 0); 643 brelse(bp, 0);
644 return (EINVAL); 644 return (EINVAL);
645 } 645 }
646 /* 646 /*
647 * Don't forget before you leave from home ;-) 647 * Don't forget before you leave from home ;-)
648 */ 648 */
649 brelse(bp, 0); 649 brelse(bp, 0);
650 650
651 /* 651 /*
652 * return with the symbolic name to caller's. 652 * return with the symbolic name to caller's.
653 */ 653 */
654 if (use_pnbuf) { 654 if (use_pnbuf) {
655 error = uiomove(symname, symlen, uio); 655 error = uiomove(symname, symlen, uio);
656 PNBUF_PUT(symname); 656 PNBUF_PUT(symname);
657 return (error); 657 return (error);
658 } 658 }
659 uio->uio_resid -= symlen; 659 uio->uio_resid -= symlen;
660 uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + symlen; 660 uio->uio_iov->iov_base = (char *)uio->uio_iov->iov_base + symlen;
661 uio->uio_iov->iov_len -= symlen; 661 uio->uio_iov->iov_len -= symlen;
662 return (0); 662 return (0);
663} 663}
664 664
665int 665int
666cd9660_link(void *v) 666cd9660_link(void *v)
667{ 667{
668 struct vop_link_v2_args /* { 668 struct vop_link_v2_args /* {
669 struct vnode *a_dvp; 669 struct vnode *a_dvp;
670 struct vnode *a_vp; 670 struct vnode *a_vp;
671 struct componentname *a_cnp; 671 struct componentname *a_cnp;
672 } */ *ap = v; 672 } */ *ap = v;
673 673
674 VOP_ABORTOP(ap->a_dvp, ap->a_cnp); 674 VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
675 return (EROFS); 675 return (EROFS);
676} 676}
677 677
678int 678int
679cd9660_symlink(void *v) 679cd9660_symlink(void *v)
680{ 680{
681 struct vop_symlink_v3_args /* { 681 struct vop_symlink_v3_args /* {
682 struct vnode *a_dvp; 682 struct vnode *a_dvp;
683 struct vnode **a_vpp; 683 struct vnode **a_vpp;
684 struct componentname *a_cnp; 684 struct componentname *a_cnp;
685 struct vattr *a_vap; 685 struct vattr *a_vap;
686 char *a_target; 686 char *a_target;
687 } */ *ap = v; 687 } */ *ap = v;
688 688
689 VOP_ABORTOP(ap->a_dvp, ap->a_cnp); 689 VOP_ABORTOP(ap->a_dvp, ap->a_cnp);
690 return (EROFS); 690 return (EROFS);
691} 691}
692 692
693/* 693/*
694 * Calculate the logical to physical mapping if not done already, 694 * Calculate the logical to physical mapping if not done already,
695 * then call the device strategy routine. 695 * then call the device strategy routine.
696 */ 696 */
697int 697int
698cd9660_strategy(void *v) 698cd9660_strategy(void *v)
699{ 699{
700 struct vop_strategy_args /* { 700 struct vop_strategy_args /* {
701 struct vnode *a_vp; 701 struct vnode *a_vp;
702 struct buf *a_bp; 702 struct buf *a_bp;
703 } */ *ap = v; 703 } */ *ap = v;
704 struct buf *bp = ap->a_bp; 704 struct buf *bp = ap->a_bp;
705 struct vnode *vp = ap->a_vp; 705 struct vnode *vp = ap->a_vp;
706 struct iso_node *ip; 706 struct iso_node *ip;
707 int error; 707 int error;
708 708
709 ip = VTOI(vp); 709 ip = VTOI(vp);
710 if (vp->v_type == VBLK || vp->v_type == VCHR) 710 if (vp->v_type == VBLK || vp->v_type == VCHR)
711 panic("cd9660_strategy: spec"); 711 panic("cd9660_strategy: spec");
712 if (bp->b_blkno == bp->b_lblkno) { 712 if (bp->b_blkno == bp->b_lblkno) {
713 error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL); 713 error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL);
714 if (error) { 714 if (error) {
715 bp->b_error = error; 715 bp->b_error = error;
716 biodone(bp); 716 biodone(bp);
717 return (error); 717 return (error);
718 } 718 }
719 if ((long)bp->b_blkno == -1) 719 if ((long)bp->b_blkno == -1)
720 clrbuf(bp); 720 clrbuf(bp);
721 } 721 }
722 if ((long)bp->b_blkno == -1) { 722 if ((long)bp->b_blkno == -1) {
723 biodone(bp); 723 biodone(bp);
724 return (0); 724 return (0);
725 } 725 }
726 vp = ip->i_mnt->im_devvp; 726 vp = ip->i_mnt->im_devvp;
727 return (VOP_STRATEGY(vp, bp)); 727 return (VOP_STRATEGY(vp, bp));
728} 728}
729 729
730/* 730/*
731 * Print out the contents of an inode. 731 * Print out the contents of an inode.
732 */ 732 */
733/*ARGSUSED*/ 733/*ARGSUSED*/
734int 734int
735cd9660_print(void *v) 735cd9660_print(void *v)
736{ 736{
737 737
738 printf("tag VT_ISOFS, isofs vnode\n"); 738 printf("tag VT_ISOFS, isofs vnode\n");
739 return (0); 739 return (0);
740} 740}
741 741
742/* 742/*
743 * Return POSIX pathconf information applicable to cd9660 filesystems. 743 * Return POSIX pathconf information applicable to cd9660 filesystems.
744 */ 744 */
745int 745int
746cd9660_pathconf(void *v) 746cd9660_pathconf(void *v)
747{ 747{
748 struct vop_pathconf_args /* { 748 struct vop_pathconf_args /* {
749 struct vnode *a_vp; 749 struct vnode *a_vp;
750 int a_name; 750 int a_name;
751 register_t *a_retval; 751 register_t *a_retval;
752 } */ *ap = v; 752 } */ *ap = v;
753 switch (ap->a_name) { 753 switch (ap->a_name) {
754 case _PC_LINK_MAX: 754 case _PC_LINK_MAX:
755 *ap->a_retval = 1; 755 *ap->a_retval = 1;
756 return (0); 756 return (0);
757 case _PC_NAME_MAX: 757 case _PC_NAME_MAX:
758 if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP) 758 if (VTOI(ap->a_vp)->i_mnt->iso_ftype == ISO_FTYPE_RRIP)
759 *ap->a_retval = ISO_MAXNAMLEN; 759 *ap->a_retval = ISO_MAXNAMLEN;
760 else 760 else
761 *ap->a_retval = 37; 761 *ap->a_retval = 37;
762 return (0); 762 return (0);
763 case _PC_PATH_MAX: 763 case _PC_PATH_MAX:
764 *ap->a_retval = PATH_MAX; 764 *ap->a_retval = PATH_MAX;
765 return (0); 765 return (0);
766 case _PC_PIPE_BUF: 766 case _PC_PIPE_BUF:
767 *ap->a_retval = PIPE_BUF; 767 *ap->a_retval = PIPE_BUF;
768 return (0); 768 return (0);
769 case _PC_CHOWN_RESTRICTED: 769 case _PC_CHOWN_RESTRICTED:
770 *ap->a_retval = 1; 770 *ap->a_retval = 1;
771 return (0); 771 return (0);
772 case _PC_NO_TRUNC: 772 case _PC_NO_TRUNC:
773 *ap->a_retval = 1; 773 *ap->a_retval = 1;
774 return (0); 774 return (0);
775 case _PC_SYNC_IO: 775 case _PC_SYNC_IO:
776 *ap->a_retval = 1; 776 *ap->a_retval = 1;
777 return (0); 777 return (0);
778 case _PC_FILESIZEBITS: 778 case _PC_FILESIZEBITS:
779 *ap->a_retval = 32; 779 *ap->a_retval = 32;
780 return (0); 780 return (0);
781 default: 781 default:
782 return genfs_pathconf(ap); 782 return genfs_pathconf(ap);
783 } 783 }
784 /* NOTREACHED */ 784 /* NOTREACHED */
785} 785}
786 786
787/* 787/*
788 * Allow changing the size for special files (and fifos). 788 * Allow changing the size for special files (and fifos).
789 */ 789 */
790int 790int
791cd9660_setattr(void *v) 791cd9660_setattr(void *v)
792{ 792{
793 struct vop_setattr_args /* { 793 struct vop_setattr_args /* {
794 struct vnodeop_desc *a_desc; 794 struct vnodeop_desc *a_desc;
795 struct vnode *a_vp; 795 struct vnode *a_vp;
796 struct vattr *a_vap; 796 struct vattr *a_vap;
797 kauth_cred_t a_cred; 797 kauth_cred_t a_cred;
798 struct proc *a_p; 798 struct proc *a_p;
799 } */ *ap = v; 799 } */ *ap = v;
800 struct vattr *vap = ap->a_vap; 800 struct vattr *vap = ap->a_vap;
801 struct vnode *vp = ap->a_vp; 801 struct vnode *vp = ap->a_vp;
802 802
803 /* 803 /*
804 * Only size is changeable. 804 * Only size is changeable.
805 */ 805 */
806 if (vap->va_type != VNON 806 if (vap->va_type != VNON
807 || vap->va_nlink != (nlink_t)VNOVAL 807 || vap->va_nlink != (nlink_t)VNOVAL
808 || vap->va_fsid != VNOVAL 808 || vap->va_fsid != VNOVAL
809 || vap->va_fileid != VNOVAL 809 || vap->va_fileid != VNOVAL
810 || vap->va_blocksize != VNOVAL 810 || vap->va_blocksize != VNOVAL
811 || vap->va_rdev != (dev_t)VNOVAL 811 || vap->va_rdev != (dev_t)VNOVAL
812 || (int)vap->va_bytes != VNOVAL 812 || (int)vap->va_bytes != VNOVAL
813 || vap->va_gen != VNOVAL 813 || vap->va_gen != VNOVAL
814 || vap->va_flags != VNOVAL 814 || vap->va_flags != VNOVAL
815 || vap->va_uid != (uid_t)VNOVAL 815 || vap->va_uid != (uid_t)VNOVAL
816 || vap->va_gid != (gid_t)VNOVAL 816 || vap->va_gid != (gid_t)VNOVAL
817 || vap->va_atime.tv_sec != VNOVAL 817 || vap->va_atime.tv_sec != VNOVAL
818 || vap->va_mtime.tv_sec != VNOVAL 818 || vap->va_mtime.tv_sec != VNOVAL
819 || vap->va_mode != (mode_t)VNOVAL) 819 || vap->va_mode != (mode_t)VNOVAL)
820 return EOPNOTSUPP; 820 return EOPNOTSUPP;
821 821
822 if (vap->va_size != VNOVAL 822 if (vap->va_size != VNOVAL
823 && vp->v_type != VCHR 823 && vp->v_type != VCHR
824 && vp->v_type != VBLK 824 && vp->v_type != VBLK
825 && vp->v_type != VFIFO) 825 && vp->v_type != VFIFO)
826 return EOPNOTSUPP; 826 return EOPNOTSUPP;
827 827
828 return 0; 828 return 0;
829} 829}
830 830
831/* 831/*
832 * Global vfs data structures for isofs 
833 */ 
834#define cd9660_create genfs_eopnotsupp 
835#define cd9660_mknod genfs_eopnotsupp 
836#define cd9660_write genfs_eopnotsupp 
837#define cd9660_fsync genfs_nullop 
838#define cd9660_remove genfs_eopnotsupp 
839#define cd9660_rename genfs_eopnotsupp 
840#define cd9660_mkdir genfs_eopnotsupp 
841#define cd9660_rmdir genfs_eopnotsupp 
842#define cd9660_advlock genfs_einval 
843#define cd9660_bwrite genfs_eopnotsupp 
844#define cd9660_revoke genfs_revoke 
845 
846/* 
847 * Global vfs data structures for cd9660 832 * Global vfs data structures for cd9660
848 */ 833 */
849int (**cd9660_vnodeop_p)(void *); 834int (**cd9660_vnodeop_p)(void *);
850const struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = { 835const struct vnodeopv_entry_desc cd9660_vnodeop_entries[] = {
851 { &vop_default_desc, vn_default_error }, 836 { &vop_default_desc, vn_default_error },
852 { &vop_parsepath_desc, genfs_parsepath }, /* parsepath */ 837 { &vop_parsepath_desc, genfs_parsepath }, /* parsepath */
853 { &vop_lookup_desc, cd9660_lookup }, /* lookup */ 838 { &vop_lookup_desc, cd9660_lookup }, /* lookup */
854 { &vop_create_desc, cd9660_create }, /* create */ 839 { &vop_create_desc, genfs_eopnotsupp }, /* create */
855 { &vop_mknod_desc, cd9660_mknod }, /* mknod */ 840 { &vop_mknod_desc, genfs_eopnotsupp }, /* mknod */
856 { &vop_open_desc, cd9660_open }, /* open */ 841 { &vop_open_desc, genfs_nullop }, /* open */
857 { &vop_close_desc, cd9660_close }, /* close */ 842 { &vop_close_desc, genfs_nullop }, /* close */
858 { &vop_access_desc, cd9660_access }, /* access */ 843 { &vop_access_desc, cd9660_access }, /* access */
859 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 844 { &vop_accessx_desc, genfs_accessx }, /* accessx */
860 { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 845 { &vop_getattr_desc, cd9660_getattr }, /* getattr */
861 { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 846 { &vop_setattr_desc, cd9660_setattr }, /* setattr */
862 { &vop_read_desc, cd9660_read }, /* read */ 847 { &vop_read_desc, cd9660_read }, /* read */
863 { &vop_write_desc, cd9660_write }, /* write */ 848 { &vop_write_desc, genfs_eopnotsupp }, /* write */
864 { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */ 849 { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
865 { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */ 850 { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
866 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 851 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */
867 { &vop_ioctl_desc, cd9660_ioctl }, /* ioctl */ 852 { &vop_ioctl_desc, genfs_enoioctl }, /* ioctl */
868 { &vop_poll_desc, cd9660_poll }, /* poll */ 853 { &vop_poll_desc, genfs_poll }, /* poll */
869 { &vop_revoke_desc, cd9660_revoke }, /* revoke */ 854 { &vop_revoke_desc, genfs_revoke }, /* revoke */
870 { &vop_mmap_desc, cd9660_mmap }, /* mmap */ 855 { &vop_mmap_desc, genfs_mmap }, /* mmap */
871 { &vop_fsync_desc, cd9660_fsync }, /* fsync */ 856 { &vop_fsync_desc, genfs_nullop }, /* fsync */
872 { &vop_seek_desc, cd9660_seek }, /* seek */ 857 { &vop_seek_desc, genfs_seek }, /* seek */
873 { &vop_remove_desc, cd9660_remove }, /* remove */ 858 { &vop_remove_desc, genfs_eopnotsupp }, /* remove */
874 { &vop_link_desc, cd9660_link }, /* link */ 859 { &vop_link_desc, cd9660_link }, /* link */
875 { &vop_rename_desc, cd9660_rename }, /* rename */ 860 { &vop_rename_desc, genfs_eopnotsupp }, /* rename */
876 { &vop_mkdir_desc, cd9660_mkdir }, /* mkdir */ 861 { &vop_mkdir_desc, genfs_eopnotsupp }, /* mkdir */
877 { &vop_rmdir_desc, cd9660_rmdir }, /* rmdir */ 862 { &vop_rmdir_desc, genfs_eopnotsupp }, /* rmdir */
878 { &vop_symlink_desc, cd9660_symlink }, /* symlink */ 863 { &vop_symlink_desc, cd9660_symlink }, /* symlink */
879 { &vop_readdir_desc, cd9660_readdir }, /* readdir */ 864 { &vop_readdir_desc, cd9660_readdir }, /* readdir */
880 { &vop_readlink_desc, cd9660_readlink }, /* readlink */ 865 { &vop_readlink_desc, cd9660_readlink }, /* readlink */
881 { &vop_abortop_desc, cd9660_abortop }, /* abortop */ 866 { &vop_abortop_desc, genfs_abortop }, /* abortop */
882 { &vop_inactive_desc, cd9660_inactive }, /* inactive */ 867 { &vop_inactive_desc, cd9660_inactive }, /* inactive */
883 { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 868 { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
884 { &vop_lock_desc, genfs_lock }, /* lock */ 869 { &vop_lock_desc, genfs_lock }, /* lock */
885 { &vop_unlock_desc, genfs_unlock }, /* unlock */ 870 { &vop_unlock_desc, genfs_unlock }, /* unlock */
886 { &vop_bmap_desc, cd9660_bmap }, /* bmap */ 871 { &vop_bmap_desc, cd9660_bmap }, /* bmap */
887 { &vop_strategy_desc, cd9660_strategy }, /* strategy */ 872 { &vop_strategy_desc, cd9660_strategy }, /* strategy */
888 { &vop_print_desc, cd9660_print }, /* print */ 873 { &vop_print_desc, cd9660_print }, /* print */
889 { &vop_islocked_desc, genfs_islocked }, /* islocked */ 874 { &vop_islocked_desc, genfs_islocked }, /* islocked */
890 { &vop_pathconf_desc, cd9660_pathconf }, /* pathconf */ 875 { &vop_pathconf_desc, cd9660_pathconf }, /* pathconf */
891 { &vop_advlock_desc, cd9660_advlock }, /* advlock */ 876 { &vop_advlock_desc, genfs_einval }, /* advlock */
892 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 877 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */
893 { &vop_getpages_desc, genfs_getpages }, /* getpages */ 878 { &vop_getpages_desc, genfs_getpages }, /* getpages */
894 { &vop_putpages_desc, genfs_putpages }, /* putpages */ 879 { &vop_putpages_desc, genfs_putpages }, /* putpages */
895 { NULL, NULL } 880 { NULL, NULL }
896}; 881};
897const struct vnodeopv_desc cd9660_vnodeop_opv_desc = 882const struct vnodeopv_desc cd9660_vnodeop_opv_desc =
898 { &cd9660_vnodeop_p, cd9660_vnodeop_entries }; 883 { &cd9660_vnodeop_p, cd9660_vnodeop_entries };
899 884
900/* 885/*
901 * Special device vnode ops 886 * Special device vnode ops
902 */ 887 */
903int (**cd9660_specop_p)(void *); 888int (**cd9660_specop_p)(void *);
904const struct vnodeopv_entry_desc cd9660_specop_entries[] = { 889const struct vnodeopv_entry_desc cd9660_specop_entries[] = {
905 { &vop_default_desc, vn_default_error }, 890 { &vop_default_desc, vn_default_error },
906 GENFS_SPECOP_ENTRIES, 891 GENFS_SPECOP_ENTRIES,
907 { &vop_close_desc, spec_close }, /* close */ 892 { &vop_close_desc, spec_close }, /* close */
908 { &vop_access_desc, cd9660_access }, /* access */ 893 { &vop_access_desc, cd9660_access }, /* access */
909 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 894 { &vop_accessx_desc, genfs_accessx }, /* accessx */
910 { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 895 { &vop_getattr_desc, cd9660_getattr }, /* getattr */
911 { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 896 { &vop_setattr_desc, cd9660_setattr }, /* setattr */
912 { &vop_read_desc, spec_read }, /* read */ 897 { &vop_read_desc, spec_read }, /* read */
913 { &vop_write_desc, spec_write }, /* write */ 898 { &vop_write_desc, spec_write }, /* write */
914 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 899 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */
915 { &vop_fsync_desc, spec_fsync }, /* fsync */ 900 { &vop_fsync_desc, spec_fsync }, /* fsync */
916 { &vop_inactive_desc, cd9660_inactive }, /* inactive */ 901 { &vop_inactive_desc, cd9660_inactive }, /* inactive */
917 { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 902 { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
918 { &vop_lock_desc, genfs_lock }, /* lock */ 903 { &vop_lock_desc, genfs_lock }, /* lock */
919 { &vop_unlock_desc, genfs_unlock }, /* unlock */ 904 { &vop_unlock_desc, genfs_unlock }, /* unlock */
920 { &vop_print_desc, cd9660_print }, /* print */ 905 { &vop_print_desc, cd9660_print }, /* print */
921 { &vop_islocked_desc, genfs_islocked }, /* islocked */ 906 { &vop_islocked_desc, genfs_islocked }, /* islocked */
922 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 907 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */
923 { NULL, NULL } 908 { NULL, NULL }
924}; 909};
925const struct vnodeopv_desc cd9660_specop_opv_desc = 910const struct vnodeopv_desc cd9660_specop_opv_desc =
926 { &cd9660_specop_p, cd9660_specop_entries }; 911 { &cd9660_specop_p, cd9660_specop_entries };
927 912
928int (**cd9660_fifoop_p)(void *); 913int (**cd9660_fifoop_p)(void *);
929const struct vnodeopv_entry_desc cd9660_fifoop_entries[] = { 914const struct vnodeopv_entry_desc cd9660_fifoop_entries[] = {
930 { &vop_default_desc, vn_default_error }, 915 { &vop_default_desc, vn_default_error },
931 GENFS_FIFOOP_ENTRIES, 916 GENFS_FIFOOP_ENTRIES,
932 { &vop_close_desc, vn_fifo_bypass }, /* close */ 917 { &vop_close_desc, vn_fifo_bypass }, /* close */
933 { &vop_access_desc, cd9660_access }, /* access */ 918 { &vop_access_desc, cd9660_access }, /* access */
934 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 919 { &vop_accessx_desc, genfs_accessx }, /* accessx */
935 { &vop_getattr_desc, cd9660_getattr }, /* getattr */ 920 { &vop_getattr_desc, cd9660_getattr }, /* getattr */
936 { &vop_setattr_desc, cd9660_setattr }, /* setattr */ 921 { &vop_setattr_desc, cd9660_setattr }, /* setattr */
937 { &vop_read_desc, vn_fifo_bypass }, /* read */ 922 { &vop_read_desc, vn_fifo_bypass }, /* read */
938 { &vop_write_desc, vn_fifo_bypass }, /* write */ 923 { &vop_write_desc, vn_fifo_bypass }, /* write */
939 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */ 924 { &vop_fcntl_desc, genfs_fcntl }, /* fcntl */
940 { &vop_fsync_desc, vn_fifo_bypass }, /* fsync */ 925 { &vop_fsync_desc, vn_fifo_bypass }, /* fsync */
941 { &vop_inactive_desc, cd9660_inactive }, /* inactive */ 926 { &vop_inactive_desc, cd9660_inactive }, /* inactive */
942 { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */ 927 { &vop_reclaim_desc, cd9660_reclaim }, /* reclaim */
943 { &vop_lock_desc, genfs_lock }, /* lock */ 928 { &vop_lock_desc, genfs_lock }, /* lock */
944 { &vop_unlock_desc, genfs_unlock }, /* unlock */ 929 { &vop_unlock_desc, genfs_unlock }, /* unlock */
945 { &vop_strategy_desc, vn_fifo_bypass }, /* strategy */ 930 { &vop_strategy_desc, vn_fifo_bypass }, /* strategy */
946 { &vop_print_desc, cd9660_print }, /* print */ 931 { &vop_print_desc, cd9660_print }, /* print */
947 { &vop_islocked_desc, genfs_islocked }, /* islocked */ 932 { &vop_islocked_desc, genfs_islocked }, /* islocked */
948 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 933 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */
949 { NULL, NULL } 934 { NULL, NULL }
950}; 935};
951const struct vnodeopv_desc cd9660_fifoop_opv_desc = 936const struct vnodeopv_desc cd9660_fifoop_opv_desc =
952 { &cd9660_fifoop_p, cd9660_fifoop_entries }; 937 { &cd9660_fifoop_p, cd9660_fifoop_entries };

cvs diff -r1.220 -r1.221 src/sys/fs/puffs/puffs_vnops.c (switch to unified diff)

--- src/sys/fs/puffs/puffs_vnops.c 2021/07/18 23:56:13 1.220
+++ src/sys/fs/puffs/puffs_vnops.c 2021/07/19 01:30:24 1.221
@@ -1,1257 +1,1253 @@ @@ -1,1257 +1,1253 @@
1/* $NetBSD: puffs_vnops.c,v 1.220 2021/07/18 23:56:13 dholland Exp $ */ 1/* $NetBSD: puffs_vnops.c,v 1.221 2021/07/19 01:30:24 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved. 4 * Copyright (c) 2005, 2006, 2007 Antti Kantee. All Rights Reserved.
5 * 5 *
6 * Development of this software was supported by the 6 * Development of this software was supported by the
7 * Google Summer of Code program and the Ulla Tuominen Foundation. 7 * Google Summer of Code program and the Ulla Tuominen Foundation.
8 * The Google SoC project was mentored by Bill Studenmund. 8 * The Google SoC project was mentored by Bill Studenmund.
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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 22 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE. 29 * SUCH DAMAGE.
30 */ 30 */
31 31
32#include <sys/cdefs.h> 32#include <sys/cdefs.h>
33__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.220 2021/07/18 23:56:13 dholland Exp $"); 33__KERNEL_RCSID(0, "$NetBSD: puffs_vnops.c,v 1.221 2021/07/19 01:30:24 dholland Exp $");
34 34
35#include <sys/param.h> 35#include <sys/param.h>
36#include <sys/buf.h> 36#include <sys/buf.h>
37#include <sys/lockf.h> 37#include <sys/lockf.h>
38#include <sys/malloc.h> 38#include <sys/malloc.h>
39#include <sys/mount.h> 39#include <sys/mount.h>
40#include <sys/namei.h> 40#include <sys/namei.h>
41#include <sys/vnode.h> 41#include <sys/vnode.h>
42#include <sys/proc.h> 42#include <sys/proc.h>
43#include <sys/kernel.h> /* For hz, getticks() */ 43#include <sys/kernel.h> /* For hz, getticks() */
44 44
45#include <uvm/uvm.h> 45#include <uvm/uvm.h>
46 46
47#include <fs/puffs/puffs_msgif.h> 47#include <fs/puffs/puffs_msgif.h>
48#include <fs/puffs/puffs_sys.h> 48#include <fs/puffs/puffs_sys.h>
49 49
50#include <miscfs/fifofs/fifo.h> 50#include <miscfs/fifofs/fifo.h>
51#include <miscfs/genfs/genfs.h> 51#include <miscfs/genfs/genfs.h>
52#include <miscfs/specfs/specdev.h> 52#include <miscfs/specfs/specdev.h>
53 53
54int puffs_vnop_lookup(void *); 54int puffs_vnop_lookup(void *);
55int puffs_vnop_create(void *); 55int puffs_vnop_create(void *);
56int puffs_vnop_access(void *); 56int puffs_vnop_access(void *);
57int puffs_vnop_mknod(void *); 57int puffs_vnop_mknod(void *);
58int puffs_vnop_open(void *); 58int puffs_vnop_open(void *);
59int puffs_vnop_close(void *); 59int puffs_vnop_close(void *);
60int puffs_vnop_getattr(void *); 60int puffs_vnop_getattr(void *);
61int puffs_vnop_setattr(void *); 61int puffs_vnop_setattr(void *);
62int puffs_vnop_reclaim(void *); 62int puffs_vnop_reclaim(void *);
63int puffs_vnop_readdir(void *); 63int puffs_vnop_readdir(void *);
64int puffs_vnop_poll(void *); 64int puffs_vnop_poll(void *);
65int puffs_vnop_fsync(void *); 65int puffs_vnop_fsync(void *);
66int puffs_vnop_seek(void *); 66int puffs_vnop_seek(void *);
67int puffs_vnop_remove(void *); 67int puffs_vnop_remove(void *);
68int puffs_vnop_mkdir(void *); 68int puffs_vnop_mkdir(void *);
69int puffs_vnop_rmdir(void *); 69int puffs_vnop_rmdir(void *);
70int puffs_vnop_link(void *); 70int puffs_vnop_link(void *);
71int puffs_vnop_readlink(void *); 71int puffs_vnop_readlink(void *);
72int puffs_vnop_symlink(void *); 72int puffs_vnop_symlink(void *);
73int puffs_vnop_rename(void *); 73int puffs_vnop_rename(void *);
74int puffs_vnop_read(void *); 74int puffs_vnop_read(void *);
75int puffs_vnop_write(void *); 75int puffs_vnop_write(void *);
76int puffs_vnop_fallocate(void *); 76int puffs_vnop_fallocate(void *);
77int puffs_vnop_fdiscard(void *); 77int puffs_vnop_fdiscard(void *);
78int puffs_vnop_fcntl(void *); 78int puffs_vnop_fcntl(void *);
79int puffs_vnop_ioctl(void *); 79int puffs_vnop_ioctl(void *);
80int puffs_vnop_inactive(void *); 80int puffs_vnop_inactive(void *);
81int puffs_vnop_print(void *); 81int puffs_vnop_print(void *);
82int puffs_vnop_pathconf(void *); 82int puffs_vnop_pathconf(void *);
83int puffs_vnop_advlock(void *); 83int puffs_vnop_advlock(void *);
84int puffs_vnop_strategy(void *); 84int puffs_vnop_strategy(void *);
85int puffs_vnop_bmap(void *); 85int puffs_vnop_bmap(void *);
86int puffs_vnop_mmap(void *); 86int puffs_vnop_mmap(void *);
87int puffs_vnop_getpages(void *); 87int puffs_vnop_getpages(void *);
88int puffs_vnop_abortop(void *); 88int puffs_vnop_abortop(void *);
89int puffs_vnop_getextattr(void *); 89int puffs_vnop_getextattr(void *);
90int puffs_vnop_setextattr(void *); 90int puffs_vnop_setextattr(void *);
91int puffs_vnop_listextattr(void *); 91int puffs_vnop_listextattr(void *);
92int puffs_vnop_deleteextattr(void *); 92int puffs_vnop_deleteextattr(void *);
93 93
94int puffs_vnop_spec_read(void *); 94int puffs_vnop_spec_read(void *);
95int puffs_vnop_spec_write(void *); 95int puffs_vnop_spec_write(void *);
96int puffs_vnop_fifo_read(void *); 96int puffs_vnop_fifo_read(void *);
97int puffs_vnop_fifo_write(void *); 97int puffs_vnop_fifo_write(void *);
98 98
99int puffs_vnop_checkop(void *); 99int puffs_vnop_checkop(void *);
100 100
101#define puffs_vnop_lock genfs_lock 
102#define puffs_vnop_unlock genfs_unlock 
103#define puffs_vnop_islocked genfs_islocked 
104 
105int (**puffs_vnodeop_p)(void *); 101int (**puffs_vnodeop_p)(void *);
106const struct vnodeopv_entry_desc puffs_vnodeop_entries[] = { 102const struct vnodeopv_entry_desc puffs_vnodeop_entries[] = {
107 { &vop_default_desc, vn_default_error }, 103 { &vop_default_desc, vn_default_error },
108 { &vop_parsepath_desc, genfs_parsepath }, /* parsepath */ 104 { &vop_parsepath_desc, genfs_parsepath }, /* parsepath */
109 { &vop_lookup_desc, puffs_vnop_lookup }, /* REAL lookup */ 105 { &vop_lookup_desc, puffs_vnop_lookup }, /* REAL lookup */
110 { &vop_create_desc, puffs_vnop_checkop }, /* create */ 106 { &vop_create_desc, puffs_vnop_checkop }, /* create */
111 { &vop_mknod_desc, puffs_vnop_checkop }, /* mknod */ 107 { &vop_mknod_desc, puffs_vnop_checkop }, /* mknod */
112 { &vop_open_desc, puffs_vnop_open }, /* REAL open */ 108 { &vop_open_desc, puffs_vnop_open }, /* REAL open */
113 { &vop_close_desc, puffs_vnop_checkop }, /* close */ 109 { &vop_close_desc, puffs_vnop_checkop }, /* close */
114 { &vop_access_desc, puffs_vnop_access }, /* REAL access */ 110 { &vop_access_desc, puffs_vnop_access }, /* REAL access */
115 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 111 { &vop_accessx_desc, genfs_accessx }, /* accessx */
116 { &vop_getattr_desc, puffs_vnop_checkop }, /* getattr */ 112 { &vop_getattr_desc, puffs_vnop_checkop }, /* getattr */
117 { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */ 113 { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */
118 { &vop_read_desc, puffs_vnop_checkop }, /* read */ 114 { &vop_read_desc, puffs_vnop_checkop }, /* read */
119 { &vop_write_desc, puffs_vnop_checkop }, /* write */ 115 { &vop_write_desc, puffs_vnop_checkop }, /* write */
120 { &vop_fallocate_desc, puffs_vnop_fallocate }, /* fallocate */ 116 { &vop_fallocate_desc, puffs_vnop_fallocate }, /* fallocate */
121 { &vop_fdiscard_desc, puffs_vnop_fdiscard }, /* fdiscard */ 117 { &vop_fdiscard_desc, puffs_vnop_fdiscard }, /* fdiscard */
122 { &vop_fsync_desc, puffs_vnop_fsync }, /* REAL fsync */ 118 { &vop_fsync_desc, puffs_vnop_fsync }, /* REAL fsync */
123 { &vop_seek_desc, puffs_vnop_checkop }, /* seek */ 119 { &vop_seek_desc, puffs_vnop_checkop }, /* seek */
124 { &vop_remove_desc, puffs_vnop_checkop }, /* remove */ 120 { &vop_remove_desc, puffs_vnop_checkop }, /* remove */
125 { &vop_link_desc, puffs_vnop_checkop }, /* link */ 121 { &vop_link_desc, puffs_vnop_checkop }, /* link */
126 { &vop_rename_desc, puffs_vnop_checkop }, /* rename */ 122 { &vop_rename_desc, puffs_vnop_checkop }, /* rename */
127 { &vop_mkdir_desc, puffs_vnop_checkop }, /* mkdir */ 123 { &vop_mkdir_desc, puffs_vnop_checkop }, /* mkdir */
128 { &vop_rmdir_desc, puffs_vnop_checkop }, /* rmdir */ 124 { &vop_rmdir_desc, puffs_vnop_checkop }, /* rmdir */
129 { &vop_symlink_desc, puffs_vnop_checkop }, /* symlink */ 125 { &vop_symlink_desc, puffs_vnop_checkop }, /* symlink */
130 { &vop_readdir_desc, puffs_vnop_checkop }, /* readdir */ 126 { &vop_readdir_desc, puffs_vnop_checkop }, /* readdir */
131 { &vop_readlink_desc, puffs_vnop_checkop }, /* readlink */ 127 { &vop_readlink_desc, puffs_vnop_checkop }, /* readlink */
132 { &vop_getpages_desc, puffs_vnop_checkop }, /* getpages */ 128 { &vop_getpages_desc, puffs_vnop_checkop }, /* getpages */
133 { &vop_putpages_desc, genfs_putpages }, /* REAL putpages */ 129 { &vop_putpages_desc, genfs_putpages }, /* REAL putpages */
134 { &vop_pathconf_desc, puffs_vnop_checkop }, /* pathconf */ 130 { &vop_pathconf_desc, puffs_vnop_checkop }, /* pathconf */
135 { &vop_advlock_desc, puffs_vnop_advlock }, /* advlock */ 131 { &vop_advlock_desc, puffs_vnop_advlock }, /* advlock */
136 { &vop_strategy_desc, puffs_vnop_strategy }, /* REAL strategy */ 132 { &vop_strategy_desc, puffs_vnop_strategy }, /* REAL strategy */
137 { &vop_revoke_desc, genfs_revoke }, /* REAL revoke */ 133 { &vop_revoke_desc, genfs_revoke }, /* REAL revoke */
138 { &vop_abortop_desc, puffs_vnop_abortop }, /* REAL abortop */ 134 { &vop_abortop_desc, puffs_vnop_abortop }, /* REAL abortop */
139 { &vop_inactive_desc, puffs_vnop_inactive }, /* REAL inactive */ 135 { &vop_inactive_desc, puffs_vnop_inactive }, /* REAL inactive */
140 { &vop_reclaim_desc, puffs_vnop_reclaim }, /* REAL reclaim */ 136 { &vop_reclaim_desc, puffs_vnop_reclaim }, /* REAL reclaim */
141 { &vop_lock_desc, puffs_vnop_lock }, /* REAL lock */ 137 { &vop_lock_desc, genfs_lock }, /* REAL lock */
142 { &vop_unlock_desc, puffs_vnop_unlock }, /* REAL unlock */ 138 { &vop_unlock_desc, genfs_unlock }, /* REAL unlock */
143 { &vop_bmap_desc, puffs_vnop_bmap }, /* REAL bmap */ 139 { &vop_bmap_desc, puffs_vnop_bmap }, /* REAL bmap */
144 { &vop_print_desc, puffs_vnop_print }, /* REAL print */ 140 { &vop_print_desc, puffs_vnop_print }, /* REAL print */
145 { &vop_islocked_desc, puffs_vnop_islocked }, /* REAL islocked */ 141 { &vop_islocked_desc, genfs_islocked }, /* REAL islocked */
146 { &vop_bwrite_desc, genfs_nullop }, /* REAL bwrite */ 142 { &vop_bwrite_desc, genfs_nullop }, /* REAL bwrite */
147 { &vop_mmap_desc, puffs_vnop_mmap }, /* REAL mmap */ 143 { &vop_mmap_desc, puffs_vnop_mmap }, /* REAL mmap */
148 { &vop_poll_desc, puffs_vnop_poll }, /* REAL poll */ 144 { &vop_poll_desc, puffs_vnop_poll }, /* REAL poll */
149 { &vop_getextattr_desc, puffs_vnop_getextattr }, /* getextattr */ 145 { &vop_getextattr_desc, puffs_vnop_getextattr }, /* getextattr */
150 { &vop_setextattr_desc, puffs_vnop_setextattr }, /* setextattr */ 146 { &vop_setextattr_desc, puffs_vnop_setextattr }, /* setextattr */
151 { &vop_listextattr_desc, puffs_vnop_listextattr }, /* listextattr */ 147 { &vop_listextattr_desc, puffs_vnop_listextattr }, /* listextattr */
152 { &vop_deleteextattr_desc, puffs_vnop_deleteextattr },/* deleteextattr */ 148 { &vop_deleteextattr_desc, puffs_vnop_deleteextattr },/* deleteextattr */
153#if 0 149#if 0
154 { &vop_openextattr_desc, puffs_vnop_checkop }, /* openextattr */ 150 { &vop_openextattr_desc, puffs_vnop_checkop }, /* openextattr */
155 { &vop_closeextattr_desc, puffs_vnop_checkop }, /* closeextattr */ 151 { &vop_closeextattr_desc, puffs_vnop_checkop }, /* closeextattr */
156#endif 152#endif
157 { &vop_kqfilter_desc, genfs_eopnotsupp }, /* kqfilter XXX */ 153 { &vop_kqfilter_desc, genfs_eopnotsupp }, /* kqfilter XXX */
158 { NULL, NULL } 154 { NULL, NULL }
159}; 155};
160const struct vnodeopv_desc puffs_vnodeop_opv_desc = 156const struct vnodeopv_desc puffs_vnodeop_opv_desc =
161 { &puffs_vnodeop_p, puffs_vnodeop_entries }; 157 { &puffs_vnodeop_p, puffs_vnodeop_entries };
162 158
163 159
164int (**puffs_specop_p)(void *); 160int (**puffs_specop_p)(void *);
165const struct vnodeopv_entry_desc puffs_specop_entries[] = { 161const struct vnodeopv_entry_desc puffs_specop_entries[] = {
166 { &vop_default_desc, vn_default_error }, 162 { &vop_default_desc, vn_default_error },
167 GENFS_SPECOP_ENTRIES, 163 GENFS_SPECOP_ENTRIES,
168 { &vop_close_desc, spec_close }, /* spec_close */ 164 { &vop_close_desc, spec_close }, /* spec_close */
169 { &vop_access_desc, puffs_vnop_checkop }, /* access */ 165 { &vop_access_desc, puffs_vnop_checkop }, /* access */
170 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 166 { &vop_accessx_desc, genfs_accessx }, /* accessx */
171 { &vop_getattr_desc, puffs_vnop_checkop }, /* getattr */ 167 { &vop_getattr_desc, puffs_vnop_checkop }, /* getattr */
172 { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */ 168 { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */
173 { &vop_read_desc, puffs_vnop_spec_read }, /* update, read */ 169 { &vop_read_desc, puffs_vnop_spec_read }, /* update, read */
174 { &vop_write_desc, puffs_vnop_spec_write }, /* update, write */ 170 { &vop_write_desc, puffs_vnop_spec_write }, /* update, write */
175 { &vop_fcntl_desc, genfs_fcntl }, /* dummy */ 171 { &vop_fcntl_desc, genfs_fcntl }, /* dummy */
176 { &vop_fsync_desc, spec_fsync }, /* vflushbuf */ 172 { &vop_fsync_desc, spec_fsync }, /* vflushbuf */
177 { &vop_inactive_desc, puffs_vnop_inactive }, /* REAL inactive */ 173 { &vop_inactive_desc, puffs_vnop_inactive }, /* REAL inactive */
178 { &vop_reclaim_desc, puffs_vnop_reclaim }, /* REAL reclaim */ 174 { &vop_reclaim_desc, puffs_vnop_reclaim }, /* REAL reclaim */
179 { &vop_lock_desc, puffs_vnop_lock }, /* REAL lock */ 175 { &vop_lock_desc, genfs_lock }, /* REAL lock */
180 { &vop_unlock_desc, puffs_vnop_unlock }, /* REAL unlock */ 176 { &vop_unlock_desc, genfs_unlock }, /* REAL unlock */
181 { &vop_print_desc, puffs_vnop_print }, /* REAL print */ 177 { &vop_print_desc, puffs_vnop_print }, /* REAL print */
182 { &vop_islocked_desc, puffs_vnop_islocked }, /* REAL islocked */ 178 { &vop_islocked_desc, genfs_islocked }, /* REAL islocked */
183 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 179 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */
184 { &vop_getextattr_desc, puffs_vnop_checkop }, /* getextattr */ 180 { &vop_getextattr_desc, puffs_vnop_checkop }, /* getextattr */
185 { &vop_setextattr_desc, puffs_vnop_checkop }, /* setextattr */ 181 { &vop_setextattr_desc, puffs_vnop_checkop }, /* setextattr */
186 { &vop_listextattr_desc, puffs_vnop_checkop }, /* listextattr */ 182 { &vop_listextattr_desc, puffs_vnop_checkop }, /* listextattr */
187 { &vop_deleteextattr_desc, puffs_vnop_checkop },/* deleteextattr */ 183 { &vop_deleteextattr_desc, puffs_vnop_checkop },/* deleteextattr */
188#if 0 184#if 0
189 { &vop_openextattr_desc, _openextattr }, /* openextattr */ 185 { &vop_openextattr_desc, _openextattr }, /* openextattr */
190 { &vop_closeextattr_desc, _closeextattr }, /* closeextattr */ 186 { &vop_closeextattr_desc, _closeextattr }, /* closeextattr */
191#endif 187#endif
192 { NULL, NULL } 188 { NULL, NULL }
193}; 189};
194const struct vnodeopv_desc puffs_specop_opv_desc = 190const struct vnodeopv_desc puffs_specop_opv_desc =
195 { &puffs_specop_p, puffs_specop_entries }; 191 { &puffs_specop_p, puffs_specop_entries };
196 192
197 193
198int (**puffs_fifoop_p)(void *); 194int (**puffs_fifoop_p)(void *);
199const struct vnodeopv_entry_desc puffs_fifoop_entries[] = { 195const struct vnodeopv_entry_desc puffs_fifoop_entries[] = {
200 { &vop_default_desc, vn_default_error }, 196 { &vop_default_desc, vn_default_error },
201 GENFS_FIFOOP_ENTRIES, 197 GENFS_FIFOOP_ENTRIES,
202 { &vop_close_desc, vn_fifo_bypass }, /* close */ 198 { &vop_close_desc, vn_fifo_bypass }, /* close */
203 { &vop_access_desc, puffs_vnop_checkop }, /* access */ 199 { &vop_access_desc, puffs_vnop_checkop }, /* access */
204 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 200 { &vop_accessx_desc, genfs_accessx }, /* accessx */
205 { &vop_getattr_desc, puffs_vnop_checkop }, /* getattr */ 201 { &vop_getattr_desc, puffs_vnop_checkop }, /* getattr */
206 { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */ 202 { &vop_setattr_desc, puffs_vnop_checkop }, /* setattr */
207 { &vop_read_desc, puffs_vnop_fifo_read }, /* read, update */ 203 { &vop_read_desc, puffs_vnop_fifo_read }, /* read, update */
208 { &vop_write_desc, puffs_vnop_fifo_write }, /* write, update */ 204 { &vop_write_desc, puffs_vnop_fifo_write }, /* write, update */
209 { &vop_fcntl_desc, genfs_fcntl }, /* dummy */ 205 { &vop_fcntl_desc, genfs_fcntl }, /* dummy */
210 { &vop_fsync_desc, vn_fifo_bypass }, /* genfs_nullop*/ 206 { &vop_fsync_desc, vn_fifo_bypass }, /* genfs_nullop*/
211 { &vop_inactive_desc, puffs_vnop_inactive }, /* REAL inactive */ 207 { &vop_inactive_desc, puffs_vnop_inactive }, /* REAL inactive */
212 { &vop_reclaim_desc, puffs_vnop_reclaim }, /* REAL reclaim */ 208 { &vop_reclaim_desc, puffs_vnop_reclaim }, /* REAL reclaim */
213 { &vop_lock_desc, puffs_vnop_lock }, /* REAL lock */ 209 { &vop_lock_desc, genfs_lock }, /* REAL lock */
214 { &vop_unlock_desc, puffs_vnop_unlock }, /* REAL unlock */ 210 { &vop_unlock_desc, genfs_unlock }, /* REAL unlock */
215 { &vop_strategy_desc, vn_fifo_bypass }, /* genfs_badop */ 211 { &vop_strategy_desc, vn_fifo_bypass }, /* genfs_badop */
216 { &vop_print_desc, puffs_vnop_print }, /* REAL print */ 212 { &vop_print_desc, puffs_vnop_print }, /* REAL print */
217 { &vop_islocked_desc, puffs_vnop_islocked }, /* REAL islocked */ 213 { &vop_islocked_desc, genfs_islocked }, /* REAL islocked */
218 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 214 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */
219#if 0 215#if 0
220 { &vop_openextattr_desc, _openextattr }, /* openextattr */ 216 { &vop_openextattr_desc, _openextattr }, /* openextattr */
221 { &vop_closeextattr_desc, _closeextattr }, /* closeextattr */ 217 { &vop_closeextattr_desc, _closeextattr }, /* closeextattr */
222#endif 218#endif
223 { &vop_getextattr_desc, puffs_vnop_checkop }, /* getextattr */ 219 { &vop_getextattr_desc, puffs_vnop_checkop }, /* getextattr */
224 { &vop_setextattr_desc, puffs_vnop_checkop }, /* setextattr */ 220 { &vop_setextattr_desc, puffs_vnop_checkop }, /* setextattr */
225 { &vop_listextattr_desc, puffs_vnop_checkop }, /* listextattr */ 221 { &vop_listextattr_desc, puffs_vnop_checkop }, /* listextattr */
226 { &vop_deleteextattr_desc, puffs_vnop_checkop }, /* deleteextattr */ 222 { &vop_deleteextattr_desc, puffs_vnop_checkop }, /* deleteextattr */
227 { NULL, NULL } 223 { NULL, NULL }
228}; 224};
229const struct vnodeopv_desc puffs_fifoop_opv_desc = 225const struct vnodeopv_desc puffs_fifoop_opv_desc =
230 { &puffs_fifoop_p, puffs_fifoop_entries }; 226 { &puffs_fifoop_p, puffs_fifoop_entries };
231 227
232 228
233/* "real" vnode operations */ 229/* "real" vnode operations */
234int (**puffs_msgop_p)(void *); 230int (**puffs_msgop_p)(void *);
235const struct vnodeopv_entry_desc puffs_msgop_entries[] = { 231const struct vnodeopv_entry_desc puffs_msgop_entries[] = {
236 { &vop_default_desc, vn_default_error }, 232 { &vop_default_desc, vn_default_error },
237 { &vop_parsepath_desc, genfs_parsepath }, 233 { &vop_parsepath_desc, genfs_parsepath },
238 { &vop_create_desc, puffs_vnop_create }, /* create */ 234 { &vop_create_desc, puffs_vnop_create }, /* create */
239 { &vop_mknod_desc, puffs_vnop_mknod }, /* mknod */ 235 { &vop_mknod_desc, puffs_vnop_mknod }, /* mknod */
240 { &vop_open_desc, puffs_vnop_open }, /* open */ 236 { &vop_open_desc, puffs_vnop_open }, /* open */
241 { &vop_close_desc, puffs_vnop_close }, /* close */ 237 { &vop_close_desc, puffs_vnop_close }, /* close */
242 { &vop_access_desc, puffs_vnop_access }, /* access */ 238 { &vop_access_desc, puffs_vnop_access }, /* access */
243 { &vop_accessx_desc, genfs_accessx }, /* accessx */ 239 { &vop_accessx_desc, genfs_accessx }, /* accessx */
244 { &vop_getattr_desc, puffs_vnop_getattr }, /* getattr */ 240 { &vop_getattr_desc, puffs_vnop_getattr }, /* getattr */
245 { &vop_setattr_desc, puffs_vnop_setattr }, /* setattr */ 241 { &vop_setattr_desc, puffs_vnop_setattr }, /* setattr */
246 { &vop_read_desc, puffs_vnop_read }, /* read */ 242 { &vop_read_desc, puffs_vnop_read }, /* read */
247 { &vop_write_desc, puffs_vnop_write }, /* write */ 243 { &vop_write_desc, puffs_vnop_write }, /* write */
248 { &vop_seek_desc, puffs_vnop_seek }, /* seek */ 244 { &vop_seek_desc, puffs_vnop_seek }, /* seek */
249 { &vop_remove_desc, puffs_vnop_remove }, /* remove */ 245 { &vop_remove_desc, puffs_vnop_remove }, /* remove */
250 { &vop_link_desc, puffs_vnop_link }, /* link */ 246 { &vop_link_desc, puffs_vnop_link }, /* link */
251 { &vop_rename_desc, puffs_vnop_rename }, /* rename */ 247 { &vop_rename_desc, puffs_vnop_rename }, /* rename */
252 { &vop_mkdir_desc, puffs_vnop_mkdir }, /* mkdir */ 248 { &vop_mkdir_desc, puffs_vnop_mkdir }, /* mkdir */
253 { &vop_rmdir_desc, puffs_vnop_rmdir }, /* rmdir */ 249 { &vop_rmdir_desc, puffs_vnop_rmdir }, /* rmdir */
254 { &vop_symlink_desc, puffs_vnop_symlink }, /* symlink */ 250 { &vop_symlink_desc, puffs_vnop_symlink }, /* symlink */
255 { &vop_readdir_desc, puffs_vnop_readdir }, /* readdir */ 251 { &vop_readdir_desc, puffs_vnop_readdir }, /* readdir */
256 { &vop_readlink_desc, puffs_vnop_readlink }, /* readlink */ 252 { &vop_readlink_desc, puffs_vnop_readlink }, /* readlink */
257 { &vop_print_desc, puffs_vnop_print }, /* print */ 253 { &vop_print_desc, puffs_vnop_print }, /* print */
258 { &vop_islocked_desc, puffs_vnop_islocked }, /* islocked */ 254 { &vop_islocked_desc, genfs_islocked }, /* islocked */
259 { &vop_pathconf_desc, puffs_vnop_pathconf }, /* pathconf */ 255 { &vop_pathconf_desc, puffs_vnop_pathconf }, /* pathconf */
260 { &vop_getpages_desc, puffs_vnop_getpages }, /* getpages */ 256 { &vop_getpages_desc, puffs_vnop_getpages }, /* getpages */
261 { NULL, NULL } 257 { NULL, NULL }
262}; 258};
263const struct vnodeopv_desc puffs_msgop_opv_desc = 259const struct vnodeopv_desc puffs_msgop_opv_desc =
264 { &puffs_msgop_p, puffs_msgop_entries }; 260 { &puffs_msgop_p, puffs_msgop_entries };
265 261
266/* 262/*
267 * for dosetattr / update_va  263 * for dosetattr / update_va
268 */ 264 */
269#define SETATTR_CHSIZE 0x01 265#define SETATTR_CHSIZE 0x01
270#define SETATTR_ASYNC 0x02 266#define SETATTR_ASYNC 0x02
271 267
272#define ERROUT(err) \ 268#define ERROUT(err) \
273do { \ 269do { \
274 error = err; \ 270 error = err; \
275 goto out; \ 271 goto out; \
276} while (/*CONSTCOND*/0) 272} while (/*CONSTCOND*/0)
277 273
278/* 274/*
279 * This is a generic vnode operation handler. It checks if the necessary 275 * This is a generic vnode operation handler. It checks if the necessary
280 * operations for the called vnode operation are implemented by userspace 276 * operations for the called vnode operation are implemented by userspace
281 * and either returns a dummy return value or proceeds to call the real 277 * and either returns a dummy return value or proceeds to call the real
282 * vnode operation from puffs_msgop_v. 278 * vnode operation from puffs_msgop_v.
283 * 279 *
284 * XXX: this should described elsewhere and autogenerated, the complexity 280 * XXX: this should described elsewhere and autogenerated, the complexity
285 * of the vnode operations vectors and their interrelationships is also 281 * of the vnode operations vectors and their interrelationships is also
286 * getting a bit out of hand. Another problem is that we need this same 282 * getting a bit out of hand. Another problem is that we need this same
287 * information in the fs server code, so keeping the two in sync manually 283 * information in the fs server code, so keeping the two in sync manually
288 * is not a viable (long term) plan. 284 * is not a viable (long term) plan.
289 */ 285 */
290 286
291/* not supported, handle locking protocol */ 287/* not supported, handle locking protocol */
292#define CHECKOP_NOTSUPP(op) \ 288#define CHECKOP_NOTSUPP(op) \
293case VOP_##op##_DESCOFFSET: \ 289case VOP_##op##_DESCOFFSET: \
294 if (pmp->pmp_vnopmask[PUFFS_VN_##op] == 0) \ 290 if (pmp->pmp_vnopmask[PUFFS_VN_##op] == 0) \
295 return genfs_eopnotsupp(v); \ 291 return genfs_eopnotsupp(v); \
296 break 292 break
297 293
298/* always succeed, no locking */ 294/* always succeed, no locking */
299#define CHECKOP_SUCCESS(op) \ 295#define CHECKOP_SUCCESS(op) \
300case VOP_##op##_DESCOFFSET: \ 296case VOP_##op##_DESCOFFSET: \
301 if (pmp->pmp_vnopmask[PUFFS_VN_##op] == 0) \ 297 if (pmp->pmp_vnopmask[PUFFS_VN_##op] == 0) \
302 return 0; \ 298 return 0; \
303 break 299 break
304 300
305int 301int
306puffs_vnop_checkop(void *v) 302puffs_vnop_checkop(void *v)
307{ 303{
308 struct vop_generic_args /* { 304 struct vop_generic_args /* {
309 struct vnodeop_desc *a_desc; 305 struct vnodeop_desc *a_desc;
310 spooky mystery contents; 306 spooky mystery contents;
311 } */ *ap = v; 307 } */ *ap = v;
312 struct vnodeop_desc *desc = ap->a_desc; 308 struct vnodeop_desc *desc = ap->a_desc;
313 struct puffs_mount *pmp; 309 struct puffs_mount *pmp;
314 struct vnode *vp; 310 struct vnode *vp;
315 int offset, rv; 311 int offset, rv;
316 312
317 offset = ap->a_desc->vdesc_vp_offsets[0]; 313 offset = ap->a_desc->vdesc_vp_offsets[0];
318#ifdef DIAGNOSTIC 314#ifdef DIAGNOSTIC
319 if (offset == VDESC_NO_OFFSET) 315 if (offset == VDESC_NO_OFFSET)
320 panic("puffs_checkop: no vnode, why did you call me?"); 316 panic("puffs_checkop: no vnode, why did you call me?");
321#endif 317#endif
322 vp = *VOPARG_OFFSETTO(struct vnode **, offset, ap); 318 vp = *VOPARG_OFFSETTO(struct vnode **, offset, ap);
323 pmp = MPTOPUFFSMP(vp->v_mount); 319 pmp = MPTOPUFFSMP(vp->v_mount);
324 320
325 DPRINTF_VERBOSE(("checkop call %s (%d), vp %p\n", 321 DPRINTF_VERBOSE(("checkop call %s (%d), vp %p\n",
326 ap->a_desc->vdesc_name, ap->a_desc->vdesc_offset, vp)); 322 ap->a_desc->vdesc_name, ap->a_desc->vdesc_offset, vp));
327 323
328 if (!ALLOPS(pmp)) { 324 if (!ALLOPS(pmp)) {
329 switch (desc->vdesc_offset) { 325 switch (desc->vdesc_offset) {
330 CHECKOP_NOTSUPP(CREATE); 326 CHECKOP_NOTSUPP(CREATE);
331 CHECKOP_NOTSUPP(MKNOD); 327 CHECKOP_NOTSUPP(MKNOD);
332 CHECKOP_NOTSUPP(GETATTR); 328 CHECKOP_NOTSUPP(GETATTR);
333 CHECKOP_NOTSUPP(SETATTR); 329 CHECKOP_NOTSUPP(SETATTR);
334 CHECKOP_NOTSUPP(READ); 330 CHECKOP_NOTSUPP(READ);
335 CHECKOP_NOTSUPP(WRITE); 331 CHECKOP_NOTSUPP(WRITE);
336 CHECKOP_NOTSUPP(FCNTL); 332 CHECKOP_NOTSUPP(FCNTL);
337 CHECKOP_NOTSUPP(IOCTL); 333 CHECKOP_NOTSUPP(IOCTL);
338 CHECKOP_NOTSUPP(REMOVE); 334 CHECKOP_NOTSUPP(REMOVE);
339 CHECKOP_NOTSUPP(LINK); 335 CHECKOP_NOTSUPP(LINK);
340 CHECKOP_NOTSUPP(RENAME); 336 CHECKOP_NOTSUPP(RENAME);
341 CHECKOP_NOTSUPP(MKDIR); 337 CHECKOP_NOTSUPP(MKDIR);
342 CHECKOP_NOTSUPP(RMDIR); 338 CHECKOP_NOTSUPP(RMDIR);
343 CHECKOP_NOTSUPP(SYMLINK); 339 CHECKOP_NOTSUPP(SYMLINK);
344 CHECKOP_NOTSUPP(READDIR); 340 CHECKOP_NOTSUPP(READDIR);
345 CHECKOP_NOTSUPP(READLINK); 341 CHECKOP_NOTSUPP(READLINK);
346 CHECKOP_NOTSUPP(PRINT); 342 CHECKOP_NOTSUPP(PRINT);
347 CHECKOP_NOTSUPP(PATHCONF); 343 CHECKOP_NOTSUPP(PATHCONF);
348 CHECKOP_NOTSUPP(GETEXTATTR); 344 CHECKOP_NOTSUPP(GETEXTATTR);
349 CHECKOP_NOTSUPP(SETEXTATTR); 345 CHECKOP_NOTSUPP(SETEXTATTR);
350 CHECKOP_NOTSUPP(LISTEXTATTR); 346 CHECKOP_NOTSUPP(LISTEXTATTR);
351 CHECKOP_NOTSUPP(DELETEEXTATTR); 347 CHECKOP_NOTSUPP(DELETEEXTATTR);
352 348
353 CHECKOP_SUCCESS(ACCESS); 349 CHECKOP_SUCCESS(ACCESS);
354 CHECKOP_SUCCESS(CLOSE); 350 CHECKOP_SUCCESS(CLOSE);
355 CHECKOP_SUCCESS(SEEK); 351 CHECKOP_SUCCESS(SEEK);
356 352
357 case VOP_GETPAGES_DESCOFFSET: 353 case VOP_GETPAGES_DESCOFFSET:
358 if (!EXISTSOP(pmp, READ)) 354 if (!EXISTSOP(pmp, READ))
359 return genfs_eopnotsupp(v); 355 return genfs_eopnotsupp(v);
360 break; 356 break;
361 357
362 default: 358 default:
363 panic("puffs_checkop: unhandled vnop %d", 359 panic("puffs_checkop: unhandled vnop %d",
364 desc->vdesc_offset); 360 desc->vdesc_offset);
365 } 361 }
366 } 362 }
367 363
368 rv = VOCALL(puffs_msgop_p, ap->a_desc->vdesc_offset, v); 364 rv = VOCALL(puffs_msgop_p, ap->a_desc->vdesc_offset, v);
369 365
370 DPRINTF_VERBOSE(("checkop return %s (%d), vp %p: %d\n", 366 DPRINTF_VERBOSE(("checkop return %s (%d), vp %p: %d\n",
371 ap->a_desc->vdesc_name, ap->a_desc->vdesc_offset, vp, rv)); 367 ap->a_desc->vdesc_name, ap->a_desc->vdesc_offset, vp, rv));
372 368
373 return rv; 369 return rv;
374} 370}
375 371
376static int callremove(struct puffs_mount *, puffs_cookie_t, puffs_cookie_t, 372static int callremove(struct puffs_mount *, puffs_cookie_t, puffs_cookie_t,
377 struct componentname *); 373 struct componentname *);
378static int callrmdir(struct puffs_mount *, puffs_cookie_t, puffs_cookie_t, 374static int callrmdir(struct puffs_mount *, puffs_cookie_t, puffs_cookie_t,
379 struct componentname *); 375 struct componentname *);
380static void callinactive(struct puffs_mount *, puffs_cookie_t, int); 376static void callinactive(struct puffs_mount *, puffs_cookie_t, int);
381static void callreclaim(struct puffs_mount *, puffs_cookie_t, int); 377static void callreclaim(struct puffs_mount *, puffs_cookie_t, int);
382static int flushvncache(struct vnode *, off_t, off_t, bool); 378static int flushvncache(struct vnode *, off_t, off_t, bool);
383static void update_va(struct vnode *, struct vattr *, struct vattr *, 379static void update_va(struct vnode *, struct vattr *, struct vattr *,
384 struct timespec *, struct timespec *, int); 380 struct timespec *, struct timespec *, int);
385static void update_parent(struct vnode *, struct vnode *); 381static void update_parent(struct vnode *, struct vnode *);
386 382
387 383
388#define PUFFS_ABORT_LOOKUP 1 384#define PUFFS_ABORT_LOOKUP 1
389#define PUFFS_ABORT_CREATE 2 385#define PUFFS_ABORT_CREATE 2
390#define PUFFS_ABORT_MKNOD 3 386#define PUFFS_ABORT_MKNOD 3
391#define PUFFS_ABORT_MKDIR 4 387#define PUFFS_ABORT_MKDIR 4
392#define PUFFS_ABORT_SYMLINK 5 388#define PUFFS_ABORT_SYMLINK 5
393 389
394/* 390/*
395 * Press the pani^Wabort button! Kernel resource allocation failed. 391 * Press the pani^Wabort button! Kernel resource allocation failed.
396 */ 392 */
397static void 393static void
398puffs_abortbutton(struct puffs_mount *pmp, int what, 394puffs_abortbutton(struct puffs_mount *pmp, int what,
399 puffs_cookie_t dck, puffs_cookie_t ck, struct componentname *cnp) 395 puffs_cookie_t dck, puffs_cookie_t ck, struct componentname *cnp)
400{ 396{
401 397
402 switch (what) { 398 switch (what) {
403 case PUFFS_ABORT_CREATE: 399 case PUFFS_ABORT_CREATE:
404 case PUFFS_ABORT_MKNOD: 400 case PUFFS_ABORT_MKNOD:
405 case PUFFS_ABORT_SYMLINK: 401 case PUFFS_ABORT_SYMLINK:
406 callremove(pmp, dck, ck, cnp); 402 callremove(pmp, dck, ck, cnp);
407 break; 403 break;
408 case PUFFS_ABORT_MKDIR: 404 case PUFFS_ABORT_MKDIR:
409 callrmdir(pmp, dck, ck, cnp); 405 callrmdir(pmp, dck, ck, cnp);
410 break; 406 break;
411 } 407 }
412 408
413 callinactive(pmp, ck, 0); 409 callinactive(pmp, ck, 0);
414 callreclaim(pmp, ck, 1); 410 callreclaim(pmp, ck, 1);
415} 411}
416 412
417/* 413/*
418 * Begin vnode operations. 414 * Begin vnode operations.
419 * 415 *
420 * A word from the keymaster about locks: generally we don't want 416 * A word from the keymaster about locks: generally we don't want
421 * to use the vnode locks at all: it creates an ugly dependency between 417 * to use the vnode locks at all: it creates an ugly dependency between
422 * the userlandia file server and the kernel. But we'll play along with 418 * the userlandia file server and the kernel. But we'll play along with
423 * the kernel vnode locks for now. However, even currently we attempt 419 * the kernel vnode locks for now. However, even currently we attempt
424 * to release locks as early as possible. This is possible for some 420 * to release locks as early as possible. This is possible for some
425 * operations which a) don't need a locked vnode after the userspace op 421 * operations which a) don't need a locked vnode after the userspace op
426 * and b) return with the vnode unlocked. Theoretically we could 422 * and b) return with the vnode unlocked. Theoretically we could
427 * unlock-do op-lock for others and order the graph in userspace, but I 423 * unlock-do op-lock for others and order the graph in userspace, but I
428 * don't want to think of the consequences for the time being. 424 * don't want to think of the consequences for the time being.
429 */ 425 */
430 426
431#define TTL_TO_TIMEOUT(ts) \ 427#define TTL_TO_TIMEOUT(ts) \
432 (getticks() + (ts->tv_sec * hz) + (ts->tv_nsec * hz / 1000000000)) 428 (getticks() + (ts->tv_sec * hz) + (ts->tv_nsec * hz / 1000000000))
433#define TTL_VALID(ts) \ 429#define TTL_VALID(ts) \
434 ((ts != NULL) && !((ts->tv_sec == 0) && (ts->tv_nsec == 0))) 430 ((ts != NULL) && !((ts->tv_sec == 0) && (ts->tv_nsec == 0)))
435#define TIMED_OUT(expire) \ 431#define TIMED_OUT(expire) \
436 ((int)((unsigned int)getticks() - (unsigned int)expire) > 0) 432 ((int)((unsigned int)getticks() - (unsigned int)expire) > 0)
437int 433int
438puffs_vnop_lookup(void *v) 434puffs_vnop_lookup(void *v)
439{ 435{
440 struct vop_lookup_v2_args /* { 436 struct vop_lookup_v2_args /* {
441 const struct vnodeop_desc *a_desc; 437 const struct vnodeop_desc *a_desc;
442 struct vnode *a_dvp; 438 struct vnode *a_dvp;
443 struct vnode **a_vpp; 439 struct vnode **a_vpp;
444 struct componentname *a_cnp; 440 struct componentname *a_cnp;
445 } */ *ap = v; 441 } */ *ap = v;
446 PUFFS_MSG_VARS(vn, lookup); 442 PUFFS_MSG_VARS(vn, lookup);
447 struct puffs_mount *pmp; 443 struct puffs_mount *pmp;
448 struct componentname *cnp; 444 struct componentname *cnp;
449 struct vnode *vp, *dvp, *cvp; 445 struct vnode *vp, *dvp, *cvp;
450 struct puffs_node *dpn, *cpn; 446 struct puffs_node *dpn, *cpn;
451 int isdot; 447 int isdot;
452 int error; 448 int error;
453 449
454 pmp = MPTOPUFFSMP(ap->a_dvp->v_mount); 450 pmp = MPTOPUFFSMP(ap->a_dvp->v_mount);
455 cnp = ap->a_cnp; 451 cnp = ap->a_cnp;
456 dvp = ap->a_dvp; 452 dvp = ap->a_dvp;
457 cvp = NULL; 453 cvp = NULL;
458 cpn = NULL; 454 cpn = NULL;
459 *ap->a_vpp = NULL; 455 *ap->a_vpp = NULL;
460 456
461 /* r/o fs? we check create later to handle EEXIST */ 457 /* r/o fs? we check create later to handle EEXIST */
462 if ((cnp->cn_flags & ISLASTCN) 458 if ((cnp->cn_flags & ISLASTCN)
463 && (dvp->v_mount->mnt_flag & MNT_RDONLY) 459 && (dvp->v_mount->mnt_flag & MNT_RDONLY)
464 && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) 460 && (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
465 return EROFS; 461 return EROFS;
466 462
467 isdot = cnp->cn_namelen == 1 && *cnp->cn_nameptr == '.'; 463 isdot = cnp->cn_namelen == 1 && *cnp->cn_nameptr == '.';
468 464
469 DPRINTF(("puffs_lookup: \"%s\", parent vnode %p, op: %x\n", 465 DPRINTF(("puffs_lookup: \"%s\", parent vnode %p, op: %x\n",
470 cnp->cn_nameptr, dvp, cnp->cn_nameiop)); 466 cnp->cn_nameptr, dvp, cnp->cn_nameiop));
471 467
472 /* 468 /*
473 * If dotdot cache is enabled, add reference to .. and return. 469 * If dotdot cache is enabled, add reference to .. and return.
474 */ 470 */
475 if (PUFFS_USE_DOTDOTCACHE(pmp) && (cnp->cn_flags & ISDOTDOT)) { 471 if (PUFFS_USE_DOTDOTCACHE(pmp) && (cnp->cn_flags & ISDOTDOT)) {
476 vp = VPTOPP(ap->a_dvp)->pn_parent; 472 vp = VPTOPP(ap->a_dvp)->pn_parent;
477 vref(vp); 473 vref(vp);
478 474
479 *ap->a_vpp = vp; 475 *ap->a_vpp = vp;
480 return 0; 476 return 0;
481 } 477 }
482 478
483 /* 479 /*
484 * Check if someone fed it into the cache 480 * Check if someone fed it into the cache
485 */ 481 */
486 if (!isdot && PUFFS_USE_NAMECACHE(pmp)) { 482 if (!isdot && PUFFS_USE_NAMECACHE(pmp)) {
487 int found, iswhiteout; 483 int found, iswhiteout;
488 484
489 found = cache_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen, 485 found = cache_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
490 cnp->cn_nameiop, cnp->cn_flags, 486 cnp->cn_nameiop, cnp->cn_flags,
491 &iswhiteout, ap->a_vpp); 487 &iswhiteout, ap->a_vpp);
492 if (iswhiteout) { 488 if (iswhiteout) {
493 cnp->cn_flags |= ISWHITEOUT; 489 cnp->cn_flags |= ISWHITEOUT;
494 } 490 }
495 491
496 if (found && *ap->a_vpp != NULLVP && PUFFS_USE_FS_TTL(pmp)) { 492 if (found && *ap->a_vpp != NULLVP && PUFFS_USE_FS_TTL(pmp)) {
497 cvp = *ap->a_vpp; 493 cvp = *ap->a_vpp;
498 cpn = VPTOPP(cvp); 494 cpn = VPTOPP(cvp);
499 495
500 if (TIMED_OUT(cpn->pn_cn_timeout)) { 496 if (TIMED_OUT(cpn->pn_cn_timeout)) {
501 cache_purge(cvp); 497 cache_purge(cvp);
502 /* 498 /*
503 * cached vnode (cvp) is still referenced 499 * cached vnode (cvp) is still referenced
504 * so that we can reuse it upon a new 500 * so that we can reuse it upon a new
505 * successful lookup.  501 * successful lookup.
506 */ 502 */
507 *ap->a_vpp = NULL; 503 *ap->a_vpp = NULL;
508 found = 0; 504 found = 0;
509 } 505 }
510 } 506 }
511 507
512 /* 508 /*
513 * Do not use negative caching, since the filesystem 509 * Do not use negative caching, since the filesystem
514 * provides no TTL for it. 510 * provides no TTL for it.
515 */ 511 */
516 if (found && *ap->a_vpp == NULLVP && PUFFS_USE_FS_TTL(pmp)) 512 if (found && *ap->a_vpp == NULLVP && PUFFS_USE_FS_TTL(pmp))
517 found = 0; 513 found = 0;
518 514
519 if (found) { 515 if (found) {
520 return *ap->a_vpp == NULLVP ? ENOENT : 0; 516 return *ap->a_vpp == NULLVP ? ENOENT : 0;
521 } 517 }
522 518
523 /* 519 /*
524 * This is what would have been left in ERROR before 520 * This is what would have been left in ERROR before
525 * the rearrangement of cache_lookup(). What with all 521 * the rearrangement of cache_lookup(). What with all
526 * the macros, I am not sure if this is a dead value 522 * the macros, I am not sure if this is a dead value
527 * below or not. 523 * below or not.
528 */ 524 */
529 error = -1; 525 error = -1;
530 } 526 }
531 527
532 if (isdot) { 528 if (isdot) {
533 /* deal with rename lookup semantics */ 529 /* deal with rename lookup semantics */
534 if (cnp->cn_nameiop == RENAME && (cnp->cn_flags & ISLASTCN)) 530 if (cnp->cn_nameiop == RENAME && (cnp->cn_flags & ISLASTCN))
535 return EISDIR; 531 return EISDIR;
536 532
537 vp = ap->a_dvp; 533 vp = ap->a_dvp;
538 vref(vp); 534 vref(vp);
539 *ap->a_vpp = vp; 535 *ap->a_vpp = vp;
540 return 0; 536 return 0;
541 } 537 }
542 538
543 if (cvp != NULL) { 539 if (cvp != NULL) {
544 if (vn_lock(cvp, LK_EXCLUSIVE) != 0) { 540 if (vn_lock(cvp, LK_EXCLUSIVE) != 0) {
545 vrele(cvp); 541 vrele(cvp);
546 cvp = NULL; 542 cvp = NULL;
547 } else 543 } else
548 mutex_enter(&cpn->pn_sizemtx); 544 mutex_enter(&cpn->pn_sizemtx);
549 } 545 }
550 546
551 PUFFS_MSG_ALLOC(vn, lookup); 547 PUFFS_MSG_ALLOC(vn, lookup);
552 puffs_makecn(&lookup_msg->pvnr_cn, &lookup_msg->pvnr_cn_cred, 548 puffs_makecn(&lookup_msg->pvnr_cn, &lookup_msg->pvnr_cn_cred,
553 cnp, PUFFS_USE_FULLPNBUF(pmp)); 549 cnp, PUFFS_USE_FULLPNBUF(pmp));
554 550
555 if (cnp->cn_flags & ISDOTDOT) 551 if (cnp->cn_flags & ISDOTDOT)
556 VOP_UNLOCK(dvp); 552 VOP_UNLOCK(dvp);
557 553
558 puffs_msg_setinfo(park_lookup, PUFFSOP_VN, 554 puffs_msg_setinfo(park_lookup, PUFFSOP_VN,
559 PUFFS_VN_LOOKUP, VPTOPNC(dvp)); 555 PUFFS_VN_LOOKUP, VPTOPNC(dvp));
560 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_lookup, dvp->v_data, NULL, error); 556 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_lookup, dvp->v_data, NULL, error);
561 DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error)); 557 DPRINTF(("puffs_lookup: return of the userspace, part %d\n", error));
562 558
563 /* 559 /*
564 * In case of error, there is no new vnode to play with, so be 560 * In case of error, there is no new vnode to play with, so be
565 * happy with the NULL value given to vpp in the beginning. 561 * happy with the NULL value given to vpp in the beginning.
566 * Also, check if this really was an error or the target was not 562 * Also, check if this really was an error or the target was not
567 * present. Either treat it as a non-error for CREATE/RENAME or 563 * present. Either treat it as a non-error for CREATE/RENAME or
568 * enter the component into the negative name cache (if desired). 564 * enter the component into the negative name cache (if desired).
569 */ 565 */
570 if (error) { 566 if (error) {
571 error = checkerr(pmp, error, __func__); 567 error = checkerr(pmp, error, __func__);
572 if (error == ENOENT) { 568 if (error == ENOENT) {
573 /* don't allow to create files on r/o fs */ 569 /* don't allow to create files on r/o fs */
574 if ((dvp->v_mount->mnt_flag & MNT_RDONLY) 570 if ((dvp->v_mount->mnt_flag & MNT_RDONLY)
575 && cnp->cn_nameiop == CREATE) { 571 && cnp->cn_nameiop == CREATE) {
576 error = EROFS; 572 error = EROFS;
577 573
578 /* adjust values if we are creating */ 574 /* adjust values if we are creating */
579 } else if ((cnp->cn_flags & ISLASTCN) 575 } else if ((cnp->cn_flags & ISLASTCN)
580 && (cnp->cn_nameiop == CREATE 576 && (cnp->cn_nameiop == CREATE
581 || cnp->cn_nameiop == RENAME)) { 577 || cnp->cn_nameiop == RENAME)) {
582 error = EJUSTRETURN; 578 error = EJUSTRETURN;
583 579
584 /* save negative cache entry */ 580 /* save negative cache entry */
585 } else { 581 } else {
586 if (PUFFS_USE_NAMECACHE(pmp) && 582 if (PUFFS_USE_NAMECACHE(pmp) &&
587 !PUFFS_USE_FS_TTL(pmp)) 583 !PUFFS_USE_FS_TTL(pmp))
588 cache_enter(dvp, NULL, cnp->cn_nameptr, 584 cache_enter(dvp, NULL, cnp->cn_nameptr,
589 cnp->cn_namelen, cnp->cn_flags); 585 cnp->cn_namelen, cnp->cn_flags);
590 } 586 }
591 } 587 }
592 goto out; 588 goto out;
593 } 589 }
594 590
595 /* 591 /*
596 * Check that we don't get our parent node back, that would cause 592 * Check that we don't get our parent node back, that would cause
597 * a pretty obvious deadlock. 593 * a pretty obvious deadlock.
598 */ 594 */
599 dpn = dvp->v_data; 595 dpn = dvp->v_data;
600 if (lookup_msg->pvnr_newnode == dpn->pn_cookie) { 596 if (lookup_msg->pvnr_newnode == dpn->pn_cookie) {
601 puffs_senderr(pmp, PUFFS_ERR_LOOKUP, EINVAL, 597 puffs_senderr(pmp, PUFFS_ERR_LOOKUP, EINVAL,
602 "lookup produced parent cookie", lookup_msg->pvnr_newnode); 598 "lookup produced parent cookie", lookup_msg->pvnr_newnode);
603 error = EPROTO; 599 error = EPROTO;
604 goto out; 600 goto out;
605 } 601 }
606 602
607 /* 603 /*
608 * Check if we looked up the cached vnode 604 * Check if we looked up the cached vnode
609 */ 605 */
610 vp = NULL; 606 vp = NULL;
611 if (cvp && (VPTOPP(cvp)->pn_cookie == lookup_msg->pvnr_newnode)) { 607 if (cvp && (VPTOPP(cvp)->pn_cookie == lookup_msg->pvnr_newnode)) {
612 int grace; 608 int grace;
613 609
614 /* 610 /*
615 * Bump grace time of this node so that it does not get  611 * Bump grace time of this node so that it does not get
616 * reclaimed too fast. We try to increase a bit more the 612 * reclaimed too fast. We try to increase a bit more the
617 * lifetime of busiest * nodes - with some limits. 613 * lifetime of busiest * nodes - with some limits.
618 */ 614 */
619 grace = 10 * puffs_sopreq_expire_timeout; 615 grace = 10 * puffs_sopreq_expire_timeout;
620 cpn->pn_cn_grace = getticks() + grace; 616 cpn->pn_cn_grace = getticks() + grace;
621 vp = cvp; 617 vp = cvp;
622 } 618 }
623 619
624 /* 620 /*
625 * No cached vnode available, or the cached vnode does not 621 * No cached vnode available, or the cached vnode does not
626 * match the userland cookie anymore: is the node known? 622 * match the userland cookie anymore: is the node known?
627 */ 623 */
628 if (vp == NULL) { 624 if (vp == NULL) {
629 error = puffs_getvnode(dvp->v_mount, 625 error = puffs_getvnode(dvp->v_mount,
630 lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype, 626 lookup_msg->pvnr_newnode, lookup_msg->pvnr_vtype,
631 lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp); 627 lookup_msg->pvnr_size, lookup_msg->pvnr_rdev, &vp);
632 if (error) { 628 if (error) {
633 puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP, 629 puffs_abortbutton(pmp, PUFFS_ABORT_LOOKUP,
634 VPTOPNC(dvp), lookup_msg->pvnr_newnode, 630 VPTOPNC(dvp), lookup_msg->pvnr_newnode,
635 ap->a_cnp); 631 ap->a_cnp);
636 goto out; 632 goto out;
637 } 633 }
638 634
639 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); 635 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
640 } 636 }
641 637
642 /* 638 /*
643 * Update cache and TTL 639 * Update cache and TTL
644 */ 640 */
645 if (PUFFS_USE_FS_TTL(pmp)) { 641 if (PUFFS_USE_FS_TTL(pmp)) {
646 struct timespec *va_ttl = &lookup_msg->pvnr_va_ttl; 642 struct timespec *va_ttl = &lookup_msg->pvnr_va_ttl;
647 struct timespec *cn_ttl = &lookup_msg->pvnr_cn_ttl; 643 struct timespec *cn_ttl = &lookup_msg->pvnr_cn_ttl;
648 update_va(vp, NULL, &lookup_msg->pvnr_va,  644 update_va(vp, NULL, &lookup_msg->pvnr_va,
649 va_ttl, cn_ttl, SETATTR_CHSIZE); 645 va_ttl, cn_ttl, SETATTR_CHSIZE);
650 } 646 }
651 647
652 KASSERT(lookup_msg->pvnr_newnode == VPTOPP(vp)->pn_cookie); 648 KASSERT(lookup_msg->pvnr_newnode == VPTOPP(vp)->pn_cookie);
653 *ap->a_vpp = vp; 649 *ap->a_vpp = vp;
654 650
655 if (PUFFS_USE_NAMECACHE(pmp)) 651 if (PUFFS_USE_NAMECACHE(pmp))
656 cache_enter(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen, 652 cache_enter(dvp, vp, cnp->cn_nameptr, cnp->cn_namelen,
657 cnp->cn_flags); 653 cnp->cn_flags);
658 654
659 /* XXX */ 655 /* XXX */
660 if ((lookup_msg->pvnr_cn.pkcn_flags & REQUIREDIR) == 0) 656 if ((lookup_msg->pvnr_cn.pkcn_flags & REQUIREDIR) == 0)
661 cnp->cn_flags &= ~REQUIREDIR; 657 cnp->cn_flags &= ~REQUIREDIR;
662 if (lookup_msg->pvnr_cn.pkcn_consume) { 658 if (lookup_msg->pvnr_cn.pkcn_consume) {
663 printf("puffs: warning: ignoring cn_consume of %zu chars\n", 659 printf("puffs: warning: ignoring cn_consume of %zu chars\n",
664 lookup_msg->pvnr_cn.pkcn_consume); 660 lookup_msg->pvnr_cn.pkcn_consume);
665 } 661 }
666 662
667 VPTOPP(vp)->pn_nlookup++; 663 VPTOPP(vp)->pn_nlookup++;
668 664
669 if (PUFFS_USE_DOTDOTCACHE(pmp) && 665 if (PUFFS_USE_DOTDOTCACHE(pmp) &&
670 (VPTOPP(vp)->pn_parent != dvp)) 666 (VPTOPP(vp)->pn_parent != dvp))
671 update_parent(vp, dvp); 667 update_parent(vp, dvp);
672 668
673 out: 669 out:
674 if (cvp != NULL) { 670 if (cvp != NULL) {
675 mutex_exit(&cpn->pn_sizemtx); 671 mutex_exit(&cpn->pn_sizemtx);
676 672
677 if (error || (cvp != vp)) 673 if (error || (cvp != vp))
678 vput(cvp); 674 vput(cvp);
679 } 675 }
680 if (error == 0) 676 if (error == 0)
681 VOP_UNLOCK(*ap->a_vpp); 677 VOP_UNLOCK(*ap->a_vpp);
682 678
683 if (cnp->cn_flags & ISDOTDOT) 679 if (cnp->cn_flags & ISDOTDOT)
684 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); 680 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
685 681
686 DPRINTF(("puffs_lookup: returning %d %p\n", error, *ap->a_vpp)); 682 DPRINTF(("puffs_lookup: returning %d %p\n", error, *ap->a_vpp));
687 PUFFS_MSG_RELEASE(lookup); 683 PUFFS_MSG_RELEASE(lookup);
688 return error; 684 return error;
689} 685}
690 686
691#define REFPN_AND_UNLOCKVP(a, b) \ 687#define REFPN_AND_UNLOCKVP(a, b) \
692do { \ 688do { \
693 mutex_enter(&b->pn_mtx); \ 689 mutex_enter(&b->pn_mtx); \
694 puffs_referencenode(b); \ 690 puffs_referencenode(b); \
695 mutex_exit(&b->pn_mtx); \ 691 mutex_exit(&b->pn_mtx); \
696 VOP_UNLOCK(a); \ 692 VOP_UNLOCK(a); \
697} while (/*CONSTCOND*/0) 693} while (/*CONSTCOND*/0)
698 694
699#define REFPN(b) \ 695#define REFPN(b) \
700do { \ 696do { \
701 mutex_enter(&b->pn_mtx); \ 697 mutex_enter(&b->pn_mtx); \
702 puffs_referencenode(b); \ 698 puffs_referencenode(b); \
703 mutex_exit(&b->pn_mtx); \ 699 mutex_exit(&b->pn_mtx); \
704} while (/*CONSTCOND*/0) 700} while (/*CONSTCOND*/0)
705 701
706#define RELEPN_AND_VP(a, b) \ 702#define RELEPN_AND_VP(a, b) \
707do { \ 703do { \
708 puffs_releasenode(b); \ 704 puffs_releasenode(b); \
709 vrele(a); \ 705 vrele(a); \
710} while (/*CONSTCOND*/0) 706} while (/*CONSTCOND*/0)
711 707
712int 708int
713puffs_vnop_create(void *v) 709puffs_vnop_create(void *v)
714{ 710{
715 struct vop_create_v3_args /* { 711 struct vop_create_v3_args /* {
716 const struct vnodeop_desc *a_desc; 712 const struct vnodeop_desc *a_desc;
717 struct vnode *a_dvp; 713 struct vnode *a_dvp;
718 struct vnode **a_vpp; 714 struct vnode **a_vpp;
719 struct componentname *a_cnp; 715 struct componentname *a_cnp;
720 struct vattr *a_vap; 716 struct vattr *a_vap;
721 } */ *ap = v; 717 } */ *ap = v;
722 PUFFS_MSG_VARS(vn, create); 718 PUFFS_MSG_VARS(vn, create);
723 struct vnode *dvp = ap->a_dvp; 719 struct vnode *dvp = ap->a_dvp;
724 struct puffs_node *dpn = VPTOPP(dvp); 720 struct puffs_node *dpn = VPTOPP(dvp);
725 struct componentname *cnp = ap->a_cnp; 721 struct componentname *cnp = ap->a_cnp;
726 struct mount *mp = dvp->v_mount; 722 struct mount *mp = dvp->v_mount;
727 struct puffs_mount *pmp = MPTOPUFFSMP(mp); 723 struct puffs_mount *pmp = MPTOPUFFSMP(mp);
728 int error; 724 int error;
729 725
730 DPRINTF(("puffs_create: dvp %p, cnp: %s\n", 726 DPRINTF(("puffs_create: dvp %p, cnp: %s\n",
731 dvp, ap->a_cnp->cn_nameptr)); 727 dvp, ap->a_cnp->cn_nameptr));
732 728
733 PUFFS_MSG_ALLOC(vn, create); 729 PUFFS_MSG_ALLOC(vn, create);
734 puffs_makecn(&create_msg->pvnr_cn, &create_msg->pvnr_cn_cred, 730 puffs_makecn(&create_msg->pvnr_cn, &create_msg->pvnr_cn_cred,
735 cnp, PUFFS_USE_FULLPNBUF(pmp)); 731 cnp, PUFFS_USE_FULLPNBUF(pmp));
736 create_msg->pvnr_va = *ap->a_vap; 732 create_msg->pvnr_va = *ap->a_vap;
737 puffs_msg_setinfo(park_create, PUFFSOP_VN, 733 puffs_msg_setinfo(park_create, PUFFSOP_VN,
738 PUFFS_VN_CREATE, VPTOPNC(dvp)); 734 PUFFS_VN_CREATE, VPTOPNC(dvp));
739 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_create, dvp->v_data, NULL, error); 735 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_create, dvp->v_data, NULL, error);
740 736
741 error = checkerr(pmp, error, __func__); 737 error = checkerr(pmp, error, __func__);
742 if (error) 738 if (error)
743 goto out; 739 goto out;
744 740
745 error = puffs_newnode(mp, dvp, ap->a_vpp, 741 error = puffs_newnode(mp, dvp, ap->a_vpp,
746 create_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 0); 742 create_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 0);
747 if (error) { 743 if (error) {
748 puffs_abortbutton(pmp, PUFFS_ABORT_CREATE, dpn->pn_cookie, 744 puffs_abortbutton(pmp, PUFFS_ABORT_CREATE, dpn->pn_cookie,
749 create_msg->pvnr_newnode, cnp); 745 create_msg->pvnr_newnode, cnp);
750 goto out; 746 goto out;
751 } 747 }
752 748
753 if (PUFFS_USE_FS_TTL(pmp)) { 749 if (PUFFS_USE_FS_TTL(pmp)) {
754 struct timespec *va_ttl = &create_msg->pvnr_va_ttl; 750 struct timespec *va_ttl = &create_msg->pvnr_va_ttl;
755 struct timespec *cn_ttl = &create_msg->pvnr_cn_ttl; 751 struct timespec *cn_ttl = &create_msg->pvnr_cn_ttl;
756 struct vattr *rvap = &create_msg->pvnr_va; 752 struct vattr *rvap = &create_msg->pvnr_va;
757 753
758 update_va(*ap->a_vpp, NULL, rvap,  754 update_va(*ap->a_vpp, NULL, rvap,
759 va_ttl, cn_ttl, SETATTR_CHSIZE); 755 va_ttl, cn_ttl, SETATTR_CHSIZE);
760 } 756 }
761 757
762 VPTOPP(*ap->a_vpp)->pn_nlookup++; 758 VPTOPP(*ap->a_vpp)->pn_nlookup++;
763 759
764 if (PUFFS_USE_DOTDOTCACHE(pmp) && 760 if (PUFFS_USE_DOTDOTCACHE(pmp) &&
765 (VPTOPP(*ap->a_vpp)->pn_parent != dvp)) 761 (VPTOPP(*ap->a_vpp)->pn_parent != dvp))
766 update_parent(*ap->a_vpp, dvp); 762 update_parent(*ap->a_vpp, dvp);
767 763
768 out: 764 out:
769 DPRINTF(("puffs_create: return %d\n", error)); 765 DPRINTF(("puffs_create: return %d\n", error));
770 PUFFS_MSG_RELEASE(create); 766 PUFFS_MSG_RELEASE(create);
771 return error; 767 return error;
772} 768}
773 769
774int 770int
775puffs_vnop_mknod(void *v) 771puffs_vnop_mknod(void *v)
776{ 772{
777 struct vop_mknod_v3_args /* { 773 struct vop_mknod_v3_args /* {
778 const struct vnodeop_desc *a_desc; 774 const struct vnodeop_desc *a_desc;
779 struct vnode *a_dvp; 775 struct vnode *a_dvp;
780 struct vnode **a_vpp; 776 struct vnode **a_vpp;
781 struct componentname *a_cnp; 777 struct componentname *a_cnp;
782 struct vattr *a_vap; 778 struct vattr *a_vap;
783 } */ *ap = v; 779 } */ *ap = v;
784 PUFFS_MSG_VARS(vn, mknod); 780 PUFFS_MSG_VARS(vn, mknod);
785 struct vnode *dvp = ap->a_dvp; 781 struct vnode *dvp = ap->a_dvp;
786 struct puffs_node *dpn = VPTOPP(dvp); 782 struct puffs_node *dpn = VPTOPP(dvp);
787 struct componentname *cnp = ap->a_cnp; 783 struct componentname *cnp = ap->a_cnp;
788 struct mount *mp = dvp->v_mount; 784 struct mount *mp = dvp->v_mount;
789 struct puffs_mount *pmp = MPTOPUFFSMP(mp); 785 struct puffs_mount *pmp = MPTOPUFFSMP(mp);
790 int error; 786 int error;
791 787
792 PUFFS_MSG_ALLOC(vn, mknod); 788 PUFFS_MSG_ALLOC(vn, mknod);
793 puffs_makecn(&mknod_msg->pvnr_cn, &mknod_msg->pvnr_cn_cred, 789 puffs_makecn(&mknod_msg->pvnr_cn, &mknod_msg->pvnr_cn_cred,
794 cnp, PUFFS_USE_FULLPNBUF(pmp)); 790 cnp, PUFFS_USE_FULLPNBUF(pmp));
795 mknod_msg->pvnr_va = *ap->a_vap; 791 mknod_msg->pvnr_va = *ap->a_vap;
796 puffs_msg_setinfo(park_mknod, PUFFSOP_VN, 792 puffs_msg_setinfo(park_mknod, PUFFSOP_VN,
797 PUFFS_VN_MKNOD, VPTOPNC(dvp)); 793 PUFFS_VN_MKNOD, VPTOPNC(dvp));
798 794
799 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_mknod, dvp->v_data, NULL, error); 795 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_mknod, dvp->v_data, NULL, error);
800 796
801 error = checkerr(pmp, error, __func__); 797 error = checkerr(pmp, error, __func__);
802 if (error) 798 if (error)
803 goto out; 799 goto out;
804 800
805 error = puffs_newnode(mp, dvp, ap->a_vpp, 801 error = puffs_newnode(mp, dvp, ap->a_vpp,
806 mknod_msg->pvnr_newnode, cnp, ap->a_vap->va_type, 802 mknod_msg->pvnr_newnode, cnp, ap->a_vap->va_type,
807 ap->a_vap->va_rdev); 803 ap->a_vap->va_rdev);
808 if (error) { 804 if (error) {
809 puffs_abortbutton(pmp, PUFFS_ABORT_MKNOD, dpn->pn_cookie, 805 puffs_abortbutton(pmp, PUFFS_ABORT_MKNOD, dpn->pn_cookie,
810 mknod_msg->pvnr_newnode, cnp); 806 mknod_msg->pvnr_newnode, cnp);
811 goto out; 807 goto out;
812 } 808 }
813 809
814 if (PUFFS_USE_FS_TTL(pmp)) { 810 if (PUFFS_USE_FS_TTL(pmp)) {
815 struct timespec *va_ttl = &mknod_msg->pvnr_va_ttl; 811 struct timespec *va_ttl = &mknod_msg->pvnr_va_ttl;
816 struct timespec *cn_ttl = &mknod_msg->pvnr_cn_ttl; 812 struct timespec *cn_ttl = &mknod_msg->pvnr_cn_ttl;
817 struct vattr *rvap = &mknod_msg->pvnr_va; 813 struct vattr *rvap = &mknod_msg->pvnr_va;
818 814
819 update_va(*ap->a_vpp, NULL, rvap,  815 update_va(*ap->a_vpp, NULL, rvap,
820 va_ttl, cn_ttl, SETATTR_CHSIZE); 816 va_ttl, cn_ttl, SETATTR_CHSIZE);
821 } 817 }
822 818
823 VPTOPP(*ap->a_vpp)->pn_nlookup++; 819 VPTOPP(*ap->a_vpp)->pn_nlookup++;
824 820
825 if (PUFFS_USE_DOTDOTCACHE(pmp) && 821 if (PUFFS_USE_DOTDOTCACHE(pmp) &&
826 (VPTOPP(*ap->a_vpp)->pn_parent != dvp)) 822 (VPTOPP(*ap->a_vpp)->pn_parent != dvp))
827 update_parent(*ap->a_vpp, dvp); 823 update_parent(*ap->a_vpp, dvp);
828 824
829 out: 825 out:
830 PUFFS_MSG_RELEASE(mknod); 826 PUFFS_MSG_RELEASE(mknod);
831 return error; 827 return error;
832} 828}
833 829
834int 830int
835puffs_vnop_open(void *v) 831puffs_vnop_open(void *v)
836{ 832{
837 struct vop_open_args /* { 833 struct vop_open_args /* {
838 const struct vnodeop_desc *a_desc; 834 const struct vnodeop_desc *a_desc;
839 struct vnode *a_vp; 835 struct vnode *a_vp;
840 int a_mode; 836 int a_mode;
841 kauth_cred_t a_cred; 837 kauth_cred_t a_cred;
842 } */ *ap = v; 838 } */ *ap = v;
843 PUFFS_MSG_VARS(vn, open); 839 PUFFS_MSG_VARS(vn, open);
844 struct vnode *vp = ap->a_vp; 840 struct vnode *vp = ap->a_vp;
845 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); 841 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
846 struct puffs_node *pn = VPTOPP(vp); 842 struct puffs_node *pn = VPTOPP(vp);
847 int mode = ap->a_mode; 843 int mode = ap->a_mode;
848 int error; 844 int error;
849 845
850 DPRINTF(("puffs_open: vp %p, mode 0x%x\n", vp, mode)); 846 DPRINTF(("puffs_open: vp %p, mode 0x%x\n", vp, mode));
851 847
852 if (vp->v_type == VREG && mode & FWRITE && !EXISTSOP(pmp, WRITE)) 848 if (vp->v_type == VREG && mode & FWRITE && !EXISTSOP(pmp, WRITE))
853 ERROUT(EROFS); 849 ERROUT(EROFS);
854 850
855 if (!EXISTSOP(pmp, OPEN)) 851 if (!EXISTSOP(pmp, OPEN))
856 ERROUT(0); 852 ERROUT(0);
857 853
858 PUFFS_MSG_ALLOC(vn, open); 854 PUFFS_MSG_ALLOC(vn, open);
859 open_msg->pvnr_mode = mode; 855 open_msg->pvnr_mode = mode;
860 puffs_credcvt(&open_msg->pvnr_cred, ap->a_cred); 856 puffs_credcvt(&open_msg->pvnr_cred, ap->a_cred);
861 puffs_msg_setinfo(park_open, PUFFSOP_VN, 857 puffs_msg_setinfo(park_open, PUFFSOP_VN,
862 PUFFS_VN_OPEN, VPTOPNC(vp)); 858 PUFFS_VN_OPEN, VPTOPNC(vp));
863 859
864 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error); 860 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_open, vp->v_data, NULL, error);
865 error = checkerr(pmp, error, __func__); 861 error = checkerr(pmp, error, __func__);
866 862
867 if (open_msg->pvnr_oflags & PUFFS_OPEN_IO_DIRECT) { 863 if (open_msg->pvnr_oflags & PUFFS_OPEN_IO_DIRECT) {
868 /* 864 /*
869 * Flush cache: 865 * Flush cache:
870 * - we do not want to discard cached write by direct write 866 * - we do not want to discard cached write by direct write
871 * - read cache is now useless and should be freed 867 * - read cache is now useless and should be freed
872 */ 868 */
873 mutex_enter(&pn->pn_sizemtx); 869 mutex_enter(&pn->pn_sizemtx);
874 flushvncache(vp, 0, 0, true); 870 flushvncache(vp, 0, 0, true);
875 mutex_exit(&pn->pn_sizemtx); 871 mutex_exit(&pn->pn_sizemtx);
876 872
877 if (mode & FREAD) 873 if (mode & FREAD)
878 pn->pn_stat |= PNODE_RDIRECT; 874 pn->pn_stat |= PNODE_RDIRECT;
879 if (mode & FWRITE) 875 if (mode & FWRITE)
880 pn->pn_stat |= PNODE_WDIRECT; 876 pn->pn_stat |= PNODE_WDIRECT;
881 } 877 }
882 out: 878 out:
883 DPRINTF(("puffs_open: returning %d\n", error)); 879 DPRINTF(("puffs_open: returning %d\n", error));
884 PUFFS_MSG_RELEASE(open); 880 PUFFS_MSG_RELEASE(open);
885 return error; 881 return error;
886} 882}
887 883
888int 884int
889puffs_vnop_close(void *v) 885puffs_vnop_close(void *v)
890{ 886{
891 struct vop_close_args /* { 887 struct vop_close_args /* {
892 const struct vnodeop_desc *a_desc; 888 const struct vnodeop_desc *a_desc;
893 struct vnode *a_vp; 889 struct vnode *a_vp;
894 int a_fflag; 890 int a_fflag;
895 kauth_cred_t a_cred; 891 kauth_cred_t a_cred;
896 } */ *ap = v; 892 } */ *ap = v;
897 PUFFS_MSG_VARS(vn, close); 893 PUFFS_MSG_VARS(vn, close);
898 struct vnode *vp = ap->a_vp; 894 struct vnode *vp = ap->a_vp;
899 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); 895 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
900 896
901 PUFFS_MSG_ALLOC(vn, close); 897 PUFFS_MSG_ALLOC(vn, close);
902 puffs_msg_setfaf(park_close); 898 puffs_msg_setfaf(park_close);
903 close_msg->pvnr_fflag = ap->a_fflag; 899 close_msg->pvnr_fflag = ap->a_fflag;
904 puffs_credcvt(&close_msg->pvnr_cred, ap->a_cred); 900 puffs_credcvt(&close_msg->pvnr_cred, ap->a_cred);
905 puffs_msg_setinfo(park_close, PUFFSOP_VN, 901 puffs_msg_setinfo(park_close, PUFFSOP_VN,
906 PUFFS_VN_CLOSE, VPTOPNC(vp)); 902 PUFFS_VN_CLOSE, VPTOPNC(vp));
907 903
908 puffs_msg_enqueue(pmp, park_close); 904 puffs_msg_enqueue(pmp, park_close);
909 PUFFS_MSG_RELEASE(close); 905 PUFFS_MSG_RELEASE(close);
910 return 0; 906 return 0;
911} 907}
912 908
913int 909int
914puffs_vnop_access(void *v) 910puffs_vnop_access(void *v)
915{ 911{
916 struct vop_access_args /* { 912 struct vop_access_args /* {
917 const struct vnodeop_desc *a_desc; 913 const struct vnodeop_desc *a_desc;
918 struct vnode *a_vp; 914 struct vnode *a_vp;
919 accmode_t a_accmode; 915 accmode_t a_accmode;
920 kauth_cred_t a_cred; 916 kauth_cred_t a_cred;
921 } */ *ap = v; 917 } */ *ap = v;
922 PUFFS_MSG_VARS(vn, access); 918 PUFFS_MSG_VARS(vn, access);
923 struct vnode *vp = ap->a_vp; 919 struct vnode *vp = ap->a_vp;
924 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); 920 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
925 accmode_t accmode = ap->a_accmode; 921 accmode_t accmode = ap->a_accmode;
926 int error; 922 int error;
927 923
928 if (accmode & VWRITE) { 924 if (accmode & VWRITE) {
929 switch (vp->v_type) { 925 switch (vp->v_type) {
930 case VDIR: 926 case VDIR:
931 case VLNK: 927 case VLNK:
932 case VREG: 928 case VREG:
933 if ((vp->v_mount->mnt_flag & MNT_RDONLY) 929 if ((vp->v_mount->mnt_flag & MNT_RDONLY)
934 || !EXISTSOP(pmp, WRITE)) 930 || !EXISTSOP(pmp, WRITE))
935 return EROFS; 931 return EROFS;
936 break; 932 break;
937 default: 933 default:
938 break; 934 break;
939 } 935 }
940 } 936 }
941 937
942 if (!EXISTSOP(pmp, ACCESS)) 938 if (!EXISTSOP(pmp, ACCESS))
943 return 0; 939 return 0;
944 940
945 PUFFS_MSG_ALLOC(vn, access); 941 PUFFS_MSG_ALLOC(vn, access);
946 access_msg->pvnr_mode = ap->a_accmode; 942 access_msg->pvnr_mode = ap->a_accmode;
947 puffs_credcvt(&access_msg->pvnr_cred, ap->a_cred); 943 puffs_credcvt(&access_msg->pvnr_cred, ap->a_cred);
948 puffs_msg_setinfo(park_access, PUFFSOP_VN, 944 puffs_msg_setinfo(park_access, PUFFSOP_VN,
949 PUFFS_VN_ACCESS, VPTOPNC(vp)); 945 PUFFS_VN_ACCESS, VPTOPNC(vp));
950 946
951 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_access, vp->v_data, NULL, error); 947 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_access, vp->v_data, NULL, error);
952 error = checkerr(pmp, error, __func__); 948 error = checkerr(pmp, error, __func__);
953 PUFFS_MSG_RELEASE(access); 949 PUFFS_MSG_RELEASE(access);
954 950
955 return error; 951 return error;
956} 952}
957 953
958static void 954static void
959update_va(struct vnode *vp, struct vattr *vap, struct vattr *rvap, 955update_va(struct vnode *vp, struct vattr *vap, struct vattr *rvap,
960 struct timespec *va_ttl, struct timespec *cn_ttl, int flags) 956 struct timespec *va_ttl, struct timespec *cn_ttl, int flags)
961{ 957{
962 struct puffs_node *pn = VPTOPP(vp); 958 struct puffs_node *pn = VPTOPP(vp);
963 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); 959 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
964 int use_metacache; 960 int use_metacache;
965 961
966 if (TTL_VALID(cn_ttl)) { 962 if (TTL_VALID(cn_ttl)) {
967 pn->pn_cn_timeout = TTL_TO_TIMEOUT(cn_ttl); 963 pn->pn_cn_timeout = TTL_TO_TIMEOUT(cn_ttl);
968 pn->pn_cn_grace = MAX(pn->pn_cn_timeout, pn->pn_cn_grace); 964 pn->pn_cn_grace = MAX(pn->pn_cn_timeout, pn->pn_cn_grace);
969 } 965 }
970 966
971 /* 967 /*
972 * Don't listen to the file server regarding special device 968 * Don't listen to the file server regarding special device
973 * size info, the file server doesn't know anything about them. 969 * size info, the file server doesn't know anything about them.
974 */ 970 */
975 if (vp->v_type == VBLK || vp->v_type == VCHR) 971 if (vp->v_type == VBLK || vp->v_type == VCHR)
976 rvap->va_size = vp->v_size; 972 rvap->va_size = vp->v_size;
977 973
978 /* Ditto for blocksize (ufs comment: this doesn't belong here) */ 974 /* Ditto for blocksize (ufs comment: this doesn't belong here) */
979 if (vp->v_type == VBLK) 975 if (vp->v_type == VBLK)
980 rvap->va_blocksize = BLKDEV_IOSIZE; 976 rvap->va_blocksize = BLKDEV_IOSIZE;
981 else if (vp->v_type == VCHR) 977 else if (vp->v_type == VCHR)
982 rvap->va_blocksize = MAXBSIZE; 978 rvap->va_blocksize = MAXBSIZE;
983 979
984 if (vap != NULL) { 980 if (vap != NULL) {
985 (void) memcpy(vap, rvap, sizeof(struct vattr)); 981 (void) memcpy(vap, rvap, sizeof(struct vattr));
986 vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0]; 982 vap->va_fsid = vp->v_mount->mnt_stat.f_fsidx.__fsid_val[0];
987 983
988 if (PUFFS_USE_METAFLUSH(pmp)) { 984 if (PUFFS_USE_METAFLUSH(pmp)) {
989 if (pn->pn_stat & PNODE_METACACHE_ATIME) 985 if (pn->pn_stat & PNODE_METACACHE_ATIME)
990 vap->va_atime = pn->pn_mc_atime; 986 vap->va_atime = pn->pn_mc_atime;
991 if (pn->pn_stat & PNODE_METACACHE_CTIME) 987 if (pn->pn_stat & PNODE_METACACHE_CTIME)
992 vap->va_ctime = pn->pn_mc_ctime; 988 vap->va_ctime = pn->pn_mc_ctime;
993 if (pn->pn_stat & PNODE_METACACHE_MTIME) 989 if (pn->pn_stat & PNODE_METACACHE_MTIME)
994 vap->va_mtime = pn->pn_mc_mtime; 990 vap->va_mtime = pn->pn_mc_mtime;
995 if (pn->pn_stat & PNODE_METACACHE_SIZE) 991 if (pn->pn_stat & PNODE_METACACHE_SIZE)
996 vap->va_size = pn->pn_mc_size; 992 vap->va_size = pn->pn_mc_size;
997 } 993 }
998 } 994 }
999 995
1000 use_metacache = PUFFS_USE_METAFLUSH(pmp) && 996 use_metacache = PUFFS_USE_METAFLUSH(pmp) &&
1001 (pn->pn_stat & PNODE_METACACHE_SIZE); 997 (pn->pn_stat & PNODE_METACACHE_SIZE);
1002 if (!use_metacache && (flags & SETATTR_CHSIZE)) { 998 if (!use_metacache && (flags & SETATTR_CHSIZE)) {
1003 if (rvap->va_size != VNOVAL 999 if (rvap->va_size != VNOVAL
1004 && vp->v_type != VBLK && vp->v_type != VCHR) { 1000 && vp->v_type != VBLK && vp->v_type != VCHR) {
1005 uvm_vnp_setsize(vp, rvap->va_size); 1001 uvm_vnp_setsize(vp, rvap->va_size);
1006 pn->pn_serversize = rvap->va_size; 1002 pn->pn_serversize = rvap->va_size;
1007 } 1003 }
1008 } 1004 }
1009 1005
1010 if ((va_ttl != NULL) && TTL_VALID(va_ttl)) { 1006 if ((va_ttl != NULL) && TTL_VALID(va_ttl)) {
1011 if (pn->pn_va_cache == NULL) 1007 if (pn->pn_va_cache == NULL)
1012 pn->pn_va_cache = pool_get(&puffs_vapool, PR_WAITOK); 1008 pn->pn_va_cache = pool_get(&puffs_vapool, PR_WAITOK);
1013 1009
1014 (void)memcpy(pn->pn_va_cache, rvap, sizeof(*rvap)); 1010 (void)memcpy(pn->pn_va_cache, rvap, sizeof(*rvap));
1015 1011
1016 pn->pn_va_timeout = TTL_TO_TIMEOUT(va_ttl); 1012 pn->pn_va_timeout = TTL_TO_TIMEOUT(va_ttl);
1017 } 1013 }
1018} 1014}
1019 1015
1020static void  1016static void
1021update_parent(struct vnode *vp, struct vnode *dvp) 1017update_parent(struct vnode *vp, struct vnode *dvp)
1022{ 1018{
1023 struct puffs_node *pn = VPTOPP(vp); 1019 struct puffs_node *pn = VPTOPP(vp);
1024 1020
1025 if (pn->pn_parent != NULL) { 1021 if (pn->pn_parent != NULL) {
1026 KASSERT(pn->pn_parent != dvp); 1022 KASSERT(pn->pn_parent != dvp);
1027 vrele(pn->pn_parent); 1023 vrele(pn->pn_parent);
1028 } 1024 }
1029 1025
1030 vref(dvp); 1026 vref(dvp);
1031 pn->pn_parent = dvp; 1027 pn->pn_parent = dvp;
1032} 1028}
1033 1029
1034int 1030int
1035puffs_vnop_getattr(void *v) 1031puffs_vnop_getattr(void *v)
1036{ 1032{
1037 struct vop_getattr_args /* { 1033 struct vop_getattr_args /* {
1038 const struct vnodeop_desc *a_desc; 1034 const struct vnodeop_desc *a_desc;
1039 struct vnode *a_vp; 1035 struct vnode *a_vp;
1040 struct vattr *a_vap; 1036 struct vattr *a_vap;
1041 kauth_cred_t a_cred; 1037 kauth_cred_t a_cred;
1042 } */ *ap = v; 1038 } */ *ap = v;
1043 PUFFS_MSG_VARS(vn, getattr); 1039 PUFFS_MSG_VARS(vn, getattr);
1044 struct vnode *vp = ap->a_vp; 1040 struct vnode *vp = ap->a_vp;
1045 struct mount *mp = vp->v_mount; 1041 struct mount *mp = vp->v_mount;
1046 struct puffs_mount *pmp = MPTOPUFFSMP(mp); 1042 struct puffs_mount *pmp = MPTOPUFFSMP(mp);
1047 struct vattr *vap, *rvap; 1043 struct vattr *vap, *rvap;
1048 struct puffs_node *pn = VPTOPP(vp); 1044 struct puffs_node *pn = VPTOPP(vp);
1049 struct timespec *va_ttl = NULL; 1045 struct timespec *va_ttl = NULL;
1050 int error = 0; 1046 int error = 0;
1051 1047
1052 /* 1048 /*
1053 * A lock is required so that we do not race with  1049 * A lock is required so that we do not race with
1054 * setattr, write and fsync when changing vp->v_size. 1050 * setattr, write and fsync when changing vp->v_size.
1055 * This is critical, since setting a stall smaler value 1051 * This is critical, since setting a stall smaler value
1056 * triggers a file truncate in uvm_vnp_setsize(), which 1052 * triggers a file truncate in uvm_vnp_setsize(), which
1057 * most of the time means data corruption (a chunk of 1053 * most of the time means data corruption (a chunk of
1058 * data is replaced by zeroes). This can be removed if 1054 * data is replaced by zeroes). This can be removed if
1059 * we decide one day that VOP_GETATTR must operate on  1055 * we decide one day that VOP_GETATTR must operate on
1060 * a locked vnode. 1056 * a locked vnode.
1061 * 1057 *
1062 * XXX Should be useless now that VOP_GETATTR has been 1058 * XXX Should be useless now that VOP_GETATTR has been
1063 * fixed to always require a shared lock at least. 1059 * fixed to always require a shared lock at least.
1064 */ 1060 */
1065 mutex_enter(&pn->pn_sizemtx); 1061 mutex_enter(&pn->pn_sizemtx);
1066 1062
1067 REFPN(pn); 1063 REFPN(pn);
1068 vap = ap->a_vap; 1064 vap = ap->a_vap;
1069 1065
1070 if (PUFFS_USE_FS_TTL(pmp)) { 1066 if (PUFFS_USE_FS_TTL(pmp)) {
1071 if (!TIMED_OUT(pn->pn_va_timeout)) { 1067 if (!TIMED_OUT(pn->pn_va_timeout)) {
1072 update_va(vp, vap, pn->pn_va_cache,  1068 update_va(vp, vap, pn->pn_va_cache,
1073 NULL, NULL, SETATTR_CHSIZE); 1069 NULL, NULL, SETATTR_CHSIZE);
1074 goto out2; 1070 goto out2;
1075 } 1071 }
1076 } 1072 }
1077 1073
1078 PUFFS_MSG_ALLOC(vn, getattr); 1074 PUFFS_MSG_ALLOC(vn, getattr);
1079 vattr_null(&getattr_msg->pvnr_va); 1075 vattr_null(&getattr_msg->pvnr_va);
1080 puffs_credcvt(&getattr_msg->pvnr_cred, ap->a_cred); 1076 puffs_credcvt(&getattr_msg->pvnr_cred, ap->a_cred);
1081 puffs_msg_setinfo(park_getattr, PUFFSOP_VN, 1077 puffs_msg_setinfo(park_getattr, PUFFSOP_VN,
1082 PUFFS_VN_GETATTR, VPTOPNC(vp)); 1078 PUFFS_VN_GETATTR, VPTOPNC(vp));
1083 1079
1084 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_getattr, vp->v_data, NULL, error); 1080 PUFFS_MSG_ENQUEUEWAIT2(pmp, park_getattr, vp->v_data, NULL, error);
1085 error = checkerr(pmp, error, __func__); 1081 error = checkerr(pmp, error, __func__);
1086 if (error) 1082 if (error)
1087 goto out; 1083 goto out;
1088 1084
1089 rvap = &getattr_msg->pvnr_va; 1085 rvap = &getattr_msg->pvnr_va;
1090 1086
1091 if (PUFFS_USE_FS_TTL(pmp)) 1087 if (PUFFS_USE_FS_TTL(pmp))
1092 va_ttl = &getattr_msg->pvnr_va_ttl; 1088 va_ttl = &getattr_msg->pvnr_va_ttl;
1093 1089
1094 update_va(vp, vap, rvap, va_ttl, NULL, SETATTR_CHSIZE); 1090 update_va(vp, vap, rvap, va_ttl, NULL, SETATTR_CHSIZE);
1095 1091
1096 out: 1092 out:
1097 PUFFS_MSG_RELEASE(getattr); 1093 PUFFS_MSG_RELEASE(getattr);
1098 1094
1099 out2: 1095 out2:
1100 puffs_releasenode(pn); 1096 puffs_releasenode(pn);
1101  1097
1102 mutex_exit(&pn->pn_sizemtx); 1098 mutex_exit(&pn->pn_sizemtx);
1103 1099
1104 return error; 1100 return error;
1105} 1101}
1106 1102
1107static void 1103static void
1108zerofill_lastpage(struct vnode *vp, voff_t off) 1104zerofill_lastpage(struct vnode *vp, voff_t off)
1109{ 1105{
1110 1106
1111 if (trunc_page(off) == off) 1107 if (trunc_page(off) == off)
1112 return; 1108 return;
1113  1109
1114 if (vp->v_writecount == 0) 1110 if (vp->v_writecount == 0)
1115 return; 1111 return;
1116 1112
1117 vsize_t len = round_page(off) - off; 1113 vsize_t len = round_page(off) - off;
1118 ubc_zerorange(&vp->v_uobj, off, len, UBC_WRITE|UBC_VNODE_FLAGS(vp)); 1114 ubc_zerorange(&vp->v_uobj, off, len, UBC_WRITE|UBC_VNODE_FLAGS(vp));
1119} 1115}
1120 1116
1121static int 1117static int
1122dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags) 1118dosetattr(struct vnode *vp, struct vattr *vap, kauth_cred_t cred, int flags)
1123{ 1119{
1124 PUFFS_MSG_VARS(vn, setattr); 1120 PUFFS_MSG_VARS(vn, setattr);
1125 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount); 1121 struct puffs_mount *pmp = MPTOPUFFSMP(vp->v_mount);
1126 struct puffs_node *pn = vp->v_data; 1122 struct puffs_node *pn = vp->v_data;
1127 vsize_t oldsize = vp->v_size; 1123 vsize_t oldsize = vp->v_size;
1128 int error = 0; 1124 int error = 0;
1129 1125
1130 KASSERT(!(flags & SETATTR_CHSIZE) || mutex_owned(&pn->pn_sizemtx)); 1126 KASSERT(!(flags & SETATTR_CHSIZE) || mutex_owned(&pn->pn_sizemtx));
1131 1127
1132 if ((vp->v_mount->mnt_flag & MNT_RDONLY) && 1128 if ((vp->v_mount->mnt_flag & MNT_RDONLY) &&
1133 (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL 1129 (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL
1134 || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL 1130 || vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL
1135 || vap->va_mode != (mode_t)VNOVAL)) 1131 || vap->va_mode != (mode_t)VNOVAL))
1136 return EROFS; 1132 return EROFS;
1137 1133
1138 if ((vp->v_mount->mnt_flag & MNT_RDONLY) 1134 if ((vp->v_mount->mnt_flag & MNT_RDONLY)
1139 && vp->v_type == VREG && vap->va_size != VNOVAL) 1135 && vp->v_type == VREG && vap->va_size != VNOVAL)
1140 return EROFS; 1136 return EROFS;
1141 1137
1142 /* 1138 /*
1143 * Flush metacache first. If we are called with some explicit 1139 * Flush metacache first. If we are called with some explicit
1144 * parameters, treat them as information overriding metacache 1140 * parameters, treat them as information overriding metacache
1145 * information. 1141 * information.
1146 */ 1142 */
1147 if (PUFFS_USE_METAFLUSH(pmp) && pn->pn_stat & PNODE_METACACHE_MASK) { 1143 if (PUFFS_USE_METAFLUSH(pmp) && pn->pn_stat & PNODE_METACACHE_MASK) {
1148 if ((pn->pn_stat & PNODE_METACACHE_ATIME) 1144 if ((pn->pn_stat & PNODE_METACACHE_ATIME)
1149 && vap->va_atime.tv_sec == VNOVAL) 1145 && vap->va_atime.tv_sec == VNOVAL)
1150 vap->va_atime = pn->pn_mc_atime; 1146 vap->va_atime = pn->pn_mc_atime;
1151 if ((pn->pn_stat & PNODE_METACACHE_CTIME) 1147 if ((pn->pn_stat & PNODE_METACACHE_CTIME)
1152 && vap->va_ctime.tv_sec == VNOVAL) 1148 && vap->va_ctime.tv_sec == VNOVAL)
1153 vap->va_ctime = pn->pn_mc_ctime; 1149 vap->va_ctime = pn->pn_mc_ctime;
1154 if ((pn->pn_stat & PNODE_METACACHE_MTIME) 1150 if ((pn->pn_stat & PNODE_METACACHE_MTIME)
1155 && vap->va_mtime.tv_sec == VNOVAL) 1151 && vap->va_mtime.tv_sec == VNOVAL)
1156 vap->va_mtime = pn->pn_mc_mtime; 1152 vap->va_mtime = pn->pn_mc_mtime;
1157 if ((pn->pn_stat & PNODE_METACACHE_SIZE) 1153 if ((pn->pn_stat & PNODE_METACACHE_SIZE)
1158 && vap->va_size == VNOVAL) 1154 && vap->va_size == VNOVAL)
1159 vap->va_size = pn->pn_mc_size; 1155 vap->va_size = pn->pn_mc_size;
1160 1156
1161 pn->pn_stat &= ~PNODE_METACACHE_MASK; 1157 pn->pn_stat &= ~PNODE_METACACHE_MASK;
1162 } 1158 }
1163 1159
1164 /* 1160 /*
1165 * Flush attribute cache so that another thread do  1161 * Flush attribute cache so that another thread do
1166 * not get a stale value during the operation. 1162 * not get a stale value during the operation.
1167 */ 1163 */
1168 if (PUFFS_USE_FS_TTL(pmp)) 1164 if (PUFFS_USE_FS_TTL(pmp))
1169 pn->pn_va_timeout = 0; 1165 pn->pn_va_timeout = 0;
1170 1166
1171 PUFFS_MSG_ALLOC(vn, setattr); 1167 PUFFS_MSG_ALLOC(vn, setattr);
1172 (void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr)); 1168 (void)memcpy(&setattr_msg->pvnr_va, vap, sizeof(struct vattr));
1173 puffs_credcvt(&setattr_msg->pvnr_cred, cred); 1169 puffs_credcvt(&setattr_msg->pvnr_cred, cred);
1174 puffs_msg_setinfo(park_setattr, PUFFSOP_VN, 1170 puffs_msg_setinfo(park_setattr, PUFFSOP_VN,
1175 PUFFS_VN_SETATTR, VPTOPNC(vp)); 1171 PUFFS_VN_SETATTR, VPTOPNC(vp));
1176 if (flags & SETATTR_ASYNC) 1172 if (flags & SETATTR_ASYNC)
1177 puffs_msg_setfaf(park_setattr); 1173 puffs_msg_setfaf(park_setattr);
1178 1174
1179 puffs_msg_enqueue(pmp, park_setattr); 1175 puffs_msg_enqueue(pmp, park_setattr);
1180 if ((flags & SETATTR_ASYNC) == 0) { 1176 if ((flags & SETATTR_ASYNC) == 0) {
1181 error = puffs_msg_wait2(pmp, park_setattr, vp->v_data, NULL); 1177 error = puffs_msg_wait2(pmp, park_setattr, vp->v_data, NULL);
1182 1178
1183 if ((error == 0) && PUFFS_USE_FS_TTL(pmp)) { 1179 if ((error == 0) && PUFFS_USE_FS_TTL(pmp)) {
1184 struct timespec *va_ttl = &setattr_msg->pvnr_va_ttl; 1180 struct timespec *va_ttl = &setattr_msg->pvnr_va_ttl;
1185 struct vattr *rvap = &setattr_msg->pvnr_va; 1181 struct vattr *rvap = &setattr_msg->pvnr_va;
1186 1182
1187 update_va(vp, NULL, rvap, va_ttl, NULL, flags); 1183 update_va(vp, NULL, rvap, va_ttl, NULL, flags);
1188 } 1184 }
1189 } 1185 }
1190 1186
1191 PUFFS_MSG_RELEASE(setattr); 1187 PUFFS_MSG_RELEASE(setattr);
1192 if ((flags & SETATTR_ASYNC) == 0) { 1188 if ((flags & SETATTR_ASYNC) == 0) {
1193 error = checkerr(pmp, error, __func__); 1189 error = checkerr(pmp, error, __func__);
1194 if (error) 1190 if (error)
1195 return error; 1191 return error;
1196 } else { 1192 } else {
1197 error = 0; 1193 error = 0;
1198 } 1194 }
1199 1195
1200 if (vap->va_size != VNOVAL) { 1196 if (vap->va_size != VNOVAL) {
1201 /* 1197 /*
1202 * If we truncated the file, make sure the data beyond  1198 * If we truncated the file, make sure the data beyond
1203 * EOF in last page does not remain in cache, otherwise  1199 * EOF in last page does not remain in cache, otherwise
1204 * if the file is later truncated to a larger size (creating 1200 * if the file is later truncated to a larger size (creating
1205 * a hole), that area will not return zeroes as it 1201 * a hole), that area will not return zeroes as it
1206 * should.  1202 * should.
1207 */ 1203 */
1208 if ((flags & SETATTR_CHSIZE) && PUFFS_USE_PAGECACHE(pmp) &&  1204 if ((flags & SETATTR_CHSIZE) && PUFFS_USE_PAGECACHE(pmp) &&
1209 (vap->va_size < oldsize)) 1205 (vap->va_size < oldsize))
1210 zerofill_lastpage(vp, vap->va_size); 1206 zerofill_lastpage(vp, vap->va_size);
1211 1207
1212 pn->pn_serversize = vap->va_size; 1208 pn->pn_serversize = vap->va_size;
1213 if (flags & SETATTR_CHSIZE) 1209 if (flags & SETATTR_CHSIZE)
1214 uvm_vnp_setsize(vp, vap->va_size); 1210 uvm_vnp_setsize(vp, vap->va_size);
1215 puffs_updatenode(pn, PUFFS_UPDATECTIME | PUFFS_UPDATEMTIME, 0); 1211 puffs_updatenode(pn, PUFFS_UPDATECTIME | PUFFS_UPDATEMTIME, 0);
1216 } 1212 }
1217 1213
1218 return 0; 1214 return 0;
1219} 1215}
1220 1216
1221int 1217int
1222puffs_vnop_setattr(void *v) 1218puffs_vnop_setattr(void *v)
1223{ 1219{
1224 struct vop_getattr_args /* { 1220 struct vop_getattr_args /* {
1225 const struct vnodeop_desc *a_desc; 1221 const struct vnodeop_desc *a_desc;
1226 struct vnode *a_vp; 1222 struct vnode *a_vp;
1227 struct vattr *a_vap; 1223 struct vattr *a_vap;
1228 kauth_cred_t a_cred; 1224 kauth_cred_t a_cred;
1229 } */ *ap = v; 1225 } */ *ap = v;
1230 struct puffs_node *pn = ap->a_vp->v_data; 1226 struct puffs_node *pn = ap->a_vp->v_data;
1231 int error; 1227 int error;
1232 1228
1233 mutex_enter(&pn->pn_sizemtx); 1229 mutex_enter(&pn->pn_sizemtx);
1234 error = dosetattr(ap->a_vp, ap->a_vap, ap->a_cred, SETATTR_CHSIZE); 1230 error = dosetattr(ap->a_vp, ap->a_vap, ap->a_cred, SETATTR_CHSIZE);
1235 mutex_exit(&pn->pn_sizemtx); 1231 mutex_exit(&pn->pn_sizemtx);
1236 1232
1237 return error; 1233 return error;
1238} 1234}
1239 1235
1240static __inline int 1236static __inline int
1241doinact(struct puffs_mount *pmp, int iaflag) 1237doinact(struct puffs_mount *pmp, int iaflag)
1242{ 1238{
1243 1239
1244 if (EXISTSOP(pmp, INACTIVE)) 1240 if (EXISTSOP(pmp, INACTIVE))
1245 if (pmp->pmp_flags & PUFFS_KFLAG_IAONDEMAND) 1241 if (pmp->pmp_flags & PUFFS_KFLAG_IAONDEMAND)
1246 if (iaflag || ALLOPS(pmp)) 1242 if (iaflag || ALLOPS(pmp))
1247 return 1; 1243 return 1;
1248 else 1244 else
1249 return 0; 1245 return 0;
1250 else 1246 else
1251 return 1; 1247 return 1;
1252 else 1248 else
1253 return 0; 1249 return 0;
1254} 1250}
1255 1251
1256static void 1252static void
1257callinactive(struct puffs_mount *pmp, puffs_cookie_t ck, int iaflag) 1253callinactive(struct puffs_mount *pmp, puffs_cookie_t ck, int iaflag)

cvs diff -r1.14 -r1.15 src/sys/fs/tmpfs/tmpfs_fifoops.c (switch to unified diff)

--- src/sys/fs/tmpfs/tmpfs_fifoops.c 2021/07/18 23:56:13 1.14
+++ src/sys/fs/tmpfs/tmpfs_fifoops.c 2021/07/19 01:30:25 1.15
@@ -1,117 +1,117 @@ @@ -1,117 +1,117 @@
1/* $NetBSD: tmpfs_fifoops.c,v 1.14 2021/07/18 23:56:13 dholland Exp $ */ 1/* $NetBSD: tmpfs_fifoops.c,v 1.15 2021/07/19 01:30:25 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005 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
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
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 for named pipes. 34 * tmpfs vnode interface for named pipes.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: tmpfs_fifoops.c,v 1.14 2021/07/18 23:56:13 dholland Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: tmpfs_fifoops.c,v 1.15 2021/07/19 01:30:25 dholland Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/vnode.h> 41#include <sys/vnode.h>
42 42
43#include <fs/tmpfs/tmpfs.h> 43#include <fs/tmpfs/tmpfs.h>
44#include <fs/tmpfs/tmpfs_fifoops.h> 44#include <fs/tmpfs/tmpfs_fifoops.h>
45 45
46/* 46/*
47 * vnode operations vector used for fifos stored in a tmpfs file system. 47 * vnode operations vector used for fifos stored in a tmpfs file system.
48 */ 48 */
49int (**tmpfs_fifoop_p)(void *); 49int (**tmpfs_fifoop_p)(void *);
50const struct vnodeopv_entry_desc tmpfs_fifoop_entries[] = { 50const struct vnodeopv_entry_desc tmpfs_fifoop_entries[] = {
51 { &vop_default_desc, vn_default_error }, 51 { &vop_default_desc, vn_default_error },
52 GENFS_FIFOOP_ENTRIES, 52 GENFS_FIFOOP_ENTRIES,
53 { &vop_close_desc, tmpfs_fifo_close }, 53 { &vop_close_desc, tmpfs_fifo_close },
54 { &vop_access_desc, tmpfs_fifo_access }, 54 { &vop_access_desc, tmpfs_access },
55 { &vop_accessx_desc, genfs_accessx }, 55 { &vop_accessx_desc, genfs_accessx },
56 { &vop_getattr_desc, tmpfs_fifo_getattr }, 56 { &vop_getattr_desc, tmpfs_getattr },
57 { &vop_setattr_desc, tmpfs_fifo_setattr }, 57 { &vop_setattr_desc, tmpfs_setattr },
58 { &vop_read_desc, tmpfs_fifo_read }, 58 { &vop_read_desc, tmpfs_fifo_read },
59 { &vop_write_desc, tmpfs_fifo_write }, 59 { &vop_write_desc, tmpfs_fifo_write },
60 { &vop_fcntl_desc, tmpfs_fifo_fcntl }, 60 { &vop_fcntl_desc, genfs_fcntl },
61 { &vop_fsync_desc, tmpfs_fifo_fsync }, 61 { &vop_fsync_desc, vn_fifo_bypass },
62 { &vop_inactive_desc, tmpfs_fifo_inactive }, 62 { &vop_inactive_desc, tmpfs_inactive },
63 { &vop_reclaim_desc, tmpfs_fifo_reclaim }, 63 { &vop_reclaim_desc, tmpfs_reclaim },
64 { &vop_lock_desc, tmpfs_fifo_lock }, 64 { &vop_lock_desc, genfs_lock },
65 { &vop_unlock_desc, tmpfs_fifo_unlock }, 65 { &vop_unlock_desc, genfs_unlock },
66 { &vop_strategy_desc, tmpfs_fifo_strategy }, 66 { &vop_strategy_desc, vn_fifo_bypass },
67 { &vop_print_desc, tmpfs_fifo_print }, 67 { &vop_print_desc, tmpfs_print },
68 { &vop_islocked_desc, tmpfs_fifo_islocked }, 68 { &vop_islocked_desc, genfs_islocked },
69 { &vop_bwrite_desc, tmpfs_fifo_bwrite }, 69 { &vop_bwrite_desc, genfs_nullop },
70 { NULL, NULL } 70 { NULL, NULL }
71}; 71};
72 72
73const struct vnodeopv_desc tmpfs_fifoop_opv_desc = { 73const struct vnodeopv_desc tmpfs_fifoop_opv_desc = {
74 &tmpfs_fifoop_p, tmpfs_fifoop_entries 74 &tmpfs_fifoop_p, tmpfs_fifoop_entries
75}; 75};
76 76
77int 77int
78tmpfs_fifo_close(void *v) 78tmpfs_fifo_close(void *v)
79{ 79{
80 struct vop_close_args /* { 80 struct vop_close_args /* {
81 struct vnode *a_vp; 81 struct vnode *a_vp;
82 int a_fflag; 82 int a_fflag;
83 kauth_cred_t a_cred; 83 kauth_cred_t a_cred;
84 } */ *ap __unused = v; 84 } */ *ap __unused = v;
85 85
86 return VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), v); 86 return VOCALL(fifo_vnodeop_p, VOFFSET(vop_close), v);
87} 87}
88 88
89int 89int
90tmpfs_fifo_read(void *v) 90tmpfs_fifo_read(void *v)
91{ 91{
92 struct vop_read_args /* { 92 struct vop_read_args /* {
93 struct vnode *a_vp; 93 struct vnode *a_vp;
94 struct uio *a_uio; 94 struct uio *a_uio;
95 int a_ioflag; 95 int a_ioflag;
96 kauth_cred_t a_cred; 96 kauth_cred_t a_cred;
97 } */ *ap = v; 97 } */ *ap = v;
98 vnode_t *vp = ap->a_vp; 98 vnode_t *vp = ap->a_vp;
99 99
100 tmpfs_update(vp, TMPFS_UPDATE_ATIME); 100 tmpfs_update(vp, TMPFS_UPDATE_ATIME);
101 return VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), v); 101 return VOCALL(fifo_vnodeop_p, VOFFSET(vop_read), v);
102} 102}
103 103
104int 104int
105tmpfs_fifo_write(void *v) 105tmpfs_fifo_write(void *v)
106{ 106{
107 struct vop_write_args /* { 107 struct vop_write_args /* {
108 struct vnode *a_vp; 108 struct vnode *a_vp;
109 struct uio *a_uio; 109 struct uio *a_uio;
110 int a_ioflag; 110 int a_ioflag;
111 kauth_cred_t a_cred; 111 kauth_cred_t a_cred;
112 } */ *ap = v; 112 } */ *ap = v;
113 vnode_t *vp = ap->a_vp; 113 vnode_t *vp = ap->a_vp;
114 114
115 tmpfs_update(vp, TMPFS_UPDATE_MTIME); 115 tmpfs_update(vp, TMPFS_UPDATE_MTIME);
116 return VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), v); 116 return VOCALL(fifo_vnodeop_p, VOFFSET(vop_write), v);
117} 117}

cvs diff -r1.15 -r1.16 src/sys/fs/tmpfs/tmpfs_specops.c (switch to unified diff)

--- src/sys/fs/tmpfs/tmpfs_specops.c 2021/07/18 23:56:13 1.15
+++ src/sys/fs/tmpfs/tmpfs_specops.c 2021/07/19 01:30:25 1.16
@@ -1,119 +1,119 @@ @@ -1,119 +1,119 @@
1/* $NetBSD: tmpfs_specops.c,v 1.15 2021/07/18 23:56:13 dholland Exp $ */ 1/* $NetBSD: tmpfs_specops.c,v 1.16 2021/07/19 01:30:25 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2005 The NetBSD Foundation, Inc. 4 * Copyright (c) 2005 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
15 * notice, this list of conditions and the following disclaimer. 15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright 16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the 17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution. 18 * documentation and/or other materials provided with the distribution.
19 * 19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
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 for special devices. 34 * tmpfs vnode interface for special devices.
35 */ 35 */
36 36
37#include <sys/cdefs.h> 37#include <sys/cdefs.h>
38__KERNEL_RCSID(0, "$NetBSD: tmpfs_specops.c,v 1.15 2021/07/18 23:56:13 dholland Exp $"); 38__KERNEL_RCSID(0, "$NetBSD: tmpfs_specops.c,v 1.16 2021/07/19 01:30:25 dholland Exp $");
39 39
40#include <sys/param.h> 40#include <sys/param.h>
41#include <sys/vnode.h> 41#include <sys/vnode.h>
42 42
43#include <fs/tmpfs/tmpfs.h> 43#include <fs/tmpfs/tmpfs.h>
44#include <fs/tmpfs/tmpfs_specops.h> 44#include <fs/tmpfs/tmpfs_specops.h>
45 45
46/* 46/*
47 * vnode operations vector used for special devices stored in a tmpfs 47 * vnode operations vector used for special devices stored in a tmpfs
48 * file system. 48 * file system.
49 */ 49 */
50 50
51int (**tmpfs_specop_p)(void *); 51int (**tmpfs_specop_p)(void *);
52 52
53const struct vnodeopv_entry_desc tmpfs_specop_entries[] = { 53const struct vnodeopv_entry_desc tmpfs_specop_entries[] = {
54 { &vop_default_desc, vn_default_error }, 54 { &vop_default_desc, vn_default_error },
55 GENFS_SPECOP_ENTRIES, 55 GENFS_SPECOP_ENTRIES,
56 { &vop_close_desc, tmpfs_spec_close }, 56 { &vop_close_desc, tmpfs_spec_close },
57 { &vop_access_desc, tmpfs_spec_access }, 57 { &vop_access_desc, tmpfs_access },
58 { &vop_accessx_desc, genfs_accessx }, 58 { &vop_accessx_desc, genfs_accessx },
59 { &vop_getattr_desc, tmpfs_spec_getattr }, 59 { &vop_getattr_desc, tmpfs_getattr },
60 { &vop_setattr_desc, tmpfs_spec_setattr }, 60 { &vop_setattr_desc, tmpfs_setattr },
61 { &vop_read_desc, tmpfs_spec_read }, 61 { &vop_read_desc, tmpfs_spec_read },
62 { &vop_write_desc, tmpfs_spec_write }, 62 { &vop_write_desc, tmpfs_spec_write },
63 { &vop_fcntl_desc, tmpfs_spec_fcntl }, 63 { &vop_fcntl_desc, genfs_fcntl },
64 { &vop_fsync_desc, tmpfs_spec_fsync }, 64 { &vop_fsync_desc, spec_fsync },
65 { &vop_inactive_desc, tmpfs_spec_inactive }, 65 { &vop_inactive_desc, tmpfs_inactive },
66 { &vop_reclaim_desc, tmpfs_spec_reclaim }, 66 { &vop_reclaim_desc, tmpfs_reclaim },
67 { &vop_lock_desc, tmpfs_spec_lock }, 67 { &vop_lock_desc, genfs_lock },
68 { &vop_unlock_desc, tmpfs_spec_unlock }, 68 { &vop_unlock_desc, genfs_unlock },
69 { &vop_print_desc, tmpfs_spec_print }, 69 { &vop_print_desc, tmpfs_print },
70 { &vop_islocked_desc, tmpfs_spec_islocked }, 70 { &vop_islocked_desc, genfs_islocked },
71 { &vop_bwrite_desc, tmpfs_spec_bwrite }, 71 { &vop_bwrite_desc, vn_bwrite },
72 { NULL, NULL } 72 { NULL, NULL }
73}; 73};
74 74
75const struct vnodeopv_desc tmpfs_specop_opv_desc = { 75const struct vnodeopv_desc tmpfs_specop_opv_desc = {
76 &tmpfs_specop_p, tmpfs_specop_entries 76 &tmpfs_specop_p, tmpfs_specop_entries
77}; 77};
78 78
79int 79int
80tmpfs_spec_close(void *v) 80tmpfs_spec_close(void *v)
81{ 81{
82 struct vop_close_args /* { 82 struct vop_close_args /* {
83 struct vnode *a_vp; 83 struct vnode *a_vp;
84 int a_fflag; 84 int a_fflag;
85 kauth_cred_t a_cred; 85 kauth_cred_t a_cred;
86 } */ *ap __unused = v; 86 } */ *ap __unused = v;
87 87
88 return VOCALL(spec_vnodeop_p, VOFFSET(vop_close), v); 88 return VOCALL(spec_vnodeop_p, VOFFSET(vop_close), v);
89} 89}
90 90
91int 91int
92tmpfs_spec_read(void *v) 92tmpfs_spec_read(void *v)
93{ 93{
94 struct vop_read_args /* { 94 struct vop_read_args /* {
95 struct vnode *a_vp; 95 struct vnode *a_vp;
96 struct uio *a_uio; 96 struct uio *a_uio;
97 int a_ioflag; 97 int a_ioflag;
98 kauth_cred_t a_cred; 98 kauth_cred_t a_cred;
99 } */ *ap = v; 99 } */ *ap = v;
100 vnode_t *vp = ap->a_vp; 100 vnode_t *vp = ap->a_vp;
101 101
102 tmpfs_update(vp, TMPFS_UPDATE_ATIME); 102 tmpfs_update(vp, TMPFS_UPDATE_ATIME);
103 return VOCALL(spec_vnodeop_p, VOFFSET(vop_read), v); 103 return VOCALL(spec_vnodeop_p, VOFFSET(vop_read), v);
104} 104}
105 105
106int 106int
107tmpfs_spec_write(void *v) 107tmpfs_spec_write(void *v)
108{ 108{
109 struct vop_write_args /* { 109 struct vop_write_args /* {
110 struct vnode *a_vp; 110 struct vnode *a_vp;
111 struct uio *a_uio; 111 struct uio *a_uio;
112 int a_ioflag; 112 int a_ioflag;
113 kauth_cred_t a_cred; 113 kauth_cred_t a_cred;
114 } */ *ap = v; 114 } */ *ap = v;
115 vnode_t *vp = ap->a_vp; 115 vnode_t *vp = ap->a_vp;
116 116
117 tmpfs_update(vp, TMPFS_UPDATE_MTIME); 117 tmpfs_update(vp, TMPFS_UPDATE_MTIME);
118 return VOCALL(spec_vnodeop_p, VOFFSET(vop_write), v); 118 return VOCALL(spec_vnodeop_p, VOFFSET(vop_write), v);
119} 119}