aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnand Jain <anand.jain@oracle.com>2018-02-22 08:58:42 -0500
committerDavid Sterba <dsterba@suse.com>2018-03-01 10:17:27 -0500
commit3c181c12c431fe33b669410d663beb9cceefcd1b (patch)
treeb61293279ddd4b89037339fff51de0a63a9e635f
parent92e222df7b8f05c565009c7383321b593eca488b (diff)
btrfs: use proper endianness accessors for super_copy
The fs_info::super_copy is a byte copy of the on-disk structure and all members must use the accessor macros/functions to obtain the right value. This was missing in update_super_roots and in sysfs readers. Moving between opposite endianness hosts will report bogus numbers in sysfs, and mount may fail as the root will not be restored correctly. If the filesystem is always used on a same endian host, this will not be a problem. Fix this by using the btrfs_set_super...() functions to set fs_info::super_copy values, and for the sysfs, use the cached fs_info::nodesize/sectorsize values. CC: stable@vger.kernel.org Fixes: df93589a17378 ("btrfs: export more from FS_INFO to sysfs") Signed-off-by: Anand Jain <anand.jain@oracle.com> Reviewed-by: Liu Bo <bo.li.liu@oracle.com> Reviewed-by: David Sterba <dsterba@suse.com> [ update changelog ] Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/sysfs.c8
-rw-r--r--fs/btrfs/transaction.c20
2 files changed, 15 insertions, 13 deletions
diff --git a/fs/btrfs/sysfs.c b/fs/btrfs/sysfs.c
index a8bafed931f4..d11c70bff5a9 100644
--- a/fs/btrfs/sysfs.c
+++ b/fs/btrfs/sysfs.c
@@ -423,7 +423,7 @@ static ssize_t btrfs_nodesize_show(struct kobject *kobj,
423{ 423{
424 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 424 struct btrfs_fs_info *fs_info = to_fs_info(kobj);
425 425
426 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->super_copy->nodesize); 426 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->nodesize);
427} 427}
428 428
429BTRFS_ATTR(, nodesize, btrfs_nodesize_show); 429BTRFS_ATTR(, nodesize, btrfs_nodesize_show);
@@ -433,8 +433,7 @@ static ssize_t btrfs_sectorsize_show(struct kobject *kobj,
433{ 433{
434 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 434 struct btrfs_fs_info *fs_info = to_fs_info(kobj);
435 435
436 return snprintf(buf, PAGE_SIZE, "%u\n", 436 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize);
437 fs_info->super_copy->sectorsize);
438} 437}
439 438
440BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show); 439BTRFS_ATTR(, sectorsize, btrfs_sectorsize_show);
@@ -444,8 +443,7 @@ static ssize_t btrfs_clone_alignment_show(struct kobject *kobj,
444{ 443{
445 struct btrfs_fs_info *fs_info = to_fs_info(kobj); 444 struct btrfs_fs_info *fs_info = to_fs_info(kobj);
446 445
447 return snprintf(buf, PAGE_SIZE, "%u\n", 446 return snprintf(buf, PAGE_SIZE, "%u\n", fs_info->sectorsize);
448 fs_info->super_copy->sectorsize);
449} 447}
450 448
451BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show); 449BTRFS_ATTR(, clone_alignment, btrfs_clone_alignment_show);
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 04f07144b45c..9220f004001c 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -1722,19 +1722,23 @@ static void update_super_roots(struct btrfs_fs_info *fs_info)
1722 1722
1723 super = fs_info->super_copy; 1723 super = fs_info->super_copy;
1724 1724
1725 /* update latest btrfs_super_block::chunk_root refs */
1725 root_item = &fs_info->chunk_root->root_item; 1726 root_item = &fs_info->chunk_root->root_item;
1726 super->chunk_root = root_item->bytenr; 1727 btrfs_set_super_chunk_root(super, root_item->bytenr);
1727 super->chunk_root_generation = root_item->generation; 1728 btrfs_set_super_chunk_root_generation(super, root_item->generation);
1728 super->chunk_root_level = root_item->level; 1729 btrfs_set_super_chunk_root_level(super, root_item->level);
1729 1730
1731 /* update latest btrfs_super_block::root refs */
1730 root_item = &fs_info->tree_root->root_item; 1732 root_item = &fs_info->tree_root->root_item;
1731 super->root = root_item->bytenr; 1733 btrfs_set_super_root(super, root_item->bytenr);
1732 super->generation = root_item->generation; 1734 btrfs_set_super_generation(super, root_item->generation);
1733 super->root_level = root_item->level; 1735 btrfs_set_super_root_level(super, root_item->level);
1736
1734 if (btrfs_test_opt(fs_info, SPACE_CACHE)) 1737 if (btrfs_test_opt(fs_info, SPACE_CACHE))
1735 super->cache_generation = root_item->generation; 1738 btrfs_set_super_cache_generation(super, root_item->generation);
1736 if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags)) 1739 if (test_bit(BTRFS_FS_UPDATE_UUID_TREE_GEN, &fs_info->flags))
1737 super->uuid_tree_generation = root_item->generation; 1740 btrfs_set_super_uuid_tree_generation(super,
1741 root_item->generation);
1738} 1742}
1739 1743
1740int btrfs_transaction_in_commit(struct btrfs_fs_info *info) 1744int btrfs_transaction_in_commit(struct btrfs_fs_info *info)