Deleted Added
full compact
pseudofs_vnops.c (84187) pseudofs_vnops.c (84246)
1/*-
2 * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
1/*-
2 * Copyright (c) 2001 Dag-Erling Co�dan Sm�rgrav
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 11 unchanged lines hidden (view full) ---

20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * $FreeBSD: head/sys/fs/pseudofs/pseudofs_vnops.c 84187 2001-09-30 19:41:29Z des $
28 * $FreeBSD: head/sys/fs/pseudofs/pseudofs_vnops.c 84246 2001-10-01 04:22:20Z des $
29 */
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/systm.h>
34#include <sys/ctype.h>
35#include <sys/dirent.h>
36#include <sys/fcntl.h>

--- 25 unchanged lines hidden (view full) ---

62#else
63#define PFS_TRACE(foo) \
64 do { /* nothing */ } while (0)
65#define PFS_RETURN(err) \
66 return (err)
67#endif
68
69/*
29 */
30
31#include <sys/param.h>
32#include <sys/kernel.h>
33#include <sys/systm.h>
34#include <sys/ctype.h>
35#include <sys/dirent.h>
36#include <sys/fcntl.h>

--- 25 unchanged lines hidden (view full) ---

62#else
63#define PFS_TRACE(foo) \
64 do { /* nothing */ } while (0)
65#define PFS_RETURN(err) \
66 return (err)
67#endif
68
69/*
70 * Returns non-zero if given file is visible to given process
71 */
72static int
73pfs_visible(struct thread *td, struct pfs_node *pn, pid_t pid)
74{
75 struct proc *proc;
76 int r;
77
78 PFS_TRACE(("%s (pid: %d, req: %d)",
79 pn->pn_name, pid, td->td_proc->p_pid));
80 if (pid == NO_PID)
81 PFS_RETURN (1);
82
83 r = 1;
84 if ((proc = pfind(pid)) == NULL)
85 PFS_RETURN (0);
86 /* XXX should lock td->td_proc? */
87 if (p_cansee(td->td_proc, proc) != 0 ||
88 (pn->pn_vis != NULL && !(pn->pn_vis)(td, proc, pn)))
89 r = 0;
90 PROC_UNLOCK(proc);
91 PFS_RETURN (r);
92}
93
94/*
70 * Verify permissions
71 */
72static int
73pfs_access(struct vop_access_args *va)
74{
75 struct vnode *vn = va->a_vp;
76 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
77 struct pfs_node *pn = pvd->pvd_pn;
78 struct vattr vattr;
79 int error;
80
81 PFS_TRACE((pn->pn_name));
82
83 error = VOP_GETATTR(vn, &vattr, va->a_cred, va->a_td);
84 if (error)
95 * Verify permissions
96 */
97static int
98pfs_access(struct vop_access_args *va)
99{
100 struct vnode *vn = va->a_vp;
101 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
102 struct pfs_node *pn = pvd->pvd_pn;
103 struct vattr vattr;
104 int error;
105
106 PFS_TRACE((pn->pn_name));
107
108 error = VOP_GETATTR(vn, &vattr, va->a_cred, va->a_td);
109 if (error)
85 return (error);
110 PFS_RETURN (error);
86 error = vaccess(vn->v_type, vattr.va_mode, vattr.va_uid,
87 vattr.va_gid, va->a_mode, va->a_cred, NULL);
111 error = vaccess(vn->v_type, vattr.va_mode, vattr.va_uid,
112 vattr.va_gid, va->a_mode, va->a_cred, NULL);
88 return (error);
113 PFS_RETURN (error);
89}
90
91/*
92 * Close a file or directory
93 */
94static int
95pfs_close(struct vop_close_args *va)
96{

--- 44 unchanged lines hidden (view full) ---

141 }
142
143 if (pvd->pvd_pid != NO_PID) {
144 if ((proc = pfind(pvd->pvd_pid)) == NULL)
145 PFS_RETURN (ENOENT);
146 vap->va_uid = proc->p_ucred->cr_ruid;
147 vap->va_gid = proc->p_ucred->cr_rgid;
148 if (pn->pn_attr != NULL)
114}
115
116/*
117 * Close a file or directory
118 */
119static int
120pfs_close(struct vop_close_args *va)
121{

--- 44 unchanged lines hidden (view full) ---

166 }
167
168 if (pvd->pvd_pid != NO_PID) {
169 if ((proc = pfind(pvd->pvd_pid)) == NULL)
170 PFS_RETURN (ENOENT);
171 vap->va_uid = proc->p_ucred->cr_ruid;
172 vap->va_gid = proc->p_ucred->cr_rgid;
173 if (pn->pn_attr != NULL)
149 error = (pn->pn_attr)(curthread, proc, pn, vap);
174 error = (pn->pn_attr)(va->a_td, proc, pn, vap);
150 PROC_UNLOCK(proc);
151 } else {
152 vap->va_uid = 0;
153 vap->va_gid = 0;
154 }
155
156 PFS_RETURN (error);
157}

