From: Valerie Aurora <val@versity.com>
To: rpdfs-devel@lists.linux.dev
Cc: Valerie Aurora <val@versity.com>
Subject: [PATCH 2/3] rpdfs: Add directory i_size accounting and helper functions
Date: Mon, 9 Mar 2026 22:04:02 +0100 [thread overview]
Message-ID: <20260309210403.105006-3-val@versity.com> (raw)
In-Reply-To: <20260309210403.105006-1-val@versity.com>
Implement directory i_size as the total length of all directory entry
names including a null termination.
Signed-off-by: Valerie Aurora <val@versity.com>
---
fs/rpdfs/dir.c | 48 ++++++++++++++++++++++++++++++++++-------
fs/rpdfs/format-block.h | 8 +++++++
fs/rpdfs/mkfs.c | 2 +-
3 files changed, 49 insertions(+), 9 deletions(-)
diff --git a/fs/rpdfs/dir.c b/fs/rpdfs/dir.c
index 7ae8faf74161..0de00704a603 100644
--- a/fs/rpdfs/dir.c
+++ b/fs/rpdfs/dir.c
@@ -363,6 +363,26 @@ static struct key_dent *alloc_key_dent(struct dentry *dentry, struct inode *inod
return kd;
}
+static void init_dir_size(struct inode *inode)
+{
+ i_size_write(inode, RPDFS_EMPTY_DIR_LEN);
+}
+
+static int is_dir_empty(struct inode *inode)
+{
+ return (i_size_read(inode) == RPDFS_EMPTY_DIR_LEN);
+}
+
+/*
+ * Helper function for readability. All consistency/corruption checks
+ * should happen in the prepare phase, so there are no checks when
+ * making changes.
+ */
+static void update_dir_size(struct inode *inode, s32 len)
+{
+ i_size_write(inode, i_size_read(inode) + len);
+}
+
/*
* Allocate an inode in a block transaction and return an allocated vfs
* inode at its ino/gen position. Like _iget, this inserts an I_NEW
@@ -429,17 +449,21 @@ static struct inode *create_new_inode(struct mnt_idmap *idmap, struct inode *dir
/* update vfs inodes */
inode_init_owner(idmap, inode, dir, mode);
- if (S_ISDIR(mode))
+ if (S_ISDIR(mode)) {
set_nlink(inode, 2);
- else
+ init_dir_size(inode);
+ } else {
set_nlink(inode, 1);
+ }
+
rpdfs_inode_init_ops(inode);
+ /* update parent vfs inode and apply changes to referenced blocks */
if (S_ISDIR(mode))
inc_nlink(dir);
- /* apply changes to referenced blocks */
if (kd) {
+ update_dir_size(dir, kd->dent.name_len + 1);
kd->dent.ig = ig;
apply_add_entry(rfi, &txn, dir, kd);
}
@@ -532,7 +556,7 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d
goto out;
}
- /* prepare all the blocks for in the txn */
+ /* prepare all the blocks for the txn */
do {
ret = rpdfs_inode_txn_prepare(rfi, &txn, old_dir, RBAF_WRITE) ?:
rpdfs_inode_txn_prepare(rfi, &txn, old_inode, RBAF_WRITE) ?:
@@ -551,6 +575,11 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d
if (ret < 0)
goto out;
+ /*
+ * TODO: walk ancestors, and if there is a directory to be
+ * deleted, check if it is empty.
+ */
+
/* apply changes to block structures */
apply_remove_entry(rfi, &txn, old_dir, old_kd);
if (new_inode)
@@ -558,11 +587,12 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d
else
apply_add_entry(rfi, &txn, new_dir, new_kd);
- /* update vfs inodes: first dir sizes .. */
- i_size_write(old_dir, i_size_read(old_dir) - old_dentry->d_name.len);
+ /* update dir sizes */
+ update_dir_size(old_dir, -(old_dentry->d_name.len + 1));
if (!new_inode)
- i_size_write(new_dir, i_size_read(new_dir) + new_dentry->d_name.len);
- /* .. then link counts .. */
+ update_dir_size(new_dir, new_dentry->d_name.len + 1);
+
+ /* and link counts */
if (new_inode) {
drop_nlink(new_inode);
if (S_ISDIR(new_inode->i_mode)) {
@@ -570,10 +600,12 @@ static int rpdfs_rename(struct mnt_idmap *idmap, struct inode *old_dir, struct d
drop_nlink(new_inode);
}
}
+
if (S_ISDIR(old_inode->i_mode) && (old_dir != new_dir)) {
drop_nlink(old_dir);
inc_nlink(new_dir);
}
+
/* .. and finally times */
now = inode_set_ctime_current(old_dir);
inode_set_mtime_to_ts(old_dir, now);
diff --git a/fs/rpdfs/format-block.h b/fs/rpdfs/format-block.h
index 1ff315668d2f..d4a0fb78d670 100644
--- a/fs/rpdfs/format-block.h
+++ b/fs/rpdfs/format-block.h
@@ -210,6 +210,14 @@ struct rpdfs_dirent {
#define RPDFS_DIRENT_DOT_DOT_HASH 1ULL
#define RPDFS_DIRENT_MIN_HASH 2ULL
+/*
+ * An empty dir contains pseudo entries for "." and "..". The reported
+ * size of directory is the length of the null-terminated names of all
+ * the directory entries. (The actual size is the number of blocks
+ * necessary to store the dirents btree.)
+ */
+#define RPDFS_EMPTY_DIR_LEN 5
+
/*
* xattrs are currently implemented as btree items, whose keys are the
* hash of the name combined with the xattr_create_counter value in the
diff --git a/fs/rpdfs/mkfs.c b/fs/rpdfs/mkfs.c
index f4cbf5538b3b..94798799c960 100644
--- a/fs/rpdfs/mkfs.c
+++ b/fs/rpdfs/mkfs.c
@@ -45,7 +45,7 @@ int rpdfs_mkfs(struct rpdfs_fs_info *rfi)
rinode->ig.ino = cpu_to_le64(RPDFS_ROOT_INO);
rinode->ig.gen = cpu_to_le64(RPDFS_ROOT_GEN);
- rinode->size = cpu_to_le64(5); /* name lens of . and .. with null term */
+ rinode->size = cpu_to_le64(RPDFS_EMPTY_DIR_LEN);
rinode->version = cpu_to_le64(1);
rinode->nlink = cpu_to_le32(2);
rinode->mode = cpu_to_le32(S_IFDIR | 0755);
--
2.49.0
next prev parent reply other threads:[~2026-03-09 21:04 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-09 21:04 [PATCH 0/3] Add rpdfs_unlink and rpdfs_rmdir Valerie Aurora
2026-03-09 21:04 ` [PATCH 1/3] rpdfs: Initialize dirents field in new rpdfs_inode_info Valerie Aurora
2026-03-09 21:04 ` Valerie Aurora [this message]
2026-03-09 21:04 ` [PATCH 3/3] rpdfs: Add rpdfs_unlink and rpdfs_rmdir Valerie Aurora
2026-03-10 16:34 ` [PATCH 0/3] " Zach Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260309210403.105006-3-val@versity.com \
--to=val@versity.com \
--cc=rpdfs-devel@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.