Skip to content

Commit bc01b42

Browse files
adam900710kdave
authored andcommitted
btrfs-progs: tune: properly open zoned devices for RW
[BUG] There is a report that, for zoned devices btrfstune is unable to convert it to block group tree. # btrfstune /dev/nullb0 --convert-to-block-group-tree Error reading 1342193664, -1 Error reading 1342193664, -1 ERROR: cannot read chunk root ERROR: open ctree failed [CAUSE] For read-write opened zoned devices, all the read/write has to be aligned to its sector size. However btrfs stores its metadata by extent_buffer::data[], which has all the structures before it, thus never aligned to zoned device sector size. Normally we would require btrfs_pread() and btrfs_pwrite() to do the extra alignment, but during open_ctree(), we are not aware if a device is zoned or not. Thus we rely on if the fd is opened with O_DIRECT flag, if the fd has O_DIRECT, then we would temporarily set fs_info->zoned for chunk tree read. Unforunately not all open_ctree_fd() callers have the flags set properly, and btrfstune is one of the missing call site. This makes all the read not properly aligned and cause read failure. [FIX] Just manually check if the target device is a zoned one, and set O_DIRECT accordingly. Issue: #765 Reviewed-by: Johannes Thumshirn <[email protected]> Reviewed-by: Naohiro Aota <[email protected]> Signed-off-by: Qu Wenruo <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent e3b5c91 commit bc01b42

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

tune/main.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "kernel-shared/transaction.h"
3030
#include "kernel-shared/volumes.h"
3131
#include "kernel-shared/free-space-tree.h"
32+
#include "kernel-shared/zoned.h"
3233
#include "common/utils.h"
3334
#include "common/open-utils.h"
3435
#include "common/device-scan.h"
@@ -194,6 +195,7 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
194195
u64 super_flags = 0;
195196
int quota = 0;
196197
int fd = -1;
198+
int oflags = O_RDWR;
197199

198200
btrfs_config_init();
199201

@@ -337,7 +339,9 @@ int BOX_MAIN(btrfstune)(int argc, char *argv[])
337339
}
338340
}
339341

340-
fd = open(device, O_RDWR);
342+
if (zoned_model(device) == ZONED_HOST_MANAGED)
343+
oflags |= O_DIRECT;
344+
fd = open(device, oflags);
341345
if (fd < 0) {
342346
error("mount check: cannot open %s: %m", device);
343347
ret = 1;

0 commit comments

Comments
 (0)