Skip to content

Commit

Permalink
WIPWIP - make btrfs pages also for locked single-device volumes
Browse files Browse the repository at this point in the history
  • Loading branch information
mvollmer committed Mar 1, 2024
1 parent 3ef5666 commit 6f9190d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 50 deletions.
11 changes: 8 additions & 3 deletions pkg/storaged/block/create-pages.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { make_swap_card } from "../swap/swap.jsx";
import { make_encryption_card } from "../crypto/encryption.jsx";
import { make_btrfs_device_card } from "../btrfs/device.jsx";
import { make_btrfs_filesystem_card } from "../btrfs/filesystem.jsx";
import { make_btrfs_subvolume_pages } from "../btrfs/subvolume.jsx";
import { make_btrfs_subvolume_pages, make_btrfs_subvolume_pages_from_child_config } from "../btrfs/volume.jsx";

import { new_page } from "../pages.jsx";

Expand Down Expand Up @@ -85,8 +85,11 @@ export function make_block_page(parent, block, card) {
// can not happen unless there is a bug in the code above.
console.error("Assertion failure: is_crypto == false");
}
if (fstab_config.length > 0 && !is_btrfs) {
card = make_filesystem_card(card, block, null, fstab_config);
if (fstab_config.length > 0) {
if (is_btrfs) {
card = make_btrfs_filesystem_card(card, block, null);
} else
card = make_filesystem_card(card, block, null, fstab_config);
} else {
card = make_locked_encrypted_data_card(card, block);
}
Expand Down Expand Up @@ -124,6 +127,8 @@ export function make_block_page(parent, block, card) {
const page = new_page(parent, card);
if (block_btrfs_blockdev && single_device_volume)
make_btrfs_subvolume_pages(page, block_btrfs_blockdev);
else if (!content_block && is_btrfs)
make_btrfs_subvolume_pages_from_child_config(page, block);

Check failure

Code scanning / CodeQL

Invocation of non-function Error

Callee is not a function: it has type undefined.
return page;
}
}
11 changes: 7 additions & 4 deletions pkg/storaged/btrfs/filesystem.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,18 @@ export function make_btrfs_filesystem_card(next, backing_block, content_block) {
return new_card({
title: _("btrfs filesystem"),
next,
actions: btrfs_device_actions(backing_block, content_block),
actions: [
{ title: _("Format"), action: () => format_dialog(client, backing_block.path), danger: true },
],
component: BtrfsFilesystemCard,
props: { backing_block, content_block },
});
}