--- 5 unchanged lines hidden (view full) ---

163pfs_lookup(struct vop_lookup_args *va)
164{
165 struct vnode *vn = va->a_dvp;
166 struct vnode **vpp = va->a_vpp;
167 struct componentname *cnp = va->a_cnp;
168 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
169 struct pfs_node *pd = pvd->pvd_pn;
170 struct pfs_node *pn, *pdn = NULL;
175 PROC_UNLOCK(proc);
176 } else {
177 vap->va_uid = 0;
178 vap->va_gid = 0;
179 }
180
181 PFS_RETURN (error);
182}

--- 5 unchanged lines hidden (view full) ---

188pfs_lookup(struct vop_lookup_args *va)
189{
190 struct vnode *vn = va->a_dvp;
191 struct vnode **vpp = va->a_vpp;
192 struct componentname *cnp = va->a_cnp;
193 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
194 struct pfs_node *pd = pvd->pvd_pn;
195 struct pfs_node *pn, *pdn = NULL;
171 struct proc *proc;
172 pid_t pid = pvd->pvd_pid;
173 char *pname;
174 int error, i, namelen;
175
176 PFS_TRACE(("%.*s", (int)cnp->cn_namelen, cnp->cn_nameptr));
177
178 if (vn->v_type != VDIR)
179 PFS_RETURN (ENOTDIR);

--- 5 unchanged lines hidden (view full) ---

185 */
186 if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
187 PFS_RETURN (EOPNOTSUPP);
188
189 /* shortcut: check if the name is too long */
190 if (cnp->cn_namelen >= PFS_NAMELEN)
191 PFS_RETURN (ENOENT);
192
196 pid_t pid = pvd->pvd_pid;
197 char *pname;
198 int error, i, namelen;
199
200 PFS_TRACE(("%.*s", (int)cnp->cn_namelen, cnp->cn_nameptr));
201
202 if (vn->v_type != VDIR)
203 PFS_RETURN (ENOTDIR);

--- 5 unchanged lines hidden (view full) ---

209 */
210 if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
211 PFS_RETURN (EOPNOTSUPP);
212
213 /* shortcut: check if the name is too long */
214 if (cnp->cn_namelen >= PFS_NAMELEN)
215 PFS_RETURN (ENOENT);
216
193 /* check that owner process exists */
194 if (pvd->pvd_pid != NO_PID) {
195 if ((proc = pfind(pvd->pvd_pid)) == NULL)
196 PFS_RETURN (ENOENT);
197 PROC_UNLOCK(proc);
198 }
217 /* check that parent directory is visisble... */
218 if (!pfs_visible(curthread, pd, pvd->pvd_pid))
219 PFS_RETURN (ENOENT);
199
200 /* self */
201 namelen = cnp->cn_namelen;
202 pname = cnp->cn_nameptr;
203 if (namelen == 1 && *pname == '.') {
204 pn = pd;
205 *vpp = vn;
206 VREF(vn);
220
221 /* self */
222 namelen = cnp->cn_namelen;
223 pname = cnp->cn_nameptr;
224 if (namelen == 1 && *pname == '.') {
225 pn = pd;
226 *vpp = vn;
227 VREF(vn);
207 goto got_vnode;
228 PFS_RETURN (0);
208 }
209
210 /* parent */
211 if (cnp->cn_flags & ISDOTDOT) {
212 if (pd->pn_type == pfstype_root)
213 PFS_RETURN (EIO);
214 KASSERT(pd->pn_parent, ("non-root directory has no parent"));
215 /*
216 * This one is tricky. Descendents of procdir nodes
217 * inherit their parent's process affinity, but
218 * there's no easy reverse mapping. For simplicity,
219 * we assume that if this node is a procdir, its
220 * parent isn't (which is correct as long as
221 * descendents of procdir nodes are never procdir
222 * nodes themselves)
223 */
224 if (pd->pn_type == pfstype_procdir)
225 pid = NO_PID;
229 }
230
231 /* parent */
232 if (cnp->cn_flags & ISDOTDOT) {
233 if (pd->pn_type == pfstype_root)
234 PFS_RETURN (EIO);
235 KASSERT(pd->pn_parent, ("non-root directory has no parent"));
236 /*
237 * This one is tricky. Descendents of procdir nodes
238 * inherit their parent's process affinity, but
239 * there's no easy reverse mapping. For simplicity,
240 * we assume that if this node is a procdir, its
241 * parent isn't (which is correct as long as
242 * descendents of procdir nodes are never procdir
243 * nodes themselves)
244 */
245 if (pd->pn_type == pfstype_procdir)
246 pid = NO_PID;
226 error = pfs_vncache_alloc(vn->v_mount, vpp, pd->pn_parent, pid);
227 if (error)
228 PFS_RETURN (error);
229 goto got_vnode;
247 pn = pd->pn_parent;
248 goto got_pnode;
230 }
231
232 /* named node */
233 for (pn = pd->pn_nodes; pn->pn_type; ++pn)
234 if (pn->pn_type == pfstype_procdir)
235 pdn = pn;
236 else if (pn->pn_name[namelen] == '\0'
237 && bcmp(pname, pn->pn_name, namelen) == 0)

--- 6 unchanged lines hidden (view full) ---

244 if ((pid = pid * 10 + pname[i] - '0') > PID_MAX)
245 break;
246 if (i == cnp->cn_namelen)
247 goto got_pnode;
248 }
249
250 PFS_RETURN (ENOENT);
251 got_pnode:
249 }
250
251 /* named node */
252 for (pn = pd->pn_nodes; pn->pn_type; ++pn)
253 if (pn->pn_type == pfstype_procdir)
254 pdn = pn;
255 else if (pn->pn_name[namelen] == '\0'
256 && bcmp(pname, pn->pn_name, namelen) == 0)

