Skip to content

Commit

Permalink
ocfs2: fix several issues of append dio
Browse files Browse the repository at this point in the history
1) Take rw EX lock in case of append dio.
2) Explicitly treat the error code -EIOCBQUEUED as normal.
3) Set di_bh to NULL after brelse if it may be used again later.

Signed-off-by: Joseph Qi <joseph.qi@huawei.com>
Cc: Yiwen Jiang <jiangyiwen@huawei.com>
Cc: Weiwei Wang <wangww631@huawei.com>
Cc: Mark Fasheh <mfasheh@suse.com>
Cc: Joel Becker <jlbec@evilplan.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Joseph Qi authored and Linus Torvalds committed Sep 4, 2015
1 parent 512f62a commit faaebf1
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 2 deletions.
7 changes: 6 additions & 1 deletion fs/ocfs2/aops.c
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,8 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
written = __blockdev_direct_IO(iocb, inode, inode->i_sb->s_bdev, iter,
offset, ocfs2_direct_IO_get_blocks,
ocfs2_dio_end_io, NULL, 0);
if (unlikely(written < 0)) {
/* overwrite aio may return -EIOCBQUEUED, and it is not an error */
if ((written < 0) && (written != -EIOCBQUEUED)) {
loff_t i_size = i_size_read(inode);

if (offset + count > i_size) {
Expand All @@ -879,12 +880,14 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,

ocfs2_inode_unlock(inode, 1);
brelse(di_bh);
di_bh = NULL;
goto clean_orphan;
}
}

ocfs2_inode_unlock(inode, 1);
brelse(di_bh);
di_bh = NULL;

ret = jbd2_journal_force_commit(journal);
if (ret < 0)
Expand Down Expand Up @@ -939,10 +942,12 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
if (tmp_ret < 0) {
ret = tmp_ret;
mlog_errno(ret);
brelse(di_bh);
goto out;
}

ocfs2_inode_unlock(inode, 1);
brelse(di_bh);

tmp_ret = jbd2_journal_force_commit(journal);
if (tmp_ret < 0) {
Expand Down
5 changes: 4 additions & 1 deletion fs/ocfs2/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2271,6 +2271,8 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
OCFS2_MOUNT_COHERENCY_BUFFERED);
int unaligned_dio = 0;
int dropped_dio = 0;
int append_write = ((iocb->ki_pos + count) >=
i_size_read(inode) ? 1 : 0);

trace_ocfs2_file_aio_write(inode, file, file->f_path.dentry,
(unsigned long long)OCFS2_I(inode)->ip_blkno,
Expand All @@ -2290,8 +2292,9 @@ static ssize_t ocfs2_file_write_iter(struct kiocb *iocb,
/*
* Concurrent O_DIRECT writes are allowed with
* mount_option "coherency=buffered".
* For append write, we must take rw EX.
*/
rw_level = (!direct_io || full_coherency);
rw_level = (!direct_io || full_coherency || append_write);

ret = ocfs2_rw_lock(inode, rw_level);
if (ret < 0) {
Expand Down

0 comments on commit faaebf1

Please sign in to comment.