/* Compressed/encrypted/sparse index root is not allowed. */ 
/* * Compressed/encrypted/sparse index root is not allowed, except for * directories of course but those are not dealt with here. */ 
static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi){	loff_t bvi_size;	ntfs_volume *vol = NTFS_SB(vi->i_sb);	ntfs_inode *ni, *base_ni, *bni;	struct inode *bvi;	MFT_RECORD *m;	ATTR_RECORD *a;	ntfs_attr_search_ctx *ctx;	INDEX_ROOT *ir;	u8 *ir_end, *index_end;	int err = 0;	ntfs_debug("Entering for i_ino 0x%lx.", vi->i_ino);	ntfs_init_big_inode(vi);	ni	= NTFS_I(vi);	base_ni = NTFS_I(base_vi);	/* Just mirror the values from the base inode. */	vi->i_blksize	= base_vi->i_blksize;	vi->i_version	= base_vi->i_version;	vi->i_uid	= base_vi->i_uid;	vi->i_gid	= base_vi->i_gid;	vi->i_nlink	= base_vi->i_nlink;	vi->i_mtime	= base_vi->i_mtime;	vi->i_ctime	= base_vi->i_ctime;	vi->i_atime	= base_vi->i_atime;	vi->i_generation = ni->seq_no = base_ni->seq_no;	/* Set inode type to zero but preserve permissions. */	vi->i_mode	= base_vi->i_mode & ~S_IFMT;	/* Map the mft record for the base inode. */	m = map_mft_record(base_ni);	if (IS_ERR(m)) {		err = PTR_ERR(m);		goto err_out;	}	ctx = ntfs_attr_get_search_ctx(base_ni, m);	if (!ctx) {		err = -ENOMEM;		goto unm_err_out;	}	/* Find the index root attribute. */	err = ntfs_attr_lookup(AT_INDEX_ROOT, ni->name, ni->name_len,			CASE_SENSITIVE, 0, NULL, 0, ctx);	if (unlikely(err)) {		if (err == -ENOENT)			ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is "					"missing.");		goto unm_err_out;	}	a = ctx->attr;	/* Set up the state. */	if (unlikely(a->non_resident)) {		ntfs_error(vol->sb, "$INDEX_ROOT attribute is not resident.");		goto unm_err_out;	}	/* Ensure the attribute name is placed before the value. */	if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=			le16_to_cpu(a->data.resident.value_offset)))) {		ntfs_error(vol->sb, "$INDEX_ROOT attribute name is placed "				"after the attribute value.");		goto unm_err_out;	}	/* Compressed/encrypted/sparse index root is not allowed. */	if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |			ATTR_IS_SPARSE)) {		ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "				"root attribute.");		goto unm_err_out;	}	ir = (INDEX_ROOT*)((u8*)a + le16_to_cpu(a->data.resident.value_offset));	ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length);	if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) {		ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is corrupt.");		goto unm_err_out;	}	index_end = (u8*)&ir->index + le32_to_cpu(ir->index.index_length);	if (index_end > ir_end) {		ntfs_error(vi->i_sb, "Index is corrupt.");		goto unm_err_out;	}	if (ir->type) {		ntfs_error(vi->i_sb, "Index type is not 0 (type is 0x%x).",				le32_to_cpu(ir->type));		goto unm_err_out;	}	ni->itype.index.collation_rule = ir->collation_rule;	ntfs_debug("Index collation rule is 0x%x.",			le32_to_cpu(ir->collation_rule));	ni->itype.index.block_size = le32_to_cpu(ir->index_block_size);	if (ni->itype.index.block_size & (ni->itype.index.block_size - 1)) {		ntfs_error(vi->i_sb, "Index block size (%u) is not a power of "				"two.", ni->itype.index.block_size);		goto unm_err_out;	}	if (ni->itype.index.block_size > PAGE_CACHE_SIZE) {		ntfs_error(vi->i_sb, "Index block size (%u) > PAGE_CACHE_SIZE "				"(%ld) is not supported.  Sorry.",				ni->itype.index.block_size, PAGE_CACHE_SIZE);		err = -EOPNOTSUPP;		goto unm_err_out;	}	if (ni->itype.index.block_size < NTFS_BLOCK_SIZE) {		ntfs_error(vi->i_sb, "Index block size (%u) < NTFS_BLOCK_SIZE "				"(%i) is not supported.  Sorry.",				ni->itype.index.block_size, NTFS_BLOCK_SIZE);		err = -EOPNOTSUPP;		goto unm_err_out;	}	ni->itype.index.block_size_bits = ffs(ni->itype.index.block_size) - 1;	/* Determine the size of a vcn in the index. */	if (vol->cluster_size <= ni->itype.index.block_size) {		ni->itype.index.vcn_size = vol->cluster_size;		ni->itype.index.vcn_size_bits = vol->cluster_size_bits;	} else {		ni->itype.index.vcn_size = vol->sector_size;		ni->itype.index.vcn_size_bits = vol->sector_size_bits;	}	/* Check for presence of index allocation attribute. */	if (!(ir->index.flags & LARGE_INDEX)) {		/* No index allocation. */		vi->i_size = ni->initialized_size = ni->allocated_size = 0;		/* We are done with the mft record, so we release it. */		ntfs_attr_put_search_ctx(ctx);		unmap_mft_record(base_ni);		m = NULL;		ctx = NULL;		goto skip_large_index_stuff;	} /* LARGE_INDEX:  Index allocation present.  Setup state. */	NInoSetIndexAllocPresent(ni);	/* Find index allocation attribute. */	ntfs_attr_reinit_search_ctx(ctx);	err = ntfs_attr_lookup(AT_INDEX_ALLOCATION, ni->name, ni->name_len,			CASE_SENSITIVE, 0, NULL, 0, ctx);	if (unlikely(err)) {		if (err == -ENOENT)			ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "					"not present but $INDEX_ROOT "					"indicated it is.");		else			ntfs_error(vi->i_sb, "Failed to lookup "					"$INDEX_ALLOCATION attribute.");		goto unm_err_out;	}	if (!a->non_resident) {		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "				"resident.");		goto unm_err_out;	}	/*	 * Ensure the attribute name is placed before the mapping pairs array.	 */	if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=			le16_to_cpu(			a->data.non_resident.mapping_pairs_offset)))) {		ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name is "				"placed after the mapping pairs array.");		goto unm_err_out;	}	if (a->flags & ATTR_IS_ENCRYPTED) {		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "				"encrypted.");		goto unm_err_out;	}	if (a->flags & ATTR_IS_SPARSE) {		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is sparse.");		goto unm_err_out;	}	if (a->flags & ATTR_COMPRESSION_MASK) {		ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "				"compressed.");		goto unm_err_out;	}	if (a->data.non_resident.lowest_vcn) {		ntfs_error(vi->i_sb, "First extent of $INDEX_ALLOCATION "				"attribute has non zero lowest_vcn.");		goto unm_err_out;	}	vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);	ni->initialized_size = sle64_to_cpu(			a->data.non_resident.initialized_size);	ni->allocated_size = sle64_to_cpu(a->data.non_resident.allocated_size);	/*	 * We are done with the mft record, so we release it.  Otherwise	 * we would deadlock in ntfs_attr_iget().	 */	ntfs_attr_put_search_ctx(ctx);	unmap_mft_record(base_ni);	m = NULL;	ctx = NULL;	/* Get the index bitmap attribute inode. */	bvi = ntfs_attr_iget(base_vi, AT_BITMAP, ni->name, ni->name_len);	if (IS_ERR(bvi)) {		ntfs_error(vi->i_sb, "Failed to get bitmap attribute.");		err = PTR_ERR(bvi);		goto unm_err_out;	}	bni = NTFS_I(bvi);	if (NInoCompressed(bni) || NInoEncrypted(bni) ||			NInoSparse(bni)) {		ntfs_error(vi->i_sb, "$BITMAP attribute is compressed and/or "				"encrypted and/or sparse.");		goto iput_unm_err_out;	}	/* Consistency check bitmap size vs. index allocation size. */	bvi_size = i_size_read(bvi);	if ((bvi_size << 3) < (vi->i_size >> ni->itype.index.block_size_bits)) {		ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) for "				"index allocation (0x%llx).", bvi_size << 3,				vi->i_size);		goto iput_unm_err_out;	}	ni->itype.index.bmp_ino = bvi;skip_large_index_stuff:	/* Setup the operations for this index inode. */	vi->i_op = NULL;	vi->i_fop = NULL;	vi->i_mapping->a_ops = &ntfs_mst_aops;	vi->i_blocks = ni->allocated_size >> 9;	/*	 * Make sure the base inode doesn't go away and attach it to the	 * index inode.	 */	igrab(base_vi);	ni->ext.base_ntfs_ino = base_ni;	ni->nr_extents = -1;	ntfs_debug("Done.");	return 0;iput_unm_err_out:	iput(bvi);unm_err_out:	if (!err)		err = -EIO;	if (ctx)		ntfs_attr_put_search_ctx(ctx);	if (m)		unmap_mft_record(base_ni);err_out:	ntfs_error(vi->i_sb, "Failed with error code %i while reading index "			"inode (mft_no 0x%lx, name_len %i.", err, vi->i_ino,			ni->name_len);	make_bad_inode(vi);	if (err != -EOPNOTSUPP && err != -ENOMEM)		NVolSetErrors(vol);	return err;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/67bb103725e4cde322cb4ddb160a12933c5c7072/inode.c/buggy/fs/ntfs/inode.c