Deleted Added
full compact
devfs_vnops.c (81620) devfs_vnops.c (83366)
1/*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 2000
5 * Poul-Henning Kamp. All rights reserved.
6 *
7 * This code is derived from software donated to Berkeley by
8 * Jan-Simon Pendry.

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

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
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95
32 * From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vnops.c 1.43
33 *
1/*
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
4 * Copyright (c) 2000
5 * Poul-Henning Kamp. All rights reserved.
6 *
7 * This code is derived from software donated to Berkeley by
8 * Jan-Simon Pendry.

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

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
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * @(#)kernfs_vnops.c 8.15 (Berkeley) 5/21/95
32 * From: FreeBSD: src/sys/miscfs/kernfs/kernfs_vnops.c 1.43
33 *
34 * $FreeBSD: head/sys/fs/devfs/devfs_vnops.c 81620 2001-08-14 06:42:32Z phk $
34 * $FreeBSD: head/sys/fs/devfs/devfs_vnops.c 83366 2001-09-12 08:38:13Z julian $
35 */
36
37/*
38 * TODO:
39 * remove empty directories
40 * mknod: hunt down DE_DELETED, compare name, reinstantiate.
41 * mkdir: want it ?
42 */

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

106 de = TAILQ_FIRST(&de->de_dlist); /* "." */
107 de = TAILQ_NEXT(de, de_list); /* ".." */
108 de = de->de_dir;
109 }
110 return (buf + i);
111}
112
113int
35 */
36
37/*
38 * TODO:
39 * remove empty directories
40 * mknod: hunt down DE_DELETED, compare name, reinstantiate.
41 * mkdir: want it ?
42 */

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

