btrfs_transaction/lib.rs
1//! # Userspace transaction infrastructure for btrfs
2//!
3//! This crate provides the write-path infrastructure needed to
4//! modify btrfs filesystems from userspace. It builds on
5//! `btrfs-disk` (the read path) and adds mutable tree blocks,
6//! B-tree search, copy-on-write, item insertion / deletion / split
7//! / balance, transaction commit, extent allocation, free-space
8//! tree maintenance, and a layer of high-level helpers (file data,
9//! inodes, dir entries, xattrs, subvolume creation, device-size
10//! patches).
11//!
12//! ## Entry points
13//!
14//! - Single-device: [`Filesystem::open`] takes a device or image
15//! file open for read+write.
16//! - Multi-device: [`filesystem::Filesystem::open_multi`] takes a
17//! `BTreeMap<devid, handle>`. Used by every multi-device tool
18//! (mkfs, rescue, tune).
19//!
20//! From there, [`Transaction::start`] opens a transaction;
21//! mutations go through [`search::search_slot`] +
22//! [`items::insert_item`] / [`items::del_items`] /
23//! [`items::update_item`] for raw access, or through the
24//! [`Transaction`] helpers (`create_inode`, `link_dir_entry`,
25//! `set_xattr`, `write_file_data`, `create_empty_tree`,
26//! `insert_root_ref`, `reserve_data_extent`, etc.) for higher-level
27//! patterns. [`Transaction::commit`] closes out the transaction;
28//! [`Transaction::abort`] discards it.
29//!
30//! Whole-tree conversion paths
31//! ([`convert::convert_to_free_space_tree`],
32//! [`convert::convert_to_block_group_tree`], plus the per-step
33//! [`convert::seed_free_space_tree`] and
34//! [`convert::create_block_group_tree`] helpers) live in the
35//! [`convert`] module.
36//!
37//! This is a clean-room implementation based on the on-disk format
38//! specification and UAPI headers. It is licensed MIT/Apache-2.0.
39//!
40//! # Stability
41//!
42//! This is a pre-1.0, experimental crate. It is a clean-room
43//! reimplementation of btrfs's read-write tree machinery and may
44//! have edge cases that testing doesn't cover. Do not use it on
45//! filesystems you care about without taking a backup first.
46
47#![warn(clippy::pedantic)]
48#![allow(clippy::cast_possible_truncation)] // nodesize ≤ 64K, offsets always fit u32
49#![allow(clippy::cast_possible_wrap)] // bytes_used u64↔i64 conversions are intentional
50#![allow(clippy::cast_sign_loss)] // bytes_used i64↔u64 conversions are intentional
51#![allow(clippy::missing_errors_doc)] // error conditions obvious from Result<T>
52#![allow(clippy::missing_panics_doc)] // path.nodes[].unwrap() always valid in context
53#![allow(clippy::module_name_repetitions)]
54// Test code uses literal byte buffers and small cast conversions that
55// pedantic clippy flags but that are intentional in unit tests.
56#![cfg_attr(
57 test,
58 allow(
59 clippy::cast_lossless,
60 clippy::identity_op,
61 clippy::match_wildcard_for_single_variants,
62 clippy::semicolon_if_nothing_returned,
63 clippy::unreadable_literal,
64 )
65)]
66
67pub mod allocation;
68pub mod balance;
69pub mod buffer;
70pub mod convert;
71pub mod cow;
72pub mod delayed_ref;
73pub mod extent_walk;
74pub mod filesystem;
75pub mod free_space;
76pub mod inode;
77pub mod items;
78pub mod path;
79pub mod search;
80pub mod split;
81pub mod transaction;
82
83pub use crate::{filesystem::Filesystem, transaction::Transaction};
84
85#[doc(hidden)]
86pub mod test_helpers;