* [PATCH 0/2] Ensure size values are rounded down
@ 2017-06-15 12:52 Nikolay Borisov
2017-06-15 12:52 ` [PATCH 1/2] btrfs: Manually implement device_total_bytes getter/setter Nikolay Borisov
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Nikolay Borisov @ 2017-06-15 12:52 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, jeffm, Nikolay Borisov
We got an internal report about a file system not wanting to mount
following 99e3ecfcb9f4 ("Btrfs: add more validation checks for superblock").
BTRFS error (device sdb1): super_total_bytes 1000203816960 mismatch with
fs_devices total_rw_bytes 1000203820544
Substracting the numbers we get a difference of less than a 4kb. Upon closer
inspection it became apparent that mkfs actually rounds down the size of the
device to a multiple of sector size. However, the same cannot be said for
various functions which modify the total size and are called from btrfs_balanace
as well as when adding a new device.
The first patch in the series re-implements the btrfs_device_total_bytes
getter/setters manually so that we can add a WARN_ON to catch future offenders.
I haven't implemented all 4 function that the macros do since we only ever use
the getter and setter.
The second patch ensures that all the values passed to the setter are rounded
down to a multiple of sectorsize. I also have an xfstest patch which passes
after this series is applied.
Nikolay Borisov (2):
btrfs: Manually implement device_total_bytes getter/setter
btrfs: Round up values which are written for total_bytes_size
fs/btrfs/ctree.h | 19 ++++++++++++++++++-
fs/btrfs/volumes.c | 18 +++++++++++++-----
2 files changed, 31 insertions(+), 6 deletions(-)
--
2.7.4
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] btrfs: Manually implement device_total_bytes getter/setter
2017-06-15 12:52 [PATCH 0/2] Ensure size values are rounded down Nikolay Borisov
@ 2017-06-15 12:52 ` Nikolay Borisov
2017-06-15 12:52 ` [PATCH 2/2] btrfs: Round up values which are written for total_bytes_size Nikolay Borisov
2017-06-15 16:09 ` [PATCH 0/2] Ensure size values are rounded down David Sterba
2 siblings, 0 replies; 4+ messages in thread
From: Nikolay Borisov @ 2017-06-15 12:52 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, jeffm, Nikolay Borisov
The device->total_bytes member needs to always be rounded down to sectorsize
so that it corresponds to the value of super->total_bytes. However, there are
multiple places where the setter is fed a value which is not rounded which
can cause a fs to be unmountable due to the check introduced in
99e3ecfcb9f4 ("Btrfs: add more validation checks for superblock")
This patch adds the necessary WARN_ON in the setter to catch future offenders.
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
fs/btrfs/ctree.h | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 0334452a7be1..c64b16a2b28d 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1552,8 +1552,25 @@ static inline void btrfs_set_##name(type *s, u##bits val) \
s->member = cpu_to_le##bits(val); \
}
+
+static inline u64 btrfs_device_total_bytes(struct extent_buffer *eb,
+ struct btrfs_dev_item *s)
+{
+ BUILD_BUG_ON(sizeof(u64) !=
+ sizeof(((struct btrfs_dev_item *)0))->total_bytes);
+ return btrfs_get_64(eb, s, offsetof(struct btrfs_dev_item, total_bytes));
+}
+static inline void btrfs_set_device_total_bytes(struct extent_buffer *eb,
+ struct btrfs_dev_item *s,
+ u64 val)
+{
+ BUILD_BUG_ON(sizeof(u64) != sizeof(((struct btrfs_dev_item *)0))->total_bytes);
+ WARN_ON(!IS_ALIGNED(val, eb->fs_info->sectorsize));
+ btrfs_set_64(eb, s, offsetof(struct btrfs_dev_item, total_bytes), val);
+}
+
+
BTRFS_SETGET_FUNCS(device_type, struct btrfs_dev_item, type, 64);
-BTRFS_SETGET_FUNCS(device_total_bytes, struct btrfs_dev_item, total_bytes, 64);
BTRFS_SETGET_FUNCS(device_bytes_used, struct btrfs_dev_item, bytes_used, 64);
BTRFS_SETGET_FUNCS(device_io_align, struct btrfs_dev_item, io_align, 32);
BTRFS_SETGET_FUNCS(device_io_width, struct btrfs_dev_item, io_width, 32);
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] btrfs: Round up values which are written for total_bytes_size
2017-06-15 12:52 [PATCH 0/2] Ensure size values are rounded down Nikolay Borisov
2017-06-15 12:52 ` [PATCH 1/2] btrfs: Manually implement device_total_bytes getter/setter Nikolay Borisov
@ 2017-06-15 12:52 ` Nikolay Borisov
2017-06-15 16:09 ` [PATCH 0/2] Ensure size values are rounded down David Sterba
2 siblings, 0 replies; 4+ messages in thread
From: Nikolay Borisov @ 2017-06-15 12:52 UTC (permalink / raw)
To: linux-btrfs; +Cc: dsterba, jeffm, Nikolay Borisov
Signed-off-by: Nikolay Borisov <nborisov@suse.com>
---
fs/btrfs/volumes.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index e37f95976443..adf32f46a73f 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2387,7 +2387,8 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
device->io_width = fs_info->sectorsize;
device->io_align = fs_info->sectorsize;
device->sector_size = fs_info->sectorsize;
- device->total_bytes = i_size_read(bdev->bd_inode);
+ device->total_bytes = round_down(i_size_read(bdev->bd_inode),
+ fs_info->sectorsize);
device->disk_total_bytes = device->total_bytes;
device->commit_total_bytes = device->total_bytes;
device->fs_info = fs_info;
@@ -2424,7 +2425,7 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
tmp = btrfs_super_total_bytes(fs_info->super_copy);
btrfs_set_super_total_bytes(fs_info->super_copy,
- tmp + device->total_bytes);
+ round_down(tmp + device->total_bytes, fs_info->sectorsize));
tmp = btrfs_super_num_devices(fs_info->super_copy);
btrfs_set_super_num_devices(fs_info->super_copy, tmp + 1);
@@ -2687,6 +2688,8 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
if (!device->writeable)
return -EACCES;
+ new_size = round_down(new_size, fs_info->sectorsize);
+
mutex_lock(&fs_info->chunk_mutex);
old_total = btrfs_super_total_bytes(super_copy);
diff = new_size - device->total_bytes;
@@ -2699,7 +2702,8 @@ int btrfs_grow_device(struct btrfs_trans_handle *trans,
fs_devices = fs_info->fs_devices;
- btrfs_set_super_total_bytes(super_copy, old_total + diff);
+ btrfs_set_super_total_bytes(super_copy,
+ round_down(old_total + diff, fs_info->sectorsize));
device->fs_devices->total_rw_bytes += diff;
btrfs_device_set_total_bytes(device, new_size);
@@ -4389,7 +4393,10 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
struct btrfs_super_block *super_copy = fs_info->super_copy;
u64 old_total = btrfs_super_total_bytes(super_copy);
u64 old_size = btrfs_device_get_total_bytes(device);
- u64 diff = old_size - new_size;
+ u64 diff;
+
+ new_size = round_down(new_size, fs_info->sectorsize);
+ diff = old_size - new_size;
if (device->is_tgtdev_for_dev_replace)
return -EINVAL;
@@ -4516,7 +4523,8 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size)
&fs_info->fs_devices->resized_devices);
WARN_ON(diff > old_total);
- btrfs_set_super_total_bytes(super_copy, old_total - diff);
+ btrfs_set_super_total_bytes(super_copy,
+ round_down(old_total - diff, fs_info->sectorsize));
mutex_unlock(&fs_info->chunk_mutex);
/* Now btrfs_update_device() will change the on-disk size. */
--
2.7.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] Ensure size values are rounded down
2017-06-15 12:52 [PATCH 0/2] Ensure size values are rounded down Nikolay Borisov
2017-06-15 12:52 ` [PATCH 1/2] btrfs: Manually implement device_total_bytes getter/setter Nikolay Borisov
2017-06-15 12:52 ` [PATCH 2/2] btrfs: Round up values which are written for total_bytes_size Nikolay Borisov
@ 2017-06-15 16:09 ` David Sterba
2 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2017-06-15 16:09 UTC (permalink / raw)
To: Nikolay Borisov; +Cc: linux-btrfs, dsterba, jeffm
On Thu, Jun 15, 2017 at 03:52:33PM +0300, Nikolay Borisov wrote:
> We got an internal report about a file system not wanting to mount
> following 99e3ecfcb9f4 ("Btrfs: add more validation checks for superblock").
>
> BTRFS error (device sdb1): super_total_bytes 1000203816960 mismatch with
> fs_devices total_rw_bytes 1000203820544
>
> Substracting the numbers we get a difference of less than a 4kb. Upon closer
> inspection it became apparent that mkfs actually rounds down the size of the
> device to a multiple of sector size. However, the same cannot be said for
> various functions which modify the total size and are called from btrfs_balanace
> as well as when adding a new device.
>
> The first patch in the series re-implements the btrfs_device_total_bytes
> getter/setters manually so that we can add a WARN_ON to catch future offenders.
> I haven't implemented all 4 function that the macros do since we only ever use
> the getter and setter.
>
> The second patch ensures that all the values passed to the setter are rounded
> down to a multiple of sectorsize. I also have an xfstest patch which passes
> after this series is applied.
>
>
> Nikolay Borisov (2):
> btrfs: Manually implement device_total_bytes getter/setter
> btrfs: Round up values which are written for total_bytes_size
The fixes look good, but I have a comment about the changelogs. The
first patch just extends the helpers, that's a minor update and should
not contain description of the bug, as it's not the real fix. OTOH, the
2nd patch is the real fix and does not contain any bug description at
all (because it was in another patch and cover letter).
Why do I care about that? Say I'm reading the code and find that some of
the superblock values are rounded down and want to find out why. I look
up the patch in history and land in ... a patch that has no changelog or
even pointers where to look for more information. I'll naturally try to
find a patch that's close in the history but could also fail to find the
right one.
The first patch should be just expansion of the SETGET macro, without
any changes, as the added WARN_ON changes the semantics a bit.
The first three paragraphs of the cover letter hold the information that
should go to the second patch because that actually fixes the problem.
Now it's also good time to extend the setter/getter with the checks.
Also please fix the over >80 lines.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-06-15 16:11 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-06-15 12:52 [PATCH 0/2] Ensure size values are rounded down Nikolay Borisov
2017-06-15 12:52 ` [PATCH 1/2] btrfs: Manually implement device_total_bytes getter/setter Nikolay Borisov
2017-06-15 12:52 ` [PATCH 2/2] btrfs: Round up values which are written for total_bytes_size Nikolay Borisov
2017-06-15 16:09 ` [PATCH 0/2] Ensure size values are rounded down David Sterba
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).