Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 15 Jun 2012 14:22:14 +0000
From:      gpf@FreeBSD.org
To:        svn-soc-all@FreeBSD.org
Subject:   socsvn commit: r237766 - soc2012/gpf/pefs_kmod/sys/fs/pefs
Message-ID:  <20120615142214.780B91065675@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gpf
Date: Fri Jun 15 14:22:12 2012
New Revision: 237766
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=237766

Log:
  - lookup a file in the checksum index tables when a new pefs vnode is
  created as a result of a VOP_LOOKUP.
  

Modified:
  soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
  soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c

Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h	Fri Jun 15 11:39:01 2012	(r237765)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs.h	Fri Jun 15 14:22:12 2012	(r237766)
@@ -123,6 +123,12 @@
 #define PEFS_CFH_SIZE 16
 #define PEFS_HT_CELL_SIZE 16
 
+struct pefs_checksum_index_entry {
+	uint32_t pcie_nhashes;
+	uint32_t pcie_offset;
+	uint64_t pcie_file_id;
+};
+
 struct pefs_checksum {
 	uint8_t pcs_version;
 	uint8_t pcs_reserved;
@@ -149,6 +155,7 @@
 	void			*pn_buf_large;
 	int			pn_flags;
 	struct pefs_tkey	pn_tkey;
+	void				*pn_checksum_index_entry;
 };
 
 #define	PM_ROOT_CANRECURSE		0x01

Modified: soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c
==============================================================================
--- soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c	Fri Jun 15 11:39:01 2012	(r237765)
+++ soc2012/gpf/pefs_kmod/sys/fs/pefs/pefs_vnops.c	Fri Jun 15 14:22:12 2012	(r237766)
@@ -56,6 +56,8 @@
 #include <sys/proc.h>
 #include <sys/sched.h>
 #include <sys/unistd.h>
+#include <sys/endian.h>
+#include <sys/fnv_hash.h>
 #include <vm/vm.h>
 #include <vm/vm_extern.h>
 #include <vm/vm_object.h>
@@ -470,10 +472,103 @@
 	return (0);
 }
 
