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); |