X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..ccc36f2f2d89f9115c479db4439aa5c88de5b44a:/bsd/vfs/vfs_vnops.c diff --git a/bsd/vfs/vfs_vnops.c b/bsd/vfs/vfs_vnops.c index e186fb484..6e77308f8 100644 --- a/bsd/vfs/vfs_vnops.c +++ b/bsd/vfs/vfs_vnops.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * @@ -90,9 +90,11 @@ static int vn_write __P((struct file *fp, struct uio *uio, struct ucred *cred, int flags, struct proc *p)); static int vn_select __P(( struct file *fp, int which, void * wql, struct proc *p)); +static int vn_kqfilt_add __P((struct file *fp, struct knote *kn, struct proc *p)); +static int vn_kqfilt_remove __P((struct vnode *vp, uintptr_t ident, struct proc *p)); struct fileops vnops = - { vn_read, vn_write, vn_ioctl, vn_select, vn_closefile }; + { vn_read, vn_write, vn_ioctl, vn_select, vn_closefile, vn_kqfilt_add }; /* * Common code for vnode open operations. @@ -102,6 +104,15 @@ int vn_open(ndp, fmode, cmode) register struct nameidata *ndp; int fmode, cmode; +{ + return vn_open_modflags(ndp,&fmode,cmode); +} + +__private_extern__ int +vn_open_modflags(ndp, fmodep, cmode) + register struct nameidata *ndp; + int *fmodep; + int cmode; { register struct vnode *vp; register struct proc *p = ndp->ni_cnd.cn_proc; @@ -110,16 +121,22 @@ vn_open(ndp, fmode, cmode) struct vattr *vap = &vat; int error; int didhold = 0; + char *nameptr; + int fmode = *fmodep; if (fmode & O_CREAT) { ndp->ni_cnd.cn_nameiop = CREATE; - ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF; + ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | AUDITVNPATH1; if ((fmode & O_EXCL) == 0) ndp->ni_cnd.cn_flags |= FOLLOW; bwillwrite(); if (error = namei(ndp)) return (error); if (ndp->ni_vp == NULL) { + nameptr = add_name(ndp->ni_cnd.cn_nameptr, + ndp->ni_cnd.cn_namelen, + ndp->ni_cnd.cn_hash, 0); + VATTR_NULL(vap); vap->va_type = VREG; vap->va_mode = cmode; @@ -127,10 +144,17 @@ vn_open(ndp, fmode, cmode) vap->va_vaflags |= VA_EXCLUSIVE; VOP_LEASE(ndp->ni_dvp, p, cred, LEASE_WRITE); if (error = VOP_CREATE(ndp->ni_dvp, &ndp->ni_vp, - &ndp->ni_cnd, vap)) + &ndp->ni_cnd, vap)) { + remove_name(nameptr); return (error); + } fmode &= ~O_TRUNC; vp = ndp->ni_vp; + + VNAME(vp) = nameptr; + if (vget(ndp->ni_dvp, 0, p) == 0) { + VPARENT(vp) = ndp->ni_dvp; + } } else { VOP_ABORTOP(ndp->ni_dvp, &ndp->ni_cnd); if (ndp->ni_dvp == ndp->ni_vp) @@ -147,7 +171,7 @@ vn_open(ndp, fmode, cmode) } } else { ndp->ni_cnd.cn_nameiop = LOOKUP; - ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF; + ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF | AUDITVNPATH1; if (error = namei(ndp)) return (error); vp = ndp->ni_vp; @@ -192,15 +216,6 @@ vn_open(ndp, fmode, cmode) goto bad; } } - if (fmode & O_TRUNC) { - VOP_UNLOCK(vp, 0, p); /* XXX */ - VOP_LEASE(vp, p, cred, LEASE_WRITE); - (void)vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */ - VATTR_NULL(vap); - vap->va_size = 0; - if (error = VOP_SETATTR(vp, vap, cred, p)) - goto bad; - } if (error = VOP_OPEN(vp, fmode, cred, p)) { goto bad; @@ -209,12 +224,14 @@ vn_open(ndp, fmode, cmode) if (fmode & FWRITE) if (++vp->v_writecount <= 0) panic("vn_open: v_writecount"); + *fmodep = fmode; return (0); bad: VOP_UNLOCK(vp, 0, p); if (didhold) ubc_rele(vp); vrele(vp); + ndp->ni_vp = NULL; return (error); } @@ -252,8 +269,17 @@ vn_close(vp, flags, cred, p) { int error; - if (flags & FWRITE) + if (flags & FWRITE) { + vp->v_writecount--; + + { + extern void notify_filemod_watchers(struct vnode *vp, struct proc *p); + + notify_filemod_watchers(vp, p); + } + } + error = VOP_CLOSE(vp, flags, cred, p); ubc_rele(vp); vrele(vp); @@ -555,7 +581,7 @@ vn_stat(vp, sb, p) sb->st_blksize = vap->va_blocksize; sb->st_flags = vap->va_flags; /* Do not give the generation number out to unpriviledged users */ - if (suser(p->p_ucred, &p->p_acflag)) + if (vap->va_gen && suser(p->p_ucred, &p->p_acflag)) sb->st_gen = 0; else sb->st_gen = vap->va_gen; @@ -688,3 +714,34 @@ vn_closefile(fp, p) return (vn_close(((struct vnode *)fp->f_data), fp->f_flag, fp->f_cred, p)); } + +static int +vn_kqfilt_add(fp, kn, p) + struct file *fp; + struct knote *kn; + struct proc *p; +{ + struct vnode *vp = (struct vnode *)fp->f_data; + int error; + + error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + if (error) return (error); + error = VOP_KQFILT_ADD(vp, kn, p); + (void)VOP_UNLOCK(vp, 0, p); + return (error); +} + +static int +vn_kqfilt_remove(vp, ident, p) + struct vnode *vp; + uintptr_t ident; + struct proc *p; +{ + int error; + + error = vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + if (error) return (error); + error = VOP_KQFILT_REMOVE(vp, ident, p); + (void)VOP_UNLOCK(vp, 0, p); + return (error); +}