+/*
+ * XXXgpf: [TODO] move most, if not all, of the checksum code to a different .c
+ */
+static uint32_t
+pefs_checksum_hash1(struct pefs_checksum *pc, struct pefs_checksum_index_entry *pcie)
+{
+	uint32_t nbucket;
+
+	nbucket = pcie->pcie_file_id % pc->pcs_hash_table_size;
+	printf("hash1: goto bucket %d\n", nbucket);
+	return (nbucket);
+}
+
+static uint32_t
+pefs_checksum_hash2(struct pefs_checksum *pc, struct pefs_checksum_index_entry *pcie)
+{
+	uint32_t nbucket;
+
+	nbucket = fnv_64_buf(&(pcie->pcie_file_id), sizeof(pcie->pcie_file_id), FNV1_64_INIT)
+			% pc->pcs_hash_table_size;
+	printf("hash2: goto bucket %d\n", nbucket);
+
+	return (nbucket);
+}
+
+static void
+pefs_checksum_index_lookup(struct pefs_checksum_index_entry *pcie, struct vnode *vp)
+{
+	struct pefs_checksum_index_entry target_pcie;
+	struct pefs_mount *pm = VFS_TO_PEFS(vp->v_mount);
+	struct pefs_checksum *pcs = &(pm->pm_checksum);
+	struct pefs_node *pn = VP_TO_PN(vp);
+	char *start, *p;
+	uint32_t pos;
+
+	pos = pefs_checksum_hash1(pcs, pcie);
+	start = &(pcs->pcs_table1[pos * PEFS_HT_CELL_SIZE]);
+	p = start;
+
+	memcpy(&(target_pcie.pcie_nhashes), p, sizeof(target_pcie.pcie_nhashes));
+	target_pcie.pcie_nhashes = le32toh(target_pcie.pcie_nhashes);
+	if (target_pcie.pcie_nhashes != 0) {
+		p+=sizeof(target_pcie.pcie_nhashes);
+
+		memcpy(&(target_pcie.pcie_offset), p, sizeof(target_pcie.pcie_offset));
+		target_pcie.pcie_offset = le32toh(target_pcie.pcie_offset);
+		p+=sizeof(target_pcie.pcie_offset);
+
+		memcpy(&(target_pcie.pcie_file_id), p, sizeof(target_pcie.pcie_file_id));
+		target_pcie.pcie_file_id = le64toh(target_pcie.pcie_file_id);
+		printf("cell %d:\n", pos);
+		printf("\thashes = %d\n\toffset = %d\n\tfile id = %llu\n",
+			target_pcie.pcie_nhashes, target_pcie.pcie_offset, target_pcie.pcie_file_id);
+
+		if (target_pcie.pcie_file_id == pcie->pcie_file_id) {
+			pn->pn_checksum_index_entry = start;
+			printf("checksum lookup: found1!\n");
+			return;
+		}
+	}
+
+	pos = pefs_checksum_hash2(pcs, pcie);
+	start = &(pcs->pcs_table2[pos * PEFS_HT_CELL_SIZE]);
+	p = start;
+
+	memcpy(&(target_pcie.pcie_nhashes), p, sizeof(target_pcie.pcie_nhashes));
+	target_pcie.pcie_nhashes = le32toh(target_pcie.pcie_nhashes);
+	if (target_pcie.pcie_nhashes != 0) {
+		p+=sizeof(target_pcie.pcie_nhashes);
+
+		memcpy(&(target_pcie.pcie_offset), p, sizeof(target_pcie.pcie_offset));
+		target_pcie.pcie_offset = le32toh(target_pcie.pcie_offset);
+		p+=sizeof(target_pcie.pcie_offset);
+
+		memcpy(&(target_pcie.pcie_file_id), p, sizeof(target_pcie.pcie_file_id));
+		target_pcie.pcie_file_id = le64toh(target_pcie.pcie_file_id);
+		printf("cell %d:\n", pos);
+		printf("\thashes = %d\n\toffset = %d\n\tfile id = %llu\n",
+			target_pcie.pcie_nhashes, target_pcie.pcie_offset, target_pcie.pcie_file_id);
+
+		if (target_pcie.pcie_file_id == pcie->pcie_file_id) {
+			pn->pn_checksum_index_entry = start;
+			printf("checksum lookup: found2!\n");
+			return;
+		}
+	}
+
+	printf("checksum lookup: not found!\n");
+	pn->pn_checksum_index_entry = NULL;
+}
+
 static int
 pefs_lookup(struct vop_cachedlookup_args *ap)
 {
+	struct pefs_checksum_index_entry pcie;
 	struct componentname *cnp = ap->a_cnp;
+	struct pefs_mount *pm;
 	struct vnode *vp = NULL;
 	struct vnode *lvp = NULL;
 	struct vnode *dvp = ap->a_dvp;
@@ -481,10 +576,12 @@
 	struct pefs_enccn enccn;
 	struct pefs_node *dpn = VP_TO_PN(dvp);
 	uint64_t flags = cnp->cn_flags;
+	char *enc_name, *buf;
 	int nokey_lookup, skip_lookup;
-	int error;
+	int error, r;
+	size_t enc_name_len, buf_len;
 
-	PEFSDEBUG("pefs_lookup: op=%lx, name=%.*s\n",
+	printf("pefs_lookup: op=%lx, name=%.*s\n",
 	    cnp->cn_nameiop, (int)cnp->cn_namelen, cnp->cn_nameptr);
 
 	pefs_enccn_init(&enccn);
@@ -557,9 +654,53 @@
 			else
 				error = pefs_node_get_haskey(dvp->v_mount, lvp,
 				    &vp, &enccn.pec_tkey);
+
 			if (error != 0) {
 				vput(lvp);
 			} else {
+				pm = VFS_TO_PEFS(vp->v_mount);
+				if ((pm->pm_flags & PM_CHECKSUM) != 0 && cnp->cn_nameiop == LOOKUP &&
+					(vp->v_type == VREG || vp->v_type == VLNK)) {
+					printf("gpf: checksum code @ lookup\n");
+					if (nokey_lookup) {
+						printf("cnp name=%.*s\n",(int)cnp->cn_namelen, cnp->cn_nameptr);
+						enc_name = cnp->cn_nameptr;
+						enc_name_len = cnp->cn_namelen;
+					}
+					else {
+						printf("enccnp name=%.*s\n",(int)enccn.pec_cn.cn_namelen, enccn.pec_cn.cn_nameptr);
+						enc_name = enccn.pec_cn.cn_nameptr;
+						enc_name_len = enccn.pec_cn.cn_namelen;
+					}
+
+					/* XXXgpf: What if user wants integrity checking for .pefs.db or .conf? */
+					/* XXXgpf: [TODO] move this check to a mini function */
+					if (strncmp(enc_name, ".pefs.db", enc_name_len) != 0 &&
+						strncmp(enc_name, ".pefs.conf", enc_name_len) != 0 &&
+						strncmp(enc_name, ".pefs.checksum", enc_name_len) != 0)
+					{
+						enc_name++;
+						enc_name_len--;
+						buf_len = MAXNAMLEN + 1;
+						buf = malloc(buf_len, M_TEMP, M_WAITOK);
+
+						r = pefs_name_pton(enc_name, enc_name_len, buf, buf_len);
+						if (r <= 0) {
+							/* XXXgpf: I sincerely doubt an error can occur here */
+							error = EINVAL;
+							printf("name_pton error: %d\n", error);
+						}
+						else {
+							memcpy(&(pcie.pcie_file_id), buf, sizeof(pcie.pcie_file_id));
+							pcie.pcie_file_id = be64toh(pcie.pcie_file_id);
+							printf("id to lookup: %llu\n", pcie.pcie_file_id);
+							pefs_checksum_index_lookup(&pcie, vp);
+						}
+
+						free(buf, M_TEMP);
+					}
+
+				}
 				*ap->a_vpp = vp;
 				if ((cnp->cn_flags & MAKEENTRY) &&
 				    cnp->cn_nameiop != CREATE)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20120615142214.780B91065675>