linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v1 1/2] fuse: use default writeback accounting
@ 2025-07-03 16:45 Joanne Koong
  2025-07-03 16:45 ` [PATCH v1 2/2] mm: remove BDI_CAP_WRITEBACK_ACCT Joanne Koong
  2025-07-04 12:59 ` [PATCH v1 1/2] fuse: use default writeback accounting kernel test robot
  0 siblings, 2 replies; 4+ messages in thread
From: Joanne Koong @ 2025-07-03 16:45 UTC (permalink / raw)
  To: miklos; +Cc: linux-fsdevel, willy, linux-mm

commit 0c58a97f919c ("fuse: remove tmp folio for writebacks and internal
rb tree") removed temp folios for dirty page writeback. Consequently,
fuse can now use the default writeback accounting.

With switching fuse to use default writeback accounting, there are some
added benefits. This updates wb->writeback_inodes tracking as well now
and updates writeback throughput estimates after writeback completion.

This commit also removes inc_wb_stat() and dec_wb_stat(). These have no
callers anymore now that fuse does not call them.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
 fs/fuse/file.c              |  7 +------
 fs/fuse/inode.c             |  2 --
 include/linux/backing-dev.h | 10 ----------
 3 files changed, 1 insertion(+), 18 deletions(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index adc4aa6810f5..8b1902d3b52f 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -1787,16 +1787,13 @@ static void fuse_writepage_finish(struct fuse_writepage_args *wpa)
 	struct backing_dev_info *bdi = inode_to_bdi(inode);
 	int i;
 
-	for (i = 0; i < ap->num_folios; i++) {
+	for (i = 0; i < ap->num_folios; i++)
 		/*
 		 * Benchmarks showed that ending writeback within the
 		 * scope of the fi->lock alleviates xarray lock
 		 * contention and noticeably improves performance.
 		 */
 		folio_end_writeback(ap->folios[i]);
-		dec_wb_stat(&bdi->wb, WB_WRITEBACK);
-		wb_writeout_inc(&bdi->wb);
-	}
 
 	wake_up(&fi->page_waitq);
 }
@@ -1988,8 +1985,6 @@ static void fuse_writepage_args_page_fill(struct fuse_writepage_args *wpa, struc
 	ap->folios[folio_index] = folio;
 	ap->descs[folio_index].offset = 0;
 	ap->descs[folio_index].length = folio_size(folio);
-
-	inc_wb_stat(&inode_to_bdi(inode)->wb, WB_WRITEBACK);
 }
 
 static struct fuse_writepage_args *fuse_writepage_args_setup(struct folio *folio,
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index bfe8d8af46f3..a6c064eb7d08 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1557,8 +1557,6 @@ static int fuse_bdi_init(struct fuse_conn *fc, struct super_block *sb)
 	if (err)
 		return err;
 
-	/* fuse does it's own writeback accounting */
-	sb->s_bdi->capabilities &= ~BDI_CAP_WRITEBACK_ACCT;
 	sb->s_bdi->capabilities |= BDI_CAP_STRICTLIMIT;
 
 	/*
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index e721148c95d0..9a1e895dd5df 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -66,16 +66,6 @@ static inline void wb_stat_mod(struct bdi_writeback *wb,
 	percpu_counter_add_batch(&wb->stat[item], amount, WB_STAT_BATCH);
 }
 
-static inline void inc_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
-{
-	wb_stat_mod(wb, item, 1);
-}
-
-static inline void dec_wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
-{
-	wb_stat_mod(wb, item, -1);
-}
-
 static inline s64 wb_stat(struct bdi_writeback *wb, enum wb_stat_item item)
 {
 	return percpu_counter_read_positive(&wb->stat[item]);
-- 
2.47.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v1 2/2] mm: remove BDI_CAP_WRITEBACK_ACCT
  2025-07-03 16:45 [PATCH v1 1/2] fuse: use default writeback accounting Joanne Koong
@ 2025-07-03 16:45 ` Joanne Koong
  2025-07-04 12:35   ` David Hildenbrand
  2025-07-04 12:59 ` [PATCH v1 1/2] fuse: use default writeback accounting kernel test robot
  1 sibling, 1 reply; 4+ messages in thread
From: Joanne Koong @ 2025-07-03 16:45 UTC (permalink / raw)
  To: miklos; +Cc: linux-fsdevel, willy, linux-mm

There are no users of BDI_CAP_WRITEBACK_ACCT now that fuse doesn't do
its own writeback accounting. This commit removes
BDI_CAP_WRITEBACK_ACCT.

Signed-off-by: Joanne Koong <joannelkoong@gmail.com>
---
 include/linux/backing-dev.h |  4 +---
 mm/backing-dev.c            |  2 +-
 mm/page-writeback.c         | 43 ++++++++++++++++---------------------
 3 files changed, 20 insertions(+), 29 deletions(-)

diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h
index 9a1e895dd5df..3e64f14739dd 100644
--- a/include/linux/backing-dev.h
+++ b/include/linux/backing-dev.h
@@ -108,12 +108,10 @@ int bdi_set_strict_limit(struct backing_dev_info *bdi, unsigned int strict_limit
  *
  * BDI_CAP_WRITEBACK:		Supports dirty page writeback, and dirty pages
  *				should contribute to accounting
- * BDI_CAP_WRITEBACK_ACCT:	Automatically account writeback pages
  * BDI_CAP_STRICTLIMIT:		Keep number of dirty pages below bdi threshold
  */
 #define BDI_CAP_WRITEBACK		(1 << 0)
-#define BDI_CAP_WRITEBACK_ACCT		(1 << 1)
-#define BDI_CAP_STRICTLIMIT		(1 << 2)
+#define BDI_CAP_STRICTLIMIT		(1 << 1)
 
 extern struct backing_dev_info noop_backing_dev_info;
 
diff --git a/mm/backing-dev.c b/mm/backing-dev.c
index 783904d8c5ef..35f11e75e30e 100644
--- a/mm/backing-dev.c
+++ b/mm/backing-dev.c
@@ -1026,7 +1026,7 @@ struct backing_dev_info *bdi_alloc(int node_id)
 		kfree(bdi);
 		return NULL;
 	}
-	bdi->capabilities = BDI_CAP_WRITEBACK | BDI_CAP_WRITEBACK_ACCT;
+	bdi->capabilities = BDI_CAP_WRITEBACK;
 	bdi->ra_pages = VM_READAHEAD_PAGES;
 	bdi->io_pages = VM_READAHEAD_PAGES;
 	timer_setup(&bdi->laptop_mode_wb_timer, laptop_mode_timer_fn, 0);
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 72b0ff0d4bae..11f9a909e8de 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -3016,26 +3016,22 @@ bool __folio_end_writeback(struct folio *folio)
 
 	if (mapping && mapping_use_writeback_tags(mapping)) {
 		struct inode *inode = mapping->host;
-		struct backing_dev_info *bdi = inode_to_bdi(inode);
+		struct bdi_writeback *wb = inode_to_wb(inode);
 		unsigned long flags;
 
 		xa_lock_irqsave(&mapping->i_pages, flags);
 		ret = folio_xor_flags_has_waiters(folio, 1 << PG_writeback);
 		__xa_clear_mark(&mapping->i_pages, folio_index(folio),
 					PAGECACHE_TAG_WRITEBACK);
-		if (bdi->capabilities & BDI_CAP_WRITEBACK_ACCT) {
-			struct bdi_writeback *wb = inode_to_wb(inode);
 
-			wb_stat_mod(wb, WB_WRITEBACK, -nr);
-			__wb_writeout_add(wb, nr);
-			if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK))
-				wb_inode_writeback_end(wb);
+		wb_stat_mod(wb, WB_WRITEBACK, -nr);
+		__wb_writeout_add(wb, nr);
+		if (!mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK)) {
+			wb_inode_writeback_end(wb);
+			if (mapping->host)
+				sb_clear_inode_writeback(mapping->host);
 		}
 
