Example #1
0
struct inode *ovl_d_select_inode(struct dentry *dentry, unsigned file_flags)
{
	int err;
	struct path realpath;
	enum ovl_path_type type;

	if (d_is_dir(dentry))
		return d_backing_inode(dentry);

	type = ovl_path_real(dentry, &realpath);
	if (ovl_open_need_copy_up(file_flags, type, realpath.dentry)) {
		err = ovl_want_write(dentry);
		if (err)
			return ERR_PTR(err);

		if (file_flags & O_TRUNC)
			err = ovl_copy_up_truncate(dentry);
		else
			err = ovl_copy_up(dentry);
		ovl_drop_write(dentry);
		if (err)
			return ERR_PTR(err);

		ovl_path_upper(dentry, &realpath);
	}

	if (realpath.dentry->d_flags & DCACHE_OP_SELECT_INODE)
		return realpath.dentry->d_op->d_select_inode(realpath.dentry, file_flags);

	return d_backing_inode(realpath.dentry);
}
Example #2
0
static struct file *ovl_open(struct dentry *dentry, struct file *file,
			     const struct cred *cred)
{
	int err;
	struct path realpath;
	enum ovl_path_type type;

	type = ovl_path_real(dentry, &realpath);
	if (ovl_open_need_copy_up(file->f_flags, type, realpath.dentry)) {
		if (file->f_flags & O_TRUNC)
			err = ovl_copy_up_truncate(dentry, 0);
		else
			err = ovl_copy_up(dentry);
		if (err)
			return ERR_PTR(err);

		ovl_path_upper(dentry, &realpath);
	}

	return vfs_open(&realpath, file, cred);
}
Example #3
0
int ovl_setattr(struct dentry *dentry, struct iattr *attr)
{
	struct dentry *upperdentry;
	int err;

	if ((attr->ia_valid & ATTR_SIZE) && !ovl_dentry_upper(dentry))
		err = ovl_copy_up_truncate(dentry, attr->ia_size);
	else
		err = ovl_copy_up(dentry);
	if (err)
		return err;

	upperdentry = ovl_dentry_upper(dentry);

	if (attr->ia_valid & (ATTR_KILL_SUID|ATTR_KILL_SGID))
		attr->ia_valid &= ~ATTR_MODE;

	mutex_lock(&upperdentry->d_inode->i_mutex);
	err = notify_change(upperdentry, attr);
	mutex_unlock(&upperdentry->d_inode->i_mutex);

	return err;
}