From owner-svn-soc-all@FreeBSD.ORG Fri Jun 15 14:22:16 2012 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from socsvn.FreeBSD.org (unknown [IPv6:2001:4f8:fff6::2f]) by hub.freebsd.org (Postfix) with SMTP id 780B91065675 for ; Fri, 15 Jun 2012 14:22:14 +0000 (UTC) (envelope-from gpf@FreeBSD.org) Received: by socsvn.FreeBSD.org (sSMTP sendmail emulation); Fri, 15 Jun 2012 14:22:14 +0000 Date: Fri, 15 Jun 2012 14:22:14 +0000 From: gpf@FreeBSD.org To: svn-soc-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Message-Id: <20120615142214.780B91065675@hub.freebsd.org> Cc: Subject: socsvn commit: r237766 - soc2012/gpf/pefs_kmod/sys/fs/pefs X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 15 Jun 2012 14:22:16 -0000 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 #include #include +#include +#include #include #include #include @@ -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)