-		if (mapping->host && !mapping_tagged(mapping,
-						     PAGECACHE_TAG_WRITEBACK))
-			sb_clear_inode_writeback(mapping->host);
-
 		xa_unlock_irqrestore(&mapping->i_pages, flags);
 	} else {
 		ret = folio_xor_flags_has_waiters(folio, 1 << PG_writeback);
@@ -3060,7 +3056,7 @@ void __folio_start_writeback(struct folio *folio, bool keep_write)
 	if (mapping && mapping_use_writeback_tags(mapping)) {
 		XA_STATE(xas, &mapping->i_pages, folio_index(folio));
 		struct inode *inode = mapping->host;
-		struct backing_dev_info *bdi = inode_to_bdi(inode);
+		struct bdi_writeback *wb = inode_to_wb(inode);
 		unsigned long flags;
 		bool on_wblist;
 
@@ -3071,21 +3067,18 @@ void __folio_start_writeback(struct folio *folio, bool keep_write)
 		on_wblist = mapping_tagged(mapping, PAGECACHE_TAG_WRITEBACK);
 
 		xas_set_mark(&xas, PAGECACHE_TAG_WRITEBACK);
-		if (bdi->capabilities & BDI_CAP_WRITEBACK_ACCT) {
-			struct bdi_writeback *wb = inode_to_wb(inode);
-
-			wb_stat_mod(wb, WB_WRITEBACK, nr);
-			if (!on_wblist)
-				wb_inode_writeback_start(wb);
+		wb_stat_mod(wb, WB_WRITEBACK, nr);
+		if (!on_wblist) {
+			wb_inode_writeback_start(wb);
+			/*
+			 * We can come through here when swapping anonymous
+			 * folios, so we don't necessarily have an inode to
+			 * track for sync.
+			 */
+			if (mapping->host)
+				sb_mark_inode_writeback(mapping->host);
 		}
 
-		/*
-		 * We can come through here when swapping anonymous
-		 * folios, so we don't necessarily have an inode to
-		 * track for sync.
-		 */
-		if (mapping->host && !on_wblist)
-			sb_mark_inode_writeback(mapping->host);
 		if (!folio_test_dirty(folio))
 			xas_clear_mark(&xas, PAGECACHE_TAG_DIRTY);
 		if (!keep_write)
-- 
2.47.1



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v1 2/2] mm: remove BDI_CAP_WRITEBACK_ACCT
  2025-07-03 16:45 ` [PATCH v1 2/2] mm: remove BDI_CAP_WRITEBACK_ACCT Joanne Koong
@ 2025-07-04 12:35   ` David Hildenbrand
  0 siblings, 0 replies; 4+ messages in thread
From: David Hildenbrand @ 2025-07-04 12:35 UTC (permalink / raw)
  To: Joanne Koong, miklos; +Cc: linux-fsdevel, willy, linux-mm

On 03.07.25 18:45, Joanne Koong wrote:
> There are no users of BDI_CAP_WRITEBACK_ACCT now that fuse doesn't do
> its own writeback accounting. This commit removes
> BDI_CAP_WRITEBACK_ACCT.
> 
> Signed-off-by: Joanne Koong <joannelkoong@gmail.com>

Acked-by: David Hildenbrand <david@redhat.com>

-- 
Cheers,

David / dhildenb



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v1 1/2] fuse: use default writeback accounting
  2025-07-03 16:45 [PATCH v1 1/2] fuse: use default writeback accounting Joanne Koong
  2025-07-03 16:45 ` [PATCH v1 2/2] mm: remove BDI_CAP_WRITEBACK_ACCT Joanne Koong
@ 2025-07-04 12:59 ` kernel test robot
  1 sibling, 0 replies; 4+ messages in thread
From: kernel test robot @ 2025-07-04 12:59 UTC (permalink / raw)
  To: Joanne Koong, miklos; +Cc: oe-kbuild-all, linux-fsdevel, willy, linux-mm

Hi Joanne,

kernel test robot noticed the following build warnings:

[auto build test WARNING on mszeredi-fuse/for-next]
[also build test WARNING on akpm-mm/mm-everything linus/master v6.16-rc4 next-20250703]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Joanne-Koong/mm-remove-BDI_CAP_WRITEBACK_ACCT/20250704-004813
base:   https://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git for-next
patch link:    https://lore.kernel.org/r/20250703164556.1576674-1-joannelkoong%40gmail.com
patch subject: [PATCH v1 1/2] fuse: use default writeback accounting
config: microblaze-randconfig-r073-20250704 (https://download.01.org/0day-ci/archive/20250704/202507042032.MdzNkWm3-lkp@intel.com/config)
compiler: microblaze-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250704/202507042032.MdzNkWm3-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202507042032.MdzNkWm3-lkp@intel.com/

All warnings (new ones prefixed by >>):

   fs/fuse/file.c: In function 'fuse_writepage_finish':
>> fs/fuse/file.c:1787:27: warning: unused variable 'bdi' [-Wunused-variable]
     struct backing_dev_info *bdi = inode_to_bdi(inode);
                              ^~~
   fs/fuse/file.c: In function 'fuse_writepage_args_page_fill':
>> fs/fuse/file.c:1982:16: warning: unused variable 'inode' [-Wunused-variable]
     struct inode *inode = folio->mapping->host;
                   ^~~~~


vim +/bdi +1787 fs/fuse/file.c

3be5a52b30aa5c Miklos Szeredi  2008-04-30  1781  
509a6458b44f72 Joanne Koong    2024-08-26  1782  static void fuse_writepage_finish(struct fuse_writepage_args *wpa)
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1783  {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1784  	struct fuse_args_pages *ap = &wpa->ia.ap;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1785  	struct inode *inode = wpa->inode;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1786  	struct fuse_inode *fi = get_fuse_inode(inode);
0c58a97f919c24 Joanne Koong    2025-04-14 @1787  	struct backing_dev_info *bdi = inode_to_bdi(inode);
385b126815d927 Pavel Emelyanov 2013-06-29  1788  	int i;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1789  
ef2027c20ad4a6 Joanne Koong    2025-07-03  1790  	for (i = 0; i < ap->num_folios; i++)
0c58a97f919c24 Joanne Koong    2025-04-14  1791  		/*
0c58a97f919c24 Joanne Koong    2025-04-14  1792  		 * Benchmarks showed that ending writeback within the
0c58a97f919c24 Joanne Koong    2025-04-14  1793  		 * scope of the fi->lock alleviates xarray lock
0c58a97f919c24 Joanne Koong    2025-04-14  1794  		 * contention and noticeably improves performance.
0c58a97f919c24 Joanne Koong    2025-04-14  1795  		 */
0c58a97f919c24 Joanne Koong    2025-04-14  1796  		folio_end_writeback(ap->folios[i]);
c04e3b21181923 Joanne Koong    2024-08-26  1797  
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1798  	wake_up(&fi->page_waitq);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1799  }
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1800  
f15ecfef058d94 Kirill Tkhai    2018-11-09  1801  /* Called under fi->lock, may release and reacquire it */
fcee216beb9c15 Max Reitz       2020-05-06  1802  static void fuse_send_writepage(struct fuse_mount *fm,
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1803  				struct fuse_writepage_args *wpa, loff_t size)
f15ecfef058d94 Kirill Tkhai    2018-11-09  1804  __releases(fi->lock)
f15ecfef058d94 Kirill Tkhai    2018-11-09  1805  __acquires(fi->lock)
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1806  {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1807  	struct fuse_inode *fi = get_fuse_inode(wpa->inode);
ff7c3ee4842d87 Joanne Koong    2025-05-12  1808  	struct fuse_args_pages *ap = &wpa->ia.ap;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1809  	struct fuse_write_in *inarg = &wpa->ia.write.in;
ff7c3ee4842d87 Joanne Koong    2025-05-12  1810  	struct fuse_args *args = &ap->args;
ff7c3ee4842d87 Joanne Koong    2025-05-12  1811  	__u64 data_size = 0;
ff7c3ee4842d87 Joanne Koong    2025-05-12  1812  	int err, i;
ff7c3ee4842d87 Joanne Koong    2025-05-12  1813  
ff7c3ee4842d87 Joanne Koong    2025-05-12  1814  	for (i = 0; i < ap->num_folios; i++)
ff7c3ee4842d87 Joanne Koong    2025-05-12  1815  		data_size += ap->descs[i].length;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1816  
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1817  	fi->writectr++;
385b126815d927 Pavel Emelyanov 2013-06-29  1818  	if (inarg->offset + data_size <= size) {
385b126815d927 Pavel Emelyanov 2013-06-29  1819  		inarg->size = data_size;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1820  	} else if (inarg->offset < size) {
385b126815d927 Pavel Emelyanov 2013-06-29  1821  		inarg->size = size - inarg->offset;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1822  	} else {
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1823  		/* Got truncated off completely */
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1824  		goto out_free;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1825  	}
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1826  
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1827  	args->in_args[1].size = inarg->size;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1828  	args->force = true;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1829  	args->nocreds = true;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1830  
fcee216beb9c15 Max Reitz       2020-05-06  1831  	err = fuse_simple_background(fm, args, GFP_ATOMIC);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1832  	if (err == -ENOMEM) {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1833  		spin_unlock(&fi->lock);
fcee216beb9c15 Max Reitz       2020-05-06  1834  		err = fuse_simple_background(fm, args, GFP_NOFS | __GFP_NOFAIL);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1835  		spin_lock(&fi->lock);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1836  	}
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1837  
f15ecfef058d94 Kirill Tkhai    2018-11-09  1838  	/* Fails on broken connection only */
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1839  	if (unlikely(err))
f15ecfef058d94 Kirill Tkhai    2018-11-09  1840  		goto out_free;
f15ecfef058d94 Kirill Tkhai    2018-11-09  1841  
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1842  	return;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1843  
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1844   out_free:
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1845  	fi->writectr--;
509a6458b44f72 Joanne Koong    2024-08-26  1846  	fuse_writepage_finish(wpa);
f15ecfef058d94 Kirill Tkhai    2018-11-09  1847  	spin_unlock(&fi->lock);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1848  	fuse_writepage_free(wpa);
f15ecfef058d94 Kirill Tkhai    2018-11-09  1849  	spin_lock(&fi->lock);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1850  }
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1851  
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1852  /*
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1853   * If fi->writectr is positive (no truncate or fsync going on) send
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1854   * all queued writepage requests.
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1855   *
f15ecfef058d94 Kirill Tkhai    2018-11-09  1856   * Called with fi->lock
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1857   */
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1858  void fuse_flush_writepages(struct inode *inode)
f15ecfef058d94 Kirill Tkhai    2018-11-09  1859  __releases(fi->lock)
f15ecfef058d94 Kirill Tkhai    2018-11-09  1860  __acquires(fi->lock)
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1861  {
fcee216beb9c15 Max Reitz       2020-05-06  1862  	struct fuse_mount *fm = get_fuse_mount(inode);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1863  	struct fuse_inode *fi = get_fuse_inode(inode);
9de5be06d0a89c Miklos Szeredi  2019-04-24  1864  	loff_t crop = i_size_read(inode);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1865  	struct fuse_writepage_args *wpa;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1866  
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1867  	while (fi->writectr >= 0 && !list_empty(&fi->queued_writes)) {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1868  		wpa = list_entry(fi->queued_writes.next,
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1869  				 struct fuse_writepage_args, queue_entry);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1870  		list_del_init(&wpa->queue_entry);
fcee216beb9c15 Max Reitz       2020-05-06  1871  		fuse_send_writepage(fm, wpa, crop);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1872  	}
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1873  }
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1874  
fcee216beb9c15 Max Reitz       2020-05-06  1875  static void fuse_writepage_end(struct fuse_mount *fm, struct fuse_args *args,
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1876  			       int error)
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1877  {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1878  	struct fuse_writepage_args *wpa =
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1879  		container_of(args, typeof(*wpa), ia.ap.args);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1880  	struct inode *inode = wpa->inode;
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1881  	struct fuse_inode *fi = get_fuse_inode(inode);
3466958beb31a8 Vivek Goyal     2021-04-06  1882  	struct fuse_conn *fc = get_fuse_conn(inode);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1883  
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1884  	mapping_set_error(inode->i_mapping, error);
3466958beb31a8 Vivek Goyal     2021-04-06  1885  	/*
3466958beb31a8 Vivek Goyal     2021-04-06  1886  	 * A writeback finished and this might have updated mtime/ctime on
3466958beb31a8 Vivek Goyal     2021-04-06  1887  	 * server making local mtime/ctime stale.  Hence invalidate attrs.
3466958beb31a8 Vivek Goyal     2021-04-06  1888  	 * Do this only if writeback_cache is not enabled.  If writeback_cache
3466958beb31a8 Vivek Goyal     2021-04-06  1889  	 * is enabled, we trust local ctime/mtime.
3466958beb31a8 Vivek Goyal     2021-04-06  1890  	 */
3466958beb31a8 Vivek Goyal     2021-04-06  1891  	if (!fc->writeback_cache)
fa5eee57e33e79 Miklos Szeredi  2021-10-22  1892  		fuse_invalidate_attr_mask(inode, FUSE_STATX_MODIFY);
f15ecfef058d94 Kirill Tkhai    2018-11-09  1893  	spin_lock(&fi->lock);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1894  	fi->writectr--;
509a6458b44f72 Joanne Koong    2024-08-26  1895  	fuse_writepage_finish(wpa);
f15ecfef058d94 Kirill Tkhai    2018-11-09  1896  	spin_unlock(&fi->lock);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1897  	fuse_writepage_free(wpa);
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1898  }
3be5a52b30aa5c Miklos Szeredi  2008-04-30  1899  
a9667ac88e2b20 Miklos Szeredi  2021-09-01  1900  static struct fuse_file *__fuse_write_file_get(struct fuse_inode *fi)
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1901  {
84840efc3c0f22 Miklos Szeredi  2021-10-22  1902  	struct fuse_file *ff;
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1903  
f15ecfef058d94 Kirill Tkhai    2018-11-09  1904  	spin_lock(&fi->lock);
84840efc3c0f22 Miklos Szeredi  2021-10-22  1905  	ff = list_first_entry_or_null(&fi->write_files, struct fuse_file,
72523425fb434e Miklos Szeredi  2013-10-01  1906  				      write_entry);
84840efc3c0f22 Miklos Szeredi  2021-10-22  1907  	if (ff)
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1908  		fuse_file_get(ff);
f15ecfef058d94 Kirill Tkhai    2018-11-09  1909  	spin_unlock(&fi->lock);
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1910  
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1911  	return ff;
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1912  }
adcadfa8f373f3 Pavel Emelyanov 2013-06-29  1913  
a9667ac88e2b20 Miklos Szeredi  2021-09-01  1914  static struct fuse_file *fuse_write_file_get(struct fuse_inode *fi)
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1915  {
a9667ac88e2b20 Miklos Szeredi  2021-09-01  1916  	struct fuse_file *ff = __fuse_write_file_get(fi);
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1917  	WARN_ON(!ff);
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1918  	return ff;
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1919  }
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1920  
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1921  int fuse_write_inode(struct inode *inode, struct writeback_control *wbc)
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1922  {
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1923  	struct fuse_inode *fi = get_fuse_inode(inode);
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1924  	struct fuse_file *ff;
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1925  	int err;
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1926  
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1927  	/*
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1928  	 * Inode is always written before the last reference is dropped and
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1929  	 * hence this should not be reached from reclaim.
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1930  	 *
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1931  	 * Writing back the inode from reclaim can deadlock if the request
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1932  	 * processing itself needs an allocation.  Allocations triggering
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1933  	 * reclaim while serving a request can't be prevented, because it can
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1934  	 * involve any number of unrelated userspace processes.
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1935  	 */
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1936  	WARN_ON(wbc->for_reclaim);
5c791fe1e2a4f4 Miklos Szeredi  2021-10-22  1937  
a9667ac88e2b20 Miklos Szeredi  2021-09-01  1938  	ff = __fuse_write_file_get(fi);
ab9e13f7c771b5 Maxim Patlasov  2014-04-28  1939  	err = fuse_flush_times(inode, ff);
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1940  	if (ff)
e26ee4efbc7961 Amir Goldstein  2024-02-01  1941  		fuse_file_put(ff, false);
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1942  
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1943  	return err;
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1944  }
1e18bda86e2dcc Miklos Szeredi  2014-04-28  1945  
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1946  static struct fuse_writepage_args *fuse_writepage_args_alloc(void)
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1947  {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1948  	struct fuse_writepage_args *wpa;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1949  	struct fuse_args_pages *ap;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1950  
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1951  	wpa = kzalloc(sizeof(*wpa), GFP_NOFS);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1952  	if (wpa) {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1953  		ap = &wpa->ia.ap;
cbe9c115b7441d Joanne Koong    2024-10-24  1954  		ap->num_folios = 0;
68bfb7eb7f7de3 Joanne Koong    2024-10-24  1955  		ap->folios = fuse_folios_alloc(1, GFP_NOFS, &ap->descs);
cbe9c115b7441d Joanne Koong    2024-10-24  1956  		if (!ap->folios) {
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1957  			kfree(wpa);
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1958  			wpa = NULL;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1959  		}
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1960  	}
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1961  	return wpa;
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1962  
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1963  }
33826ebbbe4b45 Miklos Szeredi  2019-09-10  1964  
660585b56e63ca Miklos Szeredi  2021-09-01  1965  static void fuse_writepage_add_to_bucket(struct fuse_conn *fc,
660585b56e63ca Miklos Szeredi  2021-09-01  1966  					 struct fuse_writepage_args *wpa)
660585b56e63ca Miklos Szeredi  2021-09-01  1967  {
660585b56e63ca Miklos Szeredi  2021-09-01  1968  	if (!fc->sync_fs)
660585b56e63ca Miklos Szeredi  2021-09-01  1969  		return;
660585b56e63ca Miklos Szeredi  2021-09-01  1970  
660585b56e63ca Miklos Szeredi  2021-09-01  1971  	rcu_read_lock();
660585b56e63ca Miklos Szeredi  2021-09-01  1972  	/* Prevent resurrection of dead bucket in unlikely race with syncfs */
660585b56e63ca Miklos Szeredi  2021-09-01  1973  	do {
660585b56e63ca Miklos Szeredi  2021-09-01  1974  		wpa->bucket = rcu_dereference(fc->curr_bucket);
660585b56e63ca Miklos Szeredi  2021-09-01  1975  	} while (unlikely(!atomic_inc_not_zero(&wpa->bucket->count)));
660585b56e63ca Miklos Szeredi  2021-09-01  1976  	rcu_read_unlock();
660585b56e63ca Miklos Szeredi  2021-09-01  1977  }
660585b56e63ca Miklos Szeredi  2021-09-01  1978  
0acad9289be33d Joanne Koong    2024-08-26  1979  static void fuse_writepage_args_page_fill(struct fuse_writepage_args *wpa, struct folio *folio,
0c58a97f919c24 Joanne Koong    2025-04-14  1980  					  uint32_t folio_index)
0acad9289be33d Joanne Koong    2024-08-26  1981  {
0acad9289be33d Joanne Koong    2024-08-26 @1982  	struct inode *inode = folio->mapping->host;
0acad9289be33d Joanne Koong    2024-08-26  1983  	struct fuse_args_pages *ap = &wpa->ia.ap;
0acad9289be33d Joanne Koong    2024-08-26  1984  
0c58a97f919c24 Joanne Koong    2025-04-14  1985  	ap->folios[folio_index] = folio;
68bfb7eb7f7de3 Joanne Koong    2024-10-24  1986  	ap->descs[folio_index].offset = 0;
f3cb8bd908c72e Joanne Koong    2025-05-12  1987  	ap->descs[folio_index].length = folio_size(folio);
0acad9289be33d Joanne Koong    2024-08-26  1988  }
0acad9289be33d Joanne Koong    2024-08-26  1989  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2025-07-04 13:00 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2025-07-03 16:45 [PATCH v1 1/2] fuse: use default writeback accounting Joanne Koong
2025-07-03 16:45 ` [PATCH v1 2/2] mm: remove BDI_CAP_WRITEBACK_ACCT Joanne Koong
2025-07-04 12:35   ` David Hildenbrand
2025-07-04 12:59 ` [PATCH v1 1/2] fuse: use default writeback accounting kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox