* [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly
@ 2019-10-26 10:11 Qu Wenruo
2019-11-01 10:52 ` David Sterba
0 siblings, 1 reply; 4+ messages in thread
From: Qu Wenruo @ 2019-10-26 10:11 UTC (permalink / raw)
To: linux-btrfs; +Cc: Christian Pernegger
For log zeroing, we only need to reset log_root and log_root_level to 0.
However current zero-log still goes full open_ctree() which can be
rejected easily by extent tree corruption.
So this patch will change the behavior to modifying super block
directly, avoid any possible rejection from open_ctree()
Reported-by: Christian Pernegger <pernegger@gmail.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
---
cmds/rescue.c | 48 ++++++++++++++++++++++++++++++++++++------------
1 file changed, 36 insertions(+), 12 deletions(-)
diff --git a/cmds/rescue.c b/cmds/rescue.c
index e8eab6808bc3..3e2dedf04fda 100644
--- a/cmds/rescue.c
+++ b/cmds/rescue.c
@@ -19,6 +19,9 @@
#include "kerncompat.h"
#include <getopt.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
#include "ctree.h"
#include "volumes.h"
#include "transaction.h"
@@ -164,10 +167,11 @@ static const char * const cmd_rescue_zero_log_usage[] = {
static int cmd_rescue_zero_log(const struct cmd_struct *cmd,
int argc, char **argv)
{
- struct btrfs_root *root;
- struct btrfs_trans_handle *trans;
- struct btrfs_super_block *sb;
char *devname;
+ u8 buf[BTRFS_SUPER_INFO_SIZE];
+ u8 result[BTRFS_CSUM_SIZE];
+ struct btrfs_super_block *sb = (struct btrfs_super_block *)buf;
+ int fd;
int ret;
clean_args_no_options(cmd, argc, argv);
@@ -187,24 +191,44 @@ static int cmd_rescue_zero_log(const struct cmd_struct *cmd,
goto out;
}
- root = open_ctree(devname, 0, OPEN_CTREE_WRITES | OPEN_CTREE_PARTIAL);
- if (!root) {
- error("could not open ctree");
- return 1;
+ fd = open(devname, O_RDWR);
+ if (fd < 0) {
+ ret = -errno;
+ error("failed to open '%s': %m", devname);
+ goto out;
+ }
+ /*
+ * Log tree only exists in the primary super block, so SBREAD_DEFAULT
+ * is enough.
+ */
+ ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET,
+ SBREAD_DEFAULT);
+ if (ret < 0) {
+ errno = -ret;
+ error("failed to read super block on '%s': %m", devname);
+ goto close_fd;
}
- sb = root->fs_info->super_copy;
printf("Clearing log on %s, previous log_root %llu, level %u\n",
devname,
(unsigned long long)btrfs_super_log_root(sb),
(unsigned)btrfs_super_log_root_level(sb));
- trans = btrfs_start_transaction(root, 1);
- BUG_ON(IS_ERR(trans));
btrfs_set_super_log_root(sb, 0);
btrfs_set_super_log_root_level(sb, 0);
- btrfs_commit_transaction(trans, root);
- close_ctree(root);
+ btrfs_csum_data(btrfs_super_csum_type(sb), (u8 *)sb + BTRFS_CSUM_SIZE,
+ result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
+ memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE);
+ ret = pwrite64(fd, sb, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
+ if (ret != BTRFS_SUPER_INFO_SIZE) {
+ ret = -EIO;
+ errno = -ret;
+ error("failed to write super block for '%s': %m", devname);
+ } else {
+ ret = 0;
+ }
+close_fd:
+ close(fd);
out:
return !!ret;
}
--
2.23.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly
2019-10-26 10:11 [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly Qu Wenruo
@ 2019-11-01 10:52 ` David Sterba
2019-11-01 10:56 ` Qu WenRuo
0 siblings, 1 reply; 4+ messages in thread
From: David Sterba @ 2019-11-01 10:52 UTC (permalink / raw)
To: Qu Wenruo; +Cc: linux-btrfs, Christian Pernegger
On Sat, Oct 26, 2019 at 06:11:27PM +0800, Qu Wenruo wrote:
> + /*
> + * Log tree only exists in the primary super block, so SBREAD_DEFAULT
> + * is enough.
For read it should be enough to read the default one, but do you mean
that 1st and 2nd copy don't have the log_root values set? They're
written from the same buffer so I'd expect the contents to be the same.
> + ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET,
> + SBREAD_DEFAULT);
> + if (ret < 0) {
> + errno = -ret;
> + error("failed to read super block on '%s': %m", devname);
> + goto close_fd;
> }
>
> - sb = root->fs_info->super_copy;
> printf("Clearing log on %s, previous log_root %llu, level %u\n",
> devname,
> (unsigned long long)btrfs_super_log_root(sb),
> (unsigned)btrfs_super_log_root_level(sb));
> - trans = btrfs_start_transaction(root, 1);
> - BUG_ON(IS_ERR(trans));
> btrfs_set_super_log_root(sb, 0);
> btrfs_set_super_log_root_level(sb, 0);
> - btrfs_commit_transaction(trans, root);
> - close_ctree(root);
> + btrfs_csum_data(btrfs_super_csum_type(sb), (u8 *)sb + BTRFS_CSUM_SIZE,
> + result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
> + memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE);
> + ret = pwrite64(fd, sb, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
So this only writes on the one device that's passed to the command.
Previously it would update superblocks on all devices.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly
2019-11-01 10:52 ` David Sterba
@ 2019-11-01 10:56 ` Qu WenRuo
2019-11-01 11:08 ` David Sterba
0 siblings, 1 reply; 4+ messages in thread
From: Qu WenRuo @ 2019-11-01 10:56 UTC (permalink / raw)
To: dsterba, linux-btrfs, Christian Pernegger
On 2019/11/1 下午6:52, David Sterba wrote:
> On Sat, Oct 26, 2019 at 06:11:27PM +0800, Qu Wenruo wrote:
>> + /*
>> + * Log tree only exists in the primary super block, so SBREAD_DEFAULT
>> + * is enough.
>
> For read it should be enough to read the default one, but do you mean
> that 1st and 2nd copy don't have the log_root values set? They're
> written from the same buffer so I'd expect the contents to be the same.
Log tree update only happens for primary sb.
The kernel code has this:
btrfs_sync_log()
|- ret = write_all_supers(fs_info, 1)
|- write_dev_supers(max_mirrors); # max_mirrors == 1
|- for (i = 0; i < max_mirrors; i++)
>
>> + ret = btrfs_read_dev_super(fd, sb, BTRFS_SUPER_INFO_OFFSET,
>> + SBREAD_DEFAULT);
>> + if (ret < 0) {
>> + errno = -ret;
>> + error("failed to read super block on '%s': %m", devname);
>> + goto close_fd;
>> }
>>
>> - sb = root->fs_info->super_copy;
>> printf("Clearing log on %s, previous log_root %llu, level %u\n",
>> devname,
>> (unsigned long long)btrfs_super_log_root(sb),
>> (unsigned)btrfs_super_log_root_level(sb));
>> - trans = btrfs_start_transaction(root, 1);
>> - BUG_ON(IS_ERR(trans));
>> btrfs_set_super_log_root(sb, 0);
>> btrfs_set_super_log_root_level(sb, 0);
>> - btrfs_commit_transaction(trans, root);
>> - close_ctree(root);
>> + btrfs_csum_data(btrfs_super_csum_type(sb), (u8 *)sb + BTRFS_CSUM_SIZE,
>> + result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
>> + memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE);
>> + ret = pwrite64(fd, sb, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
>
> So this only writes on the one device that's passed to the command.
> Previously it would update superblocks on all devices.
Oh, you got me.
That's indeed the case. I guess we need to do the same skip_bg behavior
just like kernel to handle multiple devices.
Thanks,
Qu
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly
2019-11-01 10:56 ` Qu WenRuo
@ 2019-11-01 11:08 ` David Sterba
0 siblings, 0 replies; 4+ messages in thread
From: David Sterba @ 2019-11-01 11:08 UTC (permalink / raw)
To: Qu WenRuo; +Cc: dsterba, linux-btrfs, Christian Pernegger
On Fri, Nov 01, 2019 at 10:56:36AM +0000, Qu WenRuo wrote:
> >> + btrfs_csum_data(btrfs_super_csum_type(sb), (u8 *)sb + BTRFS_CSUM_SIZE,
> >> + result, BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE);
> >> + memcpy(&sb->csum[0], result, BTRFS_CSUM_SIZE);
> >> + ret = pwrite64(fd, sb, BTRFS_SUPER_INFO_SIZE, BTRFS_SUPER_INFO_OFFSET);
> >
> > So this only writes on the one device that's passed to the command.
> > Previously it would update superblocks on all devices.
>
> Oh, you got me.
>
> That's indeed the case. I guess we need to do the same skip_bg behavior
> just like kernel to handle multiple devices.
In progs we can add another mode for open_ctree to open only devices,
then iterate over their superblocks and update it in place.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-11-01 11:08 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-10-26 10:11 [PATCH] btrfs-progs: rescue-zero-log: Modify super block directly Qu Wenruo
2019-11-01 10:52 ` David Sterba
2019-11-01 10:56 ` Qu WenRuo
2019-11-01 11:08 ` 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).