Example #1
0
/**
 * __vxfs_iget - generic find inode facility
 * @sbp:		VFS superblock
 * @ino:		inode number
 * @ilistp:		inode list
 *
 * Description:
 *  Search the for inode number @ino in the filesystem
 *  described by @sbp.  Use the specified inode table (@ilistp).
 *  Returns the matching VxFS inode on success, else a NULL pointer.
 */
static struct vxfs_inode_info *
__vxfs_iget(ino_t ino, struct inode *ilistp)
{
	struct page			*pp;
	u_long				offset;

	offset = (ino % (PAGE_SIZE / VXFS_ISIZE)) * VXFS_ISIZE;
	pp = vxfs_get_page(ilistp->i_mapping, ino * VXFS_ISIZE / PAGE_SIZE);

	if (!IS_ERR(pp)) {
		struct vxfs_inode_info	*vip;
		struct vxfs_dinode	*dip;
		caddr_t			kaddr = (char *)page_address(pp);

		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL)))
			goto fail;
		dip = (struct vxfs_dinode *)(kaddr + offset);
		memcpy(vip, dip, sizeof(*vip));
#ifdef DIAGNOSTIC
		vxfs_dumpi(vip, ino);
#endif
		vxfs_put_page(pp);
		return (vip);
	}

	printk(KERN_WARNING "vxfs: error on page %p\n", pp);
	return NULL;

fail:
	printk(KERN_WARNING "vxfs: unable to read inode %ld\n", ino);
	vxfs_put_page(pp);
	return NULL;
}
Example #2
0
/**
 * vxfs_blkiget - find inode based on extent #
 * @sbp:	superblock of the filesystem we search in
 * @extent:	number of the extent to search
 * @ino:	inode number to search
 *
 * Description:
 *  vxfs_blkiget searches inode @ino in the filesystem described by
 *  @sbp in the extent @extent.
 *  Returns the matching VxFS inode on success, else a NULL pointer.
 *
 * NOTE:
 *  While __vxfs_iget uses the pagecache vxfs_blkiget uses the
 *  buffercache.  This function should not be used outside the
 *  read_super() method, otherwise the data may be incoherent.
 */
struct vxfs_inode_info *
vxfs_blkiget(struct super_block *sbp, u_long extent, ino_t ino)
{
	struct buffer_head		*bp;
	u_long				block, offset;

	block = extent + ((ino * VXFS_ISIZE) / sbp->s_blocksize);
	offset = ((ino % (sbp->s_blocksize / VXFS_ISIZE)) * VXFS_ISIZE);
	bp = sb_bread(sbp, block);

	if (buffer_mapped(bp)) {
		struct vxfs_inode_info	*vip;
		struct vxfs_dinode	*dip;

		if (!(vip = kmem_cache_alloc(vxfs_inode_cachep, SLAB_KERNEL)))
			goto fail;
		dip = (struct vxfs_dinode *)(bp->b_data + offset);
		memcpy(vip, dip, sizeof(*vip));
#ifdef DIAGNOSTIC
		vxfs_dumpi(vip, ino);
#endif
		brelse(bp);
		return (vip);
	}

fail:
	printk(KERN_WARNING "vxfs: unable to read block %ld\n", block);
	brelse(bp);
	return NULL;
}
/**
 * vxfs_read_fshead - read the fileset headers
 * @sbp:	superblock to which the fileset belongs
 *
 * Description:
 *   vxfs_read_fshead will fill the inode and structural inode list in @sb.
 *
 * Returns:
 *   Zero on success, else a negative error code (-EINVAL).
 */
int
vxfs_read_fshead(struct super_block *sbp)
{
	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
	struct vxfs_fsh			*pfp, *sfp;
	struct vxfs_inode_info		*vip, *tip;

	if (!(vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino))) {
		printk(KERN_ERR "vxfs: unabled to read fsh inode\n");
		return -EINVAL;
	} else if (!VXFS_ISFSH(vip)) {
		printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
				vip->vii_mode & VXFS_TYPE_MASK); 
		return -EINVAL;
	}


#ifdef DIAGNOSTIC
	printk("vxfs: fsh inode dump:\n");
	vxfs_dumpi(vip, infp->vsi_fshino);
#endif

	if (!(infp->vsi_fship = vxfs_get_fake_inode(sbp, vip))) {
		printk(KERN_ERR "vxfs: unabled to get fsh inode\n");
		return -EINVAL;
	}

	if (!(sfp = vxfs_getfsh(infp->vsi_fship, 0))) {
		printk(KERN_ERR "vxfs: unabled to get structural fsh\n");
		return -EINVAL;
	} 

#ifdef DIAGNOSTIC
	vxfs_dumpfsh(sfp);