106 de = TAILQ_FIRST(&de->de_dlist); /* "." */
107 de = TAILQ_NEXT(de, de_list); /* ".." */
108 de = de->de_dir;
109 }
110 return (buf + i);
111}
112
113int
114devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct proc *p)
114devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td)
115{
116 int error;
117 struct vnode *vp;
118 dev_t dev;
119
115{
116 int error;
117 struct vnode *vp;
118 dev_t dev;
119
120 if (p == NULL)
121 p = curproc; /* XXX */
120 if (td == NULL)
121 td = curthread; /* XXX */
122loop:
123 vp = de->de_vnode;
124 if (vp != NULL) {
122loop:
123 vp = de->de_vnode;
124 if (vp != NULL) {
125 if (vget(vp, LK_EXCLUSIVE, p ? p : curproc))
125 if (vget(vp, LK_EXCLUSIVE, td ? td : curthread))
126 goto loop;
127 *vpp = vp;
128 return (0);
129 }
130 if (de->de_dirent->d_type == DT_CHR) {
131 dev = *devfs_itod(de->de_inode);
132 if (dev == NULL)
133 return (ENOENT);

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

148 vp->v_type = VDIR;
149 } else if (de->de_dirent->d_type == DT_LNK) {
150 vp->v_type = VLNK;
151 } else {
152 vp->v_type = VBAD;
153 }
154 vp->v_data = de;
155 de->de_vnode = vp;
126 goto loop;
127 *vpp = vp;
128 return (0);
129 }
130 if (de->de_dirent->d_type == DT_CHR) {
131 dev = *devfs_itod(de->de_inode);
132 if (dev == NULL)
133 return (ENOENT);

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

148 vp->v_type = VDIR;
149 } else if (de->de_dirent->d_type == DT_LNK) {
150 vp->v_type = VLNK;
151 } else {
152 vp->v_type = VBAD;
153 }
154 vp->v_data = de;
155 de->de_vnode = vp;
156 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
156 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
157 *vpp = vp;
158 return (0);
159}
160
161static int
162devfs_access(ap)
163 struct vop_access_args /* {
164 struct vnode *a_vp;
165 int a_mode;
166 struct ucred *a_cred;
157 *vpp = vp;
158 return (0);
159}
160
161static int
162devfs_access(ap)
163 struct vop_access_args /* {
164 struct vnode *a_vp;
165 int a_mode;
166 struct ucred *a_cred;
167 struct proc *a_p;
167 struct thread *a_td;
168 } */ *ap;
169{
170 struct vnode *vp = ap->a_vp;
171 struct devfs_dirent *de;
172
173 de = vp->v_data;
174 if (vp->v_type == VDIR)
175 de = de->de_dir;
176
177 return (vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
178 ap->a_mode, ap->a_cred, NULL));
179}
180
181static int
182devfs_getattr(ap)
183 struct vop_getattr_args /* {
184 struct vnode *a_vp;
185 struct vattr *a_vap;
186 struct ucred *a_cred;
168 } */ *ap;
169{
170 struct vnode *vp = ap->a_vp;
171 struct devfs_dirent *de;
172
173 de = vp->v_data;
174 if (vp->v_type == VDIR)
175 de = de->de_dir;
176
177 return (vaccess(vp->v_type, de->de_mode, de->de_uid, de->de_gid,
178 ap->a_mode, ap->a_cred, NULL));
179}
180
181static int
182devfs_getattr(ap)
183 struct vop_getattr_args /* {
184 struct vnode *a_vp;
185 struct vattr *a_vap;
186 struct ucred *a_cred;
187 struct proc *a_p;
187 struct thread *a_td;
188 } */ *ap;
189{
190 struct vnode *vp = ap->a_vp;
191 struct vattr *vap = ap->a_vap;
192 int error = 0;
193 struct devfs_dirent *de;
194 dev_t dev;
195

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

247 struct vop_lookup_args /* {
248 struct vnode * a_dvp;
249 struct vnode ** a_vpp;
250 struct componentname * a_cnp;
251 } */ *ap;
252{
253 struct componentname *cnp;
254 struct vnode *dvp, **vpp;
188 } */ *ap;
189{
190 struct vnode *vp = ap->a_vp;
191 struct vattr *vap = ap->a_vap;
192 int error = 0;
193 struct devfs_dirent *de;
194 dev_t dev;
195

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

247 struct vop_lookup_args /* {
248 struct vnode * a_dvp;
249 struct vnode ** a_vpp;
250 struct componentname * a_cnp;
251 } */ *ap;
252{
253 struct componentname *cnp;
254 struct vnode *dvp, **vpp;
255 struct proc *p;
255 struct thread *td;
256 struct devfs_dirent *de, *dd;
257 struct devfs_mount *dmp;
258 dev_t cdev, *cpdev;
259 int error, cloned, flags, nameiop;
260 char specname[SPECNAMELEN + 1], *pname;
261
262 cnp = ap->a_cnp;
263 vpp = ap->a_vpp;
264 dvp = ap->a_dvp;
265 pname = cnp->cn_nameptr;
256 struct devfs_dirent *de, *dd;
257 struct devfs_mount *dmp;
258 dev_t cdev, *cpdev;
259 int error, cloned, flags, nameiop;
260 char specname[SPECNAMELEN + 1], *pname;
261
262 cnp = ap->a_cnp;
263 vpp = ap->a_vpp;
264 dvp = ap->a_dvp;
265 pname = cnp->cn_nameptr;
266 p = cnp->cn_proc;
266 td = cnp->cn_thread;
267 flags = cnp->cn_flags;
268 nameiop = cnp->cn_nameiop;
269 dmp = VFSTODEVFS(dvp->v_mount);
270 cloned = 0;
271 dd = dvp->v_data;
272
273 *vpp = NULLVP;
274
275 if (nameiop == RENAME)
276 return (EOPNOTSUPP);
277
278 if (dvp->v_type != VDIR)
279 return (ENOTDIR);
280
281 if ((flags & ISDOTDOT) && (dvp->v_flag & VROOT))
282 return (EIO);
283
267 flags = cnp->cn_flags;
268 nameiop = cnp->cn_nameiop;
269 dmp = VFSTODEVFS(dvp->v_mount);
270 cloned = 0;
271 dd = dvp->v_data;
272
273 *vpp = NULLVP;
274
275 if (nameiop == RENAME)
276 return (EOPNOTSUPP);
277
278 if (dvp->v_type != VDIR)
279 return (ENOTDIR);
280
281 if ((flags & ISDOTDOT) && (dvp->v_flag & VROOT))
282 return (EIO);
283
284 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_proc);
284 error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td);
285 if (error)
286 return (error);
287
288 if (cnp->cn_namelen == 1 && *pname == '.') {
289 if (nameiop != LOOKUP)
290 return (EINVAL);
291 *vpp = dvp;
292 VREF(dvp);
293 return (0);
294 }
295
296 if (flags & ISDOTDOT) {
297 if (nameiop != LOOKUP)
298 return (EINVAL);
285 if (error)
286 return (error);
287
288 if (cnp->cn_namelen == 1 && *pname == '.') {
289 if (nameiop != LOOKUP)
290 return (EINVAL);
291 *vpp = dvp;
292 VREF(dvp);
293 return (0);
294 }
295
296 if (flags & ISDOTDOT) {
297 if (nameiop != LOOKUP)
298 return (EINVAL);
299 VOP_UNLOCK(dvp, 0, p);
299 VOP_UNLOCK(dvp, 0, td);
300 de = TAILQ_FIRST(&dd->de_dlist); /* "." */
301 de = TAILQ_NEXT(de, de_list); /* ".." */
302 de = de->de_dir;
300 de = TAILQ_FIRST(&dd->de_dlist); /* "." */
301 de = TAILQ_NEXT(de, de_list); /* ".." */
302 de = de->de_dir;
303 error = devfs_allocv(de, dvp->v_mount, vpp, p);
303 error = devfs_allocv(de, dvp->v_mount, vpp, td);
304 if (error) {
304 if (error) {
305 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
305 vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
306 return (error);
307 }
308 if ((flags & LOCKPARENT) && (flags & ISLASTCN))
306 return (error);
307 }
308 if ((flags & LOCKPARENT) && (flags & ISLASTCN))
309 error = vn_lock(dvp, LK_EXCLUSIVE, p);
309 error = vn_lock(dvp, LK_EXCLUSIVE, td);
310 if (error)
311 vput(*vpp);
312 return (error);
313 }
314
315 devfs_populate(dmp);
316 dd = dvp->v_data;
317 TAILQ_FOREACH(de, &dd->de_dlist, de_list) {

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

352 }
353
354notfound:
355
356 if ((nameiop == CREATE || nameiop == RENAME) &&
357 (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
358 cnp->cn_flags |= SAVENAME;
359 if (!(flags & LOCKPARENT))
310 if (error)
311 vput(*vpp);
312 return (error);
313 }
314
315 devfs_populate(dmp);
316 dd = dvp->v_data;
317 TAILQ_FOREACH(de, &dd->de_dlist, de_list) {

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

352 }
353
354notfound:
355
356 if ((nameiop == CREATE || nameiop == RENAME) &&
357 (flags & (LOCKPARENT | WANTPARENT)) && (flags & ISLASTCN)) {
358 cnp->cn_flags |= SAVENAME;
359 if (!(flags & LOCKPARENT))
360 VOP_UNLOCK(dvp, 0, p);
360 VOP_UNLOCK(dvp, 0, td);
361 return (EJUSTRETURN);
362 }
363 return (ENOENT);
364
365
366found:
367
368 if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
361 return (EJUSTRETURN);
362 }
363 return (ENOENT);
364
365
366found:
367
368 if ((cnp->cn_nameiop == DELETE) && (flags & ISLASTCN)) {
369 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, p);
369 error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
370 if (error)
371 return (error);
372 if (*vpp == dvp) {
373 VREF(dvp);
374 *vpp = dvp;
375 return (0);
376 }
370 if (error)
371 return (error);
372 if (*vpp == dvp) {
373 VREF(dvp);
374 *vpp = dvp;
375 return (0);
376 }
377 error = devfs_allocv(de, dvp->v_mount, vpp, p);
377 error = devfs_allocv(de, dvp->v_mount, vpp, td);
378 if (error)
379 return (error);
380 if (!(flags & LOCKPARENT))
378 if (error)
379 return (error);
380 if (!(flags & LOCKPARENT))
381 VOP_UNLOCK(dvp, 0, p);
381 VOP_UNLOCK(dvp, 0, td);
382 return (0);
383 }
382 return (0);
383 }
384 error = devfs_allocv(de, dvp->v_mount, vpp, p);
384 error = devfs_allocv(de, dvp->v_mount, vpp, td);
385 if (error)
386 return (error);
387 if (!(flags & LOCKPARENT) || !(flags & ISLASTCN))
385 if (error)
386 return (error);
387 if (!(flags & LOCKPARENT) || !(flags & ISLASTCN))
388 VOP_UNLOCK(dvp, 0, p);
388 VOP_UNLOCK(dvp, 0, td);
389 return (0);
390}
391
392static int
393devfs_lookup(struct vop_lookup_args *ap)
394{
395 int j;
396 struct devfs_mount *dmp;
397
398 dmp = VFSTODEVFS(ap->a_dvp->v_mount);
389 return (0);
390}
391
392static int
393devfs_lookup(struct vop_lookup_args *ap)
394{
395 int j;
396 struct devfs_mount *dmp;
397
398 dmp = VFSTODEVFS(ap->a_dvp->v_mount);
399 lockmgr(&dmp->dm_lock, LK_SHARED, 0, curproc);
399 lockmgr(&dmp->dm_lock, LK_SHARED, 0, curthread);
400 j = devfs_lookupx(ap);
400 j = devfs_lookupx(ap);
401 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
401 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
402 return (j);
403}
404
405static int
406devfs_mknod(struct vop_mknod_args *ap)
407/*
408struct vop_mknod_args {
409 struct vnodeop_desc *a_desc;
410 struct vnode *a_dvp;
411 struct vnode **a_vpp;
412 struct componentname *a_cnp;
413 struct vattr *a_vap;
414};
415*/
416{
417 struct componentname *cnp;
418 struct vnode *dvp, **vpp;
402 return (j);
403}
404
405static int
406devfs_mknod(struct vop_mknod_args *ap)
407/*
408struct vop_mknod_args {
409 struct vnodeop_desc *a_desc;
410 struct vnode *a_dvp;
411 struct vnode **a_vpp;
412 struct componentname *a_cnp;
413 struct vattr *a_vap;
414};
415*/
416{
417 struct componentname *cnp;
418 struct vnode *dvp, **vpp;
419 struct proc *p;
419 struct thread *td;
420 struct devfs_dirent *dd, *de;
421 struct devfs_mount *dmp;
422 int cloned, flags, nameiop;
423 int error;
424
425 dvp = ap->a_dvp;
426 dmp = VFSTODEVFS(dvp->v_mount);
420 struct devfs_dirent *dd, *de;
421 struct devfs_mount *dmp;
422 int cloned, flags, nameiop;
423 int error;
424
425 dvp = ap->a_dvp;
426 dmp = VFSTODEVFS(dvp->v_mount);
427 lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curproc);
427 lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curthread);
428
429 cnp = ap->a_cnp;
430 vpp = ap->a_vpp;
428
429 cnp = ap->a_cnp;
430 vpp = ap->a_vpp;
431 p = cnp->cn_proc;
431 td = cnp->cn_thread;
432 flags = cnp->cn_flags;
433 nameiop = cnp->cn_nameiop;
434 cloned = 0;
435 dd = dvp->v_data;
436
437 error = ENOENT;
438 TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
439 if (cnp->cn_namelen != de->de_dirent->d_namlen)
440 continue;
441 if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
442 de->de_dirent->d_namlen) != 0)
443 continue;
444 if (de->de_flags & DE_WHITEOUT)
445 break;
446 goto notfound;
447 }
448 if (de == NULL)
449 goto notfound;
450 de->de_flags &= ~DE_WHITEOUT;
432 flags = cnp->cn_flags;
433 nameiop = cnp->cn_nameiop;
434 cloned = 0;
435 dd = dvp->v_data;
436
437 error = ENOENT;
438 TAILQ_FOREACH(de, &dd->de_dlist, de_list) {
439 if (cnp->cn_namelen != de->de_dirent->d_namlen)
440 continue;
441 if (bcmp(cnp->cn_nameptr, de->de_dirent->d_name,
442 de->de_dirent->d_namlen) != 0)
443 continue;
444 if (de->de_flags & DE_WHITEOUT)
445 break;
446 goto notfound;
447 }
448 if (de == NULL)
449 goto notfound;
450 de->de_flags &= ~DE_WHITEOUT;
451 error = devfs_allocv(de, dvp->v_mount, vpp, p);
451 error = devfs_allocv(de, dvp->v_mount, vpp, td);
452notfound:
452notfound:
453 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
453 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
454 return (error);
455}
456
457
458/* ARGSUSED */
459static int
460devfs_print(ap)
461 struct vop_print_args /* {

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

507 if (ap->a_vp->v_type != VDIR)
508 return (ENOTDIR);
509
510 uio = ap->a_uio;
511 if (uio->uio_offset < 0)
512 return (EINVAL);
513
514 dmp = VFSTODEVFS(ap->a_vp->v_mount);
454 return (error);
455}
456
457
458/* ARGSUSED */
459static int
460devfs_print(ap)
461 struct vop_print_args /* {

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

507 if (ap->a_vp->v_type != VDIR)
508 return (ENOTDIR);
509
510 uio = ap->a_uio;
511 if (uio->uio_offset < 0)
512 return (EINVAL);
513
514 dmp = VFSTODEVFS(ap->a_vp->v_mount);
515 lockmgr(&dmp->dm_lock, LK_SHARED, 0, curproc);
515 lockmgr(&dmp->dm_lock, LK_SHARED, 0, curthread);
516 devfs_populate(dmp);
517 error = 0;
518 de = ap->a_vp->v_data;
519 off = 0;
520 oldoff = uio->uio_offset;
521 TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
522 if (dd->de_flags & DE_WHITEOUT)
523 continue;

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

548 dp < dpe;
549 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
550 oldoff += dp->d_reclen;
551 *cookiep++ = (u_long) oldoff;
552 }
553 *ap->a_ncookies = ncookies;
554 *ap->a_cookies = cookiebuf;
555 }
516 devfs_populate(dmp);
517 error = 0;
518 de = ap->a_vp->v_data;
519 off = 0;
520 oldoff = uio->uio_offset;
521 TAILQ_FOREACH(dd, &de->de_dlist, de_list) {
522 if (dd->de_flags & DE_WHITEOUT)
523 continue;

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

548 dp < dpe;
549 dp = (struct dirent *)((caddr_t) dp + dp->d_reclen)) {
550 oldoff += dp->d_reclen;
551 *cookiep++ = (u_long) oldoff;
552 }
553 *ap->a_ncookies = ncookies;
554 *ap->a_cookies = cookiebuf;
555 }
556 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
556 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
557 uio->uio_offset = off;
558 return (error);
559}
560
561static int
562devfs_readlink(ap)
563 struct vop_readlink_args /* {
564 struct vnode *a_vp;

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

605 struct componentname *a_cnp;
606 } */ *ap;
607{
608 struct vnode *vp = ap->a_vp;
609 struct devfs_dirent *dd;
610 struct devfs_dirent *de;
611 struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount);
612
557 uio->uio_offset = off;
558 return (error);
559}
560
561static int
562devfs_readlink(ap)
563 struct vop_readlink_args /* {
564 struct vnode *a_vp;

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

605 struct componentname *a_cnp;
606 } */ *ap;
607{
608 struct vnode *vp = ap->a_vp;
609 struct devfs_dirent *dd;
610 struct devfs_dirent *de;
611 struct devfs_mount *dmp = VFSTODEVFS(vp->v_mount);
612
613 lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curproc);
613 lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curthread);
614 dd = ap->a_dvp->v_data;
615 de = vp->v_data;
616 de->de_flags |= DE_WHITEOUT;
614 dd = ap->a_dvp->v_data;
615 de = vp->v_data;
616 de->de_flags |= DE_WHITEOUT;
617 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
617 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
618 return (0);
619}
620
621/*
622 * Revoke is called on a tty when a terminal session ends. The vnode
623 * is orphaned by setting v_op to deadfs so we need to let go of it
624 * as well so that we create a new one next time around.
625 */

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

