* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* %sccs.include.redist.c%
* @(#)vfs_vnops.c 7.29 (Berkeley) %G%
{ vn_read
, vn_write
, vn_ioctl
, vn_select
, vn_close
};
* Common code for vnode open operations.
* Check permissions, and call the VOP_OPEN or VOP_CREATE routine.
vn_open(ndp
, p
, fmode
, cmode
)
register struct nameidata
*ndp
;
register struct vnode
*vp
;
register struct ucred
*cred
= p
->p_ucred
;
struct vattr
*vap
= &vat
;
ndp
->ni_nameiop
= CREATE
| LOCKPARENT
| LOCKLEAF
;
if ((fmode
& FEXCL
) == 0)
ndp
->ni_nameiop
|= FOLLOW
;
if (error
= namei(ndp
, p
))
if (ndp
->ni_vp
== NULL
) {
if (error
= VOP_CREATE(ndp
, vap
, p
))
if (ndp
->ni_dvp
== ndp
->ni_vp
)
ndp
->ni_nameiop
= LOOKUP
| FOLLOW
| LOCKLEAF
;
if (error
= namei(ndp
, p
))
if (vp
->v_type
== VSOCK
) {
if ((fmode
& FCREAT
) == 0) {
if (error
= VOP_ACCESS(vp
, VREAD
, cred
, p
))
if (fmode
& (FWRITE
|FTRUNC
)) {
if (vp
->v_type
== VDIR
) {
if ((error
= vn_writechk(vp
)) ||
(error
= VOP_ACCESS(vp
, VWRITE
, cred
, p
)))
if (error
= VOP_SETATTR(vp
, vap
, cred
, p
))
error
= VOP_OPEN(vp
, fmode
, cred
, p
);
* Check for write permissions on the specified vnode.
* The read-only status of the file system is checked.
* Also, prototype text segments cannot be written.
register struct vnode
*vp
;
* Disallow write attempts on read-only file systems;
* unless the file is a socket or a block or character
* device resident on the file system.
if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) {
case VREG
: case VDIR
: case VLNK
:
* If there's shared text associated with
* the vnode, try to free it up once. If
* we fail, we can't allow writing.
if ((vp
->v_flag
& VTEXT
) && !vnode_pager_uncache(vp
))
* Vnode version of rdwri() for calls on file systems.
vn_rdwr(rw
, vp
, base
, len
, offset
, segflg
, ioflg
, cred
, aresid
, p
)
if ((ioflg
& IO_NODELOCKED
) == 0)
auio
.uio_offset
= offset
;
auio
.uio_segflg
= segflg
;
error
= VOP_READ(vp
, &auio
, ioflg
, cred
);
error
= VOP_WRITE(vp
, &auio
, ioflg
, cred
);
*aresid
= auio
.uio_resid
;
if (auio
.uio_resid
&& error
== 0)
if ((ioflg
& IO_NODELOCKED
) == 0)
register struct vnode
*vp
= (struct vnode
*)fp
->f_data
;
uio
->uio_offset
= fp
->f_offset
;
error
= VOP_READ(vp
, uio
, (fp
->f_flag
& FNDELAY
) ? IO_NDELAY
: 0, cred
);
fp
->f_offset
+= count
- uio
->uio_resid
;
register struct vnode
*vp
= (struct vnode
*)fp
->f_data
;
int count
, error
, ioflag
= 0;
if (vp
->v_type
== VREG
&& (fp
->f_flag
& FAPPEND
))
if (fp
->f_flag
& FNDELAY
)
uio
->uio_offset
= fp
->f_offset
;
error
= VOP_WRITE(vp
, uio
, ioflag
, cred
);
fp
->f_offset
= uio
->uio_offset
;
fp
->f_offset
+= count
- uio
->uio_resid
;
* Get stat info for a vnode.
register struct stat
*sb
;
register struct vattr
*vap
;
error
= VOP_GETATTR(vp
, vap
, p
->p_ucred
, p
);
sb
->st_dev
= vap
->va_fsid
;
sb
->st_ino
= vap
->va_fileid
;
sb
->st_nlink
= vap
->va_nlink
;
sb
->st_uid
= vap
->va_uid
;
sb
->st_gid
= vap
->va_gid
;
sb
->st_rdev
= vap
->va_rdev
;
sb
->st_size
= vap
->va_size
;
sb
->st_atime
= vap
->va_atime
.tv_sec
;
sb
->st_mtime
= vap
->va_mtime
.tv_sec
;
sb
->st_ctime
= vap
->va_ctime
.tv_sec
;
sb
->st_blksize
= vap
->va_blocksize
;
sb
->st_flags
= vap
->va_flags
;
sb
->st_gen
= vap
->va_gen
;
sb
->st_blocks
= vap
->va_bytes
/ S_BLKSIZE
;
vn_ioctl(fp
, com
, data
, p
)
register struct vnode
*vp
= ((struct vnode
*)fp
->f_data
);
if (error
= VOP_GETATTR(vp
, &vattr
, p
->p_ucred
, p
))
*(off_t
*)data
= vattr
.va_size
- fp
->f_offset
;
if (com
== FIONBIO
|| com
== FIOASYNC
) /* XXX */
error
= VOP_IOCTL(vp
, com
, data
, fp
->f_flag
, p
->p_ucred
, p
);
if (error
== 0 && com
== TIOCSCTTY
) {
p
->p_session
->s_ttyvp
= vp
;
return (VOP_SELECT(((struct vnode
*)fp
->f_data
), which
, fp
->f_flag
,
register struct file
*fp
;
struct vnode
*vp
= ((struct vnode
*)fp
->f_data
);
* Must delete vnode reference from this file entry
* before VOP_CLOSE, so that only other references
fp
->f_data
= (caddr_t
) 0;
error
= VOP_CLOSE(vp
, fp
->f_flag
, fp
->f_cred
, p
);
* vn_fhtovp() - convert a fh to a vnode ptr (optionally locked)
* - look up fsid in mount list (if not found ret error)
* - get vp by calling VFS_FHTOVP() macro
* - if lockflag lock it with VOP_LOCK()
vn_fhtovp(fhp
, lockflag
, vpp
)
register struct mount
*mp
;
if ((mp
= getvfs(&fhp
->fh_fsid
)) == NULL
)
if (VFS_FHTOVP(mp
, &fhp
->fh_fid
, vpp
))