All of lore.kernel.org
 help / color / mirror / Atom feed
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


  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.