On Fri, Sep 01, 2017 at 07:31:58PM +0800, Qu Wenruo wrote: > > > On 2017年09月01日 16:59, Naohiro Aota wrote: > > __endio_write_update_ordered() repeats the search until it reaches the end > > of the specified range. This works well with direct IO path, because before > > the function is called, it's ensured that there are ordered extents filling > > whole the range. It's not the case, however, when it's called from > > run_delalloc_range(): it is possible to have error in the midle of the loop > > in e.g. run_delalloc_nocow(), so that there exisits the range not covered > > by any ordered extents. By cleaning such "uncomplete" range, > > __endio_write_update_ordered() stucks at offset where there're no ordered > > extents. > > > > Since the ordered extents are created from head to tail, we can stop the > > search if there are no offset progress. > > > > Signed-off-by: Naohiro Aota <naohiro.a...@wdc.com> > > Fixes: 524272607e88 ("btrfs: Handle delalloc error correctly to avoid > > ordered extent hang") > > Cc: <sta...@vger.kernel.org> # 4.12 > > --- > > fs/btrfs/inode.c | 4 ++++ > > 1 file changed, 4 insertions(+) > > > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > > index ae4c0a1bef38..fd5934121b4b 100644 > > --- a/fs/btrfs/inode.c > > +++ b/fs/btrfs/inode.c > > @@ -8309,6 +8309,7 @@ static void __endio_write_update_ordered(struct inode > > *inode, > > btrfs_work_func_t func; > > u64 ordered_offset = offset; > > u64 ordered_bytes = bytes; > > + u64 last_offset; > > int ret; > > > > if (btrfs_is_free_space_inode(BTRFS_I(inode))) { > > @@ -8320,6 +8321,7 @@ static void __endio_write_update_ordered(struct inode > > *inode, > > } > > > > again: > > + last_offset = ordered_offset; > > ret = btrfs_dec_test_first_ordered_pending(inode, &ordered, > > &ordered_offset, > > ordered_bytes, > > @@ -8330,6 +8332,8 @@ static void __endio_write_update_ordered(struct inode > > *inode, > > btrfs_init_work(&ordered->work, func, finish_ordered_fn, NULL, NULL); > > btrfs_queue_work(wq, &ordered->work); > > out_test: > > + if (ordered_offset == last_offset) > > + return; > > Such check seems strange to me. > > For ordered_offset == last_offset case, it means > btrfs_dec_test_ordered_pending() doesn't find any ordered extent in that > range, so we can exit. > This takes me a while to dig into btrfs_dec_test_first_ordered_pending(). > > Extra comment will help here, or to modify > btrfs_dev_test_ordered_pending() to explicitly info caller there is no > extra pending ordered extent.
I'll update the patch with the comment based on your note, please send a patch with the proposed code changes if you like. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html