All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] Add rpdfs_unlink() and rpdfs_rmdir()
@ 2026-02-26 20:38 Valerie Aurora
  2026-03-03 23:14 ` Zach Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Valerie Aurora @ 2026-02-26 20:38 UTC (permalink / raw)
  To: rpdfs-devel; +Cc: Valerie Aurora

Copied from rpdfs_rename() and the extra bits removed.

Signed-off-by: Valerie Aurora <val@versity.com>
---
 fs/rpdfs/dir.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 76 insertions(+), 1 deletion(-)

diff --git a/fs/rpdfs/dir.c b/fs/rpdfs/dir.c
index 115f879d8fb1..473f7a7e6c13 100644
--- a/fs/rpdfs/dir.c
+++ b/fs/rpdfs/dir.c
@@ -491,6 +491,74 @@ static struct dentry *rpdfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
 	return ERR_PTR(create_and_instantiate_new(idmap, dir, dentry, S_IFDIR | mode));
 }
 
+static int rpdfs_unlink(struct inode *dir, struct dentry *dentry)
+{
+	struct rpdfs_fs_info *rfi = RPDFS_INODE_FS(dir);
+	struct inode *inode = d_inode(dentry);
+	struct key_dent *kd = NULL;
+	DECLARE_RPDFS_TXN(txn);
+	int ret;
+
+	kd = alloc_key_dent(dentry, inode);
+	if (!kd) {
+		ret = -ENOMEM;
+		goto out;
+	}
+
+	/* prepare all the blocks for the txn */
+	do {
+		ret = rpdfs_inode_txn_prepare(rfi, &txn, dir, RBAF_WRITE) ?:
+		      rpdfs_inode_txn_prepare(rfi, &txn, inode, RBAF_WRITE) ?:
+		      prepare_remove_entry(rfi, &txn, dir, kd);
+	} while (rpdfs_txn_retry(rfi, &txn, &ret));
+	if (ret < 0)
+		goto out;
+
+	/*
+	 * The VFS did a bunch of checks before calling this function,
+	 * but some other node could have made changes between then and
+	 * now. The prepare functions only succeed if the inodes have
+	 * not been freed or reused, and if the directory entry to be
+	 * removed is still there. The remaining check is if the target
+	 * dir of an rmdir is still empty.
+	 */
+
+	if (S_ISDIR(inode->i_mode)) {
+		if (!simple_empty(dentry)) {
+			ret = -ENOTEMPTY;
+			goto out;
+		}
+		drop_nlink(dir);
+		clear_nlink(inode);
+	} else {
+		drop_nlink(inode);
+	}
+	inode_set_ctime_current(inode);
+
+	/* apply changes to block structures */
+	apply_remove_entry(rfi, &txn, dir, kd);
+
+	/* update dir size and time */
+	i_size_write(dir, i_size_read(dir) - dentry->d_name.len);
+	inode_set_mtime_to_ts(dir, inode_set_ctime_current(dir));
+
+	/* update block storage of vfs inodes */
+	rpdfs_inode_txn_update(rfi, &txn, dir);
+	rpdfs_inode_txn_update(rfi, &txn, inode);
+
+	ret = 0;
+out:
+	rpdfs_txn_reset(rfi, &txn);
+	kfree(kd);
+
+	return ret;
+}
+
+static int rpdfs_rmdir(struct inode *dir, struct dentry *dentry)
+{
+	return rpdfs_unlink(dir, dentry);
+}
+
 /*
  * The vfs has verified the cached directories.  Our inode refresh will
  * fail if the inodes have been reused, so we don't have to test if
@@ -532,7 +600,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 +619,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)
@@ -680,6 +753,8 @@ const struct inode_operations rpdfs_dir_iops = {
 	.lookup		= rpdfs_lookup,
 	.mkdir		= rpdfs_mkdir,
 	.rename		= rpdfs_rename,
+	.unlink 	= rpdfs_unlink,
+	.rmdir 		= rpdfs_rmdir,
 };
 
 const struct file_operations rpdfs_dir_fops = {
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [PATCH] Add rpdfs_unlink() and rpdfs_rmdir()
  2026-02-26 20:38 [PATCH] Add rpdfs_unlink() and rpdfs_rmdir() Valerie Aurora
@ 2026-03-03 23:14 ` Zach Brown
  0 siblings, 0 replies; 2+ messages in thread
From: Zach Brown @ 2026-03-03 23:14 UTC (permalink / raw)
  To: Valerie Aurora; +Cc: rpdfs-devel

On Thu, Feb 26, 2026 at 09:38:58PM +0100, Valerie Aurora wrote:

> +	/* prepare all the blocks for the txn */
> +	do {
> +		ret = rpdfs_inode_txn_prepare(rfi, &txn, dir, RBAF_WRITE) ?:
> +		      rpdfs_inode_txn_prepare(rfi, &txn, inode, RBAF_WRITE) ?:
> +		      prepare_remove_entry(rfi, &txn, dir, kd);
> +	} while (rpdfs_txn_retry(rfi, &txn, &ret));
> +	if (ret < 0)
> +		goto out;
> +
> +	/*
> +	 * The VFS did a bunch of checks before calling this function,
> +	 * but some other node could have made changes between then and
> +	 * now. The prepare functions only succeed if the inodes have
> +	 * not been freed or reused, and if the directory entry to be
> +	 * removed is still there. The remaining check is if the target
> +	 * dir of an rmdir is still empty.
> +	 */
> +
> +	if (S_ISDIR(inode->i_mode)) {
> +		if (!simple_empty(dentry)) {
> +			ret = -ENOTEMPTY;
> +			goto out;
> +		}

simple_empty() only checks the dcache.  It's for in-memory systems only.
A dir that had entries that weren't cached would pass this test.  Just
check nlink.

And this is in the apply phase so it can't generate an error.  It should
have been detected in prepare.  Maybe a simple prepare_unlink() that
checks the prepared inodes?

- z

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-03-03 23:14 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-26 20:38 [PATCH] Add rpdfs_unlink() and rpdfs_rmdir() Valerie Aurora
2026-03-03 23:14 ` Zach Brown

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.