--- 6 unchanged lines hidden (view full) ---

263 if ((pid = pid * 10 + pname[i] - '0') > PID_MAX)
264 break;
265 if (i == cnp->cn_namelen)
266 goto got_pnode;
267 }
268
269 PFS_RETURN (ENOENT);
270 got_pnode:
252 if (!pn->pn_parent)
271 if (pn != pd->pn_parent && !pn->pn_parent)
253 pn->pn_parent = pd;
272 pn->pn_parent = pd;
273 if (!pfs_visible(curthread, pn, pvd->pvd_pid))
274 PFS_RETURN (ENOENT);
254 error = pfs_vncache_alloc(vn->v_mount, vpp, pn, pid);
255 if (error)
256 PFS_RETURN (error);
275 error = pfs_vncache_alloc(vn->v_mount, vpp, pn, pid);
276 if (error)
277 PFS_RETURN (error);
257 got_vnode:
258 if (cnp->cn_flags & MAKEENTRY)
259 cache_enter(vn, *vpp, cnp);
260 PFS_RETURN (0);
261}
262
263/*
264 * Open a file or directory.
265 */
266static int
267pfs_open(struct vop_open_args *va)
268{
269 struct vnode *vn = va->a_vp;
270 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
271 struct pfs_node *pn = pvd->pvd_pn;
272 int mode = va->a_mode;
278 if (cnp->cn_flags & MAKEENTRY)
279 cache_enter(vn, *vpp, cnp);
280 PFS_RETURN (0);
281}
282
283/*
284 * Open a file or directory.
285 */
286static int
287pfs_open(struct vop_open_args *va)
288{
289 struct vnode *vn = va->a_vp;
290 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
291 struct pfs_node *pn = pvd->pvd_pn;
292 int mode = va->a_mode;
273 struct proc *proc;
274 int error;
275
276 PFS_TRACE(("%s (mode 0x%x)", pn->pn_name, mode));
277
293
294 PFS_TRACE(("%s (mode 0x%x)", pn->pn_name, mode));
295
296 /*
297 * check if the file is visible to the caller
298 *
299 * XXX Not sure if this is necessary, as the VFS system calls
300 * XXX pfs_lookup() and pfs_access() first, and pfs_lookup()
301 * XXX calls pfs_visible(). There's a race condition here, but
302 * XXX calling pfs_visible() from here doesn't really close it,
303 * XXX and the only consequence of that race is an EIO further
304 * XXX down the line.
305 */
306 if (!pfs_visible(va->a_td, pn, pvd->pvd_pid))
307 PFS_RETURN (ENOENT);
308
278 /* check if the requested mode is permitted */
279 if (((mode & FREAD) && !(mode & PFS_RD)) ||
280 ((mode & FWRITE) && !(mode & PFS_WR)))
281 PFS_RETURN (EPERM);
282
283 /* we don't support locking */
284 if ((mode & O_SHLOCK) || (mode & O_EXLOCK))
285 PFS_RETURN (EOPNOTSUPP);
286
309 /* check if the requested mode is permitted */
310 if (((mode & FREAD) && !(mode & PFS_RD)) ||
311 ((mode & FWRITE) && !(mode & PFS_WR)))
312 PFS_RETURN (EPERM);
313
314 /* we don't support locking */
315 if ((mode & O_SHLOCK) || (mode & O_EXLOCK))
316 PFS_RETURN (EOPNOTSUPP);
317
287 error = 0;
288 if (pvd->pvd_pid != NO_PID) {
289 if ((proc = pfind(pvd->pvd_pid)) == NULL)
290 PFS_RETURN (ENOENT);
291 /* XXX should lock va->a_td->td_proc? */
292 if (p_cansee(va->a_td->td_proc, proc) != 0)
293 error = ENOENT;
294 PROC_UNLOCK(proc);
295 }
296
297 PFS_RETURN (error);
318 PFS_RETURN (0);
298}
299
300/*
301 * Read from a file
302 */
303static int
304pfs_read(struct vop_read_args *va)
305{

--- 9 unchanged lines hidden (view full) ---

315 PFS_TRACE((pn->pn_name));
316
317 if (vn->v_type != VREG)
318 PFS_RETURN (EINVAL);
319
320 if (!(pn->pn_flags & PFS_RD))
321 PFS_RETURN (EBADF);
322
319}
320
321/*
322 * Read from a file
323 */
324static int
325pfs_read(struct vop_read_args *va)
326{

--- 9 unchanged lines hidden (view full) ---

336 PFS_TRACE((pn->pn_name));
337
338 if (vn->v_type != VREG)
339 PFS_RETURN (EINVAL);
340
341 if (!(pn->pn_flags & PFS_RD))
342 PFS_RETURN (EBADF);
343
344 /*
345 * This is necessary because either process' privileges may
346 * have changed since the open() call.
347 */
348 if (!pfs_visible(curthread, pn, pvd->pvd_pid))
349 PFS_RETURN (EIO);
350
351 /* XXX duplicates bits of pfs_visible() */
323 if (pvd->pvd_pid != NO_PID) {
324 if ((proc = pfind(pvd->pvd_pid)) == NULL)
325 PFS_RETURN (EIO);
326 _PHOLD(proc);
327 PROC_UNLOCK(proc);
328 }
329
330 if (pn->pn_flags & PFS_RAWRD) {

--- 29 unchanged lines hidden (view full) ---

360 sbuf_delete(sb);
361 PFS_RETURN (error);
362}
363
364/*
365 * Iterate through directory entries
366 */
367static int
352 if (pvd->pvd_pid != NO_PID) {
353 if ((proc = pfind(pvd->pvd_pid)) == NULL)
354 PFS_RETURN (EIO);
355 _PHOLD(proc);
356 PROC_UNLOCK(proc);
357 }
358
359 if (pn->pn_flags & PFS_RAWRD) {

--- 29 unchanged lines hidden (view full) ---

389 sbuf_delete(sb);
390 PFS_RETURN (error);
391}
392
393/*
394 * Iterate through directory entries
395 */
396static int
368pfs_iterate(struct pfs_info *pi, struct pfs_node **pn, struct proc **p)
397pfs_iterate(struct thread *td, pid_t pid, struct pfs_node **pn, struct proc **p)
369{
370 if ((*pn)->pn_type == pfstype_none)
371 return (-1);
372
398{
399 if ((*pn)->pn_type == pfstype_none)
400 return (-1);
401
402 again:
373 if ((*pn)->pn_type != pfstype_procdir)
374 ++*pn;
375
376 while ((*pn)->pn_type == pfstype_procdir) {
377 if (*p == NULL)
378 *p = LIST_FIRST(&allproc);
379 else
380 *p = LIST_NEXT(*p, p_list);
381 if (*p != NULL)
403 if ((*pn)->pn_type != pfstype_procdir)
404 ++*pn;
405
406 while ((*pn)->pn_type == pfstype_procdir) {
407 if (*p == NULL)
408 *p = LIST_FIRST(&allproc);
409 else
410 *p = LIST_NEXT(*p, p_list);
411 if (*p != NULL)
382 return (0);
412 break;
383 ++*pn;
384 }
385
386 if ((*pn)->pn_type == pfstype_none)
387 return (-1);
413 ++*pn;
414 }
415
416 if ((*pn)->pn_type == pfstype_none)
417 return (-1);
418
419 if (!pfs_visible(td, *pn, *p ? (*p)->p_pid : pid))
420 goto again;
388
389 return (0);
390}
391
392/*
393 * Return directory entries.
394 */
395static int
396pfs_readdir(struct vop_readdir_args *va)
397{
398 struct vnode *vn = va->a_vp;
399 struct pfs_info *pi = (struct pfs_info *)vn->v_mount->mnt_data;
400 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
401 struct pfs_node *pd = pvd->pvd_pn;
421
422 return (0);
423}
424
425/*
426 * Return directory entries.
427 */
428static int
429pfs_readdir(struct vop_readdir_args *va)
430{
431 struct vnode *vn = va->a_vp;
432 struct pfs_info *pi = (struct pfs_info *)vn->v_mount->mnt_data;
433 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
434 struct pfs_node *pd = pvd->pvd_pn;
435 pid_t pid = pvd->pvd_pid;
402 struct pfs_node *pn;
403 struct dirent entry;
404 struct uio *uio;
405 struct proc *p;
406 off_t offset;
407 int error, i, resid;
408
409 PFS_TRACE((pd->pn_name));
410
411 if (vn->v_type != VDIR)
412 PFS_RETURN (ENOTDIR);
413 uio = va->a_uio;
414
436 struct pfs_node *pn;
437 struct dirent entry;
438 struct uio *uio;
439 struct proc *p;
440 off_t offset;
441 int error, i, resid;
442
443 PFS_TRACE((pd->pn_name));
444
445 if (vn->v_type != VDIR)
446 PFS_RETURN (ENOTDIR);
447 uio = va->a_uio;
448
449 /* check if the directory is visible to the caller */
450 if (!pfs_visible(curthread, pd, pid))
451 PFS_RETURN (ENOENT);
452
415 /* only allow reading entire entries */
416 offset = uio->uio_offset;
417 resid = uio->uio_resid;
418 if (offset < 0 || offset % PFS_DELEN != 0 || resid < PFS_DELEN)
419 PFS_RETURN (EINVAL);
420
421 /* skip unwanted entries */
422 sx_slock(&allproc_lock);
423 for (pn = pd->pn_nodes, p = NULL; offset > 0; offset -= PFS_DELEN)
453 /* only allow reading entire entries */
454 offset = uio->uio_offset;
455 resid = uio->uio_resid;
456 if (offset < 0 || offset % PFS_DELEN != 0 || resid < PFS_DELEN)
457 PFS_RETURN (EINVAL);
458
459 /* skip unwanted entries */
460 sx_slock(&allproc_lock);
461 for (pn = pd->pn_nodes, p = NULL; offset > 0; offset -= PFS_DELEN)
424 if (pfs_iterate(pi, &pn, &p) == -1)
462 if (pfs_iterate(curthread, pid, &pn, &p) == -1)
425 break;
426
427 /* fill in entries */
428 entry.d_reclen = PFS_DELEN;
463 break;
464
465 /* fill in entries */
466 entry.d_reclen = PFS_DELEN;
429 while (pfs_iterate(pi, &pn, &p) != -1 && resid > 0) {
467 while (pfs_iterate(curthread, pid, &pn, &p) != -1 && resid > 0) {
430 if (!pn->pn_parent)
431 pn->pn_parent = pd;
432 if (!pn->pn_fileno)
433 pfs_fileno_alloc(pi, pn);
468 if (!pn->pn_parent)
469 pn->pn_parent = pd;
470 if (!pn->pn_fileno)
471 pfs_fileno_alloc(pi, pn);
434 if (pvd->pvd_pid != NO_PID)
435 entry.d_fileno = pn->pn_fileno * NO_PID + pvd->pvd_pid;
472 if (pid != NO_PID)
473 entry.d_fileno = pn->pn_fileno * NO_PID + pid;
436 else
437 entry.d_fileno = pn->pn_fileno;
438 /* PFS_DELEN was picked to fit PFS_NAMLEN */
439 for (i = 0; i < PFS_NAMELEN - 1 && pn->pn_name[i] != '\0'; ++i)
440 entry.d_name[i] = pn->pn_name[i];
441 entry.d_name[i] = 0;
442 entry.d_namlen = i;
443 switch (pn->pn_type) {

--- 84 unchanged lines hidden (view full) ---

528}
529
530/*
531 * Reclaim a vnode
532 */
533static int
534pfs_reclaim(struct vop_reclaim_args *va)
535{
474 else
475 entry.d_fileno = pn->pn_fileno;
476 /* PFS_DELEN was picked to fit PFS_NAMLEN */
477 for (i = 0; i < PFS_NAMELEN - 1 && pn->pn_name[i] != '\0'; ++i)
478 entry.d_name[i] = pn->pn_name[i];
479 entry.d_name[i] = 0;
480 entry.d_namlen = i;
481 switch (pn->pn_type) {

--- 84 unchanged lines hidden (view full) ---

566}
567
568/*
569 * Reclaim a vnode
570 */
571static int
572pfs_reclaim(struct vop_reclaim_args *va)
573{
574 struct vnode *vn = va->a_vp;
575 struct pfs_vdata *pvd = (struct pfs_vdata *)vn->v_data;
576 struct pfs_node *pn = pvd->pvd_pn;
577
578 PFS_TRACE((pn->pn_name));
579
536 return (pfs_vncache_free(va->a_vp));
537}
538
539/*
540 * Set attributes
541 */
542static int
543pfs_setattr(struct vop_setattr_args *va)

--- 27 unchanged lines hidden (view full) ---

571 PFS_TRACE((pn->pn_name));
572
573 if (vn->v_type != VREG)
574 PFS_RETURN (EINVAL);
575
576 if (!(pn->pn_flags & PFS_WR))
577 PFS_RETURN (EBADF);
578
580 return (pfs_vncache_free(va->a_vp));
581}
582
583/*
584 * Set attributes
585 */
586static int
587pfs_setattr(struct vop_setattr_args *va)

--- 27 unchanged lines hidden (view full) ---

615 PFS_TRACE((pn->pn_name));
616
617 if (vn->v_type != VREG)
618 PFS_RETURN (EINVAL);
619
620 if (!(pn->pn_flags & PFS_WR))
621 PFS_RETURN (EBADF);
622
623 /*
624 * This is necessary because either process' privileges may
625 * have changed since the open() call.
626 */
627 if (!pfs_visible(curthread, pn, pvd->pvd_pid))
628 PFS_RETURN (EIO);
629
630 /* XXX duplicates bits of pfs_visible() */
579 if (pvd->pvd_pid != NO_PID) {
580 if ((proc = pfind(pvd->pvd_pid)) == NULL)
581 PFS_RETURN (EIO);
582 _PHOLD(proc);
583 PROC_UNLOCK(proc);
584 }
585
586 if (pn->pn_flags & PFS_RAWWR) {

--- 44 unchanged lines hidden (view full) ---

631 { &vop_readlink_desc, (vop_t *)pfs_readlink },
632 { &vop_reclaim_desc, (vop_t *)pfs_reclaim },
633 { &vop_remove_desc, (vop_t *)pfs_badop },
634 { &vop_rename_desc, (vop_t *)pfs_badop },
635 { &vop_rmdir_desc, (vop_t *)pfs_badop },
636 { &vop_setattr_desc, (vop_t *)pfs_setattr },
637 { &vop_symlink_desc, (vop_t *)pfs_badop },
638 { &vop_write_desc, (vop_t *)pfs_write },
631 if (pvd->pvd_pid != NO_PID) {
632 if ((proc = pfind(pvd->pvd_pid)) == NULL)
633 PFS_RETURN (EIO);
634 _PHOLD(proc);
635 PROC_UNLOCK(proc);
636 }
637
638 if (pn->pn_flags & PFS_RAWWR) {

--- 44 unchanged lines hidden (view full) ---

683 { &vop_readlink_desc, (vop_t *)pfs_readlink },
684 { &vop_reclaim_desc, (vop_t *)pfs_reclaim },
685 { &vop_remove_desc, (vop_t *)pfs_badop },
686 { &vop_rename_desc, (vop_t *)pfs_badop },
687 { &vop_rmdir_desc, (vop_t *)pfs_badop },
688 { &vop_setattr_desc, (vop_t *)pfs_setattr },
689 { &vop_symlink_desc, (vop_t *)pfs_badop },
690 { &vop_write_desc, (vop_t *)pfs_write },
639 /* XXX I've probably forgotten a few that need pfs_erofs */
691 /* XXX I've probably forgotten a few that need pfs_badop */
640 { NULL, (vop_t *)NULL }
641};
642
643static struct vnodeopv_desc pfs_vnodeop_opv_desc =
644 { &pfs_vnodeop_p, pfs_vnodeop_entries };
645
646VNODEOP_SET(pfs_vnodeop_opv_desc);
692 { NULL, (vop_t *)NULL }
693};
694
695static struct vnodeopv_desc pfs_vnodeop_opv_desc =
696 { &pfs_vnodeop_p, pfs_vnodeop_entries };
697
698VNODEOP_SET(pfs_vnodeop_opv_desc);