Message ID | 20141217133331.282ffc6f592fb329f3b7edad@linux-foundation.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Wed, Dec 17, 2014 at 01:33:31PM -0800, Andrew Morton wrote: > > So I now have a mess on my hands due to reordering > ocfs2-fix-journal-commit-deadlock.patch ahead of this patch. > > It concerns the label "out:". Should it be placed before or after the > call to ocfs2_unlock_pages()? > > My current copy of ocfs2_write_end_nolock() is below, followed by my > current version of > ocfs2-call-ocfs2_journal_access_di-before-ocfs2_journal_dirty-in-ocfs2_write_end_nolock.patch You want "out:" after ocfs2_unlock_pages() to give us a chance to free any locked pages on the write contesxt. Btw, I have the following notes for this patch: Putting the journal_access_di in ocfs2_write_end is the correct thing to do, thanks. I think we want to keep the journal_access_di in ocfs2_write_begin though as we may change the disk inode when marking unwritten extents (see the call to ocfs2_mark_extent_written()). So: - I would remove the comment above journal_access_di in write_begin but not the actual call as we may dirty the inode buffer later. - Move the call to journal_access_di to the top of ocfs2_write_end_nolock as I believe you might be missing some inode buffer updates there too. Thanks Andrew, --Mark -- Mark Fasheh
On 2014/12/18 7:00, Mark Fasheh wrote: > On Wed, Dec 17, 2014 at 01:33:31PM -0800, Andrew Morton wrote: >> >> So I now have a mess on my hands due to reordering >> ocfs2-fix-journal-commit-deadlock.patch ahead of this patch. >> >> It concerns the label "out:". Should it be placed before or after the >> call to ocfs2_unlock_pages()? >> >> My current copy of ocfs2_write_end_nolock() is below, followed by my >> current version of >> ocfs2-call-ocfs2_journal_access_di-before-ocfs2_journal_dirty-in-ocfs2_write_end_nolock.patch > > You want "out:" after ocfs2_unlock_pages() to give us a chance to free any > locked pages on the write contesxt. > > Btw, I have the following notes for this patch: > > > Putting the journal_access_di in ocfs2_write_end is the correct thing to do, > thanks. I think we want to keep the journal_access_di in ocfs2_write_begin > though as we may change the disk inode when marking unwritten extents > (see the call to ocfs2_mark_extent_written()). So: > > - I would remove the comment above journal_access_di in write_begin but not > the actual call as we may dirty the inode buffer later. > Hi, Mark, About this patch, do you mean that: keep the journal_access_di() in ocfs2_write_begin, and call journal_access_di() in the top ocfs2_write_end() again? But I don't think it as a good idea. In some scenario, jbd2_journal_restart() might be called after we call ocfs2_journal_access_di. and jbd2_journal_commit_transaction() will commit the transaction. So calling ocfs2_journal_access_di() in ocfs2_write_end() will lead to buffer_uptodate(bh) == 0, so BUG. Am I right? Thanks, yangwenfang > - Move the call to journal_access_di to the top of ocfs2_write_end_nolock as > I believe you might be missing some inode buffer updates there too. > > > Thanks Andrew, > --Mark > > -- > Mark Fasheh > > . >
diff -puN fs/ocfs2/aops.c~ocfs2-call-ocfs2_journal_access_di-before-ocfs2_journal_dirty-in-ocfs2_write_end_nolock fs/ocfs2/aops.c --- a/fs/ocfs2/aops.c~ocfs2-call-ocfs2_journal_access_di-before-ocfs2_journal_dirty-in-ocfs2_write_end_nolock +++ a/fs/ocfs2/aops.c @@ -1822,16 +1822,6 @@ try_again: if (ret) goto out_commit; } - /* - * We don't want this to fail in ocfs2_write_end(), so do it - * here. - */ - ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh, - OCFS2_JOURNAL_ACCESS_WRITE); - if (ret) { - mlog_errno(ret); - goto out_quota; - } /* * Fill our page array first. That way we've grabbed enough so @@ -1982,7 +1972,7 @@ int ocfs2_write_end_nolock(struct addres loff_t pos, unsigned len, unsigned copied, struct page *page, void *fsdata) { - int i; + int i, ret; unsigned from, to, start = pos & (PAGE_CACHE_SIZE - 1); struct inode *inode = mapping->host; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); @@ -2032,6 +2022,14 @@ int ocfs2_write_end_nolock(struct addres } } + ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), wc->w_di_bh, + OCFS2_JOURNAL_ACCESS_WRITE); + if (ret) { + copied = ret; + mlog_errno(ret); + goto out; + } + out_write_size: pos += copied; if (pos > i_size_read(inode)) { @@ -2053,6 +2051,7 @@ out_write_size: */ ocfs2_unlock_pages(wc); +out: ocfs2_commit_trans(osb, handle); ocfs2_run_deallocs(osb, &wc->w_dealloc);