[PATCH 5/8] rpdfs: add basic file data initialization
Valerie Aurora <[email protected]> Fri, 24 Apr 2026 16:05:17 +0200
| Newsgroups | dev.linux.lists.rpdfs-devel |
|---|---|
| Message-ID | <[email protected]> |
Initialize the file data root, plus a few simple routines to calculate mapping block levels. Rename the field in the inode from "data" to "data_root" to avoid confusion with the "data" member of struct rpdfs_block_handle. Signed-off-by: Valerie Aurora <[email protected]> --- fs/rpdfs/Makefile | 1 + fs/rpdfs/data.c | 90 +++++++++++++++++++++++++++++++++++++++++ fs/rpdfs/data.h | 11 +++++ fs/rpdfs/format-block.h | 6 +-- fs/rpdfs/inode.c | 8 ++++ fs/rpdfs/inode.h | 1 + 6 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 fs/rpdfs/data.c create mode 100644 fs/rpdfs/data.h diff --git a/fs/rpdfs/Makefile b/fs/rpdfs/Makefile index d995103ea5a8..f8301d86682b 100644 --- a/fs/rpdfs/Makefile +++ b/fs/rpdfs/Makefile @@ -12,6 +12,7 @@ rpdfs-y := balloc.o \ block.o \ btree.o \ btree_txn.o \ + data.o \ dir.o \ file.o \ ht.o \ diff --git a/fs/rpdfs/data.c b/fs/rpdfs/data.c new file mode 100644 index 000000000000..b7538004d14a --- /dev/null +++ b/fs/rpdfs/data.c @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include <linux/fs.h> +#include <linux/pagemap.h> +#include <linux/gfp.h> +#include <linux/writeback.h> + +#include "balloc.h" +#include "inode.h" +#include "format-block.h" +#include "pr.h" +#include "super.h" +#include "data.h" + +/* + * File data is stored in simple tree of mapping blocks with data all + * at the same level of the tree. The topmost block in the tree and its + * level are stored in the inode. The tree is sparse and branches are + * grown as necessary to index newly written data blocks. While + * manipulating the tree, we use levels to identify the blocks at + * various levels of the tree, with the highest levels closer to the + * root. + * + * The data root field in the inode contains both the persistent + * reference (block number, etc.) to the root block of the tree, plus + * the height of the tree (the level of the block it points to, plus 1). + * The root block reference is not part of an mapping block. + * + * The level of a block is: + * + * 0 = data block + * 1 = references to data blocks + * 2 = references to single mapping blocks (pointing to data blocks) + * 3 = references to double mapping blocks + * 4 = references to triple mapping blocks + * + * Thus a data root reference with height 1 points to a block of level 0 + * = a single block of data at logical file offset 0. + */ + +/* + * Return the logical block number containing offset within a file. + */ +static u64 lblk_from_offset(u64 offset) +{ + return offset >> RPDFS_BLOCK_SHIFT; +} + +/* + * Calculate the index of the block reference for this logical block + * within an mapping block at this level (1 = pointers to data blocks). + */ +static u32 calc_ref_ind(u64 lblk, int level) +{ + u32 ind; + int i; + + BUG_ON(level < 1); + + for (i = 1; i < level; i++) + lblk >>= RPDFS_DATA_REFS_PER_BLK_SHIFT; + + ind = lblk & (RPDFS_DATA_REFS_PER_BLK - 1ULL); + + return ind; +} + +/* + * Calculate the height of the tree (level of the root pointer) needed + * to index the logical block lblk in this file. + */ +static u8 height_from_lblk(u64 lblk) +{ + u8 height = 2; + + if (lblk == 0) + return 1; + + while (lblk >>= RPDFS_DATA_REFS_PER_BLK_SHIFT) + height++; + + return height; +} + +void rpdfs_data_root_init(struct rpdfs_data_root *data) +{ + data->height = 0; + data->ref.bnr = 0; + data->ref.alloc_counter = 0; +} diff --git a/fs/rpdfs/data.h b/fs/rpdfs/data.h new file mode 100644 index 000000000000..bb6b0c7dea86 --- /dev/null +++ b/fs/rpdfs/data.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef RPDFS_DATA_H +#define RPDFS_DATA_H + +#include "format-block.h" + +void rpdfs_data_root_init(struct rpdfs_data_root *data); + +extern const struct address_space_operations rpdfs_aops; + +#endif diff --git a/fs/rpdfs/format-block.h b/fs/rpdfs/format-block.h index 395e6d2d17e7..04b4ddf5d614 100644 --- a/fs/rpdfs/format-block.h +++ b/fs/rpdfs/format-block.h @@ -6,7 +6,7 @@ #include <linux/align.h> #define RPDFS_BLOCK_SHIFT 12 -#define RPDFS_BLOCK_SIZE (1 << RPDFS_BLOCK_SHIFT) +#define RPDFS_BLOCK_SIZE (1ULL << RPDFS_BLOCK_SHIFT) #define RPDFS_BLOCK_MASK (RPDFS_BLOCK_SIZE - 1ULL) struct rpdfs_block_ref { @@ -138,7 +138,7 @@ struct rpdfs_data_root { #define RPDFS_DATA_REFS_PER_BLK_SHIFT const_ilog2(RPDFS_DATA_REFS_PER_BLK) -struct rpdfs_indirect_block { +struct rpdfs_map_block { struct rpdfs_block_ref refs[RPDFS_DATA_REFS_PER_BLK]; }; @@ -168,7 +168,7 @@ struct rpdfs_inode { __le64 crtime_nsec; struct rpdfs_btree_root dirents; struct rpdfs_btree_root xattrs; - struct rpdfs_data_root data; + struct rpdfs_data_root data_root; }; #define RPDFS_ROOT_INO 1 diff --git a/fs/rpdfs/inode.c b/fs/rpdfs/inode.c index 7abd2c58373f..947a8f1703a3 100644 --- a/fs/rpdfs/inode.c +++ b/fs/rpdfs/inode.c @@ -9,6 +9,7 @@ #include "btree.h" #include "compare.h" +#include "data.h" #include "dir.h" #include "file.h" #include "inode.h" @@ -80,6 +81,8 @@ static void copy_rinode_to_vfs_inode(struct inode *inode, struct rpdfs_inode *ri ri->xattrs = rinode->xattrs; ri->xattr_creates = rinode->xattr_creates; + + ri->data_root = rinode->data_root; } __always_unused @@ -118,6 +121,8 @@ static void print_inode_change(struct inode *inode, struct rpdfs_inode *rinode) print_diff64("dirents", ri->dirents.ref.bnr, rinode->dirents.ref.bnr); print_diff64("xattrs", ri->xattrs.ref.bnr, rinode->xattrs.ref.bnr); print_diff64("xattr_creates", ri->xattr_creates, rinode->xattr_creates); + print_diff64("data_root.height", ri->data_root.height, rinode->data_root.height); + print_diff64("data_root.ref.bnr", ri->data_root.ref.bnr, rinode->data_root.ref.bnr); } static __le64 cpu_ts64_to_le64_ns(struct timespec64 ts) @@ -145,6 +150,8 @@ static void copy_vfs_inode_to_rinode(struct rpdfs_inode *rinode, struct inode *i rinode->xattrs = ri->xattrs; rinode->xattr_creates = ri->xattr_creates; + + rinode->data_root = ri->data_root; } /* @@ -342,6 +349,7 @@ struct inode *rpdfs_new_inode(struct super_block *sb, struct rpdfs_ino_gen *ig) rpdfs_btree_root_init(&ri->dirents); rpdfs_btree_root_init(&ri->xattrs); + rpdfs_data_root_init(&ri->data_root); ts = inode_set_ctime_current(inode); inode_set_mtime_to_ts(inode, ts); diff --git a/fs/rpdfs/inode.h b/fs/rpdfs/inode.h index 3b0be2d83e61..3892fdcc8b1b 100644 --- a/fs/rpdfs/inode.h +++ b/fs/rpdfs/inode.h @@ -25,6 +25,7 @@ struct rpdfs_inode_info { struct rpdfs_ino_gen ig; struct rpdfs_btree_root dirents; struct rpdfs_btree_root xattrs; + struct rpdfs_data_root data_root; struct inode vfs_inode; }; -- 2.49.0