socsvn commit: r237766 - soc2012/gpf/pefs_kmod/sys/fs/pefs
gpf at FreeBSD.org
gpf at FreeBSD.org
Fri Jun 15 14:22:16 UTC 2012
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)
More information about the svn-soc-all
mailing list