예제 #1
0
static ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
				     struct file *filp, loff_t *ppos,
				     size_t count, unsigned int flags)
{
	struct dentry *dentry = filp->f_path.dentry;
	struct inode *inode = dentry->d_inode;
	ssize_t ret;

	dprintk("NFS splice_write(%s/%s, %lu@%llu)\n",
		dentry->d_parent->d_name.name, dentry->d_name.name,
		(unsigned long) count, (unsigned long long) *ppos);

	/*
	 * The combination of splice and an O_APPEND destination is disallowed.
	 */

	nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, count);

	ret = generic_file_splice_write(pipe, filp, ppos, count, flags);
	if (ret >= 0 && nfs_need_sync_write(filp, inode)) {
		int err = nfs_do_fsync(nfs_file_open_context(filp), inode);
		if (err < 0)
			ret = err;
	}
	return ret;
}
예제 #2
0
파일: file.c 프로젝트: LBSHackathon/linux
ssize_t nfs_file_write(struct kiocb *iocb, struct iov_iter *from)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	unsigned long written = 0;
	ssize_t result;
	size_t count = iov_iter_count(from);

	result = nfs_key_timeout_notify(file, inode);
	if (result)
		return result;

	if (iocb->ki_flags & IOCB_DIRECT) {
		result = generic_write_checks(iocb, from);
		if (result <= 0)
			return result;
		return nfs_file_direct_write(iocb, from);
	}

	dprintk("NFS: write(%pD2, %zu@%Ld)\n",
		file, count, (long long) iocb->ki_pos);

	result = -EBUSY;
	if (IS_SWAPFILE(inode))
		goto out_swapfile;
	/*
	 * O_APPEND implies that we must revalidate the file length.
	 */
	if (iocb->ki_flags & IOCB_APPEND) {
		result = nfs_revalidate_file_size(inode, file);
		if (result)
			goto out;
	}

	result = count;
	if (!count)
		goto out;

	result = generic_file_write_iter(iocb, from);
	if (result > 0)
		written = result;

	/* Return error values for O_DSYNC and IS_SYNC() */
	if (result >= 0 && nfs_need_sync_write(file, inode)) {
		int err = vfs_fsync(file, 0);
		if (err < 0)
			result = err;
	}
	if (result > 0)
		nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
out:
	return result;

out_swapfile:
	printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
	goto out;
}
예제 #3
0
ssize_t nfs_file_write(struct kiocb *iocb, const struct iovec *iov,
		       unsigned long nr_segs, loff_t pos)
{
	struct dentry * dentry = iocb->ki_filp->f_path.dentry;
	struct inode * inode = dentry->d_inode;
	unsigned long written = 0;
	ssize_t result;
	size_t count = iov_length(iov, nr_segs);

	if (iocb->ki_filp->f_flags & O_DIRECT)
		return nfs_file_direct_write(iocb, iov, nr_segs, pos, true);

	dprintk("NFS: write(%s/%s, %lu@%Ld)\n",
		dentry->d_parent->d_name.name, dentry->d_name.name,
		(unsigned long) count, (long long) pos);

	result = -EBUSY;
	if (IS_SWAPFILE(inode))
		goto out_swapfile;
	/*
	 * O_APPEND implies that we must revalidate the file length.
	 */
	if (iocb->ki_filp->f_flags & O_APPEND) {
		result = nfs_revalidate_file_size(inode, iocb->ki_filp);
		if (result)
			goto out;
	}

	result = count;
	if (!count)
		goto out;

	result = generic_file_aio_write(iocb, iov, nr_segs, pos);
	if (result > 0)
		written = result;

	/* Return error values for O_DSYNC and IS_SYNC() */
	if (result >= 0 && nfs_need_sync_write(iocb->ki_filp, inode)) {
		int err = vfs_fsync(iocb->ki_filp, 0);
		if (err < 0)
			result = err;
	}
	if (result > 0)
		nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
out:
	return result;

out_swapfile:
	printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
	goto out;
}