4.4-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman gregkh@linuxfoundation.org
This reverts commit c4baa4a5870cb02f713def1620052bfca7a82bbb which is commit 28f5a8a7c033cbf3e32277f4cc9c6afd74f05300 upstream.
It shouldn't be applied to the 4.4-stable tree.
Ben and Alex write:
Now that ocfs2_setattr() calls this outside of the inode locked region, what prevents another task adding a new dio request immediately afterward?
In the kernel 4.6, firstly, we use the inode_lock() in do_truncate() to prevent another bio to be issued from this node. Furthermore, we use the ocfs2_rw_lock() and ocfs2_inode_lock() in ocfs2_setattr() to guarantee no more bio will be issued from the other nodes in this cluster.
Also, ocfs2_dio_end_io_write() was introduced in 4.6 and it looks like the dio completion path didn't previously take the inode lock. So it doesn't look this fix is needed in 3.18 or 4.4.
Yes, ocfs2_dio_end_io_write() was introduced in 4.6 and the problem this patch fixes is only exist in the kernel 4.6 and above 4.6.
Reported-by: Ben Hutchings ben.hutchings@codethink.co.uk Cc: Alex Chen alex.chen@huawei.com Cc: Jun Piao piaojun@huawei.com Cc: Joseph Qi jiangqi903@gmail.com Cc: Changwei Ge ge.changwei@h3c.com Cc: Mark Fasheh mfasheh@versity.com Cc: Joel Becker jlbec@evilplan.org Cc: Junxiao Bi junxiao.bi@oracle.com Cc: Andrew Morton akpm@linux-foundation.org Cc: Linus Torvalds torvalds@linux-foundation.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- fs/ocfs2/file.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
--- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -1166,13 +1166,6 @@ int ocfs2_setattr(struct dentry *dentry, } size_change = S_ISREG(inode->i_mode) && attr->ia_valid & ATTR_SIZE; if (size_change) { - /* - * Here we should wait dio to finish before inode lock - * to avoid a deadlock between ocfs2_setattr() and - * ocfs2_dio_end_io_write() - */ - inode_dio_wait(inode); - status = ocfs2_rw_lock(inode, 1); if (status < 0) { mlog_errno(status); @@ -1193,6 +1186,8 @@ int ocfs2_setattr(struct dentry *dentry, if (status) goto bail_unlock;
+ inode_dio_wait(inode); + if (i_size_read(inode) >= attr->ia_size) { if (ocfs2_should_order_data(inode)) { status = ocfs2_begin_ordered_truncate(inode,