#endif

	if (!(pfp = vxfs_getfsh(infp->vsi_fship, 1))) {
		printk(KERN_ERR "vxfs: unabled to get primary fsh\n");
		return -EINVAL;
	}

#ifdef DIAGNOSTIC
	vxfs_dumpfsh(pfp);
#endif

	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
	if (!tip || ((infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip)) == NULL)) {
		printk(KERN_ERR "vxfs: unabled to get structual list inode\n");
		return -EINVAL;
	} else if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
		printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n",
				VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
		return -EINVAL;
	}

	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
	if (!tip || ((infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip)) == NULL)) {
		printk(KERN_ERR "vxfs: unabled to get inode list inode\n");
		return -EINVAL;
	} else if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
		printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
		return -EINVAL;
	}

	return 0;
}
/**
 * vxfs_read_fshead - read the fileset headers
 * @sbp:	superblock to which the fileset belongs
 *
 * Description:
 *   vxfs_read_fshead will fill the inode and structural inode list in @sb.
 *
 * Returns:
 *   Zero on success, else a negative error code (-EINVAL).
 */
int
vxfs_read_fshead(struct super_block *sbp)
{
	struct vxfs_sb_info		*infp = VXFS_SBI(sbp);
	struct vxfs_fsh			*pfp, *sfp;
	struct vxfs_inode_info		*vip, *tip;

	vip = vxfs_blkiget(sbp, infp->vsi_iext, infp->vsi_fshino);
	if (!vip) {
		printk(KERN_ERR "vxfs: unable to read fsh inode\n");
		return -EINVAL;
	}
	if (!VXFS_ISFSH(vip)) {
		printk(KERN_ERR "vxfs: fsh list inode is of wrong type (%x)\n",
				vip->vii_mode & VXFS_TYPE_MASK); 
		goto out_free_fship;
	}


#ifdef DIAGNOSTIC
	printk(KERN_INFO "vxfs: fsh inode dump:\n");
	vxfs_dumpi(vip, infp->vsi_fshino);
#endif

	infp->vsi_fship = vxfs_get_fake_inode(sbp, vip);
	if (!infp->vsi_fship) {
		printk(KERN_ERR "vxfs: unable to get fsh inode\n");
		goto out_free_fship;
	}

	sfp = vxfs_getfsh(infp->vsi_fship, 0);
	if (!sfp) {
		printk(KERN_ERR "vxfs: unable to get structural fsh\n");
		goto out_iput_fship;
	} 

#ifdef DIAGNOSTIC
	vxfs_dumpfsh(sfp);
#endif

	pfp = vxfs_getfsh(infp->vsi_fship, 1);
	if (!pfp) {
		printk(KERN_ERR "vxfs: unable to get primary fsh\n");
		goto out_free_sfp;
	}

#ifdef DIAGNOSTIC
	vxfs_dumpfsh(pfp);
#endif

	tip = vxfs_blkiget(sbp, infp->vsi_iext, sfp->fsh_ilistino[0]);
	if (!tip)
		goto out_free_pfp;

	infp->vsi_stilist = vxfs_get_fake_inode(sbp, tip);
	if (!infp->vsi_stilist) {
		printk(KERN_ERR "vxfs: unable to get structural list inode\n");
		kfree(tip);
		goto out_free_pfp;
	}
	if (!VXFS_ISILT(VXFS_INO(infp->vsi_stilist))) {
		printk(KERN_ERR "vxfs: structual list inode is of wrong type (%x)\n",
				VXFS_INO(infp->vsi_stilist)->vii_mode & VXFS_TYPE_MASK); 
		goto out_iput_stilist;
	}

	tip = vxfs_stiget(sbp, pfp->fsh_ilistino[0]);
	if (!tip)
		goto out_iput_stilist;
	infp->vsi_ilist = vxfs_get_fake_inode(sbp, tip);
	if (!infp->vsi_ilist) {
		printk(KERN_ERR "vxfs: unable to get inode list inode\n");
		kfree(tip);
		goto out_iput_stilist;
	}
	if (!VXFS_ISILT(VXFS_INO(infp->vsi_ilist))) {
		printk(KERN_ERR "vxfs: inode list inode is of wrong type (%x)\n",
				VXFS_INO(infp->vsi_ilist)->vii_mode & VXFS_TYPE_MASK);
		goto out_iput_ilist;
	}

	return 0;

 out_iput_ilist:
 	iput(infp->vsi_ilist);
 out_iput_stilist:
 	iput(infp->vsi_stilist);
 out_free_pfp:
	kfree(pfp);
 out_free_sfp:
 	kfree(sfp);
 out_iput_fship:
	iput(infp->vsi_fship);
	return -EINVAL;
 out_free_fship:
 	kfree(vip);
	return -EINVAL;
}