/* * Obtain a vnode for the specified inode number. An exclusively locked * vnode is returned. */ int hammer_vfs_vget(struct mount *mp, struct vnode *dvp, ino_t ino, struct vnode **vpp) { struct hammer_transaction trans; struct hammer_mount *hmp = (void *)mp->mnt_data; struct hammer_inode *ip; int error; u_int32_t localization; lwkt_gettoken(&hmp->fs_token); hammer_simple_transaction(&trans, hmp); /* * If a directory vnode is supplied (mainly NFS) then we can acquire * the PFS domain from it. Otherwise we would only be able to vget * inodes in the root PFS. */ if (dvp) { localization = HAMMER_DEF_LOCALIZATION + VTOI(dvp)->obj_localization; } else { localization = HAMMER_DEF_LOCALIZATION; } /* * Lookup the requested HAMMER inode. The structure must be * left unlocked while we manipulate the related vnode to avoid * a deadlock. */ ip = hammer_get_inode(&trans, NULL, ino, hmp->asof, localization, 0, &error); if (ip == NULL) { *vpp = NULL; } else { error = hammer_get_vnode(ip, vpp); hammer_rel_inode(ip, 0); } hammer_done_transaction(&trans); lwkt_reltoken(&hmp->fs_token); return (error); }
/* * Convert a file handle back to a vnode. * * Use rootvp to enforce PFS isolation when a PFS is exported via a * null mount. */ static int hammer_vfs_fhtovp(struct mount *mp, struct vnode *rootvp, struct fid *fhp, struct vnode **vpp) { hammer_mount_t hmp = (void *)mp->mnt_data; struct hammer_transaction trans; struct hammer_inode *ip; struct hammer_inode_info info; int error; u_int32_t localization; bcopy(fhp->fid_data + 0, &info.obj_id, sizeof(info.obj_id)); bcopy(fhp->fid_data + 8, &info.obj_asof, sizeof(info.obj_asof)); if (rootvp) localization = VTOI(rootvp)->obj_localization; else localization = (u_int32_t)fhp->fid_ext << 16; lwkt_gettoken(&hmp->fs_token); hammer_simple_transaction(&trans, hmp); /* * Get/allocate the hammer_inode structure. The structure must be * unlocked while we manipulate the related vnode to avoid a * deadlock. */ ip = hammer_get_inode(&trans, NULL, info.obj_id, info.obj_asof, localization, 0, &error); if (ip) { error = hammer_get_vnode(ip, vpp); hammer_rel_inode(ip, 0); } else { *vpp = NULL; } hammer_done_transaction(&trans); lwkt_reltoken(&hmp->fs_token); return (error); }
static inline int _vnode_validate(hammer_dedup_cache_t dcp, void *data, int *errorp) { struct hammer_transaction trans; hammer_inode_t ip; struct vnode *vp; struct buf *bp; /* off_t dooffset; */ int result, error; result = error = 0; *errorp = 0; hammer_simple_transaction(&trans, dcp->hmp); ip = hammer_get_inode(&trans, NULL, dcp->obj_id, HAMMER_MAX_TID, dcp->localization, 0, &error); if (ip == NULL) { kprintf("dedup: unable to find objid %016llx:%08x\n", (long long)dcp->obj_id, dcp->localization); *errorp = 1; goto failed2; } error = hammer_get_vnode(ip, &vp); if (error) { kprintf("dedup: unable to acquire vnode for %016llx:%08x\n", (long long)dcp->obj_id, dcp->localization); *errorp = 2; goto failed; } if ((bp = findblk(ip->vp, dcp->file_offset, FINDBLK_NBLOCK)) != NULL) { dfly_brelse(bp); /* bremfree(bp) */ /* XXX if (mapped to userspace) goto done, *errorp = 4 */ if ((bp->b_flags & B_CACHE) == 0 || bp->b_flags & B_DIRTY) { *errorp = 5; goto done; } /* XXX if (bp->b_bio2.bio_offset != dcp->data_offset) { error = VOP_BMAP(ip->vp, dcp->file_offset, &dooffset, NULL, NULL, BUF_CMD_READ); if (error) { *errorp = 6; goto done; } if (dooffset != dcp->data_offset) { *errorp = 7; goto done; } hammer_live_dedup_bmap_saves++; } */ if (bcmp(data, bp->b_data, dcp->bytes) == 0) result = 1; done: dfly_brelse(bp); /* XX free to buffer not kfree ... bqrelse(bp);*/ } else { *errorp = 3; } vput(vp); failed: hammer_rel_inode(ip, 0); failed2: hammer_done_transaction(&trans); return (result); }