ext4: fix deadlock in journal_unmap_buffer()
We cannot wait for transaction commit in journal_unmap_buffer() because we hold page lock which ranks below transaction start. We solve the issue by bailing out of journal_unmap_buffer() and jbd2_journal_invalidatepage() with -EBUSY. Caller is then responsible for waiting for transaction commit to finish and try invalidation again. Since the issue can happen only for page stradding i_size, it is simple enough to manually call jbd2_journal_invalidatepage() for such page from ext4_setattr(), check the return value and wait if necessary. Signed-off-by: Jan Kara <jack@suse.cz> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
This commit is contained in:
@@ -1098,7 +1098,7 @@ void jbd2_journal_set_triggers(struct buffer_head *,
|
||||
extern int jbd2_journal_dirty_metadata (handle_t *, struct buffer_head *);
|
||||
extern int jbd2_journal_forget (handle_t *, struct buffer_head *);
|
||||
extern void journal_sync_buffer (struct buffer_head *);
|
||||
extern void jbd2_journal_invalidatepage(journal_t *,
|
||||
extern int jbd2_journal_invalidatepage(journal_t *,
|
||||
struct page *, unsigned long);
|
||||
extern int jbd2_journal_try_to_free_buffers(journal_t *, struct page *, gfp_t);
|
||||
extern int jbd2_journal_stop(handle_t *);
|
||||
|
Reference in New Issue
Block a user