diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-24 15:55:26 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-24 15:55:26 -0400 |
commit | 0e01df100b6bf22a1de61b66657502a6454153c5 (patch) | |
tree | aae8f9787efc3014696b3e5ae854c1cf9e472bdd /fs/jbd2 | |
parent | a56f489502e28caac56c8a0735549740f0ae0711 (diff) | |
parent | 12735f881952c32b31bc4e433768f18489f79ec9 (diff) |
Merge tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
Pull ext4 updates from Ted Ts'o:
"Fix a number of bugs, most notably a potential stale data exposure
after a crash and a potential BUG_ON crash if a file has the data
journalling flag enabled while it has dirty delayed allocation blocks
that haven't been written yet. Also fix a potential crash in the new
project quota code and a maliciously corrupted file system.
In addition, fix some DAX-specific bugs, including when there is a
transient ENOSPC situation and races between writes via direct I/O and
an mmap'ed segment that could lead to lost I/O.
Finally the usual set of miscellaneous cleanups"
* tag 'ext4_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (23 commits)
ext4: pre-zero allocated blocks for DAX IO
ext4: refactor direct IO code
ext4: fix race in transient ENOSPC detection
ext4: handle transient ENOSPC properly for DAX
dax: call get_blocks() with create == 1 for write faults to unwritten extents
ext4: remove unmeetable inconsisteny check from ext4_find_extent()
jbd2: remove excess descriptions for handle_s
ext4: remove unnecessary bio get/put
ext4: silence UBSAN in ext4_mb_init()
ext4: address UBSAN warning in mb_find_order_for_block()
ext4: fix oops on corrupted filesystem
ext4: fix check of dqget() return value in ext4_ioctl_setproject()
ext4: clean up error handling when orphan list is corrupted
ext4: fix hang when processing corrupted orphaned inode list
ext4: remove trailing \n from ext4_warning/ext4_error calls
ext4: fix races between changing inode journal mode and ext4_writepages
ext4: handle unwritten or delalloc buffers before enabling data journaling
ext4: fix jbd2 handle extension in ext4_ext_truncate_extend_restart()
ext4: do not ask jbd2 to write data for delalloc buffers
jbd2: add support for avoiding data writes during transaction commits
...
Diffstat (limited to 'fs/jbd2')
-rw-r--r-- | fs/jbd2/commit.c | 4 | ||||
-rw-r--r-- | fs/jbd2/journal.c | 3 | ||||
-rw-r--r-- | fs/jbd2/transaction.c | 22 |
3 files changed, 24 insertions, 5 deletions
diff --git a/fs/jbd2/commit.c b/fs/jbd2/commit.c index 2ad98d6e19f4..70078096117d 100644 --- a/fs/jbd2/commit.c +++ b/fs/jbd2/commit.c | |||
@@ -219,6 +219,8 @@ static int journal_submit_data_buffers(journal_t *journal, | |||
219 | 219 | ||
220 | spin_lock(&journal->j_list_lock); | 220 | spin_lock(&journal->j_list_lock); |
221 | list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { | 221 | list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { |
222 | if (!(jinode->i_flags & JI_WRITE_DATA)) | ||
223 | continue; | ||
222 | mapping = jinode->i_vfs_inode->i_mapping; | 224 | mapping = jinode->i_vfs_inode->i_mapping; |
223 | jinode->i_flags |= JI_COMMIT_RUNNING; | 225 | jinode->i_flags |= JI_COMMIT_RUNNING; |
224 | spin_unlock(&journal->j_list_lock); | 226 | spin_unlock(&journal->j_list_lock); |
@@ -256,6 +258,8 @@ static int journal_finish_inode_data_buffers(journal_t *journal, | |||
256 | /* For locking, see the comment in journal_submit_data_buffers() */ | 258 | /* For locking, see the comment in journal_submit_data_buffers() */ |
257 | spin_lock(&journal->j_list_lock); | 259 | spin_lock(&journal->j_list_lock); |
258 | list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { | 260 | list_for_each_entry(jinode, &commit_transaction->t_inode_list, i_list) { |
261 | if (!(jinode->i_flags & JI_WAIT_DATA)) | ||
262 | continue; | ||
259 | jinode->i_flags |= JI_COMMIT_RUNNING; | 263 | jinode->i_flags |= JI_COMMIT_RUNNING; |
260 | spin_unlock(&journal->j_list_lock); | 264 | spin_unlock(&journal->j_list_lock); |
261 | err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping); | 265 | err = filemap_fdatawait(jinode->i_vfs_inode->i_mapping); |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 435f0b26ac20..b31852f76f46 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -94,7 +94,8 @@ EXPORT_SYMBOL(jbd2_journal_blocks_per_page); | |||
94 | EXPORT_SYMBOL(jbd2_journal_invalidatepage); | 94 | EXPORT_SYMBOL(jbd2_journal_invalidatepage); |
95 | EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); | 95 | EXPORT_SYMBOL(jbd2_journal_try_to_free_buffers); |
96 | EXPORT_SYMBOL(jbd2_journal_force_commit); | 96 | EXPORT_SYMBOL(jbd2_journal_force_commit); |
97 | EXPORT_SYMBOL(jbd2_journal_file_inode); | 97 | EXPORT_SYMBOL(jbd2_journal_inode_add_write); |
98 | EXPORT_SYMBOL(jbd2_journal_inode_add_wait); | ||
98 | EXPORT_SYMBOL(jbd2_journal_init_jbd_inode); | 99 | EXPORT_SYMBOL(jbd2_journal_init_jbd_inode); |
99 | EXPORT_SYMBOL(jbd2_journal_release_jbd_inode); | 100 | EXPORT_SYMBOL(jbd2_journal_release_jbd_inode); |
100 | EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate); | 101 | EXPORT_SYMBOL(jbd2_journal_begin_ordered_truncate); |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 2c56c3e32194..1749519b362f 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
@@ -2462,7 +2462,8 @@ void jbd2_journal_refile_buffer(journal_t *journal, struct journal_head *jh) | |||
2462 | /* | 2462 | /* |
2463 | * File inode in the inode list of the handle's transaction | 2463 | * File inode in the inode list of the handle's transaction |
2464 | */ | 2464 | */ |
2465 | int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) | 2465 | static int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode, |
2466 | unsigned long flags) | ||
2466 | { | 2467 | { |
2467 | transaction_t *transaction = handle->h_transaction; | 2468 | transaction_t *transaction = handle->h_transaction; |
2468 | journal_t *journal; | 2469 | journal_t *journal; |
@@ -2487,12 +2488,14 @@ int jbd2_journal_file_inode(handle_t *handle, struct jbd2_inode *jinode) | |||
2487 | * and if jinode->i_next_transaction == transaction, commit code | 2488 | * and if jinode->i_next_transaction == transaction, commit code |
2488 | * will only file the inode where we want it. | 2489 | * will only file the inode where we want it. |
2489 | */ | 2490 | */ |
2490 | if (jinode->i_transaction == transaction || | 2491 | if ((jinode->i_transaction == transaction || |
2491 | jinode->i_next_transaction == transaction) | 2492 | jinode->i_next_transaction == transaction) && |
2493 | (jinode->i_flags & flags) == flags) | ||
2492 | return 0; | 2494 | return 0; |
2493 | 2495 | ||
2494 | spin_lock(&journal->j_list_lock); | 2496 | spin_lock(&journal->j_list_lock); |
2495 | 2497 | jinode->i_flags |= flags; | |
2498 | /* Is inode already attached where we need it? */ | ||
2496 | if (jinode->i_transaction == transaction || | 2499 | if (jinode->i_transaction == transaction || |
2497 | jinode->i_next_transaction == transaction) | 2500 | jinode->i_next_transaction == transaction) |
2498 | goto done; | 2501 | goto done; |
@@ -2523,6 +2526,17 @@ done: | |||
2523 | return 0; | 2526 | return 0; |
2524 | } | 2527 | } |
2525 | 2528 | ||
2529 | int jbd2_journal_inode_add_write(handle_t *handle, struct jbd2_inode *jinode) | ||
2530 | { | ||
2531 | return jbd2_journal_file_inode(handle, jinode, | ||
2532 | JI_WRITE_DATA | JI_WAIT_DATA); | ||
2533 | } | ||
2534 | |||
2535 | int jbd2_journal_inode_add_wait(handle_t *handle, struct jbd2_inode *jinode) | ||
2536 | { | ||
2537 | return jbd2_journal_file_inode(handle, jinode, JI_WAIT_DATA); | ||
2538 | } | ||
2539 | |||
2526 | /* | 2540 | /* |
2527 | * File truncate and transaction commit interact with each other in a | 2541 | * File truncate and transaction commit interact with each other in a |
2528 | * non-trivial way. If a transaction writing data block A is | 2542 | * non-trivial way. If a transaction writing data block A is |