diff mbox

[V9fs-developer,9p,V2] Define and implement TLINK for 9P2000.L

Message ID 1275329787-27559-1-git-send-email-jvrao@linux.vnet.ibm.com (mailing list archive)
State Accepted, archived
Delegated to: Eric Van Hensbergen
Headers show

Commit Message

jvrao May 31, 2010, 6:16 p.m. UTC
None
diff mbox

Patch

diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 1e13b5e..5acd355 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -1194,6 +1194,49 @@  clunk_fid:
 }
 
 /**
+ * v9fs_vfs_link_dotl - create a hardlink for dotl
+ * @old_dentry: dentry for file to link to
+ * @dir: inode destination for new link
+ * @dentry: dentry for link
+ *
+ */
+
+static int
+v9fs_vfs_link_dotl(struct dentry *old_dentry, struct inode *dir,
+		struct dentry *dentry)
+{
+	int err;
+	struct p9_fid *dfid;
+	char *name;
+	struct v9fs_session_info *v9ses;
+
+	P9_DPRINTK(P9_DEBUG_VFS,
+		" %lu,%s,%s\n", dir->i_ino, dentry->d_name.name,
+		old_dentry->d_name.name);
+
+	v9ses = v9fs_inode2v9ses(dir);
+	dfid = v9fs_fid_lookup(dentry->d_parent);
+	if (IS_ERR(dfid))
+		return PTR_ERR(dfid);
+
+	name = (char *) dentry->d_name.name;
+
+	err = p9_client_link(dfid, (char *)old_dentry->d_name.name,
+			(char *)dentry->d_name.name);
+	if (err < 0) {
+		P9_DPRINTK(P9_DEBUG_VFS, "p9_client_link failed %d\n", err);
+		return err;
+	}
+
+	dentry->d_op = old_dentry->d_op;
+	/* Hard link, so we can use old_dentry's inode. Just i_count++ */
+	atomic_inc(&old_dentry->d_inode->i_count);
+	d_instantiate(dentry, old_dentry->d_inode);
+
+	return err;
+}
+
+/**
  * v9fs_vfs_mknod - create a special file
  * @dir: inode destination for new link
  * @dentry: dentry for file
@@ -1254,7 +1297,7 @@  static const struct inode_operations v9fs_dir_inode_operations_dotl = {
 	.create = v9fs_vfs_create,
 	.lookup = v9fs_vfs_lookup,
 	.symlink = v9fs_vfs_symlink,
-	.link = v9fs_vfs_link,
+	.link = v9fs_vfs_link_dotl,
 	.unlink = v9fs_vfs_unlink,
 	.mkdir = v9fs_vfs_mkdir,
 	.rmdir = v9fs_vfs_rmdir,
diff --git a/include/net/9p/9p.h b/include/net/9p/9p.h
index f1b0b31..6df324e 100644
--- a/include/net/9p/9p.h
+++ b/include/net/9p/9p.h
@@ -135,6 +135,8 @@  enum p9_msg_t {
 	P9_RRENAME,
 	P9_TREADDIR = 40,
 	P9_RREADDIR,
+	P9_TLINK = 70,
+	P9_RLINK,
 	P9_TVERSION = 100,
 	P9_RVERSION,
 	P9_TAUTH = 102,
diff --git a/include/net/9p/client.h b/include/net/9p/client.h
index cd6de1c..c214240 100644
--- a/include/net/9p/client.h
+++ b/include/net/9p/client.h
@@ -226,6 +226,7 @@  struct p9_fid *p9_client_walk(struct p9_fid *oldfid, int nwname, char **wnames,
 int p9_client_open(struct p9_fid *fid, int mode);
 int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
 							char *extension);
+int p9_client_link(struct p9_fid *fid, char *name, char *linkname);
 int p9_client_clunk(struct p9_fid *fid);
 int p9_client_remove(struct p9_fid *fid);
 int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
diff --git a/net/9p/client.c b/net/9p/client.c
index 5398b98..7f4d8f9 100644
--- a/net/9p/client.c
+++ b/net/9p/client.c
@@ -1093,6 +1093,27 @@  error:
 }
 EXPORT_SYMBOL(p9_client_fcreate);
 
+int p9_client_link(struct p9_fid *dfid, char *oldname, char *newname)
+{
+	int err = 0;
+	struct p9_client *clnt;
+	struct p9_req_t *req;
+
+	P9_DPRINTK(P9_DEBUG_9P, ">>> TLINK fid %d oldname %s newname %s\n",
+			dfid->fid, oldname, newname);
+	clnt = dfid->clnt;
+	req = p9_client_rpc(clnt, P9_TLINK, "dss", dfid->fid, oldname, newname);
+	if (IS_ERR(req)) {
+		err = PTR_ERR(req);
+		goto error;
+	}
+	P9_DPRINTK(P9_DEBUG_9P, "<<< RLINK\n");
+	p9_free_req(clnt, req);
+error:
+	return err;
+}
+EXPORT_SYMBOL(p9_client_link);
+
 int p9_client_clunk(struct p9_fid *fid)
 {
 	int err;