Пример #1
0
static int
ufs_open_namei(uufsd_t *ufs, ino_t root, ino_t base, const char *path, int pathlen,
		ino_t *res_inode)
{
	int retval, namelen;
	const char *base_name;
	ino_t dir, inode;

	retval = ufs_dir_namei(ufs, root, base, path, pathlen, &base_name, &namelen, &dir);
	if (retval) return retval;

	if (!namelen) {
		*res_inode = dir;
		return 0;
	}

	retval = ufs_lookup(ufs, dir, base_name, namelen, &inode);

	if (retval) {
		*res_inode = 0;
	} else {
		*res_inode = inode;
	}
	return retval;
}
Пример #2
0
static int
ufs_dir_namei(uufsd_t *ufs, ino_t root, ino_t dir, const char *pathname, int pathlen,
		const char **name, int *namelen,
		ino_t *res_ino)
{
	char c;
	const char *thisname;
	int len;
	ino_t inode;
	int retval;

	if ((c = *pathname) == '/') {
		dir = root;
		pathname++;
		pathlen--;
	}
	while (1) {
		thisname = pathname;
		for (len=0; --pathlen >= 0;len++) {
			c = *(pathname++);
			if (c == '/')
				break;
		}
		if (pathlen < 0)
			break;
		retval = ufs_lookup (ufs, dir, thisname, len, &inode);
		if (retval) return retval;
		dir = inode;
	}
	*name = thisname;
	*namelen = len;
	*res_ino = dir;
	return 0;
}
Пример #3
0
/*
 * look-up a file in absolute pathname from the root directory
 */
ino32_t
ufs_lookup_path(const char *path)
{
	char fn[FFS_MAXNAMLEN + 1];
	char *p;
	ino32_t ino = UFS_ROOTINO;

	do {
		while (*path == '/')
			path++;
		for (p = fn; *path && *path != '/'; )
			*p++ = *path++;
		*p++ = '\0';
		ino = ufs_lookup(ino, fn);
	} while (ino && *path);

	return ino;
}
Пример #4
0
static int
ufs_extattr_lookup(struct vnode *start_dvp, int lockparent, char *dirname,
    struct vnode **vp, struct thread *td)
{
	struct vop_cachedlookup_args vargs;
	struct componentname cnp;
	struct vnode *target_vp;
	int error;

	bzero(&cnp, sizeof(cnp));
	cnp.cn_nameiop = LOOKUP;
	cnp.cn_flags = ISLASTCN;
	if (lockparent == UE_GETDIR_LOCKPARENT)
		cnp.cn_flags |= LOCKPARENT;
	cnp.cn_lkflags = LK_EXCLUSIVE;
	cnp.cn_thread = td;
	cnp.cn_cred = td->td_ucred;
	cnp.cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
	cnp.cn_nameptr = cnp.cn_pnbuf;
	error = copystr(dirname, cnp.cn_pnbuf, MAXPATHLEN,
	    (size_t *) &cnp.cn_namelen);
	if (error) {
		if (lockparent == UE_GETDIR_LOCKPARENT_DONT) {
			VOP_UNLOCK(start_dvp, 0);
		}
		uma_zfree(namei_zone, cnp.cn_pnbuf);
		printf("ufs_extattr_lookup: copystr failed\n");
		return (error);
	}
	cnp.cn_namelen--;	/* trim nul termination */
	vargs.a_gen.a_desc = NULL;
	vargs.a_dvp = start_dvp;
	vargs.a_vpp = &target_vp;
	vargs.a_cnp = &cnp;
	error = ufs_lookup(&vargs);
	uma_zfree(namei_zone, cnp.cn_pnbuf);
	if (error) {
		/*
		 * Error condition, may have to release the lock on the parent
		 * if ufs_lookup() didn't.
		 */
		if (lockparent == UE_GETDIR_LOCKPARENT_DONT)
			VOP_UNLOCK(start_dvp, 0);

		/*
		 * Check that ufs_lookup() didn't release the lock when we
		 * didn't want it to.
		 */
		if (lockparent == UE_GETDIR_LOCKPARENT)
			ASSERT_VOP_LOCKED(start_dvp, "ufs_extattr_lookup");

		return (error);
	}
/*
	if (target_vp == start_dvp)
		panic("ufs_extattr_lookup: target_vp == start_dvp");
*/

	if (target_vp != start_dvp && lockparent == UE_GETDIR_LOCKPARENT_DONT)
		VOP_UNLOCK(start_dvp, 0);

	if (lockparent == UE_GETDIR_LOCKPARENT)
		ASSERT_VOP_LOCKED(start_dvp, "ufs_extattr_lookup");

