Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-5.3-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux

Pull btrfs fixes from David Sterba:
"Here are two fixes, one of them urgent fixing a bug introduced in 5.2
and reported by many users. It took time to identify the root cause,
catching the 5.3 release is higly desired also to push the fix to 5.2
stable tree.

The bug is a mess up of return values after adding proper error
handling and honestly the kind of bug that can cause sleeping
disorders until it's caught. My appologies to everybody who was
affected.

Summary of what could happen:

1) either a hang when committing a transaction, if this happens
there's no risk of corruption, still the hang is very inconvenient
and can't be resolved without a reboot

2) writeback for some btree nodes may never be started and we end up
committing a transaction without noticing that, this is really
serious and that will lead to the "parent transid verify failed"
messages"

* tag 'for-5.3-rc8-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux:
Btrfs: fix unwritten extent buffers and hangs on future writeback attempts
Btrfs: fix assertion failure during fsync and use of stale transaction

+34 -17
+26 -9
fs/btrfs/extent_io.c
··· 3628 3628 TASK_UNINTERRUPTIBLE); 3629 3629 } 3630 3630 3631 + static void end_extent_buffer_writeback(struct extent_buffer *eb) 3632 + { 3633 + clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); 3634 + smp_mb__after_atomic(); 3635 + wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK); 3636 + } 3637 + 3631 3638 /* 3632 3639 * Lock eb pages and flush the bio if we can't the locks 3633 3640 * ··· 3706 3699 3707 3700 if (!trylock_page(p)) { 3708 3701 if (!flush) { 3709 - ret = flush_write_bio(epd); 3710 - if (ret < 0) { 3702 + int err; 3703 + 3704 + err = flush_write_bio(epd); 3705 + if (err < 0) { 3706 + ret = err; 3711 3707 failed_page_nr = i; 3712 3708 goto err_unlock; 3713 3709 } ··· 3725 3715 /* Unlock already locked pages */ 3726 3716 for (i = 0; i < failed_page_nr; i++) 3727 3717 unlock_page(eb->pages[i]); 3718 + /* 3719 + * Clear EXTENT_BUFFER_WRITEBACK and wake up anyone waiting on it. 3720 + * Also set back EXTENT_BUFFER_DIRTY so future attempts to this eb can 3721 + * be made and undo everything done before. 3722 + */ 3723 + btrfs_tree_lock(eb); 3724 + spin_lock(&eb->refs_lock); 3725 + set_bit(EXTENT_BUFFER_DIRTY, &eb->bflags); 3726 + end_extent_buffer_writeback(eb); 3727 + spin_unlock(&eb->refs_lock); 3728 + percpu_counter_add_batch(&fs_info->dirty_metadata_bytes, eb->len, 3729 + fs_info->dirty_metadata_batch); 3730 + btrfs_clear_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN); 3731 + btrfs_tree_unlock(eb); 3728 3732 return ret; 3729 - } 3730 - 3731 - static void end_extent_buffer_writeback(struct extent_buffer *eb) 3732 - { 3733 - clear_bit(EXTENT_BUFFER_WRITEBACK, &eb->bflags); 3734 - smp_mb__after_atomic(); 3735 - wake_up_bit(&eb->bflags, EXTENT_BUFFER_WRITEBACK); 3736 3733 } 3737 3734 3738 3735 static void set_btree_ioerr(struct page *page)
+8 -8
fs/btrfs/tree-log.c
··· 4985 4985 BTRFS_I(inode), 4986 4986 LOG_OTHER_INODE_ALL, 4987 4987 0, LLONG_MAX, ctx); 4988 - iput(inode); 4988 + btrfs_add_delayed_iput(inode); 4989 4989 } 4990 4990 } 4991 4991 continue; ··· 5000 5000 ret = btrfs_log_inode(trans, root, BTRFS_I(inode), 5001 5001 LOG_OTHER_INODE, 0, LLONG_MAX, ctx); 5002 5002 if (ret) { 5003 - iput(inode); 5003 + btrfs_add_delayed_iput(inode); 5004 5004 continue; 5005 5005 } 5006 5006 ··· 5009 5009 key.offset = 0; 5010 5010 ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); 5011 5011 if (ret < 0) { 5012 - iput(inode); 5012 + btrfs_add_delayed_iput(inode); 5013 5013 continue; 5014 5014 } 5015 5015 ··· 5056 5056 } 5057 5057 path->slots[0]++; 5058 5058 } 5059 - iput(inode); 5059 + btrfs_add_delayed_iput(inode); 5060 5060 } 5061 5061 5062 5062 return ret; ··· 5689 5689 } 5690 5690 5691 5691 if (btrfs_inode_in_log(BTRFS_I(di_inode), trans->transid)) { 5692 - iput(di_inode); 5692 + btrfs_add_delayed_iput(di_inode); 5693 5693 break; 5694 5694 } 5695 5695 ··· 5701 5701 if (!ret && 5702 5702 btrfs_must_commit_transaction(trans, BTRFS_I(di_inode))) 5703 5703 ret = 1; 5704 - iput(di_inode); 5704 + btrfs_add_delayed_iput(di_inode); 5705 5705 if (ret) 5706 5706 goto next_dir_inode; 5707 5707 if (ctx->log_new_dentries) { ··· 5848 5848 if (!ret && ctx && ctx->log_new_dentries) 5849 5849 ret = log_new_dir_dentries(trans, root, 5850 5850 BTRFS_I(dir_inode), ctx); 5851 - iput(dir_inode); 5851 + btrfs_add_delayed_iput(dir_inode); 5852 5852 if (ret) 5853 5853 goto out; 5854 5854 } ··· 5891 5891 ret = btrfs_log_inode(trans, root, BTRFS_I(inode), 5892 5892 LOG_INODE_EXISTS, 5893 5893 0, LLONG_MAX, ctx); 5894 - iput(inode); 5894 + btrfs_add_delayed_iput(inode); 5895 5895 if (ret) 5896 5896 return ret; 5897 5897