fs/btrfs/tree-mod-log.c

Source file repositories/reference/linux-study-clean/fs/btrfs/tree-mod-log.c

File Facts

System
Linux kernel
Corpus path
fs/btrfs/tree-mod-log.c
Extension
.c
Size
29690 bytes
Lines
1147
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct tree_mod_root {
	u64 logical;
	u8 level;
};

struct tree_mod_elem {
	struct rb_node node;
	u64 logical;
	u64 seq;
	enum btrfs_mod_log_op op;

	/*
	 * This is used for BTRFS_MOD_LOG_KEY_* and BTRFS_MOD_LOG_MOVE_KEYS
	 * operations.
	 */
	int slot;

	/* This is used for BTRFS_MOD_LOG_KEY* and BTRFS_MOD_LOG_ROOT_REPLACE. */
	u64 generation;

	union {
		/*
		 * This is used for the following op types:
		 *
		 *    BTRFS_MOD_LOG_KEY_REMOVE_WHILE_FREEING
		 *    BTRFS_MOD_LOG_KEY_REMOVE_WHILE_MOVING
		 *    BTRFS_MOD_LOG_KEY_REMOVE
		 *    BTRFS_MOD_LOG_KEY_REPLACE
		 */
		struct {
			struct btrfs_disk_key key;
			u64 blockptr;
		} slot_change;

		/* This is used for op == BTRFS_MOD_LOG_MOVE_KEYS. */
		struct {
			int dst_slot;
			int nr_items;
		} move;

		/* This is used for op == BTRFS_MOD_LOG_ROOT_REPLACE. */
		struct tree_mod_root old_root;
	};
};

/*
 * Pull a new tree mod seq number for our operation.
 */
static u64 btrfs_inc_tree_mod_seq(struct btrfs_fs_info *fs_info)
{
	return atomic64_inc_return(&fs_info->tree_mod_seq);
}

/*
 * This adds a new blocker to the tree mod log's blocker list if the @elem
 * passed does not already have a sequence number set. So when a caller expects
 * to record tree modifications, it should ensure to set elem->seq to zero
 * before calling btrfs_get_tree_mod_seq.
 * Returns a fresh, unused tree log modification sequence number, even if no new
 * blocker was added.
 */
u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
			   struct btrfs_seq_list *elem)
{
	write_lock(&fs_info->tree_mod_log_lock);
	if (!elem->seq) {
		elem->seq = btrfs_inc_tree_mod_seq(fs_info);
		list_add_tail(&elem->list, &fs_info->tree_mod_seq_list);
		set_bit(BTRFS_FS_TREE_MOD_LOG_USERS, &fs_info->flags);
	}
	write_unlock(&fs_info->tree_mod_log_lock);

	return elem->seq;
}

void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
			    struct btrfs_seq_list *elem)
{
	struct rb_root *tm_root;
	struct rb_node *node;
	struct rb_node *next;
	struct tree_mod_elem *tm;
	u64 min_seq = BTRFS_SEQ_LAST;
	u64 seq_putting = elem->seq;

	if (!seq_putting)
		return;

	write_lock(&fs_info->tree_mod_log_lock);
	list_del(&elem->list);

Annotation

Implementation Notes