Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6307daad authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jlbec/ocfs2:
  ocfs2: Handle O_DIRECT when writing to a refcounted cluster.
parents f843b0fc 86470e98
Loading
Loading
Loading
Loading
+15 −6
Original line number Diff line number Diff line
@@ -1772,7 +1772,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
					 loff_t *ppos,
					 size_t count,
					 int appending,
					 int *direct_io)
					 int *direct_io,
					 int *has_refcount)
{
	int ret = 0, meta_level = 0;
	struct inode *inode = dentry->d_inode;
@@ -1833,6 +1834,8 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
							       saved_pos,
							       count,
							       &meta_level);
			if (has_refcount)
				*has_refcount = 1;
		}

		if (ret < 0) {
@@ -1856,6 +1859,10 @@ static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
			break;
		}

		if (has_refcount && *has_refcount == 1) {
			*direct_io = 0;
			break;
		}
		/*
		 * Allowing concurrent direct writes means
		 * i_size changes wouldn't be synchronized, so
@@ -1899,7 +1906,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
				    loff_t pos)
{
	int ret, direct_io, appending, rw_level, have_alloc_sem  = 0;
	int can_do_direct;
	int can_do_direct, has_refcount = 0;
	ssize_t written = 0;
	size_t ocount;		/* original count */
	size_t count;		/* after file limit checks */
@@ -1942,7 +1949,7 @@ relock:
	can_do_direct = direct_io;
	ret = ocfs2_prepare_inode_for_write(file->f_path.dentry, ppos,
					    iocb->ki_left, appending,
					    &can_do_direct);
					    &can_do_direct, &has_refcount);
	if (ret < 0) {
		mlog_errno(ret);
		goto out;
@@ -2006,14 +2013,16 @@ out_dio:
	/* buffered aio wouldn't have proper lock coverage today */
	BUG_ON(ret == -EIOCBQUEUED && !(file->f_flags & O_DIRECT));

	if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode)) {
	if ((file->f_flags & O_DSYNC && !direct_io) || IS_SYNC(inode) ||
	    (file->f_flags & O_DIRECT && has_refcount)) {
		ret = filemap_fdatawrite_range(file->f_mapping, pos,
					       pos + count - 1);
		if (ret < 0)
			written = ret;

		if (!ret && (old_size != i_size_read(inode) ||
		    old_clusters != OCFS2_I(inode)->ip_clusters)) {
		    old_clusters != OCFS2_I(inode)->ip_clusters ||
		    has_refcount)) {
			ret = jbd2_journal_force_commit(osb->journal->j_journal);
			if (ret < 0)
				written = ret;
@@ -2062,7 +2071,7 @@ static int ocfs2_splice_to_file(struct pipe_inode_info *pipe,
	int ret;

	ret = ocfs2_prepare_inode_for_write(out->f_path.dentry,	&sd->pos,
					    sd->total_len, 0, NULL);
					    sd->total_len, 0, NULL, NULL);
	if (ret < 0) {
		mlog_errno(ret);
		return ret;