678 uid = vap->va_uid;
679 if (vap->va_gid == (gid_t)VNOVAL)
680 gid = de->de_gid;
681 else
682 gid = vap->va_gid;
683 if (uid != de->de_uid || gid != de->de_gid) {
684 if (((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
685 (gid != de->de_gid && !groupmember(gid, ap->a_cred))) &&
618 return (0);
619}
620
621/*
622 * Revoke is called on a tty when a terminal session ends. The vnode
623 * is orphaned by setting v_op to deadfs so we need to let go of it
624 * as well so that we create a new one next time around.
625 */

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

678 uid = vap->va_uid;
679 if (vap->va_gid == (gid_t)VNOVAL)
680 gid = de->de_gid;
681 else
682 gid = vap->va_gid;
683 if (uid != de->de_uid || gid != de->de_gid) {
684 if (((ap->a_cred->cr_uid != de->de_uid) || uid != de->de_uid ||
685 (gid != de->de_gid && !groupmember(gid, ap->a_cred))) &&
686 (error = suser(ap->a_p)) != 0)
686 (error = suser(ap->a_td->td_proc)) != 0)
687 return (error);
688 de->de_uid = uid;
689 de->de_gid = gid;
690 c = 1;
691 }
692 if (vap->va_mode != (mode_t)VNOVAL) {
693 if ((ap->a_cred->cr_uid != de->de_uid) &&
687 return (error);
688 de->de_uid = uid;
689 de->de_gid = gid;
690 c = 1;
691 }
692 if (vap->va_mode != (mode_t)VNOVAL) {
693 if ((ap->a_cred->cr_uid != de->de_uid) &&
694 (error = suser(ap->a_p)))
694 (error = suser(ap->a_td->td_proc)))
695 return (error);
696 de->de_mode = vap->va_mode;
697 c = 1;
698 }
699 if (vap->va_atime.tv_sec != VNOVAL) {
700 if ((ap->a_cred->cr_uid != de->de_uid) &&
695 return (error);
696 de->de_mode = vap->va_mode;
697 c = 1;
698 }
699 if (vap->va_atime.tv_sec != VNOVAL) {
700 if ((ap->a_cred->cr_uid != de->de_uid) &&
701 (error = suser(ap->a_p)))
701 (error = suser(ap->a_td->td_proc)))
702 return (error);
703 de->de_atime = vap->va_atime;
704 c = 1;
705 }
706 if (vap->va_mtime.tv_sec != VNOVAL) {
707 if ((ap->a_cred->cr_uid != de->de_uid) &&
702 return (error);
703 de->de_atime = vap->va_atime;
704 c = 1;
705 }
706 if (vap->va_mtime.tv_sec != VNOVAL) {
707 if ((ap->a_cred->cr_uid != de->de_uid) &&
708 (error = suser(ap->a_p)))
708 (error = suser(ap->a_td->td_proc)))
709 return (error);
710 de->de_mtime = vap->va_mtime;
711 c = 1;
712 }
713
714 if (c)
715 getnanotime(&de->de_ctime);
716 return (0);

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

726 char *a_target;
727 } */ *ap;
728{
729 int i, error;
730 struct devfs_dirent *dd;
731 struct devfs_dirent *de;
732 struct devfs_mount *dmp;
733
709 return (error);
710 de->de_mtime = vap->va_mtime;
711 c = 1;
712 }
713
714 if (c)
715 getnanotime(&de->de_ctime);
716 return (0);

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

