Esempio n. 1
0
/*
 * unionfs_lookup is the only special function which takes a dentry, yet we
 * do NOT want to call __unionfs_d_revalidate_chain because by definition,
 * we don't have a valid dentry here yet.
 */
static struct dentry *unionfs_lookup(struct inode *dir,
				     struct dentry *dentry,
				     /* XXX: pass flags to lower? */
				     unsigned int flags_unused)
{
	struct dentry *ret, *parent;
	int err = 0;

	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_CHILD);
	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);

	/*
	 * As long as we lock/dget the parent, then can skip validating the
	 * parent now; we may have to rebuild this dentry on the next
	 * ->d_revalidate, however.
	 */

	/* allocate dentry private data.  We free it in ->d_release */
	err = new_dentry_private_data(dentry, UNIONFS_DMUTEX_CHILD);
	if (unlikely(err)) {
		ret = ERR_PTR(err);
		goto out;
	}

	ret = unionfs_lookup_full(dentry, parent, INTERPOSE_LOOKUP);

	if (!IS_ERR(ret)) {
		if (ret)
			dentry = ret;
		/* lookup_full can return multiple positive dentries */
		if (dentry->d_inode && !S_ISDIR(dentry->d_inode->i_mode)) {
			BUG_ON(dbstart(dentry) < 0);
			unionfs_postcopyup_release(dentry);
		}
		unionfs_copy_attr_times(dentry->d_inode);
	}

	unionfs_check_inode(dir);
	if (!IS_ERR(ret))
		unionfs_check_dentry(dentry);
	unionfs_check_dentry(parent);
	unionfs_unlock_dentry(dentry); /* locked in new_dentry_private data */

out:
	unionfs_unlock_parent(dentry, parent);
	unionfs_read_unlock(dentry->d_sb);

	return ret;
}
Esempio n. 2
0
/*
 * This is a utility function that fills in a unionfs dentry.
 * Caller must lock this dentry with unionfs_lock_dentry.
 *
 * Returns: 0 (ok), or -ERRNO if an error occurred.
 * XXX: get rid of _partial_lookup and make callers call _lookup_full directly
 */
int unionfs_partial_lookup(struct dentry *dentry, struct dentry *parent)
{
	struct dentry *tmp;
	int err = -ENOSYS;

	tmp = unionfs_lookup_full(dentry, parent, INTERPOSE_PARTIAL);

	if (!tmp) {
		err = 0;
		goto out;
	}
	if (IS_ERR(tmp)) {
		err = PTR_ERR(tmp);
		goto out;
	}
	/* XXX: need to change the interface */
	BUG_ON(tmp != dentry);
out:
	return err;
}