From f9e7869965b195602169f1d10f36bd6f594ecca8 Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Tue, 5 Nov 2024 13:48:20 +1030 Subject: [PATCH] Revert "btrfs-progs: mkfs: refactor add_file_items" This reverts commit 8b6231b5ffccebd770c5c9bcd4d498a146b6600a. --- mkfs/rootdir.c | 153 +++++++++++++++++++++++-------------------------- 1 file changed, 71 insertions(+), 82 deletions(-) diff --git a/mkfs/rootdir.c b/mkfs/rootdir.c index 704f59e76..ffe9aa1f9 100644 --- a/mkfs/rootdir.c +++ b/mkfs/rootdir.c @@ -362,76 +362,6 @@ static int add_symbolic_link(struct btrfs_trans_handle *trans, return ret; } -/* - * keep our extent size at 1MB max, this makes it easier to work - * inside the tiny block groups created during mkfs - */ -#define MAX_EXTENT_SIZE SZ_1M - -static int read_and_write_extent(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_inode_item *btrfs_inode, - u64 objectid, int fd, u64 file_pos, char *buf, - u64 size, const char *path_name) -{ - int ret; - u32 sectorsize = root->fs_info->sectorsize; - u64 bytes_read, first_block, to_read, to_write; - struct btrfs_key key; - - to_read = min(file_pos + MAX_EXTENT_SIZE, size) - file_pos; - - bytes_read = 0; - - while (bytes_read < to_read) { - ssize_t ret_read; - - ret_read = pread(fd, buf + bytes_read, to_read - bytes_read, - file_pos + bytes_read); - if (ret_read == -1) { - error("cannot read %s at offset %llu length %llu: %m", - path_name, file_pos + bytes_read, - to_read - bytes_read); - return -errno; - } - - bytes_read += ret_read; - } - - to_write = round_up(to_read, sectorsize); - memset(buf + to_read, 0, to_write - to_read); - - ret = btrfs_reserve_extent(trans, root, to_write, 0, 0, - (u64)-1, &key, 1); - if (ret) - return ret; - - first_block = key.objectid; - - ret = write_data_to_disk(root->fs_info, buf, first_block, - to_write); - if (ret) { - error("failed to write %s", path_name); - return ret; - } - - for (unsigned int i = 0; i < to_write / sectorsize; i++) { - ret = btrfs_csum_file_block(trans, first_block + (i * sectorsize), - BTRFS_EXTENT_CSUM_OBJECTID, - root->fs_info->csum_type, - buf + (i * sectorsize)); - if (ret) - return ret; - } - - ret = btrfs_record_file_extent(trans, root, objectid, btrfs_inode, - file_pos, first_block, to_write); - if (ret) - return ret; - - return to_read; -} - static int add_file_items(struct btrfs_trans_handle *trans, struct btrfs_root *root, struct btrfs_inode_item *btrfs_inode, u64 objectid, @@ -440,9 +370,15 @@ static int add_file_items(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info = trans->fs_info; int ret = -1; ssize_t ret_read; + u64 bytes_read = 0; + struct btrfs_key key; + int blocks; u32 sectorsize = fs_info->sectorsize; + u64 first_block = 0; u64 file_pos = 0; - char *buf = NULL; + u64 cur_bytes; + u64 total_bytes; + void *buf = NULL; int fd; if (st->st_size == 0) @@ -454,6 +390,10 @@ static int add_file_items(struct btrfs_trans_handle *trans, return ret; } + blocks = st->st_size / sectorsize; + if (st->st_size % sectorsize) + blocks += 1; + if (st->st_size <= BTRFS_MAX_INLINE_DATA_SIZE(fs_info) && st->st_size < sectorsize) { char *buffer = malloc(st->st_size); @@ -463,10 +403,10 @@ static int add_file_items(struct btrfs_trans_handle *trans, goto end; } - ret_read = pread(fd, buffer, st->st_size, 0); + ret_read = pread(fd, buffer, st->st_size, bytes_read); if (ret_read == -1) { - error("cannot read %s at offset %u length %llu: %m", - path_name, 0, (unsigned long long)st->st_size); + error("cannot read %s at offset %llu length %llu: %m", + path_name, bytes_read, (unsigned long long)st->st_size); free(buffer); goto end; } @@ -479,22 +419,71 @@ static int add_file_items(struct btrfs_trans_handle *trans, goto end; } - buf = malloc(MAX_EXTENT_SIZE); + /* round up our st_size to the FS blocksize */ + total_bytes = (u64)blocks * sectorsize; + + buf = malloc(sectorsize); if (!buf) { ret = -ENOMEM; goto end; } - while (file_pos < st->st_size) { - ret = read_and_write_extent(trans, root, btrfs_inode, objectid, - fd, file_pos, buf, st->st_size, - path_name); - if (ret < 0) - break; +again: + + /* + * keep our extent size at 1MB max, this makes it easier to work inside + * the tiny block groups created during mkfs + */ + cur_bytes = min(total_bytes, (u64)SZ_1M); + ret = btrfs_reserve_extent(trans, root, cur_bytes, 0, 0, (u64)-1, + &key, 1); + if (ret) + goto end; + + first_block = key.objectid; + bytes_read = 0; + + while (bytes_read < cur_bytes) { + + memset(buf, 0, sectorsize); + + ret_read = pread(fd, buf, sectorsize, file_pos + bytes_read); + if (ret_read == -1) { + error("cannot read %s at offset %llu length %u: %m", + path_name, file_pos + bytes_read, sectorsize); + goto end; + } + + ret = write_data_to_disk(root->fs_info, buf, + first_block + bytes_read, sectorsize); + if (ret) { + error("failed to write %s", path_name); + goto end; + } + + ret = btrfs_csum_file_block(trans, first_block + bytes_read, + BTRFS_EXTENT_CSUM_OBJECTID, + fs_info->csum_type, buf); + if (ret) + goto end; + + bytes_read += sectorsize; + } + + if (bytes_read) { + ret = btrfs_record_file_extent(trans, root, objectid, + btrfs_inode, file_pos, first_block, cur_bytes); + if (ret) + goto end; - file_pos += ret; } + file_pos += cur_bytes; + total_bytes -= cur_bytes; + + if (total_bytes) + goto again; + end: free(buf); close(fd);