From: Christoph Hellwig Date: Mon, 4 Nov 2024 08:05:58 +0000 (+0100) Subject: writeback: split wbc_attach_and_unlock_inode X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fwriteback-cleanups;p=users%2Fhch%2Fmisc.git writeback: split wbc_attach_and_unlock_inode Signed-off-by: Christoph Hellwig --- diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 77db1f10023e..2b0b2a81d565 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -721,23 +721,21 @@ bool cleanup_offline_cgwb(struct bdi_writeback *wb) } /** - * wbc_attach_and_unlock_inode - associate wbc with target inode and unlock it + * wbc_attach_inode - associate wbc with target inode * @wbc: writeback_control of interest * @inode: target inode * * @inode is locked and about to be written back under the control of @wbc. - * Record @inode's writeback context into @wbc and unlock the i_lock. On - * writeback completion, wbc_detach_inode() should be called. This is used - * to track the cgroup writeback context. + * Record @inode's writeback context into @wbc. On writeback completion, + * wbc_detach_inode() should be called. This is used to track the cgroup + * writeback context. */ -static void wbc_attach_and_unlock_inode(struct writeback_control *wbc, - struct inode *inode) - __releases(&inode->i_lock) +static void wbc_attach_inode(struct writeback_control *wbc, struct inode *inode) { - if (!inode_cgwb_enabled(inode)) { - spin_unlock(&inode->i_lock); + if (!inode_cgwb_enabled(inode)) return; - } + + lockdep_assert_held(&inode->i_lock); wbc->wb = inode_to_wb(inode); wbc->inode = inode; @@ -750,15 +748,17 @@ static void wbc_attach_and_unlock_inode(struct writeback_control *wbc, wbc->wb_tcand_bytes = 0; wb_get(wbc->wb); - spin_unlock(&inode->i_lock); +} - /* - * A dying wb indicates that either the blkcg associated with the - * memcg changed or the associated memcg is dying. In the first - * case, a replacement wb should already be available and we should - * refresh the wb immediately. In the second case, trying to - * refresh will keep failing. - */ +/* + * A dying wb indicates that either the blkcg associated with the memcg changed + * or the associated memcg is dying. In the first case, a replacement wb should + * already be available and we should refresh the wb immediately. In the second + * case, trying to refresh will keep failing. + */ +static void wbc_switch_dying_wb(struct writeback_control *wbc, + struct inode *inode) +{ if (unlikely(wb_dying(wbc->wb) && !css_is_dying(wbc->wb->memcg_css))) inode_switch_wbs(inode, wbc->wb_id); } @@ -777,7 +777,10 @@ void wbc_attach_fdatawrite_inode(struct writeback_control *wbc, { spin_lock(&inode->i_lock); inode_attach_wb(inode, NULL); - wbc_attach_and_unlock_inode(wbc, inode); + wbc_attach_inode(wbc, inode); + spin_unlock(&inode->i_lock); + + wbc_switch_dying_wb(wbc, inode); } EXPORT_SYMBOL_GPL(wbc_attach_fdatawrite_inode); @@ -786,7 +789,7 @@ EXPORT_SYMBOL_GPL(wbc_attach_fdatawrite_inode); * @wbc: writeback_control of the just finished writeback * * To be called after a writeback attempt of an inode finishes and undoes - * wbc_attach_and_unlock_inode(). Can be called under any context. + * wbc_attach_inode(). Can be called under any context. * * As concurrent write sharing of an inode is expected to be very rare and * memcg only tracks page ownership on first-use basis severely confining @@ -1244,11 +1247,14 @@ static void bdi_split_work_to_wbs(struct backing_dev_info *bdi, } } -static inline void wbc_attach_and_unlock_inode(struct writeback_control *wbc, - struct inode *inode) - __releases(&inode->i_lock) +static inline void wbc_attach_inode(struct writeback_control *wbc, + struct inode *inode) +{ +} + +static void wbc_switch_dying_wb(struct writeback_control *wbc, + struct inode *inode) { - spin_unlock(&inode->i_lock); } #endif /* CONFIG_CGROUP_WRITEBACK */ @@ -1798,7 +1804,10 @@ static int writeback_single_inode(struct inode *inode, !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_WRITEBACK))) goto out; inode->i_state |= I_SYNC; - wbc_attach_and_unlock_inode(wbc, inode); + wbc_attach_inode(wbc, inode); + spin_unlock(&inode->i_lock); + + wbc_switch_dying_wb(wbc, inode); ret = __writeback_single_inode(inode, wbc); @@ -1965,7 +1974,10 @@ static long writeback_sb_inodes(struct super_block *sb, continue; } inode->i_state |= I_SYNC; - wbc_attach_and_unlock_inode(&wbc, inode); + wbc_attach_inode(&wbc, inode); + spin_unlock(&inode->i_lock); + + wbc_switch_dying_wb(&wbc, inode); write_chunk = writeback_chunk_size(wb, work); wbc.nr_to_write = write_chunk;