Example #1
0
static ssize_t unionfs_splice_write(struct pipe_inode_info *pipe,
				    struct file *file, loff_t *ppos,
				    size_t len, unsigned int flags)
{
	ssize_t err = 0;
	struct file *lower_file;
	struct dentry *dentry = file->f_path.dentry;
	struct dentry *parent;

	unionfs_read_lock(dentry->d_sb, UNIONFS_SMUTEX_PARENT);
	parent = unionfs_lock_parent(dentry, UNIONFS_DMUTEX_PARENT);
	unionfs_lock_dentry(dentry, UNIONFS_DMUTEX_CHILD);

	err = unionfs_file_revalidate(file, parent, true);
	if (unlikely(err))
		goto out;

	lower_file = unionfs_lower_file(file);
	err = vfs_splice_from(pipe, lower_file, ppos, len, flags);
	/* update our inode times+sizes upon a successful lower write */
	if (err >= 0) {
		fsstack_copy_inode_size(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
		fsstack_copy_attr_times(dentry->d_inode,
					lower_file->f_path.dentry->d_inode);
		unionfs_check_file(file);
	}

out:
	unionfs_unlock_dentry(dentry);
	unionfs_unlock_parent(dentry, parent);
	unionfs_read_unlock(dentry->d_sb);
	return err;
}
Example #2
0
long do_vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
			  loff_t *ppos, size_t len, unsigned int flags)
{
	long err;

	LKTRTrace("%.*s, pos %lld, len %zu, 0x%x\n",
		  AuDLNPair(out->f_dentry), *ppos, len, flags);

	lockdep_off();
	err = vfs_splice_from(pipe, out, ppos, len, flags);
	lockdep_on();
	if (err >= 0)
		au_update_fuse_h_inode(out->f_vfsmnt, out->f_dentry); /*ignore*/
	return err;
}