[RFC][PATCH 4/6] 9p: 9P server fid management

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patchset provides support for in-kernel 9P2000 servers.

This patch adds the 9P server fid management.

Signed-off-by: Latchesar Ionkov <[email protected]>
---
 net/9p/srv/fid.c |  178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 178 insertions(+), 0 deletions(-)
 create mode 100644 net/9p/srv/fid.c

diff --git a/net/9p/srv/fid.c b/net/9p/srv/fid.c
new file mode 100644
index 0000000..7c86204
--- /dev/null
+++ b/net/9p/srv/fid.c
@@ -0,0 +1,178 @@
+/*
+ * net/9p/srv/fid.c
+ *
+ * Fid Management
+ *
+ *  Copyright (C) 2007 by Latchesar Ionkov <[email protected]>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to:
+ *  Free Software Foundation
+ *  51 Franklin Street, Fifth Floor
+ *  Boston, MA  02111-1301  USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/list.h>
+#include <linux/hash.h>
+#include <linux/parser.h>
+#include <net/9p/9p.h>
+#include <net/9p/transport.h>
+#include <net/9p/srv.h>
+#include "srvimpl.h"
+
+struct p9srv_fidpool *p9srv_fidpool_create(void)
+{
+	int i;
+	struct p9srv_fidpool *fp;
+
+	fp = kmalloc(sizeof(struct p9srv_fidpool), GFP_KERNEL);
+	if (!fp)
+		return ERR_PTR(-ENOMEM);
+
+	spin_lock_init(&fp->lock);
+	for (i = 0; i < FID_HTABLE_SIZE; i++)
+		INIT_HLIST_HEAD(&fp->hash[i]);
+
+	P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p\n", fp);
+	return fp;
+}
+
+void p9srv_fidpool_destroy(struct p9srv_fidpool *fp)
+{
+	int i;
+
+	P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p\n", fp);
+	for (i = 0; i < FID_HTABLE_SIZE; i++)
+		BUG_ON(!hlist_empty(&fp->hash[i]));
+
+	kfree(fp);
+}
+
+void p9srv_fidpool_reset(struct p9srv_fidpool *fp)
+{
+	int i;
+	struct p9srv_fid *cfid;
+	struct hlist_node *hn, *htmp;
+	HLIST_HEAD(hh);
+
+	P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p\n", fp);
+	spin_lock(&fp->lock);
+	for (i = 0; i < FID_HTABLE_SIZE; i++) {
+		hlist_for_each_entry_safe(cfid, hn, htmp, &fp->hash[i],
+								fid_list) {
+			hlist_del(hn);
+			hlist_add_head(hn, &hh);
+		}
+	}
+	spin_unlock(&fp->lock);
+
+	hlist_for_each_entry_safe(cfid, hn, htmp, &hh, fid_list) {
+		atomic_set(&cfid->refcount, 1);
+		p9srv_fid_decref(cfid);
+	}
+}
+
+struct p9srv_fid *p9srv_fid_create(struct p9srv_fidpool *fp, u32 fid)
+{
+	unsigned long hash;
+	struct p9srv_fid *cfid, *nfid;
+	struct hlist_node *hn;
+
+	P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p fid %d\n", fp, fid);
+	hash = hash_long(fid, FID_HTABLE_BITS);
+	nfid = kmalloc(sizeof(struct p9srv_fid), GFP_KERNEL);
+	if (!nfid)
+		return ERR_PTR(-ENOMEM);
+
+	nfid->fid = fid;
+	atomic_set(&nfid->refcount, 0);
+	nfid->conn = NULL;
+	nfid->aux = NULL;
+	nfid->omode = ~0;
+	nfid->type = 0;
+	nfid->diroffset = 0;
+	nfid->uid = ~0;
+	nfid->fidpool = fp;
+	INIT_HLIST_NODE(&nfid->fid_list);
+	spin_lock(&fp->lock);
+	hlist_for_each_entry(cfid, hn, &fp->hash[hash], fid_list) {
+		if (cfid->fid == fid) {
+			spin_unlock(&fp->lock);
+			kfree(nfid);
+			return ERR_PTR(-EEXIST);
+		}
+	}
+
+	hlist_add_head(&nfid->fid_list, &fp->hash[hash]);
+	spin_unlock(&fp->lock);
+	p9srv_fid_incref(nfid);
+	return nfid;
+}
+
+struct p9srv_fid *p9srv_fid_find(struct p9srv_fidpool *fp, u32 fid)
+{
+	unsigned long hash;
+	struct p9srv_fid *cfid;
+	struct hlist_node *hn;
+
+	hash = hash_long(fid, FID_HTABLE_BITS);
+	spin_lock(&fp->lock);
+	hlist_for_each_entry(cfid, hn, &fp->hash[hash], fid_list) {
+		if (cfid->fid == fid) {
+			spin_unlock(&fp->lock);
+			p9srv_fid_incref(cfid);
+			return cfid;
+		}
+	}
+	spin_unlock(&fp->lock);
+
+	return NULL;
+}
+EXPORT_SYMBOL(p9srv_fid_find);
+
+void p9srv_fid_incref(struct p9srv_fid *fid)
+{
+	if (fid)
+		atomic_inc(&fid->refcount);
+
+	P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p fid %d count %d\n",
+		fid->fidpool, fid->fid, atomic_read(&fid->refcount));
+}
+EXPORT_SYMBOL(p9srv_fid_incref);
+
+void p9srv_fid_decref(struct p9srv_fid *fid)
+{
+	int n;
+
+	if (!fid)
+		return;
+
+	n = atomic_dec_and_test(&fid->refcount);
+	P9_DPRINTK(P9SRV_DEBUG_FID, "fidpool %p fid %d count %d \n",
+		fid->fidpool, fid->fid, atomic_read(&fid->refcount));
+	if (n) {
+		P9_DPRINTK(P9SRV_DEBUG_FID, "destroy fidpool %p fid %d\n",
+			fid->fidpool, fid->fid);
+		spin_lock(&fid->fidpool->lock);
+		hlist_del(&fid->fid_list);
+		spin_unlock(&fid->fidpool->lock);
+		if (fid->conn && fid->conn->srv && fid->conn->srv->fiddestroy)
+			(*fid->conn->srv->fiddestroy)(fid);
+		kfree(fid);
+	}
+}
+EXPORT_SYMBOL(p9srv_fid_decref);
-- 
1.5.2.4

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux