All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/1] rpdfs: Add support for rpdfs_link()
@ 2026-10-19 18:21 Chris Kirby
  2026-10-23 17:50 ` Zach Brown
  0 siblings, 1 reply; 2+ messages in thread
From: Chris Kirby @ 2026-10-19 18:21 UTC (permalink / raw)
  To: rpdfs-devel; +Cc: Chris Kirby

Add support for the link inode operation.

Signed-off-by: Chris Kirby <ckirby@versity.com>
---
 fs/rpdfs/dir.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

diff --git a/fs/rpdfs/dir.c b/fs/rpdfs/dir.c
index 8a48817699d7..42af325012ab 100644
--- a/fs/rpdfs/dir.c
+++ b/fs/rpdfs/dir.c
@@ -10,6 +10,7 @@
 #include "format-block.h"
 #include "inode.h"
 #include "rlock.h"
+#include "pr.h"
 
 /*
  * A collection of the arguments that describe a directory entry for the
@@ -393,6 +394,89 @@ 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_link(struct dentry *old_dentry, struct inode *new_dir,
+		      struct dentry *new_dentry)
+{
+	struct rpdfs_fs_info *rfi = RPDFS_INODE_FS(new_dir);
+	struct inode *old_inode = d_inode(old_dentry);
+	struct inode *new_inode = d_inode(new_dentry);
+	struct inode *old_dir = d_inode(old_dentry->d_parent);
+	DECLARE_RPDFS_RLOCK_HOLD(old_dir_hold);
+	DECLARE_RPDFS_RLOCK_HOLD(new_dir_hold);
+	DECLARE_RPDFS_RLOCK_HOLD(old_inode_hold);
+	DECLARE_RPDFS_RLOCK_HOLD(new_inode_hold);
+	struct dent_args old_da;
+	struct dent_args new_da;
+	struct timespec64 now;
+	int ret = 0;
+
+	/*
+	 * max link count and the existence of the link target were both checked
+	 * by vfs_link(). But we don't yet have our rlocks, so we need to repeat
+	 * those checks below. The existence check is handled by validate_dentry().
+	 */
+
+	if (new_dentry->d_name.len > RPDFS_NAME_MAX) {
+		ret = -ENAMETOOLONG;
+		goto out;
+	}
+
+	init_dent_args(&old_da, old_dentry, NULL);
+	init_dent_args(&new_da, new_dentry, NULL);
+
+	ret = rpdfs_inode_rlock_refresh_many(old_dir, &old_dir_hold,
+					     new_dir, &new_dir_hold,
+					     old_inode, &old_inode_hold,
+					     new_inode, &new_inode_hold,
+					     RPDFS_RLOCK_MODE_EX_WR) ?:
+		validate_dentry(old_dir, old_dentry, &old_da) ?:
+		validate_dentry(new_dir, new_dentry, &new_da);
+	if (ret < 0)
+		goto out;
+
+	if (old_inode->i_nlink >= RPDFS_LINK_MAX) {
+		ret = -EMLINK;
+		goto out_unlock;
+	}
+
+	set_dent_args_inode(&new_da, old_inode);
+	ret = insert_entry(new_dir, &new_da);
+	if (ret < 0)
+		goto out_unlock;
+
+	inc_nlink(new_dir);
+	inc_nlink(old_inode);
+
+	set_dir_i_size(new_dir);
+
+	now = inode_set_ctime_current(old_dir);
+	inode_set_mtime_to_ts(old_dir, now);
+	if (new_dir != old_dir) {
+		inode_set_ctime_to_ts(new_dir, now);
+		inode_set_mtime_to_ts(new_dir, now);
+	}
+	inode_set_ctime_to_ts(old_inode, now);
+	ihold(old_inode);
+	mark_inode_dirty(old_inode);
+	mark_inode_dirty(new_dir);
+
+	d_instantiate(new_dentry, old_inode);
+
+	rpdfs_inode_update(rfi, old_inode);
+	rpdfs_inode_update(rfi, old_dir);
+	if (new_dir != old_dir)
+		rpdfs_inode_update(rfi, new_dir);
+
+out_unlock:
+	rpdfs_rlock_unlock(rfi, &old_dir_hold);
+	rpdfs_rlock_unlock(rfi, &new_dir_hold);
+	rpdfs_rlock_unlock(rfi, &old_inode_hold);
+	rpdfs_rlock_unlock(rfi, &new_inode_hold);
+
+out:
+	return ret;
+}
+
 /*
  * The VFS did a bunch of checks before calling our unlink
  * implementation, but some other node could have made changes between
@@ -673,6 +757,7 @@ static int rpdfs_readdir(struct file *file, struct dir_context *ctx)
 const struct inode_operations rpdfs_dir_iops = {
 	.create		= rpdfs_create,
 	.getattr	= rpdfs_getattr,
+	.link		= rpdfs_link,
 	.lookup		= rpdfs_lookup,
 	.mkdir		= rpdfs_mkdir,
 	.rename		= rpdfs_rename,
-- 
2.55.0


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

end of thread, other threads:[~2026-10-23 17:50 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-19 18:21 [PATCH 1/1] rpdfs: Add support for rpdfs_link() Chris Kirby
2026-10-23 17:50 ` 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.