726 char *a_target;
727 } */ *ap;
728{
729 int i, error;
730 struct devfs_dirent *dd;
731 struct devfs_dirent *de;
732 struct devfs_mount *dmp;
733
734 error = suser(ap->a_cnp->cn_proc);
734 error = suser(ap->a_cnp->cn_thread->td_proc);
735 if (error)
736 return(error);
737 dmp = VFSTODEVFS(ap->a_dvp->v_mount);
738 dd = ap->a_dvp->v_data;
739 de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen);
740 de->de_uid = 0;
741 de->de_gid = 0;
742 de->de_mode = 0755;
743 de->de_inode = dmp->dm_inode++;
744 de->de_dirent->d_type = DT_LNK;
745 i = strlen(ap->a_target) + 1;
746 MALLOC(de->de_symlink, char *, i, M_DEVFS, M_WAITOK);
747 bcopy(ap->a_target, de->de_symlink, i);
735 if (error)
736 return(error);
737 dmp = VFSTODEVFS(ap->a_dvp->v_mount);
738 dd = ap->a_dvp->v_data;
739 de = devfs_newdirent(ap->a_cnp->cn_nameptr, ap->a_cnp->cn_namelen);
740 de->de_uid = 0;
741 de->de_gid = 0;
742 de->de_mode = 0755;
743 de->de_inode = dmp->dm_inode++;
744 de->de_dirent->d_type = DT_LNK;
745 i = strlen(ap->a_target) + 1;
746 MALLOC(de->de_symlink, char *, i, M_DEVFS, M_WAITOK);
747 bcopy(ap->a_target, de->de_symlink, i);
748 lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curproc);
748 lockmgr(&dmp->dm_lock, LK_EXCLUSIVE, 0, curthread);
749 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list);
750 devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, 0);
749 TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list);
750 devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, 0);
751 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curproc);
751 lockmgr(&dmp->dm_lock, LK_RELEASE, 0, curthread);
752 return (0);
753}
754
755static vop_t **devfs_vnodeop_p;
756static struct vnodeopv_entry_desc devfs_vnodeop_entries[] = {
757 { &vop_default_desc, (vop_t *) vop_defaultop },
758 { &vop_access_desc, (vop_t *) devfs_access },
759 { &vop_getattr_desc, (vop_t *) devfs_getattr },

--- 36 unchanged lines hidden ---
752 return (0);
753}
754
755static vop_t **devfs_vnodeop_p;
756static struct vnodeopv_entry_desc devfs_vnodeop_entries[] = {
757 { &vop_default_desc, (vop_t *) vop_defaultop },
758 { &vop_access_desc, (vop_t *) devfs_access },
759 { &vop_getattr_desc, (vop_t *) devfs_getattr },

--- 36 unchanged lines hidden ---