Esempio n. 1
0
File: dir.c Progetto: gxt/linux
static struct dentry *ovl_check_empty_and_clear(struct dentry *dentry)
{
	int err;
	struct dentry *ret = NULL;
	enum ovl_path_type type = ovl_path_type(dentry);
	LIST_HEAD(list);

	err = ovl_check_empty_dir(dentry, &list);
	if (err) {
		ret = ERR_PTR(err);
		goto out_free;
	}

	/*
	 * When removing an empty opaque directory, then it makes no sense to
	 * replace it with an exact replica of itself.
	 *
	 * If no upperdentry then skip clearing whiteouts.
	 *
	 * Can race with copy-up, since we don't hold the upperdir mutex.
	 * Doesn't matter, since copy-up can't create a non-empty directory
	 * from an empty one.
	 */
	if (OVL_TYPE_UPPER(type) && OVL_TYPE_MERGE(type))
		ret = ovl_clear_empty(dentry, &list);

out_free:
	ovl_cache_free(&list);

	return ret;
}
Esempio n. 2
0
int ovl_removexattr(struct dentry *dentry, const char *name)
{
	int err;
	struct path realpath;
	enum ovl_path_type type = ovl_path_real(dentry, &realpath);

	err = ovl_want_write(dentry);
	if (err)
		goto out;

	err = -ENODATA;
	if (ovl_need_xattr_filter(dentry, type) && ovl_is_private_xattr(name))
		goto out_drop_write;

	if (!OVL_TYPE_UPPER(type)) {
		err = vfs_getxattr(realpath.dentry, name, NULL, 0);
		if (err < 0)
			goto out_drop_write;

		err = ovl_copy_up(dentry);
		if (err)
			goto out_drop_write;

		ovl_path_upper(dentry, &realpath);
	}

	err = vfs_removexattr(realpath.dentry, name);
out_drop_write:
	ovl_drop_write(dentry);
out:
	return err;
}
Esempio n. 3
0
File: super.c Progetto: cshzc/linux
enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
{
	enum ovl_path_type type = ovl_path_type(dentry);

	if (!OVL_TYPE_UPPER(type))
		ovl_path_lower(dentry, path);
	else
		ovl_path_upper(dentry, path);

	return type;
}
Esempio n. 4
0
int ovl_xattr_set(struct dentry *dentry, const char *name, const void *value,
		  size_t size, int flags)
{
	int err;
	struct path realpath;
	enum ovl_path_type type = ovl_path_real(dentry, &realpath);
	const struct cred *old_cred;

	err = ovl_want_write(dentry);
	if (err)
		goto out;

	if (!value && !OVL_TYPE_UPPER(type)) {
		err = vfs_getxattr(realpath.dentry, name, NULL, 0);
		if (err < 0)
			goto out_drop_write;
	}

	err = ovl_copy_up(dentry);
	if (err)
		goto out_drop_write;

	if (!OVL_TYPE_UPPER(type))
		ovl_path_upper(dentry, &realpath);

	old_cred = ovl_override_creds(dentry->d_sb);
	if (value)
		err = vfs_setxattr(realpath.dentry, name, value, size, flags);
	else {
		WARN_ON(flags != XATTR_REPLACE);
		err = vfs_removexattr(realpath.dentry, name);
	}
	revert_creds(old_cred);

out_drop_write:
	ovl_drop_write(dentry);
out:
	return err;
}
Esempio n. 5
0
static bool ovl_open_need_copy_up(int flags, enum ovl_path_type type,
				  struct dentry *realdentry)
{
	if (OVL_TYPE_UPPER(type))
		return false;

	if (special_file(realdentry->d_inode->i_mode))
		return false;

	if (!(OPEN_FMODE(flags) & FMODE_WRITE) && !(flags & O_TRUNC))
		return false;

	return true;
}