Пример #1
0
int
sysvbfs_create(void *arg)
{
	struct vop_create_args /* {
		struct vnode *a_dvp;
		struct vnode **a_vpp;
		struct componentname *a_cnp;
		struct vattr *a_vap;
	} */ *a = arg;
	struct sysvbfs_node *bnode = a->a_dvp->v_data;
	struct sysvbfs_mount *bmp = bnode->bmp;
	struct bfs *bfs = bmp->bfs;
	struct mount *mp = bmp->mountp;
	struct bfs_dirent *dirent;
	struct bfs_fileattr attr;
	struct vattr *va = a->a_vap;
	kauth_cred_t cr = a->a_cnp->cn_cred;
	int err = 0;

	DPRINTF("%s: %s\n", __func__, a->a_cnp->cn_nameptr);
	KDASSERT(a->a_vap->va_type == VREG);
	attr.uid = kauth_cred_geteuid(cr);
	attr.gid = kauth_cred_getegid(cr);
	attr.mode = va->va_mode;

	if ((err = bfs_file_create(bfs, a->a_cnp->cn_nameptr, 0, 0, &attr))
	    != 0) {
		DPRINTF("%s: bfs_file_create failed.\n", __func__);
		goto unlock_exit;
	}

	if (!bfs_dirent_lookup_by_name(bfs, a->a_cnp->cn_nameptr, &dirent))
		panic("no dirent for created file.");

	if ((err = sysvbfs_vget(mp, dirent->inode, a->a_vpp)) != 0) {
		DPRINTF("%s: sysvbfs_vget failed.\n", __func__);
		goto unlock_exit;
	}
	bnode = (*a->a_vpp)->v_data;
	bnode->update_ctime = true;
	bnode->update_mtime = true;
	bnode->update_atime = true;

 unlock_exit:
	/* unlock parent directory */
	vput(a->a_dvp);	/* locked at sysvbfs_lookup(); */

	return err;
}
Пример #2
0
int
sysvbfs_lookup(void *arg)
{
	struct vop_lookup_v2_args /* {
		struct vnode *a_dvp;
		struct vnode **a_vpp;
		struct componentname *a_cnp;
	} */ *a = arg;
	struct vnode *v = a->a_dvp;
	struct sysvbfs_node *bnode = v->v_data;
	struct bfs *bfs = bnode->bmp->bfs;	/* my filesystem */
	struct vnode *vpp = NULL;
	struct bfs_dirent *dirent = NULL;
	struct componentname *cnp = a->a_cnp;
	int nameiop = cnp->cn_nameiop;
	const char *name = cnp->cn_nameptr;
	int namelen = cnp->cn_namelen;
	int error;

	DPRINTF("%s: %s op=%d %d\n", __func__, name, nameiop,
	    cnp->cn_flags);

	*a->a_vpp = NULL;

	KASSERT((cnp->cn_flags & ISDOTDOT) == 0);

	if ((error = VOP_ACCESS(a->a_dvp, VEXEC, cnp->cn_cred)) != 0) {
		return error;	/* directory permission. */
	}

	/* Deny last component write operation on a read-only mount */
	if ((cnp->cn_flags & ISLASTCN) && (v->v_mount->mnt_flag & MNT_RDONLY) &&
	    (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
		return EROFS;

	if (namelen == 1 && name[0] == '.') {	/* "." */
		vref(v);
		*a->a_vpp = v;
	} else {				/* Regular file */
		if (!bfs_dirent_lookup_by_name(bfs, cnp->cn_nameptr,
		    &dirent)) {
			if (nameiop != CREATE && nameiop != RENAME) {
				DPRINTF("%s: no such a file. (1)\n",
				    __func__);
				return ENOENT;
			}
			if ((error = VOP_ACCESS(v, VWRITE, cnp->cn_cred)) != 0)
				return error;
			return EJUSTRETURN;
		}

		/* Allocate v-node */
		if ((error = sysvbfs_vget(v->v_mount, dirent->inode, &vpp)) != 0) {
			DPRINTF("%s: can't get vnode.\n", __func__);
			return error;
		}
		VOP_UNLOCK(vpp);
		*a->a_vpp = vpp;
	}

	return 0;
}