const BtrfsFilesystemCard = ({ card, backing_block, content_block }) => {
const block_btrfs = client.blocks_fsys_btrfs[content_block.path];
const block_btrfs = content_block && client.blocks_fsys_btrfs[content_block.path];
const uuid = block_btrfs && block_btrfs.data.uuid;
const label = block_btrfs && block_btrfs.data.label;
const use = btrfs_device_usage(client, uuid, block_btrfs.path);

// Changing the label is only supported when the device is not mounted
// otherwise we will get btrfs filesystem error ERROR: device /dev/vda5 is
Expand All @@ -74,10 +75,12 @@ const BtrfsFilesystemCard = ({ card, backing_block, content_block }) => {
{_("edit")}
</StorageLink>}
/>
{ content_block &&
<StorageDescription title={_("UUID")} value={content_block.IdUUID} />
}
{ block_btrfs &&
<StorageDescription title={_("Usage")}>
<StorageUsageBar key="s" stats={use} />
<StorageUsageBar key="s" stats={btrfs_device_usage(client, uuid, block_btrfs.path)} />
</StorageDescription>
}
</DescriptionList>
Expand Down
99 changes: 56 additions & 43 deletions pkg/storaged/btrfs/subvolume.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -250,61 +250,74 @@ function dirname(path) {
return path.substr(0, i);
}

export function make_btrfs_subvolume_pages(parent, volume) {
let subvols = client.uuids_btrfs_subvols[volume.data.uuid];
if (!subvols) {
const block = client.blocks[volume.path];
/*
* Try to show subvolumes based on fstab entries, this is a bit tricky
* as mounts where subvolid cannot be shown userfriendly.
*
* The real subvolume data structure has "id" fields and
* "parent" fields that refer to the ids to form a tree. We
* want to do the same here, and we give fake ids to our fake
* subvolumes for this reason. We don't store these fake ids
* in the "id" field since we don't want them to be taken
* seriously by the rest of the code.
*/
let fake_id = 5;
subvols = [{ pathname: "/", id: 5, fake_id: fake_id++ }];
const subvols_by_pathname = { };
for (const config of block.Configuration) {
if (config[0] == "fstab") {
const opts = config[1].opts;
if (!opts)
continue;

const fstab_subvol = parse_subvol_from_options(decode_filename(opts.v));

if (fstab_subvol && fstab_subvol.pathname && fstab_subvol.pathname !== "/") {
fstab_subvol.fake_id = fake_id++;
subvols_by_pathname[fstab_subvol.pathname] = fstab_subvol;
subvols.push(fstab_subvol);
}
function get_subvols_from_fstab(configuration) {
/*
* Try to show subvolumes based on fstab entries, this is a bit tricky
* as mounts where subvolid cannot be shown userfriendly.
*
* The real subvolume data structure has "id" fields and
* "parent" fields that refer to the ids to form a tree. We
* want to do the same here, and we give fake ids to our fake
* subvolumes for this reason. We don't store these fake ids
* in the "id" field since we don't want them to be taken
* seriously by the rest of the code.
*/
let fake_id = 5;
subvols = [{ pathname: "/", id: 5, fake_id: fake_id++ }];

Check warning

Code scanning / CodeQL

Missing variable declaration Warning

Variable subvols is used like a local variable, but is missing a declaration.
const subvols_by_pathname = { };
for (const config of configuration) {
if (config[0] == "fstab") {
const opts = config[1].opts;
if (!opts)
continue;

const fstab_subvol = parse_subvol_from_options(decode_filename(opts.v));

if (fstab_subvol && fstab_subvol.pathname && fstab_subvol.pathname !== "/") {
fstab_subvol.fake_id = fake_id++;
subvols_by_pathname[fstab_subvol.pathname] = fstab_subvol;
subvols.push(fstab_subvol);
}
}
}

// Find parents
for (const pn in subvols_by_pathname) {
let dn = pn;
while (true) {
dn = dirname(dn);
if (!dn) {
subvols_by_pathname[pn].parent = 5;
break;
} else if (subvols_by_pathname[dn]) {
subvols_by_pathname[pn].parent = subvols_by_pathname[dn].fake_id;
break;
}
// Find parents
for (const pn in subvols_by_pathname) {
let dn = pn;
while (true) {
dn = dirname(dn);
if (!dn) {
subvols_by_pathname[pn].parent = 5;
break;
} else if (subvols_by_pathname[dn]) {
subvols_by_pathname[pn].parent = subvols_by_pathname[dn].fake_id;
break;
}
}
}
}

export function make_btrfs_subvolume_pages(parent, volume) {
let subvols = client.uuids_btrfs_subvols[volume.data.uuid];
if (!subvols) {
const block = client.blocks[volume.path];
subvols = get_subvols_from_fstab(block.Configuration);
}

const root = subvols.find(s => s.id == 5);
if (root)
make_btrfs_subvolume_page(parent, volume, root, "", subvols);
}

export function make_btrfs_subvolume_pages_from_child_config(parent, backing_block) {
const block_crypto = client.blocks_crypto[backing_block.path];
const subvols = get_subvols_from_fstab(block_crypto.ChildConfiguration);

Check warning

Code scanning / CodeQL

Use of returnless function Warning

the
function get_subvols_from_fstab
does not return anything, yet the return value is used.

const root = subvols.find(s => s.id == 5);

Check failure

Code scanning / CodeQL

Property access on null or undefined Error

The base expression of this property access is always undefined.
if (root)
make_btrfs_subvolume_page(parent, null, root, "", subvols);
}

function make_btrfs_subvolume_page(parent, volume, subvol, path_prefix, subvols) {
const actions = [];

Expand Down

0 comments on commit 6f9190d

Please sign in to comment.