mirror of
https://github.com/Le0xFF/VoidLinuxInstaller.git
synced 2024-08-17 14:40:22 +03:00
Get rid of btrfs_map_physical
Use `btrfs inspect-internal map-swapfile` command, as reported in official documentation: [Hibernation](https://btrfs.readthedocs.io/en/latest/Swapfile.html#hibernation)
This commit is contained in:
parent
25c0c6684a
commit
8b495857b4
@ -546,14 +546,10 @@ function create_swapfile {
|
|||||||
fi
|
fi
|
||||||
echo -e -n "\nA swapfile of ${BLUE_LIGHT}${swap_size}GB${NORMAL} will be created in ${BLUE_LIGHT}/var/swap/${NORMAL} btrfs subvolume...\n\n"
|
echo -e -n "\nA swapfile of ${BLUE_LIGHT}${swap_size}GB${NORMAL} will be created in ${BLUE_LIGHT}/var/swap/${NORMAL} btrfs subvolume...\n\n"
|
||||||
btrfs subvolume create /var/swap
|
btrfs subvolume create /var/swap
|
||||||
truncate -s 0 /var/swap/swapfile
|
btrfs filesystem mkswapfile /var/swap/swapfile --size "${swap_size}"G
|
||||||
chattr +C /var/swap/swapfile
|
|
||||||
chmod 600 /var/swap/swapfile
|
|
||||||
dd if=/dev/zero of=/var/swap/swapfile bs=100M count="$((${swap_size} * 10))" status=progress
|
|
||||||
mkswap --label SwapFile /var/swap/swapfile
|
mkswap --label SwapFile /var/swap/swapfile
|
||||||
swapon /var/swap/swapfile
|
swapon /var/swap/swapfile
|
||||||
gcc -O2 "$HOME"/btrfs_map_physical.c -o "$HOME"/btrfs_map_physical
|
RESUME_OFFSET=$(btrfs inspect-internal map-swapfile -r /var/swap/swapfile)
|
||||||
RESUME_OFFSET=$(($("$HOME"/btrfs_map_physical /var/swap/swapfile | awk -F " " 'FNR == 2 {print $NF}') / $(getconf PAGESIZE)))
|
|
||||||
if [[ $bootloader =~ $regex_EFISTUB ]]; then
|
if [[ $bootloader =~ $regex_EFISTUB ]]; then
|
||||||
sed -i "/OPTIONS=/s/\"$/ resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET&/" /etc/default/efibootmgr-kernel-hook
|
sed -i "/OPTIONS=/s/\"$/ resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET&/" /etc/default/efibootmgr-kernel-hook
|
||||||
elif [[ $bootloader =~ $regex_GRUB2 ]]; then
|
elif [[ $bootloader =~ $regex_GRUB2 ]]; then
|
||||||
|
580
vli.sh
580
vli.sh
@ -86,10 +86,6 @@ function kill_script {
|
|||||||
rm -f "$HOME"/chroot.sh
|
rm -f "$HOME"/chroot.sh
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -f "$HOME"/btrfs_map_physical.c ]]; then
|
|
||||||
rm -f "$HOME"/btrfs_map_physical.c
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo -e -n "\n${GREEN_LIGHT}Everything's done, quitting.${NORMAL}\n\n"
|
echo -e -n "\n${GREEN_LIGHT}Everything's done, quitting.${NORMAL}\n\n"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
@ -679,14 +675,10 @@ function create_swapfile {
|
|||||||
fi
|
fi
|
||||||
echo -e -n "\nA swapfile of ${BLUE_LIGHT}${swap_size}GB${NORMAL} will be created in ${BLUE_LIGHT}/var/swap/${NORMAL} btrfs subvolume...\n\n"
|
echo -e -n "\nA swapfile of ${BLUE_LIGHT}${swap_size}GB${NORMAL} will be created in ${BLUE_LIGHT}/var/swap/${NORMAL} btrfs subvolume...\n\n"
|
||||||
btrfs subvolume create /var/swap
|
btrfs subvolume create /var/swap
|
||||||
truncate -s 0 /var/swap/swapfile
|
btrfs filesystem mkswapfile /var/swap/swapfile --size "${swap_size}"G
|
||||||
chattr +C /var/swap/swapfile
|
|
||||||
chmod 600 /var/swap/swapfile
|
|
||||||
dd if=/dev/zero of=/var/swap/swapfile bs=100M count="$((${swap_size} * 10))" status=progress
|
|
||||||
mkswap --label SwapFile /var/swap/swapfile
|
mkswap --label SwapFile /var/swap/swapfile
|
||||||
swapon /var/swap/swapfile
|
swapon /var/swap/swapfile
|
||||||
gcc -O2 "$HOME"/btrfs_map_physical.c -o "$HOME"/btrfs_map_physical
|
RESUME_OFFSET=$(btrfs inspect-internal map-swapfile -r /var/swap/swapfile)
|
||||||
RESUME_OFFSET=$(($("$HOME"/btrfs_map_physical /var/swap/swapfile | awk -F " " 'FNR == 2 {print $NF}') / $(getconf PAGESIZE)))
|
|
||||||
if [[ $bootloader =~ $regex_EFISTUB ]]; then
|
if [[ $bootloader =~ $regex_EFISTUB ]]; then
|
||||||
sed -i "/OPTIONS=/s/\"$/ resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET&/" /etc/default/efibootmgr-kernel-hook
|
sed -i "/OPTIONS=/s/\"$/ resume=UUID=$ROOT_UUID resume_offset=$RESUME_OFFSET&/" /etc/default/efibootmgr-kernel-hook
|
||||||
elif [[ $bootloader =~ $regex_GRUB2 ]]; then
|
elif [[ $bootloader =~ $regex_GRUB2 ]]; then
|
||||||
@ -1415,571 +1407,6 @@ EndOfChrootScript
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function create_btrfs_map_physical_c {
|
|
||||||
|
|
||||||
if [[ -f "$HOME"/btrfs_map_physical.c ]]; then
|
|
||||||
rm -f "$HOME"/btrfs_map_physical.c
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat >>"$HOME"/btrfs_map_physical.c <<'EndOfProgram'
|
|
||||||
// SPDX-FileCopyrightText: Omar Sandoval <osandov@osandov.com>
|
|
||||||
// SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <linux/btrfs.h>
|
|
||||||
#include <linux/btrfs_tree.h>
|
|
||||||
#include <asm/byteorder.h>
|
|
||||||
|
|
||||||
#define le16_to_cpu __le16_to_cpu
|
|
||||||
#define le32_to_cpu __le32_to_cpu
|
|
||||||
#define le64_to_cpu __le64_to_cpu
|
|
||||||
|
|
||||||
static const char *progname = "btrfs_map_physical";
|
|
||||||
|
|
||||||
static void usage(bool error)
|
|
||||||
{
|
|
||||||
fprintf(error ? stderr : stdout,
|
|
||||||
"usage: %s [OPTION]... PATH\n"
|
|
||||||
"\n"
|
|
||||||
"Map the logical and physical extents of a file on Btrfs\n\n"
|
|
||||||
"Pipe this to `column -ts $'\\t'` for prettier output.\n"
|
|
||||||
"\n"
|
|
||||||
"Btrfs represents a range of data in a file with a \"file extent\". Each\n"
|
|
||||||
"file extent refers to a subset of an \"extent\". Each extent has a\n"
|
|
||||||
"location in the logical address space of the filesystem belonging to a\n"
|
|
||||||
"\"chunk\". Each chunk maps has a profile (i.e., RAID level) and maps to\n"
|
|
||||||
"one or more physical locations, or \"stripes\", on disk. The extent may be\n"
|
|
||||||
"\"encoded\" on disk (currently this means compressed, but in the future it\n"
|
|
||||||
"may also be encrypted).\n"
|
|
||||||
"\n"
|
|
||||||
"An explanation of each printed field and its corresponding on-disk data\n"
|
|
||||||
"structure is provided below:\n"
|
|
||||||
"\n"
|
|
||||||
"FILE OFFSET Offset in the file where the file extent starts\n"
|
|
||||||
" [(struct btrfs_key).offset]\n"
|
|
||||||
"FILE SIZE Size of the file extent\n"
|
|
||||||
" [(struct btrfs_file_extent_item).num_bytes for most\n"
|
|
||||||
" extents, (struct btrfs_file_extent_item).ram_bytes\n"
|
|
||||||
" for inline extents]\n"
|
|
||||||
"EXTENT OFFSET Offset from the beginning of the unencoded extent\n"
|
|
||||||
" where the file extent starts\n"
|
|
||||||
" [(struct btrfs_file_extent_item).offset]\n"
|
|
||||||
"EXTENT TYPE Type of the extent (inline, preallocated, etc.)\n"
|
|
||||||
" [(struct btrfs_file_extent_item).type];\n"
|
|
||||||
" how it is encoded\n"
|
|
||||||
" [(struct btrfs_file_extent_item){compression,\n"
|
|
||||||
" encryption,other_encoding}];\n"
|
|
||||||
" and its data profile\n"
|
|
||||||
" [(struct btrfs_chunk).type]\n"
|
|
||||||
"LOGICAL SIZE Size of the unencoded extent\n"
|
|
||||||
" [(struct btrfs_file_extent_item).ram_bytes]\n"
|
|
||||||
"LOGICAL OFFSET Location of the extent in the filesystem's logical\n"
|
|
||||||
" address space\n"
|
|
||||||
" [(struct btrfs_file_extent_offset).disk_bytenr]\n"
|
|
||||||
"PHYSICAL SIZE Size of the encoded extent on disk\n"
|
|
||||||
" [(struct btrfs_file_extent_offset).disk_num_bytes]\n"
|
|
||||||
"DEVID ID of the device containing the extent\n"
|
|
||||||
" [(struct btrfs_stripe).devid]\n"
|
|
||||||
"PHYSICAL OFFSET Location of the extent on the device\n"
|
|
||||||
" [calculated from (struct btrfs_stripe).offset]\n"
|
|
||||||
"\n"
|
|
||||||
"FILE SIZE is rounded up to the sector size of the filesystem.\n"
|
|
||||||
"\n"
|
|
||||||
"Inline extents are stored with the metadata of the filesystem; this tool\n"
|
|
||||||
"does not have the ability to determine their location.\n"
|
|
||||||
"\n"
|
|
||||||
"Gaps in a file are represented with a hole file extent unless the\n"
|
|
||||||
"filesystem was formatted with the \"no-holes\" option.\n"
|
|
||||||
"\n"
|
|
||||||
"If the file extent was truncated, hole punched, cloned, or deduped,\n"
|
|
||||||
"EXTENT OFFSET may be non-zero and LOGICAL SIZE may be different from\n"
|
|
||||||
"FILE SIZE.\n"
|
|
||||||
"\n"
|
|
||||||
"Options:\n"
|
|
||||||
" -h, --help display this help message and exit\n",
|
|
||||||
progname);
|
|
||||||
exit(error ? EXIT_FAILURE : EXIT_SUCCESS);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct stripe {
|
|
||||||
uint64_t devid;
|
|
||||||
uint64_t offset;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct chunk {
|
|
||||||
uint64_t offset;
|
|
||||||
uint64_t length;
|
|
||||||
uint64_t stripe_len;
|
|
||||||
uint64_t type;
|
|
||||||
struct stripe *stripes;
|
|
||||||
size_t num_stripes;
|
|
||||||
size_t sub_stripes;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct chunk_tree {
|
|
||||||
struct chunk *chunks;
|
|
||||||
size_t num_chunks;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int read_chunk_tree(int fd, struct chunk **chunks, size_t *num_chunks)
|
|
||||||
{
|
|
||||||
struct btrfs_ioctl_search_args search = {
|
|
||||||
.key = {
|
|
||||||
.tree_id = BTRFS_CHUNK_TREE_OBJECTID,
|
|
||||||
.min_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID,
|
|
||||||
.min_type = BTRFS_CHUNK_ITEM_KEY,
|
|
||||||
.min_offset = 0,
|
|
||||||
.max_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID,
|
|
||||||
.max_type = BTRFS_CHUNK_ITEM_KEY,
|
|
||||||
.max_offset = UINT64_MAX,
|
|
||||||
.min_transid = 0,
|
|
||||||
.max_transid = UINT64_MAX,
|
|
||||||
.nr_items = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
size_t items_pos = 0, buf_off = 0;
|
|
||||||
size_t capacity = 0;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
*chunks = NULL;
|
|
||||||
*num_chunks = 0;
|
|
||||||
for (;;) {
|
|
||||||
const struct btrfs_ioctl_search_header *header;
|
|
||||||
const struct btrfs_chunk *item;
|
|
||||||
struct chunk *chunk;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (items_pos >= search.key.nr_items) {
|
|
||||||
search.key.nr_items = 4096;
|
|
||||||
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &search);
|
|
||||||
if (ret == -1) {
|
|
||||||
perror("BTRFS_IOC_TREE_SEARCH");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
items_pos = 0;
|
|
||||||
buf_off = 0;
|
|
||||||
|
|
||||||
if (search.key.nr_items == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
header = (struct btrfs_ioctl_search_header *)(search.buf + buf_off);
|
|
||||||
if (header->type != BTRFS_CHUNK_ITEM_KEY)
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
item = (void *)(header + 1);
|
|
||||||
if (*num_chunks >= capacity) {
|
|
||||||
struct chunk *tmp;
|
|
||||||
|
|
||||||
if (capacity == 0)
|
|
||||||
capacity = 1;
|
|
||||||
else
|
|
||||||
capacity *= 2;
|
|
||||||
tmp = realloc(*chunks, capacity * sizeof(**chunks));
|
|
||||||
if (!tmp) {
|
|
||||||
perror("realloc");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*chunks = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
chunk = &(*chunks)[*num_chunks];
|
|
||||||
chunk->offset = header->offset;
|
|
||||||
chunk->length = le64_to_cpu(item->length);
|
|
||||||
chunk->stripe_len = le64_to_cpu(item->stripe_len);
|
|
||||||
chunk->type = le64_to_cpu(item->type);
|
|
||||||
chunk->num_stripes = le16_to_cpu(item->num_stripes);
|
|
||||||
chunk->sub_stripes = le16_to_cpu(item->sub_stripes);
|
|
||||||
chunk->stripes = calloc(chunk->num_stripes,
|
|
||||||
sizeof(*chunk->stripes));
|
|
||||||
if (!chunk->stripes) {
|
|
||||||
perror("calloc");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
(*num_chunks)++;
|
|
||||||
|
|
||||||
for (i = 0; i < chunk->num_stripes; i++) {
|
|
||||||
const struct btrfs_stripe *stripe;
|
|
||||||
|
|
||||||
stripe = &item->stripe + i;
|
|
||||||
chunk->stripes[i].devid = le64_to_cpu(stripe->devid);
|
|
||||||
chunk->stripes[i].offset = le64_to_cpu(stripe->offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
next:
|
|
||||||
items_pos++;
|
|
||||||
buf_off += sizeof(*header) + header->len;
|
|
||||||
if (header->offset == UINT64_MAX)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
search.key.min_offset = header->offset + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct chunk *find_chunk(struct chunk *chunks, size_t num_chunks,
|
|
||||||
uint64_t logical)
|
|
||||||
{
|
|
||||||
size_t lo, hi;
|
|
||||||
|
|
||||||
if (!num_chunks)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
lo = 0;
|
|
||||||
hi = num_chunks - 1;
|
|
||||||
while (lo <= hi) {
|
|
||||||
size_t mid = lo + (hi - lo) / 2;
|
|
||||||
|
|
||||||
if (logical < chunks[mid].offset)
|
|
||||||
hi = mid - 1;
|
|
||||||
else if (logical >= chunks[mid].offset + chunks[mid].length)
|
|
||||||
lo = mid + 1;
|
|
||||||
else
|
|
||||||
return &chunks[mid];
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int print_extents(int fd, struct chunk *chunks, size_t num_chunks)
|
|
||||||
{
|
|
||||||
struct btrfs_ioctl_search_args search = {
|
|
||||||
.key = {
|
|
||||||
.min_type = BTRFS_EXTENT_DATA_KEY,
|
|
||||||
.max_type = BTRFS_EXTENT_DATA_KEY,
|
|
||||||
.min_offset = 0,
|
|
||||||
.max_offset = UINT64_MAX,
|
|
||||||
.min_transid = 0,
|
|
||||||
.max_transid = UINT64_MAX,
|
|
||||||
.nr_items = 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
struct btrfs_ioctl_ino_lookup_args args = {
|
|
||||||
.treeid = 0,
|
|
||||||
.objectid = BTRFS_FIRST_FREE_OBJECTID,
|
|
||||||
};
|
|
||||||
size_t items_pos = 0, buf_off = 0;
|
|
||||||
struct stat st;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
puts("FILE OFFSET\tFILE SIZE\tEXTENT OFFSET\tEXTENT TYPE\tLOGICAL SIZE\tLOGICAL OFFSET\tPHYSICAL SIZE\tDEVID\tPHYSICAL OFFSET");
|
|
||||||
|
|
||||||
ret = fstat(fd, &st);
|
|
||||||
if (ret == -1) {
|
|
||||||
perror("fstat");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ioctl(fd, BTRFS_IOC_INO_LOOKUP, &args);
|
|
||||||
if (ret == -1) {
|
|
||||||
perror("BTRFS_IOC_INO_LOOKUP");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
search.key.tree_id = args.treeid;
|
|
||||||
search.key.min_objectid = search.key.max_objectid = st.st_ino;
|
|
||||||
for (;;) {
|
|
||||||
const struct btrfs_ioctl_search_header *header;
|
|
||||||
const struct btrfs_file_extent_item *item;
|
|
||||||
uint8_t type;
|
|
||||||
/* Initialize to silence GCC. */
|
|
||||||
uint64_t file_offset = 0;
|
|
||||||
uint64_t file_size = 0;
|
|
||||||
uint64_t extent_offset = 0;
|
|
||||||
uint64_t logical_size = 0;
|
|
||||||
uint64_t logical_offset = 0;
|
|
||||||
uint64_t physical_size = 0;
|
|
||||||
struct chunk *chunk = NULL;
|
|
||||||
|
|
||||||
if (items_pos >= search.key.nr_items) {
|
|
||||||
search.key.nr_items = 4096;
|
|
||||||
ret = ioctl(fd, BTRFS_IOC_TREE_SEARCH, &search);
|
|
||||||
if (ret == -1) {
|
|
||||||
perror("BTRFS_IOC_TREE_SEARCH");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
items_pos = 0;
|
|
||||||
buf_off = 0;
|
|
||||||
|
|
||||||
if (search.key.nr_items == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
header = (struct btrfs_ioctl_search_header *)(search.buf + buf_off);
|
|
||||||
if (header->type != BTRFS_EXTENT_DATA_KEY)
|
|
||||||
goto next;
|
|
||||||
|
|
||||||
item = (void *)(header + 1);
|
|
||||||
|
|
||||||
type = item->type;
|
|
||||||
file_offset = header->offset;
|
|
||||||
if (type == BTRFS_FILE_EXTENT_INLINE) {
|
|
||||||
file_size = logical_size = le64_to_cpu(item->ram_bytes);
|
|
||||||
extent_offset = 0;
|
|
||||||
physical_size = (header->len -
|
|
||||||
offsetof(struct btrfs_file_extent_item,
|
|
||||||
disk_bytenr));
|
|
||||||
} else if (type == BTRFS_FILE_EXTENT_REG ||
|
|
||||||
type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
||||||
file_size = le64_to_cpu(item->num_bytes);
|
|
||||||
extent_offset = le64_to_cpu(item->offset);
|
|
||||||
logical_size = le64_to_cpu(item->ram_bytes);
|
|
||||||
logical_offset = le64_to_cpu(item->disk_bytenr);
|
|
||||||
physical_size = le64_to_cpu(item->disk_num_bytes);
|
|
||||||
if (logical_offset) {
|
|
||||||
chunk = find_chunk(chunks, num_chunks,
|
|
||||||
logical_offset);
|
|
||||||
if (!chunk) {
|
|
||||||
printf("\n");
|
|
||||||
fprintf(stderr,
|
|
||||||
"could not find chunk containing %" PRIu64 "\n",
|
|
||||||
logical_offset);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%" PRIu64 "\t", file_offset);
|
|
||||||
if (type == BTRFS_FILE_EXTENT_INLINE ||
|
|
||||||
type == BTRFS_FILE_EXTENT_REG ||
|
|
||||||
type == BTRFS_FILE_EXTENT_PREALLOC) {
|
|
||||||
printf("%" PRIu64 "\t%" PRIu64 "\t", file_size,
|
|
||||||
extent_offset);
|
|
||||||
} else {
|
|
||||||
printf("\t\t");
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case BTRFS_FILE_EXTENT_INLINE:
|
|
||||||
printf("inline");
|
|
||||||
break;
|
|
||||||
case BTRFS_FILE_EXTENT_REG:
|
|
||||||
if (logical_offset)
|
|
||||||
printf("regular");
|
|
||||||
else
|
|
||||||
printf("hole");
|
|
||||||
break;
|
|
||||||
case BTRFS_FILE_EXTENT_PREALLOC:
|
|
||||||
printf("prealloc");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("type%u", type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch (item->compression) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
printf(",compression=zlib");
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
printf(",compression=lzo");
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
printf(",compression=zstd");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf(",compression=%u", item->compression);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (item->encryption)
|
|
||||||
printf(",encryption=%u", item->encryption);
|
|
||||||
if (item->other_encoding) {
|
|
||||||
printf(",other_encoding=%u",
|
|
||||||
le16_to_cpu(item->other_encoding));
|
|
||||||
}
|
|
||||||
if (chunk) {
|
|
||||||
switch (chunk->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID0:
|
|
||||||
printf(",raid0");
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID1:
|
|
||||||
printf(",raid1");
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_DUP:
|
|
||||||
printf(",dup");
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID10:
|
|
||||||
printf(",raid10");
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID5:
|
|
||||||
printf(",raid5");
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID6:
|
|
||||||
printf(",raid6");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf(",profile%" PRIu64,
|
|
||||||
(uint64_t)(chunk->type &
|
|
||||||
BTRFS_BLOCK_GROUP_PROFILE_MASK));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\t");
|
|
||||||
|
|
||||||
if (type == BTRFS_FILE_EXTENT_INLINE ||
|
|
||||||
type == BTRFS_FILE_EXTENT_REG ||
|
|
||||||
type == BTRFS_FILE_EXTENT_PREALLOC)
|
|
||||||
printf("%" PRIu64 "\t", logical_size);
|
|
||||||
else
|
|
||||||
printf("\t");
|
|
||||||
|
|
||||||
if (type == BTRFS_FILE_EXTENT_REG ||
|
|
||||||
type == BTRFS_FILE_EXTENT_PREALLOC)
|
|
||||||
printf("%" PRIu64 "\t", logical_offset);
|
|
||||||
else
|
|
||||||
printf("\t");
|
|
||||||
|
|
||||||
if (type == BTRFS_FILE_EXTENT_INLINE ||
|
|
||||||
type == BTRFS_FILE_EXTENT_REG ||
|
|
||||||
type == BTRFS_FILE_EXTENT_PREALLOC)
|
|
||||||
printf("%" PRIu64 "\t", physical_size);
|
|
||||||
else
|
|
||||||
printf("\t");
|
|
||||||
|
|
||||||
if (chunk) {
|
|
||||||
uint64_t offset, stripe_nr, stripe_offset;
|
|
||||||
size_t stripe_index, num_stripes;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
offset = logical_offset - chunk->offset;
|
|
||||||
stripe_nr = offset / chunk->stripe_len;
|
|
||||||
stripe_offset = offset - stripe_nr * chunk->stripe_len;
|
|
||||||
switch (chunk->type & BTRFS_BLOCK_GROUP_PROFILE_MASK) {
|
|
||||||
case 0:
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID0:
|
|
||||||
stripe_index = stripe_nr % chunk->num_stripes;
|
|
||||||
stripe_nr /= chunk->num_stripes;
|
|
||||||
num_stripes = 1;
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID1:
|
|
||||||
case BTRFS_BLOCK_GROUP_DUP:
|
|
||||||
stripe_index = 0;
|
|
||||||
num_stripes = chunk->num_stripes;
|
|
||||||
break;
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID10: {
|
|
||||||
size_t factor;
|
|
||||||
|
|
||||||
factor = chunk->num_stripes / chunk->sub_stripes;
|
|
||||||
stripe_index = (stripe_nr % factor *
|
|
||||||
chunk->sub_stripes);
|
|
||||||
stripe_nr /= factor;
|
|
||||||
num_stripes = chunk->sub_stripes;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID5:
|
|
||||||
case BTRFS_BLOCK_GROUP_RAID6: {
|
|
||||||
size_t nr_parity_stripes, nr_data_stripes;
|
|
||||||
|
|
||||||
if (chunk->type & BTRFS_BLOCK_GROUP_RAID6)
|
|
||||||
nr_parity_stripes = 2;
|
|
||||||
else
|
|
||||||
nr_parity_stripes = 1;
|
|
||||||
nr_data_stripes = (chunk->num_stripes -
|
|
||||||
nr_parity_stripes);
|
|
||||||
stripe_index = stripe_nr % nr_data_stripes;
|
|
||||||
stripe_nr /= nr_data_stripes;
|
|
||||||
stripe_index = ((stripe_nr + stripe_index) %
|
|
||||||
chunk->num_stripes);
|
|
||||||
num_stripes = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
num_stripes = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < num_stripes; i++) {
|
|
||||||
if (i != 0)
|
|
||||||
printf("\n\t\t\t\t\t\t\t");
|
|
||||||
printf("%" PRIu64 "\t%" PRIu64,
|
|
||||||
chunk->stripes[stripe_index].devid,
|
|
||||||
chunk->stripes[stripe_index].offset +
|
|
||||||
stripe_nr * chunk->stripe_len +
|
|
||||||
stripe_offset);
|
|
||||||
stripe_index++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
next:
|
|
||||||
items_pos++;
|
|
||||||
buf_off += sizeof(*header) + header->len;
|
|
||||||
if (header->offset == UINT64_MAX)
|
|
||||||
break;
|
|
||||||
else
|
|
||||||
search.key.min_offset = header->offset + 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
struct option long_options[] = {
|
|
||||||
{"help", no_argument, NULL, 'h'},
|
|
||||||
};
|
|
||||||
int fd, ret;
|
|
||||||
struct chunk *chunks;
|
|
||||||
size_t num_chunks, i;
|
|
||||||
|
|
||||||
if (argv[0])
|
|
||||||
progname = argv[0];
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
int c;
|
|
||||||
|
|
||||||
c = getopt_long(argc, argv, "h", long_options, NULL);
|
|
||||||
if (c == -1)
|
|
||||||
break;
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case 'h':
|
|
||||||
usage(false);
|
|
||||||
default:
|
|
||||||
usage(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (optind != argc - 1)
|
|
||||||
usage(true);
|
|
||||||
|
|
||||||
fd = open(argv[optind], O_RDONLY);
|
|
||||||
if (fd == -1) {
|
|
||||||
perror("open");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = read_chunk_tree(fd, &chunks, &num_chunks);
|
|
||||||
if (ret == -1)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
ret = print_extents(fd, chunks, num_chunks);
|
|
||||||
out:
|
|
||||||
for (i = 0; i < num_chunks; i++)
|
|
||||||
free(chunks[i].stripes);
|
|
||||||
free(chunks);
|
|
||||||
close(fd);
|
|
||||||
return ret ? EXIT_FAILURE : EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
EndOfProgram
|
|
||||||
|
|
||||||
if [[ ! -f "$HOME"/btrfs_map_physical.c ]]; then
|
|
||||||
echo -e -n "Please run this script again to be sure that $HOME/btrfs_map_physical.c is created too."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
function intro {
|
function intro {
|
||||||
|
|
||||||
clear
|
clear
|
||||||
@ -3020,7 +2447,6 @@ function format_create_install_system {
|
|||||||
echo -e -n "\nChrooting...\n\n"
|
echo -e -n "\nChrooting...\n\n"
|
||||||
press_any_key_to_continue
|
press_any_key_to_continue
|
||||||
cp "$HOME"/chroot.sh /mnt/root/
|
cp "$HOME"/chroot.sh /mnt/root/
|
||||||
cp "$HOME"/btrfs_map_physical.c /mnt/root/
|
|
||||||
|
|
||||||
BTRFS_OPT="$BTRFS_OPT" boot_partition="$boot_partition" encryption_yn="$encryption_yn" luks_ot="$luks_ot" root_partition="$root_partition" \
|
BTRFS_OPT="$BTRFS_OPT" boot_partition="$boot_partition" encryption_yn="$encryption_yn" luks_ot="$luks_ot" root_partition="$root_partition" \
|
||||||
encrypted_name="$encrypted_name" lvm_yn="$lvm_yn" vg_name="$vg_name" lv_root_name="$lv_root_name" user_drive="$user_drive" final_drive="$final_drive" \
|
encrypted_name="$encrypted_name" lvm_yn="$lvm_yn" vg_name="$vg_name" lv_root_name="$lv_root_name" user_drive="$user_drive" final_drive="$final_drive" \
|
||||||
@ -3033,8 +2459,6 @@ function format_create_install_system {
|
|||||||
header_fcis
|
header_fcis
|
||||||
echo -e -n "\nCleaning...\n"
|
echo -e -n "\nCleaning...\n"
|
||||||
rm -f /mnt/root/chroot.sh
|
rm -f /mnt/root/chroot.sh
|
||||||
rm -f /mnt/root/btrfs_map_physical.c
|
|
||||||
rm -f /mnt/root/btrfs_map_physical
|
|
||||||
|
|
||||||
echo -e -n "\nUnmounting partitions...\n\n"
|
echo -e -n "\nUnmounting partitions...\n\n"
|
||||||
if findmnt /mnt &>/dev/null; then
|
if findmnt /mnt &>/dev/null; then
|
||||||
|
Loading…
Reference in New Issue
Block a user