/*
 * 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);
}
Esempio n. 3
0
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);
}