	/* printf("ufs_extattr_lookup: success\n"); */
	*vp = target_vp;
	return (0);
}
Пример #5
0
static int ufs_mkdir(uufsd_t *ufs, ino_t parent, ino_t inum, char *name)
{
	int		retval;
	struct ufs_vnode	*parent_vnode = NULL, *vnode = NULL;
	struct inode *parent_inode, *inode;
	ino_t		ino = inum;
	ino_t		scratch_ino;
	ufs2_daddr_t		blk;
	char			*block = 0;
	struct fs *fs = &ufs->d_fs;
	int dirsize = DIRBLKSIZ;
	int blocksize = fragroundup(fs, dirsize);

	parent_vnode = vnode_get(ufs, parent);
	if (!parent_vnode) {
		return ENOENT;
	}

	parent_inode = vnode2inode(parent_vnode);
	/*
	 * Allocate an inode, if necessary
	 */
	if (!ino) {
		retval = ufs_valloc(parent_vnode, DTTOIF(DT_DIR), &vnode);
		if (retval)
			goto cleanup;
		ino = vnode->inode.i_number;
		inode = vnode2inode(vnode);
	}

	/*
	 * Allocate a data block for the directory
	 */
	retval = ufs_block_alloc(ufs, inode, fragroundup(fs, dirsize), &blk);
	if (retval)
		goto cleanup;

	/*
	 * Create a scratch template for the directory
	 */
	retval = ufs_new_dir_block(ufs, vnode->inode.i_number, parent_vnode, &block);
	if (retval)
		goto cleanup;

	/*
	 * Get the parent's inode, if necessary
	if (parent != ino) {
		parent_vnode = vnode_get(ufs, parent);
		if (retval)
			goto cleanup;
	} else
		memset(&parent_inode, 0, sizeof(parent_inode));
	 */

	/*
	 * Create the inode structure....
	 */
	inode->i_mode = DT_DIR | (0777);
	inode->i_uid = inode->i_gid = 0;
	UFS_DINODE(inode)->di_db[0] = blk;
	inode->i_nlink = 1;
	inode->i_size = dirsize;

	/*
	 * Write out the inode and inode data block
	 */
	retval = blkwrite(ufs, fsbtodb(fs, blk), block, blocksize);
	if (retval == -1)
		goto cleanup;

	/*
	 * Link the directory into the filesystem hierarchy
	 */
	if (name) {
		retval = ufs_lookup(ufs, parent, name, strlen(name),
				       &scratch_ino);
		if (!retval) {
			retval = EEXIST;
			name = 0;
			goto cleanup;
		}
		if (retval != ENOENT)
			goto cleanup;
		retval = ufs_link(ufs, parent, name, vnode, DTTOIF(DT_DIR));
		if (retval)
			goto cleanup;
	}

	/*
	 * Update parent inode's counts
	 */
	if (parent != ino) {
		parent_inode->i_nlink++;
	}

cleanup:
	if (vnode)
		vnode_put(vnode, 1);

	if (parent_vnode)
		vnode_put(parent_vnode, 1);
	if (block)
		ufs_free_mem(&block);
	return retval;


}
Пример #6
0
static int
ufs_extattr_lookup(struct vnode *start_dvp, int lockparent, char *dirname,
    struct vnode **vp, struct proc *p)
{
	struct vop_lookup_args vargs;
	struct componentname cnp;
	struct vnode *target_vp;
	int error;

	bzero(&cnp, sizeof(cnp));
	cnp.cn_nameiop = LOOKUP;
	cnp.cn_flags = ISLASTCN;
	if (lockparent == UE_GETDIR_LOCKPARENT)
		cnp.cn_flags |= LOCKPARENT;
	cnp.cn_proc = p;
	cnp.cn_cred = p->p_ucred;
	MALLOC(cnp.cn_pnbuf, char *, MAXPATHLEN, M_NAMEI, M_WAITOK);

	cnp.cn_nameptr = cnp.cn_pnbuf;
	error = copystr(dirname, cnp.cn_pnbuf, MAXPATHLEN,
	    (size_t *) &cnp.cn_namelen);
	if (error) {
		if (lockparent == UE_GETDIR_LOCKPARENT_DONT) {
			VOP_UNLOCK(start_dvp, 0, p);
		}
		FREE(cnp.cn_pnbuf, M_NAMEI);
		printf("ufs_extattr_lookup: copystr failed\n");
		return (error);
	}
	cnp.cn_namelen--;	/* trim nul termination */
	vargs.a_desc = NULL;
	vargs.a_dvp = start_dvp;
	vargs.a_vpp = &target_vp;
	vargs.a_cnp = &cnp;
	error = ufs_lookup(&vargs);
	FREE(cnp.cn_pnbuf, M_NAMEI);

	if (error) {
		/*
		 * Error condition, may have to release the lock on the parent
		 * if ufs_lookup() didn't.
		 */
		if(lockparent == UE_GETDIR_LOCKPARENT_DONT)
			VOP_UNLOCK(start_dvp, 0, p);

#if 0
	/* -XXX does OpenBSD ufs_lookup always unlock on error? */
		/*
		 * Check that ufs_lookup() didn't release the lock when we
		 * didn't want it to.
		 */
		if ((cnp.cn_flags & PDIRUNLOCK) &&
		    (lockparent == UE_GETDIR_LOCKPARENT))
			panic("ufs_extattr_lookup: lockparent but PDIRUNLOCK");
#endif

		return (error);
	}
/*
	if (target_vp == start_dvp)
		panic("ufs_extattr_lookup: target_vp == start_dvp");
*/

#if 0
	/* PDIRUNLOCK does not exist on OpenBSD */
	if (target_vp != start_dvp &&
	    !(cnp.cn_flags & PDIRUNLOCK) &&
	    (lockparent == UE_GETDIR_LOCKPARENT_DONT))
		panic("ufs_extattr_lookup: !lockparent but !PDIRUNLOCK");

	if ((cnp.cn_flags & PDIRUNLOCK) &&
	    (lockparent == UE_GETDIR_LOCKPARENT))
		panic("ufs_extattr_lookup: lockparent but PDIRUNLOCK");
#endif

	/* printf("ufs_extattr_lookup: success\n"); */
	*vp = target_vp;
	return (0);
}