vfs_syscalls.c

来自「基于组件方式开发操作系统的OSKIT源代码」· C语言 代码 · 共 2,115 行 · 第 1/4 页

C
2,115
字号
sys_unlink(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	struct sys_unlink_args /* {		syscallarg(char *) path;	} */ *uap = v;	register struct vnode *vp;	int error;	struct nameidata nd;	NDINIT(&nd, DELETE, LOCKPARENT | LOCKLEAF, UIO_USERSPACE,	    SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	vp = nd.ni_vp;	/*	 * The root of a mounted filesystem cannot be deleted.	 */	if (vp->v_flag & VROOT) {		VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);		if (nd.ni_dvp == vp)			vrele(nd.ni_dvp);		else			vput(nd.ni_dvp);		vput(vp);		error = EBUSY;		goto out;	}	(void)vnode_pager_uncache(vp);	VOP_LEASE(nd.ni_dvp, p, p->p_ucred, LEASE_WRITE);	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);out:	return (error);}/* * Reposition read/write file offset. */intsys_lseek(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_lseek_args /* {		syscallarg(int) fd;		syscallarg(int) pad;		syscallarg(off_t) offset;		syscallarg(int) whence;	} */ *uap = v;	struct ucred *cred = p->p_ucred;	register struct filedesc *fdp = p->p_fd;	register struct file *fp;	struct vattr vattr;	int error;	if ((u_int)SCARG(uap, fd) >= fdp->fd_nfiles ||	    (fp = fdp->fd_ofiles[SCARG(uap, fd)]) == NULL)		return (EBADF);	if (fp->f_type != DTYPE_VNODE)		return (ESPIPE);	switch (SCARG(uap, whence)) {	case L_INCR:		fp->f_offset += SCARG(uap, offset);		break;	case L_XTND:		error = VOP_GETATTR((struct vnode *)fp->f_data, &vattr,				    cred, p);		if (error)			return (error);		fp->f_offset = SCARG(uap, offset) + vattr.va_size;		break;	case L_SET:		fp->f_offset = SCARG(uap, offset);		break;	default:		return (EINVAL);	}	*(off_t *)retval = fp->f_offset;	return (0);}/* * Check access permissions. */intsys_access(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_access_args /* {		syscallarg(char *) path;		syscallarg(int) flags;	} */ *uap = v;	register struct ucred *cred = p->p_ucred;	register struct vnode *vp;	int error, flags, t_gid, t_uid;	struct nameidata nd;	t_uid = cred->cr_uid;	t_gid = cred->cr_gid;	cred->cr_uid = p->p_cred->p_ruid;	cred->cr_gid = p->p_cred->p_rgid;	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,	    SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		goto out1;	vp = nd.ni_vp;	/* Flags == 0 means only check for existence. */	if (SCARG(uap, flags)) {		flags = 0;		if (SCARG(uap, flags) & R_OK)			flags |= VREAD;		if (SCARG(uap, flags) & W_OK)			flags |= VWRITE;		if (SCARG(uap, flags) & X_OK)			flags |= VEXEC;		if ((flags & VWRITE) == 0 || (error = vn_writechk(vp)) == 0)			error = VOP_ACCESS(vp, flags, cred, p);	}	vput(vp);out1:	cred->cr_uid = t_uid;	cred->cr_gid = t_gid;	return (error);}/* * Get file status; this version follows links. *//* ARGSUSED */intsys_stat(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_stat_args /* {		syscallarg(char *) path;		syscallarg(struct stat *) ub;	} */ *uap = v;	struct stat sb;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,	    SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	error = vn_stat(nd.ni_vp, &sb, p);	vput(nd.ni_vp);	if (error)		return (error);	error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));	return (error);}/* * Get file status; this version does not follow links. *//* ARGSUSED */intsys_lstat(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_lstat_args /* {		syscallarg(char *) path;		syscallarg(struct stat *) ub;	} */ *uap = v;	struct stat sb;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,	    SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	error = vn_stat(nd.ni_vp, &sb, p);	vput(nd.ni_vp);	if (error)		return (error);	error = copyout((caddr_t)&sb, (caddr_t)SCARG(uap, ub), sizeof (sb));	return (error);}/* * Get configurable pathname variables. *//* ARGSUSED */intsys_pathconf(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_pathconf_args /* {		syscallarg(char *) path;		syscallarg(int) name;	} */ *uap = v;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE,	    SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	error = VOP_PATHCONF(nd.ni_vp, SCARG(uap, name), retval);	vput(nd.ni_vp);	return (error);}/* * Return target name of a symbolic link. *//* ARGSUSED */intsys_readlink(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_readlink_args /* {		syscallarg(char *) path;		syscallarg(char *) buf;		syscallarg(int) count;	} */ *uap = v;	register struct vnode *vp;	struct iovec aiov;	struct uio auio;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, NOFOLLOW | LOCKLEAF, UIO_USERSPACE,	    SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	vp = nd.ni_vp;	if (vp->v_type != VLNK)		error = EINVAL;	else {		aiov.iov_base = SCARG(uap, buf);		aiov.iov_len = SCARG(uap, count);		auio.uio_iov = &aiov;		auio.uio_iovcnt = 1;		auio.uio_offset = 0;		auio.uio_rw = UIO_READ;		auio.uio_segflg = UIO_USERSPACE;		auio.uio_procp = p;		auio.uio_resid = SCARG(uap, count);		error = VOP_READLINK(vp, &auio, p->p_ucred);	}	vput(vp);	*retval = SCARG(uap, count) - auio.uio_resid;	return (error);}/* * Change flags of a file given a path name. *//* ARGSUSED */intsys_chflags(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_chflags_args /* {		syscallarg(char *) path;		syscallarg(int) flags;	} */ *uap = v;	register struct vnode *vp;	struct vattr vattr;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	vp = nd.ni_vp;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		VATTR_NULL(&vattr);		vattr.va_flags = SCARG(uap, flags);		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}	vput(vp);	return (error);}/* * Change flags of a file given a file descriptor. *//* ARGSUSED */intsys_fchflags(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_fchflags_args /* {		syscallarg(int) fd;		syscallarg(int) flags;	} */ *uap = v;	struct vattr vattr;	struct vnode *vp;	struct file *fp;	int error;	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)		return (error);	vp = (struct vnode *)fp->f_data;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		VATTR_NULL(&vattr);		vattr.va_flags = SCARG(uap, flags);		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}	VOP_UNLOCK(vp);	return (error);}/* * Change mode of a file given path name. *//* ARGSUSED */intsys_chmod(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_chmod_args /* {		syscallarg(char *) path;		syscallarg(int) mode;	} */ *uap = v;	register struct vnode *vp;	struct vattr vattr;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	vp = nd.ni_vp;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		VATTR_NULL(&vattr);		vattr.va_mode = SCARG(uap, mode) & ALLPERMS;		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}	vput(vp);	return (error);}/* * Change mode of a file given a file descriptor. *//* ARGSUSED */intsys_fchmod(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_fchmod_args /* {		syscallarg(int) fd;		syscallarg(int) mode;	} */ *uap = v;	struct vattr vattr;	struct vnode *vp;	struct file *fp;	int error;	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)		return (error);	vp = (struct vnode *)fp->f_data;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		VATTR_NULL(&vattr);		vattr.va_mode = SCARG(uap, mode) & ALLPERMS;		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}	VOP_UNLOCK(vp);	return (error);}/* * Set ownership given a path name. *//* ARGSUSED */intsys_chown(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_chown_args /* {		syscallarg(char *) path;		syscallarg(int) uid;		syscallarg(int) gid;	} */ *uap = v;	register struct vnode *vp;	struct vattr vattr;	int error;	struct nameidata nd;	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	vp = nd.ni_vp;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		VATTR_NULL(&vattr);		vattr.va_uid = SCARG(uap, uid);		vattr.va_gid = SCARG(uap, gid);		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}	vput(vp);	return (error);}/* * Set ownership given a file descriptor. *//* ARGSUSED */intsys_fchown(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_fchown_args /* {		syscallarg(int) fd;		syscallarg(int) uid;		syscallarg(int) gid;	} */ *uap = v;	register struct vnode *vp;	struct vattr vattr;	int error;	struct file *fp;	if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0)		return (error);	vp = (struct vnode *)fp->f_data;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		VATTR_NULL(&vattr);		vattr.va_uid = SCARG(uap, uid);		vattr.va_gid = SCARG(uap, gid);		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}	VOP_UNLOCK(vp);	return (error);}/* * Set the access and modification times given a path name. *//* ARGSUSED */intsys_utimes(p, v, retval)	struct proc *p;	void *v;	register_t *retval;{	register struct sys_utimes_args /* {		syscallarg(char *) path;		syscallarg(struct timeval *) tptr;	} */ *uap = v;	register struct vnode *vp;	struct timeval tv[2];	struct vattr vattr;	int error;	struct nameidata nd;	VATTR_NULL(&vattr);	if (SCARG(uap, tptr) == NULL) {		microtime(&tv[0]);		tv[1] = tv[0];		vattr.va_vaflags |= VA_UTIMES_NULL;	} else {		error = copyin((caddr_t)SCARG(uap, tptr), (caddr_t)tv,			       sizeof (tv));		if (error)			return (error);	}	NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, SCARG(uap, path), p);	if ((error = namei(&nd)) != 0)		return (error);	vp = nd.ni_vp;	VOP_LEASE(vp, p, p->p_ucred, LEASE_WRITE);	VOP_LOCK(vp);	if (vp->v_mount->mnt_flag & MNT_RDONLY)		error = EROFS;	else {		vattr.va_atime.tv_sec = tv[0].tv_sec;		vattr.va_atime.tv_nsec = tv[0].tv_usec * 1000;		vattr.va_mtime.tv_sec = tv[1].tv_sec;		vattr.va_mtime.tv_nsec = tv[1].tv_usec * 1000;		error = VOP_SETATTR(vp, &vattr, p->p_ucred, p);	}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?