* [PATCH 0/5] Struct to fs_info helpers
@ 2024-01-29 18:33 David Sterba
2024-01-29 18:33 ` [PATCH 1/5] btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() David Sterba
` (4 more replies)
0 siblings, 5 replies; 21+ messages in thread
From: David Sterba @ 2024-01-29 18:33 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
Add convenience helpers for getting a fs_info from page, bio, inode etc.
There's one prep patch where tests use a normal helper that expects
valid inode->root->fs_info.
David Sterba (5):
btrfs: tests: allocate dummy fs_info and root in test_find_delalloc()
btrfs: add helpers to get inode from page/folio pointers
btrfs: add helpers to get fs_info from page/folio pointers
btrfs: add helper to get fs_info from struct inode pointer
btrfs: hoist fs_info out of loops in end_bbio_data_write and
end_bbio_data_read
fs/btrfs/compression.c | 8 +++---
fs/btrfs/defrag.c | 4 +--
fs/btrfs/disk-io.c | 11 ++++----
fs/btrfs/export.c | 2 +-
fs/btrfs/extent_io.c | 45 ++++++++++++++++----------------
fs/btrfs/file.c | 14 +++++-----
fs/btrfs/free-space-cache.c | 2 +-
fs/btrfs/inode.c | 42 ++++++++++++++---------------
fs/btrfs/ioctl.c | 40 ++++++++++++++--------------
fs/btrfs/lzo.c | 4 +--
fs/btrfs/misc.h | 6 +++++
fs/btrfs/props.c | 2 +-
fs/btrfs/reflink.c | 6 ++---
fs/btrfs/relocation.c | 2 +-
fs/btrfs/tests/extent-io-tests.c | 28 +++++++++++++++++---
15 files changed, 121 insertions(+), 95 deletions(-)
--
2.42.1
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 1/5] btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() 2024-01-29 18:33 [PATCH 0/5] Struct to fs_info helpers David Sterba @ 2024-01-29 18:33 ` David Sterba 2024-01-29 18:33 ` [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers David Sterba ` (3 subsequent siblings) 4 siblings, 0 replies; 21+ messages in thread From: David Sterba @ 2024-01-29 18:33 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba Allocate fs_info and root to have a valid fs_info pointer in case it's dereferenced by a helper outside of tests, like find_lock_delalloc_range(). Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/tests/extent-io-tests.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index 25b3349595e0..865d4af4b303 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c @@ -11,6 +11,7 @@ #include "btrfs-tests.h" #include "../ctree.h" #include "../extent_io.h" +#include "../disk-io.h" #include "../btrfs_inode.h" #define PROCESS_UNLOCK (1 << 0) @@ -105,9 +106,11 @@ static void dump_extent_io_tree(const struct extent_io_tree *tree) } } -static int test_find_delalloc(u32 sectorsize) +static int test_find_delalloc(u32 sectorsize, u32 nodesize) { - struct inode *inode; + struct btrfs_fs_info *fs_info; + struct btrfs_root *root = NULL; + struct inode *inode = NULL; struct extent_io_tree *tmp; struct page *page; struct page *locked_page = NULL; @@ -121,12 +124,27 @@ static int test_find_delalloc(u32 sectorsize) test_msg("running find delalloc tests"); + fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize); + if (!fs_info) { + test_std_err(TEST_ALLOC_FS_INFO); + return -ENOMEM; + } + + root = btrfs_alloc_dummy_root(fs_info); + if (IS_ERR(root)) { + test_std_err(TEST_ALLOC_ROOT); + ret = PTR_ERR(root); + goto out; + } + inode = btrfs_new_test_inode(); if (!inode) { test_std_err(TEST_ALLOC_INODE); - return -ENOMEM; + ret = -ENOMEM; + goto out; } tmp = &BTRFS_I(inode)->io_tree; + BTRFS_I(inode)->root = root; /* * Passing NULL as we don't have fs_info but tracepoints are not used @@ -316,6 +334,8 @@ static int test_find_delalloc(u32 sectorsize) process_page_range(inode, 0, total_dirty - 1, PROCESS_UNLOCK | PROCESS_RELEASE); iput(inode); + btrfs_free_dummy_root(root); + btrfs_free_dummy_fs_info(fs_info); return ret; } @@ -794,7 +814,7 @@ int btrfs_test_extent_io(u32 sectorsize, u32 nodesize) test_msg("running extent I/O tests"); - ret = test_find_delalloc(sectorsize); + ret = test_find_delalloc(sectorsize, nodesize); if (ret) goto out; -- 2.42.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers 2024-01-29 18:33 [PATCH 0/5] Struct to fs_info helpers David Sterba 2024-01-29 18:33 ` [PATCH 1/5] btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() David Sterba @ 2024-01-29 18:33 ` David Sterba 2024-01-30 11:42 ` Johannes Thumshirn 2024-01-29 18:33 ` [PATCH 3/5] btrfs: add helpers to get fs_info " David Sterba ` (2 subsequent siblings) 4 siblings, 1 reply; 21+ messages in thread From: David Sterba @ 2024-01-29 18:33 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba Add convenience helpers to get a struct btrfs_inode from a page or folio pointer instead of open coding the chain or intermediate BTRFS_I. This is implemented as a macro so we don't need full definitions of struct page or address_space. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/disk-io.c | 3 ++- fs/btrfs/extent_io.c | 8 ++++---- fs/btrfs/inode.c | 2 +- fs/btrfs/misc.h | 3 +++ 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 26c11fce5e4e..e711bfe4d221 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -528,7 +528,8 @@ static void btree_invalidate_folio(struct folio *folio, size_t offset, size_t length) { struct extent_io_tree *tree; - tree = &BTRFS_I(folio->mapping->host)->io_tree; + + tree = &folio_to_inode(folio)->io_tree; extent_invalidate_folio(tree, folio, offset); btree_release_folio(folio, GFP_NOFS); if (folio_get_private(folio)) { diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index baa149f2152c..46667c9d61a6 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -839,7 +839,7 @@ static void submit_extent_page(struct btrfs_bio_ctrl *bio_ctrl, u64 disk_bytenr, struct page *page, size_t size, unsigned long pg_offset) { - struct btrfs_inode *inode = BTRFS_I(page->mapping->host); + struct btrfs_inode *inode = page_to_inode(page); ASSERT(pg_offset + size <= PAGE_SIZE); ASSERT(bio_ctrl->end_io_func); @@ -1171,7 +1171,7 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, int btrfs_read_folio(struct file *file, struct folio *folio) { struct page *page = &folio->page; - struct btrfs_inode *inode = BTRFS_I(page->mapping->host); + struct btrfs_inode *inode = page_to_inode(page); u64 start = page_offset(page); u64 end = start + PAGE_SIZE - 1; struct btrfs_bio_ctrl bio_ctrl = { .opf = REQ_OP_READ }; @@ -1194,7 +1194,7 @@ static inline void contiguous_readpages(struct page *pages[], int nr_pages, struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start) { - struct btrfs_inode *inode = BTRFS_I(pages[0]->mapping->host); + struct btrfs_inode *inode = page_to_inode(pages[0]); int index; btrfs_lock_and_flush_ordered_range(inode, start, end, NULL); @@ -2392,7 +2392,7 @@ int try_release_extent_mapping(struct page *page, gfp_t mask) struct extent_map *em; u64 start = page_offset(page); u64 end = start + PAGE_SIZE - 1; - struct btrfs_inode *btrfs_inode = BTRFS_I(page->mapping->host); + struct btrfs_inode *btrfs_inode = page_to_inode(page); struct extent_io_tree *tree = &btrfs_inode->io_tree; struct extent_map_tree *map = &btrfs_inode->extent_tree; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index b2d348c9c93b..2d3e5359d067 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7936,7 +7936,7 @@ static int btrfs_migrate_folio(struct address_space *mapping, static void btrfs_invalidate_folio(struct folio *folio, size_t offset, size_t length) { - struct btrfs_inode *inode = BTRFS_I(folio->mapping->host); + struct btrfs_inode *inode = folio_to_inode(folio); struct btrfs_fs_info *fs_info = inode->root->fs_info; struct extent_io_tree *tree = &inode->io_tree; struct extent_state *cached_state = NULL; diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h index 40f2d9f1a17a..8be09234c575 100644 --- a/fs/btrfs/misc.h +++ b/fs/btrfs/misc.h @@ -8,6 +8,9 @@ #include <linux/math64.h> #include <linux/rbtree.h> +#define page_to_inode(page) BTRFS_I((page)->mapping->host) +#define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) + /* * Enumerate bits using enum autoincrement. Define the @name as the n-th bit. */ -- 2.42.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers 2024-01-29 18:33 ` [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers David Sterba @ 2024-01-30 11:42 ` Johannes Thumshirn 2024-01-30 19:29 ` David Sterba 0 siblings, 1 reply; 21+ messages in thread From: Johannes Thumshirn @ 2024-01-30 11:42 UTC (permalink / raw) To: David Sterba, linux-btrfs@vger.kernel.org On 29.01.24 19:33, David Sterba wrote: > diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h > index 40f2d9f1a17a..8be09234c575 100644 > --- a/fs/btrfs/misc.h > +++ b/fs/btrfs/misc.h > @@ -8,6 +8,9 @@ > #include <linux/math64.h> > #include <linux/rbtree.h> > > +#define page_to_inode(page) BTRFS_I((page)->mapping->host) > +#define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) > + Why are you using a macro instead of an inline function here? Shouldn't inline function give us a bit more type safety, or are compilers smart enough nowadays? ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers 2024-01-30 11:42 ` Johannes Thumshirn @ 2024-01-30 19:29 ` David Sterba 2024-01-31 9:33 ` Johannes Thumshirn 0 siblings, 1 reply; 21+ messages in thread From: David Sterba @ 2024-01-30 19:29 UTC (permalink / raw) To: Johannes Thumshirn; +Cc: David Sterba, linux-btrfs@vger.kernel.org On Tue, Jan 30, 2024 at 11:42:30AM +0000, Johannes Thumshirn wrote: > On 29.01.24 19:33, David Sterba wrote: > > diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h > > index 40f2d9f1a17a..8be09234c575 100644 > > --- a/fs/btrfs/misc.h > > +++ b/fs/btrfs/misc.h > > @@ -8,6 +8,9 @@ > > #include <linux/math64.h> > > #include <linux/rbtree.h> > > > > +#define page_to_inode(page) BTRFS_I((page)->mapping->host) > > +#define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) > > + > > Why are you using a macro instead of an inline function here? As said in the changelog so we don't have to include headers with full definitions of page, folio, fs_info, ... > Shouldn't inline function give us a bit more type safety, or are > compilers smart enough nowadays? Yes type safety would be good but then it can't be an inline without bloating misc.h (and the making include cycles). I could do a type check in the macro using _Generic. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers 2024-01-30 19:29 ` David Sterba @ 2024-01-31 9:33 ` Johannes Thumshirn 2024-01-31 17:19 ` David Sterba 0 siblings, 1 reply; 21+ messages in thread From: Johannes Thumshirn @ 2024-01-31 9:33 UTC (permalink / raw) To: dsterba@suse.cz; +Cc: David Sterba, linux-btrfs@vger.kernel.org On 30.01.24 20:29, David Sterba wrote: > On Tue, Jan 30, 2024 at 11:42:30AM +0000, Johannes Thumshirn wrote: >> On 29.01.24 19:33, David Sterba wrote: >>> diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h >>> index 40f2d9f1a17a..8be09234c575 100644 >>> --- a/fs/btrfs/misc.h >>> +++ b/fs/btrfs/misc.h >>> @@ -8,6 +8,9 @@ >>> #include <linux/math64.h> >>> #include <linux/rbtree.h> >>> >>> +#define page_to_inode(page) BTRFS_I((page)->mapping->host) >>> +#define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) >>> + >> >> Why are you using a macro instead of an inline function here? > > As said in the changelog so we don't have to include headers with full > definitions of page, folio, fs_info, ... > >> Shouldn't inline function give us a bit more type safety, or are >> compilers smart enough nowadays? > > Yes type safety would be good but then it can't be an inline without > bloating misc.h (and the making include cycles). I personally would've put them into fs.h anyways. > > I could do a type check in the macro using _Generic. > ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers 2024-01-31 9:33 ` Johannes Thumshirn @ 2024-01-31 17:19 ` David Sterba 0 siblings, 0 replies; 21+ messages in thread From: David Sterba @ 2024-01-31 17:19 UTC (permalink / raw) To: Johannes Thumshirn Cc: dsterba@suse.cz, David Sterba, linux-btrfs@vger.kernel.org On Wed, Jan 31, 2024 at 09:33:58AM +0000, Johannes Thumshirn wrote: > On 30.01.24 20:29, David Sterba wrote: > > On Tue, Jan 30, 2024 at 11:42:30AM +0000, Johannes Thumshirn wrote: > >> On 29.01.24 19:33, David Sterba wrote: > >>> diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h > >>> index 40f2d9f1a17a..8be09234c575 100644 > >>> --- a/fs/btrfs/misc.h > >>> +++ b/fs/btrfs/misc.h > >>> @@ -8,6 +8,9 @@ > >>> #include <linux/math64.h> > >>> #include <linux/rbtree.h> > >>> > >>> +#define page_to_inode(page) BTRFS_I((page)->mapping->host) > >>> +#define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) > >>> + > >> > >> Why are you using a macro instead of an inline function here? > > > > As said in the changelog so we don't have to include headers with full > > definitions of page, folio, fs_info, ... > > > >> Shouldn't inline function give us a bit more type safety, or are > >> compilers smart enough nowadays? > > > > Yes type safety would be good but then it can't be an inline without > > bloating misc.h (and the making include cycles). > > I personally would've put them into fs.h anyways. Right, that's more suitable, misc.h is for all the non-fs things. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 3/5] btrfs: add helpers to get fs_info from page/folio pointers 2024-01-29 18:33 [PATCH 0/5] Struct to fs_info helpers David Sterba 2024-01-29 18:33 ` [PATCH 1/5] btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() David Sterba 2024-01-29 18:33 ` [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers David Sterba @ 2024-01-29 18:33 ` David Sterba 2024-01-30 11:58 ` Johannes Thumshirn 2024-01-29 18:33 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba 2024-01-29 18:33 ` [PATCH 5/5] btrfs: hoist fs_info out of loops in end_bbio_data_write and end_bbio_data_read David Sterba 4 siblings, 1 reply; 21+ messages in thread From: David Sterba @ 2024-01-29 18:33 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba Add convenience helpers to get a fs_info from a page or folio pointer instead of open coding the chain or using btrfs_sb() that in some cases does one more pointer hop. This is implemented as a macro so we don't need full definitions of struct page or address_space. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/compression.c | 2 +- fs/btrfs/disk-io.c | 2 +- fs/btrfs/extent_io.c | 18 +++++++++--------- fs/btrfs/inode.c | 2 +- fs/btrfs/lzo.c | 2 +- fs/btrfs/misc.h | 2 ++ 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 488089acd49f..9cae8542c7e0 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -1036,7 +1036,7 @@ static int btrfs_decompress_bio(struct compressed_bio *cb) int btrfs_decompress(int type, const u8 *data_in, struct page *dest_page, unsigned long dest_pgoff, size_t srclen, size_t destlen) { - struct btrfs_fs_info *fs_info = btrfs_sb(dest_page->mapping->host->i_sb); + struct btrfs_fs_info *fs_info = page_to_fs_info(dest_page); struct list_head *workspace; const u32 sectorsize = fs_info->sectorsize; int ret; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e711bfe4d221..ebefc69ddcfa 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -533,7 +533,7 @@ static void btree_invalidate_folio(struct folio *folio, size_t offset, extent_invalidate_folio(tree, folio, offset); btree_release_folio(folio, GFP_NOFS); if (folio_get_private(folio)) { - btrfs_warn(BTRFS_I(folio->mapping->host)->root->fs_info, + btrfs_warn(folio_to_fs_info(folio), "folio private not zero on folio %llu", (unsigned long long)folio_pos(folio)); folio_detach_private(folio); diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 46667c9d61a6..7327b276cd07 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -432,7 +432,7 @@ static bool btrfs_verify_page(struct page *page, u64 start) static void end_page_read(struct page *page, bool uptodate, u64 start, u32 len) { - struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb); + struct btrfs_fs_info *fs_info = page_to_fs_info(page); struct folio *folio = page_folio(page); ASSERT(page_offset(page) <= start && @@ -960,7 +960,7 @@ int set_folio_extent_mapped(struct folio *folio) if (folio_test_private(folio)) return 0; - fs_info = btrfs_sb(folio->mapping->host->i_sb); + fs_info = folio_to_fs_info(page); if (btrfs_is_subpage(fs_info, folio->mapping)) return btrfs_attach_subpage(fs_info, folio, BTRFS_SUBPAGE_DATA); @@ -979,7 +979,7 @@ void clear_page_extent_mapped(struct page *page) if (!folio_test_private(folio)) return; - fs_info = btrfs_sb(page->mapping->host->i_sb); + fs_info = page_to_fs_info(page); if (btrfs_is_subpage(fs_info, page->mapping)) return btrfs_detach_subpage(fs_info, folio); @@ -1780,7 +1780,7 @@ static noinline_for_stack void write_one_eb(struct extent_buffer *eb, */ static int submit_eb_subpage(struct page *page, struct writeback_control *wbc) { - struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb); + struct btrfs_fs_info *fs_info = page_to_fs_info(page); struct folio *folio = page_folio(page); int submitted = 0; u64 page_start = page_offset(page); @@ -1871,7 +1871,7 @@ static int submit_eb_page(struct page *page, struct btrfs_eb_write_context *ctx) if (!folio_test_private(folio)) return 0; - if (btrfs_sb(page->mapping->host->i_sb)->nodesize < PAGE_SIZE) + if (page_to_fs_info(page)->nodesize < PAGE_SIZE) return submit_eb_subpage(page, wbc); spin_lock(&mapping->i_private_lock); @@ -1929,7 +1929,7 @@ int btree_write_cache_pages(struct address_space *mapping, struct writeback_control *wbc) { struct btrfs_eb_write_context ctx = { .wbc = wbc }; - struct btrfs_fs_info *fs_info = BTRFS_I(mapping->host)->root->fs_info; + struct btrfs_fs_info *fs_info = page_to_fs_info(mapping->host); int ret = 0; int done = 0; int nr_to_write_done = 0; @@ -2323,7 +2323,7 @@ int extent_invalidate_folio(struct extent_io_tree *tree, struct extent_state *cached_state = NULL; u64 start = folio_pos(folio); u64 end = start + folio_size(folio) - 1; - size_t blocksize = btrfs_sb(folio->mapping->host->i_sb)->sectorsize; + size_t blocksize = folio_to_fs_info(folio)->sectorsize; /* This function is only called for the btree inode */ ASSERT(tree->owner == IO_TREE_BTREE_INODE_IO); @@ -4783,7 +4783,7 @@ static struct extent_buffer *get_next_extent_buffer( static int try_release_subpage_extent_buffer(struct page *page) { - struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb); + struct btrfs_fs_info *fs_info = page_to_fs_info(page); u64 cur = page_offset(page); const u64 end = page_offset(page) + PAGE_SIZE; int ret; @@ -4856,7 +4856,7 @@ int try_release_extent_buffer(struct page *page) struct folio *folio = page_folio(page); struct extent_buffer *eb; - if (btrfs_sb(page->mapping->host->i_sb)->nodesize < PAGE_SIZE) + if (page_to_fs_info(page)->nodesize < PAGE_SIZE) return try_release_subpage_extent_buffer(page); /* diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2d3e5359d067..27d67c4580bc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -7869,7 +7869,7 @@ static void btrfs_readahead(struct readahead_control *rac) */ static void wait_subpage_spinlock(struct page *page) { - struct btrfs_fs_info *fs_info = btrfs_sb(page->mapping->host->i_sb); + struct btrfs_fs_info *fs_info = page_to_fs_info(page); struct folio *folio = page_folio(page); struct btrfs_subpage *subpage; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index e43bc0fdc74e..110a2c304bdc 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -429,7 +429,7 @@ int lzo_decompress(struct list_head *ws, const u8 *data_in, size_t destlen) { struct workspace *workspace = list_entry(ws, struct workspace, list); - struct btrfs_fs_info *fs_info = btrfs_sb(dest_page->mapping->host->i_sb); + struct btrfs_fs_info *fs_info = page_to_fs_info(dest_page); const u32 sectorsize = fs_info->sectorsize; size_t in_len; size_t out_len; diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h index 8be09234c575..9cb671ef136c 100644 --- a/fs/btrfs/misc.h +++ b/fs/btrfs/misc.h @@ -10,6 +10,8 @@ #define page_to_inode(page) BTRFS_I((page)->mapping->host) #define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) +#define page_to_fs_info(page) BTRFS_I((page)->mapping->host)->root->fs_info +#define folio_to_fs_info(page) BTRFS_I((folio)->mapping->host)->root->fs_info /* * Enumerate bits using enum autoincrement. Define the @name as the n-th bit. -- 2.42.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 3/5] btrfs: add helpers to get fs_info from page/folio pointers 2024-01-29 18:33 ` [PATCH 3/5] btrfs: add helpers to get fs_info " David Sterba @ 2024-01-30 11:58 ` Johannes Thumshirn 2024-01-30 19:32 ` David Sterba 0 siblings, 1 reply; 21+ messages in thread From: Johannes Thumshirn @ 2024-01-30 11:58 UTC (permalink / raw) To: David Sterba, linux-btrfs@vger.kernel.org On 29.01.24 19:34, David Sterba wrote: > @@ -1929,7 +1929,7 @@ int btree_write_cache_pages(struct address_space *mapping, > struct writeback_control *wbc) > { > struct btrfs_eb_write_context ctx = { .wbc = wbc }; > - struct btrfs_fs_info *fs_info = BTRFS_I(mapping->host)->root->fs_info; > + struct btrfs_fs_info *fs_info = page_to_fs_info(mapping->host); This is wrong, page_to_fs_info() expects a struct page, but mapping->host gives you a struct inode. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 3/5] btrfs: add helpers to get fs_info from page/folio pointers 2024-01-30 11:58 ` Johannes Thumshirn @ 2024-01-30 19:32 ` David Sterba 0 siblings, 0 replies; 21+ messages in thread From: David Sterba @ 2024-01-30 19:32 UTC (permalink / raw) To: Johannes Thumshirn; +Cc: David Sterba, linux-btrfs@vger.kernel.org On Tue, Jan 30, 2024 at 11:58:40AM +0000, Johannes Thumshirn wrote: > On 29.01.24 19:34, David Sterba wrote: > > @@ -1929,7 +1929,7 @@ int btree_write_cache_pages(struct address_space *mapping, > > struct writeback_control *wbc) > > { > > struct btrfs_eb_write_context ctx = { .wbc = wbc }; > > - struct btrfs_fs_info *fs_info = BTRFS_I(mapping->host)->root->fs_info; > > + struct btrfs_fs_info *fs_info = page_to_fs_info(mapping->host); > > This is wrong, page_to_fs_info() expects a struct page, but > mapping->host gives you a struct inode. Right, strange that it did not crash. We need the type checking for such errors. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-01-29 18:33 [PATCH 0/5] Struct to fs_info helpers David Sterba ` (2 preceding siblings ...) 2024-01-29 18:33 ` [PATCH 3/5] btrfs: add helpers to get fs_info " David Sterba @ 2024-01-29 18:33 ` David Sterba 2024-01-30 11:49 ` Johannes Thumshirn 2024-01-31 7:23 ` David Sterba 2024-01-29 18:33 ` [PATCH 5/5] btrfs: hoist fs_info out of loops in end_bbio_data_write and end_bbio_data_read David Sterba 4 siblings, 2 replies; 21+ messages in thread From: David Sterba @ 2024-01-29 18:33 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba Add a convenience helper to get a fs_info from a VFS inode pointer instead of open coding the chain or using btrfs_sb() that in some cases does one more pointer hop. This is implemented as a macro so we don't need full defitions of struct page or address_space. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/compression.c | 6 +++--- fs/btrfs/defrag.c | 4 ++-- fs/btrfs/disk-io.c | 6 +++--- fs/btrfs/export.c | 2 +- fs/btrfs/extent_io.c | 12 +++++------ fs/btrfs/file.c | 14 ++++++------- fs/btrfs/free-space-cache.c | 2 +- fs/btrfs/inode.c | 38 +++++++++++++++++------------------ fs/btrfs/ioctl.c | 40 ++++++++++++++++++------------------- fs/btrfs/lzo.c | 2 +- fs/btrfs/misc.h | 1 + fs/btrfs/props.c | 2 +- fs/btrfs/reflink.c | 6 +++--- fs/btrfs/relocation.c | 2 +- 14 files changed, 69 insertions(+), 68 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 9cae8542c7e0..0b8833baf404 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -281,7 +281,7 @@ static void end_bbio_comprssed_read(struct btrfs_bio *bbio) static noinline void end_compressed_writeback(const struct compressed_bio *cb) { struct inode *inode = &cb->bbio.inode->vfs_inode; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); unsigned long index = cb->start >> PAGE_SHIFT; unsigned long end_index = (cb->start + cb->len - 1) >> PAGE_SHIFT; struct folio_batch fbatch; @@ -412,7 +412,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, struct compressed_bio *cb, int *memstall, unsigned long *pflags) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); unsigned long end_index; struct bio *orig_bio = &cb->orig_bbio->bio; u64 cur = cb->orig_bbio->file_offset + orig_bio->bi_iter.bi_size; @@ -438,7 +438,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, * This makes readahead less effective, so here disable readahead for * subpage for now, until full compressed write is supported. */ - if (btrfs_sb(inode->i_sb)->sectorsize < PAGE_SIZE) + if (fs_info->sectorsize < PAGE_SIZE) return 0; end_index = (i_size_read(inode) - 1) >> PAGE_SHIFT; diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index 8fc8118c3225..3878ce0cb88e 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -809,7 +809,7 @@ static u32 get_extent_max_capacity(const struct btrfs_fs_info *fs_info, static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em, u32 extent_thresh, u64 newer_than, bool locked) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *next; bool ret = false; @@ -1364,7 +1364,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, struct btrfs_ioctl_defrag_range_args *range, u64 newer_than, unsigned long max_to_defrag) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); unsigned long sectors_defragged = 0; u64 isize = i_size_read(inode); u64 cur; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ebefc69ddcfa..3127ca68fc9d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -497,15 +497,15 @@ static int btree_migrate_folio(struct address_space *mapping, static int btree_writepages(struct address_space *mapping, struct writeback_control *wbc) { - struct btrfs_fs_info *fs_info; int ret; if (wbc->sync_mode == WB_SYNC_NONE) { + struct btrfs_fs_info *fs_info; if (wbc->for_kupdate) return 0; - fs_info = BTRFS_I(mapping->host)->root->fs_info; + fs_info = inode_to_fs_info(mapping->host); /* this is a bit racy, but that's ok */ ret = __percpu_counter_compare(&fs_info->dirty_metadata_bytes, BTRFS_DIRTY_METADATA_THRESH, @@ -544,7 +544,7 @@ static void btree_invalidate_folio(struct folio *folio, size_t offset, static bool btree_dirty_folio(struct address_space *mapping, struct folio *folio) { - struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host); struct btrfs_subpage_info *spi = fs_info->subpage_info; struct btrfs_subpage *subpage; struct extent_buffer *eb; diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 3f2e8fb9e3e9..2f9e3c1c60f0 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c @@ -214,7 +214,7 @@ static int btrfs_get_name(struct dentry *parent, char *name, { struct inode *inode = d_inode(child); struct inode *dir = d_inode(parent); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_path *path; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_inode_ref *iref; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 7327b276cd07..9d6d4dab9ae3 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -206,7 +206,7 @@ static void __process_pages_contig(struct address_space *mapping, struct page *locked_page, u64 start, u64 end, unsigned long page_ops) { - struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host); pgoff_t start_index = start >> PAGE_SHIFT; pgoff_t end_index = end >> PAGE_SHIFT; pgoff_t index = start_index; @@ -250,7 +250,7 @@ static noinline int lock_delalloc_pages(struct inode *inode, u64 start, u64 end) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct address_space *mapping = inode->i_mapping; pgoff_t start_index = start >> PAGE_SHIFT; pgoff_t end_index = end >> PAGE_SHIFT; @@ -322,7 +322,7 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, struct page *locked_page, u64 *start, u64 *end) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; const u64 orig_start = *start; const u64 orig_end = *end; @@ -1022,7 +1022,7 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start) { struct inode *inode = page->mapping->host; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); u64 start = page_offset(page); const u64 end = start + PAGE_SIZE - 1; u64 cur = start; @@ -1929,7 +1929,7 @@ int btree_write_cache_pages(struct address_space *mapping, struct writeback_control *wbc) { struct btrfs_eb_write_context ctx = { .wbc = wbc }; - struct btrfs_fs_info *fs_info = page_to_fs_info(mapping->host); + struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host); int ret = 0; int done = 0; int nr_to_write_done = 0; @@ -2217,7 +2217,7 @@ void extent_write_locked_range(struct inode *inode, struct page *locked_page, bool found_error = false; int ret = 0; struct address_space *mapping = inode->i_mapping; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); const u32 sectorsize = fs_info->sectorsize; loff_t i_size = i_size_read(inode); u64 cur = start; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 4bca37fd6833..7e82a40e2a44 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1135,7 +1135,7 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); loff_t pos = iocb->ki_pos; int ret; loff_t oldsize; @@ -1183,7 +1183,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, struct file *file = iocb->ki_filp; loff_t pos; struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct page **pages = NULL; struct extent_changeset *data_reserved = NULL; u64 release_bytes = 0; @@ -1459,7 +1459,7 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); loff_t pos; ssize_t written = 0; ssize_t written_buffered; @@ -1785,7 +1785,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) { struct dentry *dentry = file_dentry(file); struct inode *inode = d_inode(dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; struct btrfs_log_ctx ctx; @@ -2591,7 +2591,7 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, static int btrfs_punch_hole(struct file *file, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_state *cached_state = NULL; struct btrfs_path *path; @@ -3046,7 +3046,7 @@ static long btrfs_fallocate(struct file *file, int mode, int ret; /* Do not allow fallocate in ZONED mode */ - if (btrfs_is_zoned(btrfs_sb(inode->i_sb))) + if (btrfs_is_zoned(inode_to_fs_info(inode))) return -EOPNOTSUPP; alloc_start = round_down(offset, blocksize); @@ -3751,7 +3751,7 @@ static ssize_t btrfs_direct_read(struct kiocb *iocb, struct iov_iter *to) if (fsverity_active(inode)) return 0; - if (check_direct_read(btrfs_sb(inode->i_sb), to, iocb->ki_pos)) + if (check_direct_read(inode_to_fs_info(inode), to, iocb->ki_pos)) return 0; btrfs_inode_lock(BTRFS_I(inode), BTRFS_ILOCK_SHARED); diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index f74b13f9b193..43a35c65c25f 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -397,7 +397,7 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, return -ENOMEM; io_ctl->num_pages = num_pages; - io_ctl->fs_info = btrfs_sb(inode->i_sb); + io_ctl->fs_info = inode_to_fs_info(inode); io_ctl->inode = inode; return 0; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 27d67c4580bc..015c2db7139a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2827,7 +2827,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) int btrfs_writepage_cow_fixup(struct page *page) { struct inode *inode = page->mapping->host; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_writepage_fixup *fixup; /* This page has ordered extent covering it already */ @@ -3242,7 +3242,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered) { - if (btrfs_is_zoned(btrfs_sb(ordered->inode->i_sb)) && + if (btrfs_is_zoned(inode_to_fs_info(ordered->inode)) && !test_bit(BTRFS_ORDERED_IOERR, &ordered->flags) && list_empty(&ordered->bioc_list)) btrfs_finish_ordered_zoned(ordered); @@ -3727,7 +3727,7 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf, static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *in_path) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_path *path = in_path; struct extent_buffer *leaf; struct btrfs_inode_item *inode_item; @@ -4452,8 +4452,8 @@ static void btrfs_prune_dentries(struct btrfs_root *root) int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry) { - struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); struct btrfs_root *root = dir->root; + struct btrfs_fs_info *fs_info = root->fs_info; struct inode *inode = d_inode(dentry); struct btrfs_root *dest = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; @@ -5008,7 +5008,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_drew_write_unlock(&root->snapshot_lock); btrfs_end_transaction(trans); } else { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); if (btrfs_is_zoned(fs_info)) { ret = btrfs_wait_ordered_range(inode, @@ -5211,7 +5211,7 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root, void btrfs_evict_inode(struct inode *inode) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_block_rsv *rsv = NULL; @@ -5650,7 +5650,7 @@ static inline u8 btrfs_inode_type(struct inode *inode) struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct inode *inode; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *sub_root = root; @@ -6189,7 +6189,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, struct inode *dir = args->dir; struct inode *inode = args->inode; const struct fscrypt_str *name = args->orphan ? NULL : &args->fname.disk_name; - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_root *root; struct btrfs_inode_item *inode_item; struct btrfs_key *location; @@ -6511,7 +6511,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, static int btrfs_create_common(struct inode *dir, struct dentry *dentry, struct inode *inode) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_new_inode_args new_inode_args = { .dir = dir, @@ -6581,7 +6581,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, struct btrfs_trans_handle *trans = NULL; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = d_inode(old_dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct fscrypt_name fname; u64 index; int err; @@ -7064,7 +7064,7 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, u64 *orig_start, u64 *orig_block_len, u64 *ram_bytes, bool nowait, bool strict) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct can_nocow_file_extent_args nocow_args = { 0 }; struct btrfs_path *path; int ret; @@ -7303,7 +7303,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, unsigned int iomap_flags) { const bool nowait = (iomap_flags & IOMAP_NOWAIT); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *em = *map; int type; u64 block_start, orig_start, orig_block_len, ram_bytes; @@ -7443,7 +7443,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start, struct iomap *srcmap) { struct iomap_iter *iter = container_of(iomap, struct iomap_iter, iomap); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *em; struct extent_state *cached_state = NULL; struct btrfs_dio_data *dio_data = iter->private; @@ -8120,7 +8120,7 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) struct page *page = vmf->page; struct folio *folio = page_folio(page); struct inode *inode = file_inode(vmf->vma->vm_file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; @@ -8729,7 +8729,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, struct inode *new_dir, struct dentry *new_dentry) { - struct btrfs_fs_info *fs_info = btrfs_sb(old_dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(old_dir); struct btrfs_trans_handle *trans; unsigned int trans_num_items; struct btrfs_root *root = BTRFS_I(old_dir)->root; @@ -8981,7 +8981,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { - struct btrfs_fs_info *fs_info = btrfs_sb(old_dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(old_dir); struct btrfs_new_inode_args whiteout_args = { .dir = old_dir, .dentry = old_dentry, @@ -9423,7 +9423,7 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr, static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, const char *symname) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_path *path; @@ -9604,7 +9604,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, loff_t actual_len, u64 *alloc_hint, struct btrfs_trans_handle *trans) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *em; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_key ins; @@ -9756,7 +9756,7 @@ static int btrfs_permission(struct mnt_idmap *idmap, static int btrfs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, struct file *file, umode_t mode) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 46f9a6645bf6..ec9084ee23a5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -243,7 +243,7 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_inode *binode = BTRFS_I(inode); struct btrfs_root *root = binode->root; struct btrfs_trans_handle *trans; @@ -580,7 +580,7 @@ static noinline int create_subvol(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, struct btrfs_qgroup_inherit *inherit) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_trans_handle *trans; struct btrfs_key key; struct btrfs_root_item *root_item; @@ -772,7 +772,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, struct dentry *dentry, bool readonly, struct btrfs_qgroup_inherit *inherit) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct inode *inode; struct btrfs_pending_snapshot *pending_snapshot; unsigned int trans_num_items; @@ -958,7 +958,7 @@ static noinline int btrfs_mksubvol(const struct path *parent, struct btrfs_qgroup_inherit *inherit) { struct inode *dir = d_inode(parent->dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct dentry *dentry; struct fscrypt_str name_str = FSTR_INIT((char *)name, namelen); int error; @@ -1093,7 +1093,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, { BTRFS_DEV_LOOKUP_ARGS(args); struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); u64 new_size; u64 old_size; u64 devid = 1; @@ -1401,7 +1401,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, static noinline int btrfs_ioctl_subvol_getflags(struct inode *inode, void __user *arg) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; int ret = 0; u64 flags = 0; @@ -1424,7 +1424,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; u64 root_flags; @@ -1671,7 +1671,7 @@ static noinline int search_ioctl(struct inode *inode, u64 *buf_size, char __user *ubuf) { - struct btrfs_fs_info *info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *info = inode_to_fs_info(inode); struct btrfs_root *root; struct btrfs_key key; struct btrfs_path *path; @@ -2342,9 +2342,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, bool destroy_v2) { struct dentry *parent = file->f_path.dentry; - struct btrfs_fs_info *fs_info = btrfs_sb(parent->d_sb); struct dentry *dentry; struct inode *dir = d_inode(parent); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct inode *inode; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *dest = NULL; @@ -2692,7 +2692,7 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) { BTRFS_DEV_LOOKUP_ARGS(args); struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_vol_args_v2 *vol_args; struct bdev_handle *bdev_handle = NULL; int ret; @@ -2757,7 +2757,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) { BTRFS_DEV_LOOKUP_ARGS(args); struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_vol_args *vol_args; struct bdev_handle *bdev_handle = NULL; int ret; @@ -2900,7 +2900,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *new_root; struct btrfs_dir_item *di; @@ -3174,7 +3174,7 @@ static noinline long btrfs_ioctl_wait_sync(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_scrub(struct file *file, void __user *arg) { - struct btrfs_fs_info *fs_info = btrfs_sb(file_inode(file)->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(file_inode(file)); struct btrfs_ioctl_scrub_args *sa; int ret; @@ -3692,7 +3692,7 @@ static long btrfs_ioctl_balance_progress(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_quota_ctl_args *sa; int ret; @@ -3734,7 +3734,7 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_ioctl_qgroup_assign_args *sa; struct btrfs_trans_handle *trans; @@ -3890,7 +3890,7 @@ static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_quota_rescan_args *qsa; int ret; @@ -3954,7 +3954,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, struct btrfs_ioctl_received_subvol_args *sa) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root_item *root_item = &root->root_item; struct btrfs_trans_handle *trans; @@ -4142,7 +4142,7 @@ static int btrfs_ioctl_get_fslabel(struct btrfs_fs_info *fs_info, static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_trans_handle *trans; @@ -4285,7 +4285,7 @@ check_feature_bits(fs_info, FEAT_##mask_base, change_mask, flags, \ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_ioctl_feature_flags flags[2]; @@ -4576,7 +4576,7 @@ long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; void __user *argp = (void __user *)arg; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 110a2c304bdc..3e5d3b7028e8 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -214,7 +214,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, unsigned long *total_in, unsigned long *total_out) { struct workspace *workspace = list_entry(ws, struct workspace, list); - const u32 sectorsize = btrfs_sb(mapping->host->i_sb)->sectorsize; + const u32 sectorsize = inode_to_fs_info(mapping->host)->sectorsize; struct page *page_in = NULL; char *sizes_ptr; const unsigned long max_nr_page = *out_pages; diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h index 9cb671ef136c..7fcbf9e115ca 100644 --- a/fs/btrfs/misc.h +++ b/fs/btrfs/misc.h @@ -12,6 +12,7 @@ #define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) #define page_to_fs_info(page) BTRFS_I((page)->mapping->host)->root->fs_info #define folio_to_fs_info(page) BTRFS_I((folio)->mapping->host)->root->fs_info +#define inode_to_fs_info(inode) BTRFS_I(inode)->root->fs_info /* * Enumerate bits using enum autoincrement. Define the @name as the n-th bit. diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index f9bf591a0718..ac4a0af2b554 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -302,7 +302,7 @@ static int prop_compression_validate(const struct btrfs_inode *inode, static int prop_compression_apply(struct inode *inode, const char *value, size_t len) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); int type; /* Reset to defaults */ diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c index e38cb40e150c..08d0fb46ceec 100644 --- a/fs/btrfs/reflink.c +++ b/fs/btrfs/reflink.c @@ -174,7 +174,7 @@ static int clone_copy_inline_extent(struct inode *dst, char *inline_data, struct btrfs_trans_handle **trans_out) { - struct btrfs_fs_info *fs_info = btrfs_sb(dst->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dst); struct btrfs_root *root = BTRFS_I(dst)->root; const u64 aligned_end = ALIGN(new_key->offset + datal, fs_info->sectorsize); @@ -337,7 +337,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, const u64 off, const u64 olen, const u64 olen_aligned, const u64 destoff, int no_time_update) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_path *path = NULL; struct extent_buffer *leaf; struct btrfs_trans_handle *trans; @@ -726,7 +726,7 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src, { struct inode *inode = file_inode(file); struct inode *src = file_inode(file_src); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); int ret; int wb_ret; u64 len = olen; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index d9e70106c901..0882b220bb12 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2987,7 +2987,7 @@ static int relocate_one_folio(struct inode *inode, struct file_ra_state *ra, const struct file_extent_cluster *cluster, int *cluster_nr, unsigned long index) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); u64 offset = BTRFS_I(inode)->index_cnt; const unsigned long last_index = (cluster->end - offset) >> PAGE_SHIFT; gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); -- 2.42.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-01-29 18:33 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba @ 2024-01-30 11:49 ` Johannes Thumshirn 2024-01-30 19:31 ` David Sterba 2024-01-31 7:23 ` David Sterba 1 sibling, 1 reply; 21+ messages in thread From: Johannes Thumshirn @ 2024-01-30 11:49 UTC (permalink / raw) To: David Sterba, linux-btrfs@vger.kernel.org On 29.01.24 19:34, David Sterba wrote: > diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h > index 9cb671ef136c..7fcbf9e115ca 100644 > --- a/fs/btrfs/misc.h > +++ b/fs/btrfs/misc.h > @@ -12,6 +12,7 @@ > #define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) > #define page_to_fs_info(page) BTRFS_I((page)->mapping->host)->root->fs_info > #define folio_to_fs_info(page) BTRFS_I((folio)->mapping->host)->root->fs_info > +#define inode_to_fs_info(inode) BTRFS_I(inode)->root->fs_info > If you'd switch patches 3 and 4 you could do #define page_to_fs_info(page) inode_to_fs_info(page_to_inode(page)) #define folio_to_fs_info(folio) inode_to_fs_info(folio_to_inode(folio)) ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-01-30 11:49 ` Johannes Thumshirn @ 2024-01-30 19:31 ` David Sterba 0 siblings, 0 replies; 21+ messages in thread From: David Sterba @ 2024-01-30 19:31 UTC (permalink / raw) To: Johannes Thumshirn; +Cc: David Sterba, linux-btrfs@vger.kernel.org On Tue, Jan 30, 2024 at 11:49:48AM +0000, Johannes Thumshirn wrote: > On 29.01.24 19:34, David Sterba wrote: > > diff --git a/fs/btrfs/misc.h b/fs/btrfs/misc.h > > index 9cb671ef136c..7fcbf9e115ca 100644 > > --- a/fs/btrfs/misc.h > > +++ b/fs/btrfs/misc.h > > @@ -12,6 +12,7 @@ > > #define folio_to_inode(folio) BTRFS_I((folio)->mapping->host) > > #define page_to_fs_info(page) BTRFS_I((page)->mapping->host)->root->fs_info > > #define folio_to_fs_info(page) BTRFS_I((folio)->mapping->host)->root->fs_info > > +#define inode_to_fs_info(inode) BTRFS_I(inode)->root->fs_info > > > > If you'd switch patches 3 and 4 you could do > #define page_to_fs_info(page) inode_to_fs_info(page_to_inode(page)) > #define folio_to_fs_info(folio) inode_to_fs_info(folio_to_inode(folio)) I see that it's shorter but also obfuscated by the macro indirection. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-01-29 18:33 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba 2024-01-30 11:49 ` Johannes Thumshirn @ 2024-01-31 7:23 ` David Sterba 2024-01-31 8:43 ` Qu Wenruo 1 sibling, 1 reply; 21+ messages in thread From: David Sterba @ 2024-01-31 7:23 UTC (permalink / raw) To: David Sterba; +Cc: linux-btrfs On Mon, Jan 29, 2024 at 07:33:18PM +0100, David Sterba wrote: > @@ -5211,7 +5211,7 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root, > > void btrfs_evict_inode(struct inode *inode) > { > - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); > + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); This leads to a crash in btrfs/232, happened twice: BUG: KASAN: null-ptr-deref in btrfs_evict_inode+0xac/0x6b0 [btrfs] BUG: kernel NULL pointer dereference, address: 0000000000000208 Read of size 8 at addr 0000000000000208 by task fsstress/21264 #PF: supervisor read access in kernel mode CPU: 3 PID: 21264 Comm: fsstress Not tainted 6.8.0-rc2-default+ #2288 #PF: error_code(0x0000) - not-present page Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 PGD 683f8067 Call Trace: P4D 683f8067 <TASK> dump_stack_lvl+0x46/0x70 kasan_report+0x123/0x150 ? btrfs_evict_inode+0xac/0x6b0 [btrfs] ? btrfs_evict_inode+0xac/0x6b0 [btrfs] btrfs_evict_inode+0xac/0x6b0 [btrfs] ? local_clock_noinstr+0x11/0xc0 ? btrfs_rmdir+0x380/0x380 [btrfs] ? reacquire_held_locks+0x280/0x280 ? wake_up_var+0x120/0x120 evict+0x17f/0x2d0 btrfs_create_common+0xe4/0x1c0 [btrfs] ? btrfs_tmpfile+0x2b0/0x2b0 [btrfs] ? init_special_inode+0xb9/0xe0 vfs_mknod+0x25c/0x320 do_mknodat+0x2fd/0x360 ? kern_path_create+0x50/0x50 ? getname_flags+0xb5/0x220 __x64_sys_mknodat+0x5d/0x70 do_syscall_64+0x6f/0x140 entry_SYSCALL_64_after_hwframe+0x46/0x4e The new macro does BTRFS_I(inode)->root->fs_info while the old one uses fs_info in the super block. From the context I don't see why a root pointer would be NULL or how would anyone see that right away and not introduce such crashes by using the helpers. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-01-31 7:23 ` David Sterba @ 2024-01-31 8:43 ` Qu Wenruo 2024-01-31 18:04 ` David Sterba 0 siblings, 1 reply; 21+ messages in thread From: Qu Wenruo @ 2024-01-31 8:43 UTC (permalink / raw) To: dsterba, David Sterba; +Cc: linux-btrfs On 2024/1/31 17:53, David Sterba wrote: > On Mon, Jan 29, 2024 at 07:33:18PM +0100, David Sterba wrote: >> @@ -5211,7 +5211,7 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root, >> >> void btrfs_evict_inode(struct inode *inode) >> { >> - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); >> + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); > > This leads to a crash in btrfs/232, happened twice: > > BUG: KASAN: null-ptr-deref in btrfs_evict_inode+0xac/0x6b0 [btrfs] > BUG: kernel NULL pointer dereference, address: 0000000000000208 > Read of size 8 at addr 0000000000000208 by task fsstress/21264 > #PF: supervisor read access in kernel mode > > CPU: 3 PID: 21264 Comm: fsstress Not tainted 6.8.0-rc2-default+ #2288 > #PF: error_code(0x0000) - not-present page > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 > PGD 683f8067 > Call Trace: > P4D 683f8067 > <TASK> > dump_stack_lvl+0x46/0x70 > kasan_report+0x123/0x150 > ? btrfs_evict_inode+0xac/0x6b0 [btrfs] > ? btrfs_evict_inode+0xac/0x6b0 [btrfs] > btrfs_evict_inode+0xac/0x6b0 [btrfs] > ? local_clock_noinstr+0x11/0xc0 > ? btrfs_rmdir+0x380/0x380 [btrfs] > ? reacquire_held_locks+0x280/0x280 > ? wake_up_var+0x120/0x120 > evict+0x17f/0x2d0 > > btrfs_create_common+0xe4/0x1c0 [btrfs] > ? btrfs_tmpfile+0x2b0/0x2b0 [btrfs] > ? init_special_inode+0xb9/0xe0 > vfs_mknod+0x25c/0x320 > do_mknodat+0x2fd/0x360 > ? kern_path_create+0x50/0x50 > ? getname_flags+0xb5/0x220 > __x64_sys_mknodat+0x5d/0x70 > do_syscall_64+0x6f/0x140 > entry_SYSCALL_64_after_hwframe+0x46/0x4e > > The new macro does BTRFS_I(inode)->root->fs_info while the old one uses > fs_info in the super block. From the context I don't see why a root > pointer would be NULL or how would anyone see that right away and not > introduce such crashes by using the helpers. > The function btrfs_evict_inode() only utilize BTRFS_I(inode)->root when the inode's i_nlink is not 0, and there are even explicit check on root. So I guess BTRFS_I(inode)->root can be NULL, and the old code is already handing it. If you need, I can definitely dig deeper to give a more comprehensive call trace and analyze. But it looks like if you want to grab fs_info, i_sb is way safer. Thanks, Qu ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-01-31 8:43 ` Qu Wenruo @ 2024-01-31 18:04 ` David Sterba 0 siblings, 0 replies; 21+ messages in thread From: David Sterba @ 2024-01-31 18:04 UTC (permalink / raw) To: Qu Wenruo; +Cc: dsterba, David Sterba, linux-btrfs On Wed, Jan 31, 2024 at 07:13:43PM +1030, Qu Wenruo wrote: > > > On 2024/1/31 17:53, David Sterba wrote: > > On Mon, Jan 29, 2024 at 07:33:18PM +0100, David Sterba wrote: > >> @@ -5211,7 +5211,7 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root, > >> > >> void btrfs_evict_inode(struct inode *inode) > >> { > >> - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); > >> + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); > > > > This leads to a crash in btrfs/232, happened twice: > > > > BUG: KASAN: null-ptr-deref in btrfs_evict_inode+0xac/0x6b0 [btrfs] > > BUG: kernel NULL pointer dereference, address: 0000000000000208 > > Read of size 8 at addr 0000000000000208 by task fsstress/21264 > > #PF: supervisor read access in kernel mode > > > > CPU: 3 PID: 21264 Comm: fsstress Not tainted 6.8.0-rc2-default+ #2288 > > #PF: error_code(0x0000) - not-present page > > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.2-3-gd478f380-rebuilt.opensuse.org 04/01/2014 > > PGD 683f8067 > > Call Trace: > > P4D 683f8067 > > <TASK> > > dump_stack_lvl+0x46/0x70 > > kasan_report+0x123/0x150 > > ? btrfs_evict_inode+0xac/0x6b0 [btrfs] > > ? btrfs_evict_inode+0xac/0x6b0 [btrfs] > > btrfs_evict_inode+0xac/0x6b0 [btrfs] > > ? local_clock_noinstr+0x11/0xc0 > > ? btrfs_rmdir+0x380/0x380 [btrfs] > > ? reacquire_held_locks+0x280/0x280 > > ? wake_up_var+0x120/0x120 > > evict+0x17f/0x2d0 > > > > btrfs_create_common+0xe4/0x1c0 [btrfs] > > ? btrfs_tmpfile+0x2b0/0x2b0 [btrfs] > > ? init_special_inode+0xb9/0xe0 > > vfs_mknod+0x25c/0x320 > > do_mknodat+0x2fd/0x360 > > ? kern_path_create+0x50/0x50 > > ? getname_flags+0xb5/0x220 > > __x64_sys_mknodat+0x5d/0x70 > > do_syscall_64+0x6f/0x140 > > entry_SYSCALL_64_after_hwframe+0x46/0x4e > > > > The new macro does BTRFS_I(inode)->root->fs_info while the old one uses > > fs_info in the super block. From the context I don't see why a root > > pointer would be NULL or how would anyone see that right away and not > > introduce such crashes by using the helpers. > > The function btrfs_evict_inode() only utilize BTRFS_I(inode)->root when > the inode's i_nlink is not 0, and there are even explicit check on root. > > So I guess BTRFS_I(inode)->root can be NULL, and the old code is already > handing it. Of course, now it's obvious. > If you need, I can definitely dig deeper to give a more comprehensive > call trace and analyze. Not needed, thanks, I should have read the code. > But it looks like if you want to grab fs_info, i_sb is way safer. I'd like to minimize reading the fs_info from super block if the root is available, for consistency and because sb::s_fs_info is void *. ^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH 5/5] btrfs: hoist fs_info out of loops in end_bbio_data_write and end_bbio_data_read 2024-01-29 18:33 [PATCH 0/5] Struct to fs_info helpers David Sterba ` (3 preceding siblings ...) 2024-01-29 18:33 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba @ 2024-01-29 18:33 ` David Sterba 4 siblings, 0 replies; 21+ messages in thread From: David Sterba @ 2024-01-29 18:33 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba The fs_info and sectorsize remain the same during the loops, no need to set them on each iteration. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/extent_io.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 9d6d4dab9ae3..d45247e1020a 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -464,13 +464,12 @@ static void end_bbio_data_write(struct btrfs_bio *bbio) struct bio *bio = &bbio->bio; int error = blk_status_to_errno(bio->bi_status); struct folio_iter fi; + struct btrfs_fs_info *fs_info = bbio->fs_info; + const u32 sectorsize = fs_info->sectorsize; ASSERT(!bio_flagged(bio, BIO_CLONED)); bio_for_each_folio_all(fi, bio) { struct folio *folio = fi.folio; - struct inode *inode = folio->mapping->host; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - const u32 sectorsize = fs_info->sectorsize; u64 start = folio_pos(folio) + fi.offset; u32 len = fi.length; @@ -592,17 +591,17 @@ static void begin_page_read(struct btrfs_fs_info *fs_info, struct page *page) */ static void end_bbio_data_read(struct btrfs_bio *bbio) { + struct btrfs_fs_info *fs_info = bbio->fs_info; struct bio *bio = &bbio->bio; struct processed_extent processed = { 0 }; struct folio_iter fi; + const u32 sectorsize = fs_info->sectorsize; ASSERT(!bio_flagged(bio, BIO_CLONED)); bio_for_each_folio_all(fi, &bbio->bio) { bool uptodate = !bio->bi_status; struct folio *folio = fi.folio; struct inode *inode = folio->mapping->host; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); - const u32 sectorsize = fs_info->sectorsize; u64 start; u64 end; u32 len; -- 2.42.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH 0/5 v2] Struct to fs_info helpers
@ 2024-02-01 18:02 David Sterba
2024-02-01 18:02 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba
0 siblings, 1 reply; 21+ messages in thread
From: David Sterba @ 2024-02-01 18:02 UTC (permalink / raw)
To: linux-btrfs; +Cc: David Sterba
v2:
- move helper definitions to fs.h
- add _Generic to the macros for type checking
- reuse helpers to some code duplication
Add convenience helpers for getting a fs_info from page, bio, inode etc.
There's one prep patch where tests use a normal helper that expects
valid inode->root->fs_info.
David Sterba (5):
btrfs: tests: allocate dummy fs_info and root in test_find_delalloc()
btrfs: add helpers to get inode from page/folio pointers
btrfs: add helpers to get fs_info from page/folio pointers
btrfs: add helper to get fs_info from struct inode pointer
btrfs: hoist fs_info out of loops in end_bbio_data_write and
end_bbio_data_read
fs/btrfs/compression.c | 8 +++---
fs/btrfs/defrag.c | 4 +--
fs/btrfs/disk-io.c | 11 ++++----
fs/btrfs/export.c | 2 +-
fs/btrfs/extent_io.c | 45 ++++++++++++++++----------------
fs/btrfs/file.c | 14 +++++-----
fs/btrfs/free-space-cache.c | 2 +-
fs/btrfs/fs.h | 11 ++++++++
fs/btrfs/inode.c | 42 ++++++++++++++---------------
fs/btrfs/ioctl.c | 40 ++++++++++++++--------------
fs/btrfs/lzo.c | 4 +--
fs/btrfs/props.c | 2 +-
fs/btrfs/reflink.c | 6 ++---
fs/btrfs/relocation.c | 2 +-
fs/btrfs/tests/extent-io-tests.c | 28 +++++++++++++++++---
15 files changed, 126 insertions(+), 95 deletions(-)
--
2.42.1
^ permalink raw reply [flat|nested] 21+ messages in thread* [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-02-01 18:02 [PATCH 0/5 v2] Struct to fs_info helpers David Sterba @ 2024-02-01 18:02 ` David Sterba 2024-02-02 11:34 ` Johannes Thumshirn 0 siblings, 1 reply; 21+ messages in thread From: David Sterba @ 2024-02-01 18:02 UTC (permalink / raw) To: linux-btrfs; +Cc: David Sterba Add a convenience helper to get a fs_info from a VFS inode pointer instead of open coding the chain or using btrfs_sb() that in some cases does one more pointer hop. This is implemented as a macro (still with type checking) so we don't need full definitions of struct btrfs_inode, btrfs_root or btrfs_fs_info. Signed-off-by: David Sterba <dsterba@suse.com> --- fs/btrfs/compression.c | 6 +++--- fs/btrfs/defrag.c | 4 ++-- fs/btrfs/disk-io.c | 6 +++--- fs/btrfs/export.c | 2 +- fs/btrfs/extent_io.c | 12 +++++------ fs/btrfs/file.c | 14 ++++++------- fs/btrfs/free-space-cache.c | 2 +- fs/btrfs/fs.h | 3 +++ fs/btrfs/inode.c | 38 +++++++++++++++++------------------ fs/btrfs/ioctl.c | 40 ++++++++++++++++++------------------- fs/btrfs/lzo.c | 2 +- fs/btrfs/props.c | 2 +- fs/btrfs/reflink.c | 6 +++--- fs/btrfs/relocation.c | 2 +- 14 files changed, 71 insertions(+), 68 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 9cae8542c7e0..0b8833baf404 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -281,7 +281,7 @@ static void end_bbio_comprssed_read(struct btrfs_bio *bbio) static noinline void end_compressed_writeback(const struct compressed_bio *cb) { struct inode *inode = &cb->bbio.inode->vfs_inode; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); unsigned long index = cb->start >> PAGE_SHIFT; unsigned long end_index = (cb->start + cb->len - 1) >> PAGE_SHIFT; struct folio_batch fbatch; @@ -412,7 +412,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, struct compressed_bio *cb, int *memstall, unsigned long *pflags) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); unsigned long end_index; struct bio *orig_bio = &cb->orig_bbio->bio; u64 cur = cb->orig_bbio->file_offset + orig_bio->bi_iter.bi_size; @@ -438,7 +438,7 @@ static noinline int add_ra_bio_pages(struct inode *inode, * This makes readahead less effective, so here disable readahead for * subpage for now, until full compressed write is supported. */ - if (btrfs_sb(inode->i_sb)->sectorsize < PAGE_SIZE) + if (fs_info->sectorsize < PAGE_SIZE) return 0; end_index = (i_size_read(inode) - 1) >> PAGE_SHIFT; diff --git a/fs/btrfs/defrag.c b/fs/btrfs/defrag.c index 8fc8118c3225..3878ce0cb88e 100644 --- a/fs/btrfs/defrag.c +++ b/fs/btrfs/defrag.c @@ -809,7 +809,7 @@ static u32 get_extent_max_capacity(const struct btrfs_fs_info *fs_info, static bool defrag_check_next_extent(struct inode *inode, struct extent_map *em, u32 extent_thresh, u64 newer_than, bool locked) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *next; bool ret = false; @@ -1364,7 +1364,7 @@ int btrfs_defrag_file(struct inode *inode, struct file_ra_state *ra, struct btrfs_ioctl_defrag_range_args *range, u64 newer_than, unsigned long max_to_defrag) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); unsigned long sectors_defragged = 0; u64 isize = i_size_read(inode); u64 cur; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ebefc69ddcfa..3127ca68fc9d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -497,15 +497,15 @@ static int btree_migrate_folio(struct address_space *mapping, static int btree_writepages(struct address_space *mapping, struct writeback_control *wbc) { - struct btrfs_fs_info *fs_info; int ret; if (wbc->sync_mode == WB_SYNC_NONE) { + struct btrfs_fs_info *fs_info; if (wbc->for_kupdate) return 0; - fs_info = BTRFS_I(mapping->host)->root->fs_info; + fs_info = inode_to_fs_info(mapping->host); /* this is a bit racy, but that's ok */ ret = __percpu_counter_compare(&fs_info->dirty_metadata_bytes, BTRFS_DIRTY_METADATA_THRESH, @@ -544,7 +544,7 @@ static void btree_invalidate_folio(struct folio *folio, size_t offset, static bool btree_dirty_folio(struct address_space *mapping, struct folio *folio) { - struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host); struct btrfs_subpage_info *spi = fs_info->subpage_info; struct btrfs_subpage *subpage; struct extent_buffer *eb; diff --git a/fs/btrfs/export.c b/fs/btrfs/export.c index 3f2e8fb9e3e9..2f9e3c1c60f0 100644 --- a/fs/btrfs/export.c +++ b/fs/btrfs/export.c @@ -214,7 +214,7 @@ static int btrfs_get_name(struct dentry *parent, char *name, { struct inode *inode = d_inode(child); struct inode *dir = d_inode(parent); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_path *path; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_inode_ref *iref; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 420054ad9acb..ac6b5d8895aa 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -206,7 +206,7 @@ static void __process_pages_contig(struct address_space *mapping, struct page *locked_page, u64 start, u64 end, unsigned long page_ops) { - struct btrfs_fs_info *fs_info = btrfs_sb(mapping->host->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host); pgoff_t start_index = start >> PAGE_SHIFT; pgoff_t end_index = end >> PAGE_SHIFT; pgoff_t index = start_index; @@ -250,7 +250,7 @@ static noinline int lock_delalloc_pages(struct inode *inode, u64 start, u64 end) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct address_space *mapping = inode->i_mapping; pgoff_t start_index = start >> PAGE_SHIFT; pgoff_t end_index = end >> PAGE_SHIFT; @@ -322,7 +322,7 @@ noinline_for_stack bool find_lock_delalloc_range(struct inode *inode, struct page *locked_page, u64 *start, u64 *end) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree; const u64 orig_start = *start; const u64 orig_end = *end; @@ -1002,7 +1002,7 @@ static int btrfs_do_readpage(struct page *page, struct extent_map **em_cached, struct btrfs_bio_ctrl *bio_ctrl, u64 *prev_em_start) { struct inode *inode = page->mapping->host; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); u64 start = page_offset(page); const u64 end = start + PAGE_SIZE - 1; u64 cur = start; @@ -1909,7 +1909,7 @@ int btree_write_cache_pages(struct address_space *mapping, struct writeback_control *wbc) { struct btrfs_eb_write_context ctx = { .wbc = wbc }; - struct btrfs_fs_info *fs_info = BTRFS_I(mapping->host)->root->fs_info; + struct btrfs_fs_info *fs_info = inode_to_fs_info(mapping->host); int ret = 0; int done = 0; int nr_to_write_done = 0; @@ -2197,7 +2197,7 @@ void extent_write_locked_range(struct inode *inode, struct page *locked_page, bool found_error = false; int ret = 0; struct address_space *mapping = inode->i_mapping; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); const u32 sectorsize = fs_info->sectorsize; loff_t i_size = i_size_read(inode); u64 cur = start; diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 4bca37fd6833..7e82a40e2a44 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -1135,7 +1135,7 @@ static int btrfs_write_check(struct kiocb *iocb, struct iov_iter *from, { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); loff_t pos = iocb->ki_pos; int ret; loff_t oldsize; @@ -1183,7 +1183,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb, struct file *file = iocb->ki_filp; loff_t pos; struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct page **pages = NULL; struct extent_changeset *data_reserved = NULL; u64 release_bytes = 0; @@ -1459,7 +1459,7 @@ static ssize_t btrfs_direct_write(struct kiocb *iocb, struct iov_iter *from) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); loff_t pos; ssize_t written = 0; ssize_t written_buffered; @@ -1785,7 +1785,7 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync) { struct dentry *dentry = file_dentry(file); struct inode *inode = d_inode(dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; struct btrfs_log_ctx ctx; @@ -2591,7 +2591,7 @@ int btrfs_replace_file_extents(struct btrfs_inode *inode, static int btrfs_punch_hole(struct file *file, loff_t offset, loff_t len) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct extent_state *cached_state = NULL; struct btrfs_path *path; @@ -3046,7 +3046,7 @@ static long btrfs_fallocate(struct file *file, int mode, int ret; /* Do not allow fallocate in ZONED mode */ - if (btrfs_is_zoned(btrfs_sb(inode->i_sb))) + if (btrfs_is_zoned(inode_to_fs_info(inode))) return -EOPNOTSUPP; alloc_start = round_down(offset, blocksize); @@ -3751,7 +3751,7 @@ static ssize_t btrfs_direct_read(struct kiocb *iocb, struct iov_iter *to) if (fsverity_active(inode)) return 0; - if (check_direct_read(btrfs_sb(inode->i_sb), to, iocb->ki_pos)) + if (check_direct_read(inode_to_fs_info(inode), to, iocb->ki_pos)) return 0; btrfs_inode_lock(BTRFS_I(inode), BTRFS_ILOCK_SHARED); diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index f74b13f9b193..43a35c65c25f 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c @@ -397,7 +397,7 @@ static int io_ctl_init(struct btrfs_io_ctl *io_ctl, struct inode *inode, return -ENOMEM; io_ctl->num_pages = num_pages; - io_ctl->fs_info = btrfs_sb(inode->i_sb); + io_ctl->fs_info = inode_to_fs_info(inode); io_ctl->inode = inode; return 0; diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h index ce1bfd9938b1..a8b3a8828162 100644 --- a/fs/btrfs/fs.h +++ b/fs/btrfs/fs.h @@ -836,6 +836,9 @@ struct btrfs_fs_info { #define page_to_fs_info(_page) (page_to_inode(_page)->root->fs_info) #define folio_to_fs_info(_folio) (folio_to_inode(_folio)->root->fs_info) +#define inode_to_fs_info(_inode) (BTRFS_I(_Generic((_inode), \ + struct inode *: (_inode)))->root->fs_info) + static inline u64 btrfs_get_fs_generation(const struct btrfs_fs_info *fs_info) { return READ_ONCE(fs_info->generation); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 27d67c4580bc..015c2db7139a 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -2827,7 +2827,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) int btrfs_writepage_cow_fixup(struct page *page) { struct inode *inode = page->mapping->host; - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_writepage_fixup *fixup; /* This page has ordered extent covering it already */ @@ -3242,7 +3242,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent) int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered) { - if (btrfs_is_zoned(btrfs_sb(ordered->inode->i_sb)) && + if (btrfs_is_zoned(inode_to_fs_info(ordered->inode)) && !test_bit(BTRFS_ORDERED_IOERR, &ordered->flags) && list_empty(&ordered->bioc_list)) btrfs_finish_ordered_zoned(ordered); @@ -3727,7 +3727,7 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf, static int btrfs_read_locked_inode(struct inode *inode, struct btrfs_path *in_path) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_path *path = in_path; struct extent_buffer *leaf; struct btrfs_inode_item *inode_item; @@ -4452,8 +4452,8 @@ static void btrfs_prune_dentries(struct btrfs_root *root) int btrfs_delete_subvolume(struct btrfs_inode *dir, struct dentry *dentry) { - struct btrfs_fs_info *fs_info = btrfs_sb(dentry->d_sb); struct btrfs_root *root = dir->root; + struct btrfs_fs_info *fs_info = root->fs_info; struct inode *inode = d_inode(dentry); struct btrfs_root *dest = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; @@ -5008,7 +5008,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_drew_write_unlock(&root->snapshot_lock); btrfs_end_transaction(trans); } else { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); if (btrfs_is_zoned(fs_info)) { ret = btrfs_wait_ordered_range(inode, @@ -5211,7 +5211,7 @@ static struct btrfs_trans_handle *evict_refill_and_join(struct btrfs_root *root, void btrfs_evict_inode(struct inode *inode) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_block_rsv *rsv = NULL; @@ -5650,7 +5650,7 @@ static inline u8 btrfs_inode_type(struct inode *inode) struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct inode *inode; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *sub_root = root; @@ -6189,7 +6189,7 @@ int btrfs_create_new_inode(struct btrfs_trans_handle *trans, struct inode *dir = args->dir; struct inode *inode = args->inode; const struct fscrypt_str *name = args->orphan ? NULL : &args->fname.disk_name; - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_root *root; struct btrfs_inode_item *inode_item; struct btrfs_key *location; @@ -6511,7 +6511,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, static int btrfs_create_common(struct inode *dir, struct dentry *dentry, struct inode *inode) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_new_inode_args new_inode_args = { .dir = dir, @@ -6581,7 +6581,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, struct btrfs_trans_handle *trans = NULL; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode = d_inode(old_dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct fscrypt_name fname; u64 index; int err; @@ -7064,7 +7064,7 @@ noinline int can_nocow_extent(struct inode *inode, u64 offset, u64 *len, u64 *orig_start, u64 *orig_block_len, u64 *ram_bytes, bool nowait, bool strict) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct can_nocow_file_extent_args nocow_args = { 0 }; struct btrfs_path *path; int ret; @@ -7303,7 +7303,7 @@ static int btrfs_get_blocks_direct_write(struct extent_map **map, unsigned int iomap_flags) { const bool nowait = (iomap_flags & IOMAP_NOWAIT); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *em = *map; int type; u64 block_start, orig_start, orig_block_len, ram_bytes; @@ -7443,7 +7443,7 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start, struct iomap *srcmap) { struct iomap_iter *iter = container_of(iomap, struct iomap_iter, iomap); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *em; struct extent_state *cached_state = NULL; struct btrfs_dio_data *dio_data = iter->private; @@ -8120,7 +8120,7 @@ vm_fault_t btrfs_page_mkwrite(struct vm_fault *vmf) struct page *page = vmf->page; struct folio *folio = page_folio(page); struct inode *inode = file_inode(vmf->vma->vm_file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; struct extent_state *cached_state = NULL; @@ -8729,7 +8729,7 @@ static int btrfs_rename_exchange(struct inode *old_dir, struct inode *new_dir, struct dentry *new_dentry) { - struct btrfs_fs_info *fs_info = btrfs_sb(old_dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(old_dir); struct btrfs_trans_handle *trans; unsigned int trans_num_items; struct btrfs_root *root = BTRFS_I(old_dir)->root; @@ -8981,7 +8981,7 @@ static int btrfs_rename(struct mnt_idmap *idmap, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { - struct btrfs_fs_info *fs_info = btrfs_sb(old_dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(old_dir); struct btrfs_new_inode_args whiteout_args = { .dir = old_dir, .dentry = old_dentry, @@ -9423,7 +9423,7 @@ int btrfs_start_delalloc_roots(struct btrfs_fs_info *fs_info, long nr, static int btrfs_symlink(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, const char *symname) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_path *path; @@ -9604,7 +9604,7 @@ static int __btrfs_prealloc_file_range(struct inode *inode, int mode, loff_t actual_len, u64 *alloc_hint, struct btrfs_trans_handle *trans) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct extent_map *em; struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_key ins; @@ -9756,7 +9756,7 @@ static int btrfs_permission(struct mnt_idmap *idmap, static int btrfs_tmpfile(struct mnt_idmap *idmap, struct inode *dir, struct file *file, umode_t mode) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_trans_handle *trans; struct btrfs_root *root = BTRFS_I(dir)->root; struct inode *inode; diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 46f9a6645bf6..ec9084ee23a5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -243,7 +243,7 @@ int btrfs_fileattr_set(struct mnt_idmap *idmap, struct dentry *dentry, struct fileattr *fa) { struct inode *inode = d_inode(dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_inode *binode = BTRFS_I(inode); struct btrfs_root *root = binode->root; struct btrfs_trans_handle *trans; @@ -580,7 +580,7 @@ static noinline int create_subvol(struct mnt_idmap *idmap, struct inode *dir, struct dentry *dentry, struct btrfs_qgroup_inherit *inherit) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct btrfs_trans_handle *trans; struct btrfs_key key; struct btrfs_root_item *root_item; @@ -772,7 +772,7 @@ static int create_snapshot(struct btrfs_root *root, struct inode *dir, struct dentry *dentry, bool readonly, struct btrfs_qgroup_inherit *inherit) { - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct inode *inode; struct btrfs_pending_snapshot *pending_snapshot; unsigned int trans_num_items; @@ -958,7 +958,7 @@ static noinline int btrfs_mksubvol(const struct path *parent, struct btrfs_qgroup_inherit *inherit) { struct inode *dir = d_inode(parent->dentry); - struct btrfs_fs_info *fs_info = btrfs_sb(dir->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct dentry *dentry; struct fscrypt_str name_str = FSTR_INIT((char *)name, namelen); int error; @@ -1093,7 +1093,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, { BTRFS_DEV_LOOKUP_ARGS(args); struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); u64 new_size; u64 old_size; u64 devid = 1; @@ -1401,7 +1401,7 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, static noinline int btrfs_ioctl_subvol_getflags(struct inode *inode, void __user *arg) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; int ret = 0; u64 flags = 0; @@ -1424,7 +1424,7 @@ static noinline int btrfs_ioctl_subvol_setflags(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_trans_handle *trans; u64 root_flags; @@ -1671,7 +1671,7 @@ static noinline int search_ioctl(struct inode *inode, u64 *buf_size, char __user *ubuf) { - struct btrfs_fs_info *info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *info = inode_to_fs_info(inode); struct btrfs_root *root; struct btrfs_key key; struct btrfs_path *path; @@ -2342,9 +2342,9 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, bool destroy_v2) { struct dentry *parent = file->f_path.dentry; - struct btrfs_fs_info *fs_info = btrfs_sb(parent->d_sb); struct dentry *dentry; struct inode *dir = d_inode(parent); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dir); struct inode *inode; struct btrfs_root *root = BTRFS_I(dir)->root; struct btrfs_root *dest = NULL; @@ -2692,7 +2692,7 @@ static long btrfs_ioctl_rm_dev_v2(struct file *file, void __user *arg) { BTRFS_DEV_LOOKUP_ARGS(args); struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_vol_args_v2 *vol_args; struct bdev_handle *bdev_handle = NULL; int ret; @@ -2757,7 +2757,7 @@ static long btrfs_ioctl_rm_dev(struct file *file, void __user *arg) { BTRFS_DEV_LOOKUP_ARGS(args); struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_vol_args *vol_args; struct bdev_handle *bdev_handle = NULL; int ret; @@ -2900,7 +2900,7 @@ static long btrfs_ioctl_dev_info(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *new_root; struct btrfs_dir_item *di; @@ -3174,7 +3174,7 @@ static noinline long btrfs_ioctl_wait_sync(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_scrub(struct file *file, void __user *arg) { - struct btrfs_fs_info *fs_info = btrfs_sb(file_inode(file)->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(file_inode(file)); struct btrfs_ioctl_scrub_args *sa; int ret; @@ -3692,7 +3692,7 @@ static long btrfs_ioctl_balance_progress(struct btrfs_fs_info *fs_info, static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_quota_ctl_args *sa; int ret; @@ -3734,7 +3734,7 @@ static long btrfs_ioctl_quota_ctl(struct file *file, void __user *arg) static long btrfs_ioctl_qgroup_assign(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_ioctl_qgroup_assign_args *sa; struct btrfs_trans_handle *trans; @@ -3890,7 +3890,7 @@ static long btrfs_ioctl_qgroup_limit(struct file *file, void __user *arg) static long btrfs_ioctl_quota_rescan(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_ioctl_quota_rescan_args *qsa; int ret; @@ -3954,7 +3954,7 @@ static long _btrfs_ioctl_set_received_subvol(struct file *file, struct btrfs_ioctl_received_subvol_args *sa) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root_item *root_item = &root->root_item; struct btrfs_trans_handle *trans; @@ -4142,7 +4142,7 @@ static int btrfs_ioctl_get_fslabel(struct btrfs_fs_info *fs_info, static int btrfs_ioctl_set_fslabel(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_trans_handle *trans; @@ -4285,7 +4285,7 @@ check_feature_bits(fs_info, FEAT_##mask_base, change_mask, flags, \ static int btrfs_ioctl_set_features(struct file *file, void __user *arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_super_block *super_block = fs_info->super_copy; struct btrfs_ioctl_feature_flags flags[2]; @@ -4576,7 +4576,7 @@ long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(file); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_root *root = BTRFS_I(inode)->root; void __user *argp = (void __user *)arg; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 110a2c304bdc..3e5d3b7028e8 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -214,7 +214,7 @@ int lzo_compress_pages(struct list_head *ws, struct address_space *mapping, unsigned long *total_in, unsigned long *total_out) { struct workspace *workspace = list_entry(ws, struct workspace, list); - const u32 sectorsize = btrfs_sb(mapping->host->i_sb)->sectorsize; + const u32 sectorsize = inode_to_fs_info(mapping->host)->sectorsize; struct page *page_in = NULL; char *sizes_ptr; const unsigned long max_nr_page = *out_pages; diff --git a/fs/btrfs/props.c b/fs/btrfs/props.c index f9bf591a0718..ac4a0af2b554 100644 --- a/fs/btrfs/props.c +++ b/fs/btrfs/props.c @@ -302,7 +302,7 @@ static int prop_compression_validate(const struct btrfs_inode *inode, static int prop_compression_apply(struct inode *inode, const char *value, size_t len) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); int type; /* Reset to defaults */ diff --git a/fs/btrfs/reflink.c b/fs/btrfs/reflink.c index e38cb40e150c..08d0fb46ceec 100644 --- a/fs/btrfs/reflink.c +++ b/fs/btrfs/reflink.c @@ -174,7 +174,7 @@ static int clone_copy_inline_extent(struct inode *dst, char *inline_data, struct btrfs_trans_handle **trans_out) { - struct btrfs_fs_info *fs_info = btrfs_sb(dst->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(dst); struct btrfs_root *root = BTRFS_I(dst)->root; const u64 aligned_end = ALIGN(new_key->offset + datal, fs_info->sectorsize); @@ -337,7 +337,7 @@ static int btrfs_clone(struct inode *src, struct inode *inode, const u64 off, const u64 olen, const u64 olen_aligned, const u64 destoff, int no_time_update) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); struct btrfs_path *path = NULL; struct extent_buffer *leaf; struct btrfs_trans_handle *trans; @@ -726,7 +726,7 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src, { struct inode *inode = file_inode(file); struct inode *src = file_inode(file_src); - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); int ret; int wb_ret; u64 len = olen; diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index abe594f77f99..2fca67f2b39b 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c @@ -2987,7 +2987,7 @@ static int relocate_one_page(struct inode *inode, struct file_ra_state *ra, const struct file_extent_cluster *cluster, int *cluster_nr, unsigned long page_index) { - struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); + struct btrfs_fs_info *fs_info = inode_to_fs_info(inode); u64 offset = BTRFS_I(inode)->index_cnt; const unsigned long last_index = (cluster->end - offset) >> PAGE_SHIFT; gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); -- 2.42.1 ^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-02-01 18:02 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba @ 2024-02-02 11:34 ` Johannes Thumshirn 2024-02-02 12:07 ` David Sterba 0 siblings, 1 reply; 21+ messages in thread From: Johannes Thumshirn @ 2024-02-02 11:34 UTC (permalink / raw) To: David Sterba, linux-btrfs@vger.kernel.org On 01.02.24 19:08, David Sterba wrote: > diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h > index ce1bfd9938b1..a8b3a8828162 100644 > --- a/fs/btrfs/fs.h > +++ b/fs/btrfs/fs.h > @@ -836,6 +836,9 @@ struct btrfs_fs_info { > #define page_to_fs_info(_page) (page_to_inode(_page)->root->fs_info) > #define folio_to_fs_info(_folio) (folio_to_inode(_folio)->root->fs_info) > > +#define inode_to_fs_info(_inode) (BTRFS_I(_Generic((_inode), \ > + struct inode *: (_inode)))->root->fs_info) Didn't that trip over a NULL-pointer in the last iteration? ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-02-02 11:34 ` Johannes Thumshirn @ 2024-02-02 12:07 ` David Sterba 2024-02-02 12:09 ` Johannes Thumshirn 0 siblings, 1 reply; 21+ messages in thread From: David Sterba @ 2024-02-02 12:07 UTC (permalink / raw) To: Johannes Thumshirn; +Cc: David Sterba, linux-btrfs@vger.kernel.org On Fri, Feb 02, 2024 at 11:34:06AM +0000, Johannes Thumshirn wrote: > On 01.02.24 19:08, David Sterba wrote: > > diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h > > index ce1bfd9938b1..a8b3a8828162 100644 > > --- a/fs/btrfs/fs.h > > +++ b/fs/btrfs/fs.h > > @@ -836,6 +836,9 @@ struct btrfs_fs_info { > > #define page_to_fs_info(_page) (page_to_inode(_page)->root->fs_info) > > #define folio_to_fs_info(_folio) (folio_to_inode(_folio)->root->fs_info) > > > > +#define inode_to_fs_info(_inode) (BTRFS_I(_Generic((_inode), \ > > + struct inode *: (_inode)))->root->fs_info) > > Didn't that trip over a NULL-pointer in the last iteration? It did in one particular case and it's been fixed. In general inode->root->fs_info always exists. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer 2024-02-02 12:07 ` David Sterba @ 2024-02-02 12:09 ` Johannes Thumshirn 0 siblings, 0 replies; 21+ messages in thread From: Johannes Thumshirn @ 2024-02-02 12:09 UTC (permalink / raw) To: dsterba@suse.cz; +Cc: David Sterba, linux-btrfs@vger.kernel.org On 02.02.24 13:08, David Sterba wrote: > On Fri, Feb 02, 2024 at 11:34:06AM +0000, Johannes Thumshirn wrote: >> On 01.02.24 19:08, David Sterba wrote: >>> diff --git a/fs/btrfs/fs.h b/fs/btrfs/fs.h >>> index ce1bfd9938b1..a8b3a8828162 100644 >>> --- a/fs/btrfs/fs.h >>> +++ b/fs/btrfs/fs.h >>> @@ -836,6 +836,9 @@ struct btrfs_fs_info { >>> #define page_to_fs_info(_page) (page_to_inode(_page)->root->fs_info) >>> #define folio_to_fs_info(_folio) (folio_to_inode(_folio)->root->fs_info) >>> >>> +#define inode_to_fs_info(_inode) (BTRFS_I(_Generic((_inode), \ >>> + struct inode *: (_inode)))->root->fs_info) >> >> Didn't that trip over a NULL-pointer in the last iteration? > > It did in one particular case and it's been fixed. In general > inode->root->fs_info always exists. > > Ah ok, thanks for the clarification ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2024-02-02 12:09 UTC | newest] Thread overview: 21+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2024-01-29 18:33 [PATCH 0/5] Struct to fs_info helpers David Sterba 2024-01-29 18:33 ` [PATCH 1/5] btrfs: tests: allocate dummy fs_info and root in test_find_delalloc() David Sterba 2024-01-29 18:33 ` [PATCH 2/5] btrfs: add helpers to get inode from page/folio pointers David Sterba 2024-01-30 11:42 ` Johannes Thumshirn 2024-01-30 19:29 ` David Sterba 2024-01-31 9:33 ` Johannes Thumshirn 2024-01-31 17:19 ` David Sterba 2024-01-29 18:33 ` [PATCH 3/5] btrfs: add helpers to get fs_info " David Sterba 2024-01-30 11:58 ` Johannes Thumshirn 2024-01-30 19:32 ` David Sterba 2024-01-29 18:33 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba 2024-01-30 11:49 ` Johannes Thumshirn 2024-01-30 19:31 ` David Sterba 2024-01-31 7:23 ` David Sterba 2024-01-31 8:43 ` Qu Wenruo 2024-01-31 18:04 ` David Sterba 2024-01-29 18:33 ` [PATCH 5/5] btrfs: hoist fs_info out of loops in end_bbio_data_write and end_bbio_data_read David Sterba -- strict thread matches above, loose matches on Subject: below -- 2024-02-01 18:02 [PATCH 0/5 v2] Struct to fs_info helpers David Sterba 2024-02-01 18:02 ` [PATCH 4/5] btrfs: add helper to get fs_info from struct inode pointer David Sterba 2024-02-02 11:34 ` Johannes Thumshirn 2024-02-02 12:07 ` David Sterba 2024-02-02 12:09 ` Johannes Thumshirn
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox