Files

166 lines
3.7 KiB
C
Raw Permalink Normal View History

/* SPDX-License-Identifier: GPL-2.0 */
/*
* linux/fs/apfs/node.h
*
* Copyright (C) 2018 Ernesto A. Fernández <ernesto.mnd.fernandez@gmail.com>
*/
#ifndef _APFS_NODE_H
#define _APFS_NODE_H
#include <linux/kref.h>
#include <linux/types.h>
#include "object.h"
struct apfs_query;
/*
* On-disk representation of an object map
*/
struct apfs_omap_phys {
/*00*/ struct apfs_obj_phys om_o;
/*20*/ __le32 om_flags;
__le32 om_snap_count;
__le32 om_tree_type;
__le32 om_snapshot_tree_type;
/*30*/ __le64 om_tree_oid;
__le64 om_snapshot_tree_oid;
/*40*/ __le64 om_most_recent_snap;
__le64 om_pending_revert_min;
__le64 om_pending_revert_max;
} __packed;
/*
* Structure of a value in an object map B-tree
*/
struct apfs_omap_val {
__le32 ov_flags;
__le32 ov_size;
__le64 ov_paddr;
} __packed;
/* B-tree node flags */
#define APFS_BTNODE_ROOT 0x0001
#define APFS_BTNODE_LEAF 0x0002
#define APFS_BTNODE_FIXED_KV_SIZE 0x0004
#define APFS_BTNODE_CHECK_KOFF_INVAL 0x8000
/* B-tree location constants */
#define APFS_BTOFF_INVALID 0xffff
/*
* Structure storing a location inside a B-tree node
*/
struct apfs_nloc {
__le16 off;
__le16 len;
} __packed;
/*
* Structure storing the location of a key/value pair within a B-tree node
*/
struct apfs_kvloc {
struct apfs_nloc k;
struct apfs_nloc v;
} __packed;
/*
* Structure storing the location of a key/value pair within a B-tree node
* having fixed-size key and value (flag APFS_BTNODE_FIXED_KV_SIZE is present)
*/
struct apfs_kvoff {
__le16 k;
__le16 v;
} __packed;
/*
* On-disk representation of a B-tree node
*/
struct apfs_btree_node_phys {
/*00*/ struct apfs_obj_phys btn_o;
/*20*/ __le16 btn_flags;
__le16 btn_level;
__le32 btn_nkeys;
/*28*/ struct apfs_nloc btn_table_space;
struct apfs_nloc btn_free_space;
struct apfs_nloc btn_key_free_list;
struct apfs_nloc btn_val_free_list;
/*38*/ __le64 btn_data[];
} __packed;
/*
* Structure used to store information about a B-tree that won't change
* over time
*/
struct apfs_btree_info_fixed {
__le32 bt_flags;
__le32 bt_node_size;
__le32 bt_key_size;
__le32 bt_val_size;
} __packed;
/*
* Structure used to store information about a B-tree (located at the end of
* a B-tree root node block)
*/
struct apfs_btree_info {
struct apfs_btree_info_fixed bt_fixed;
__le32 bt_longest_key;
__le32 bt_longest_val;
__le64 bt_key_count;
__le64 bt_node_count;
} __packed;
/*
* In-memory representation of an APFS node
*/
struct apfs_node {
u16 flags; /* Node flags */
u32 records; /* Number of records in the node */
int key; /* Offset of the key area in the block */
int free; /* Offset of the free area in the block */
int data; /* Offset of the data area in the block */
struct apfs_object object; /* Object holding the node */
struct kref refcount;
};
/**
* apfs_node_is_leaf - Check if a b-tree node is a leaf
* @node: the node to check
*/
static inline bool apfs_node_is_leaf(struct apfs_node *node)
{
return (node->flags & APFS_BTNODE_LEAF) != 0;
}
/**
* apfs_node_is_root - Check if a b-tree node is the root
* @node: the node to check
*/
static inline bool apfs_node_is_root(struct apfs_node *node)
{
return (node->flags & APFS_BTNODE_ROOT) != 0;
}
/**
* apfs_node_has_fixed_kv_size - Check if a b-tree node has fixed key/value
* sizes
* @node: the node to check
*/
static inline bool apfs_node_has_fixed_kv_size(struct apfs_node *node)
{
return (node->flags & APFS_BTNODE_FIXED_KV_SIZE) != 0;
}
extern struct apfs_node *apfs_read_node(struct super_block *sb, u64 block);
extern int apfs_node_query(struct super_block *sb, struct apfs_query *query);
extern int apfs_bno_from_query(struct apfs_query *query, u64 *bno);
extern void apfs_node_get(struct apfs_node *node);
extern void apfs_node_put(struct apfs_node *node);
#endif /* _APFS_NODE_H */