btrfs_uapi/label.rs
1//! # Filesystem label: reading and writing the human-readable name of a filesystem
2//!
3//! The label is a short null-terminated string (up to 255 bytes) stored in the
4//! superblock. It is visible in `/sys/fs/btrfs/<uuid>/label` and is used by
5//! tools like `blkid` to identify the filesystem. Labels are stored as
6//! [`CString`] values to preserve the kernel's null-termination contract.
7
8use crate::raw::{btrfs_ioc_get_fslabel, btrfs_ioc_set_fslabel};
9use nix::libc::c_char;
10use std::{
11 ffi::{CStr, CString},
12 os::{fd::AsRawFd, unix::io::BorrowedFd},
13};
14
15/// Maximum label length including the null terminator (BTRFS_LABEL_SIZE).
16const BTRFS_LABEL_SIZE: usize = crate::raw::BTRFS_LABEL_SIZE as usize;
17
18/// Read the label of the btrfs filesystem referred to by `fd`.
19///
20/// Returns the label as a [`CString`]. An empty string means no label is set.
21pub fn label_get(fd: BorrowedFd) -> nix::Result<CString> {
22 let mut buf = [0i8; BTRFS_LABEL_SIZE];
23 unsafe { btrfs_ioc_get_fslabel(fd.as_raw_fd(), &mut buf) }?;
24 let cstr = unsafe { CStr::from_ptr(buf.as_ptr()) };
25 // CStr::to_owned() copies the bytes into a freshly allocated CString,
26 // which is safe to return after `buf` goes out of scope.
27 Ok(cstr.to_owned())
28}
29
30/// Set the label of the btrfs filesystem referred to by `fd`.
31///
32/// The label must be shorter than 256 bytes (not counting the null terminator).
33/// Further validation (e.g. rejecting labels that contain `/`) is left to the
34/// kernel.
35pub fn label_set(fd: BorrowedFd, label: &CStr) -> nix::Result<()> {
36 let bytes = label.to_bytes();
37 if bytes.len() >= BTRFS_LABEL_SIZE {
38 return Err(nix::errno::Errno::EINVAL);
39 }
40 let mut buf = [0i8; BTRFS_LABEL_SIZE];
41 for (i, &b) in bytes.iter().enumerate() {
42 buf[i] = b as c_char;
43 }
44 unsafe { btrfs_ioc_set_fslabel(fd.as_raw_fd(), &buf) }?;
45 Ok(())
46}