* [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
* [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
* [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
* [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
* 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 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 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 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 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 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
* 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 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
* 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 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.