Exemple #1
0
/*
 * More or less lifted from ext3. I'll leave their description below:
 *
 * "For ext3 allocations, we must not reuse any blocks which are
 * allocated in the bitmap buffer's "last committed data" copy.  This
 * prevents deletes from freeing up the page for reuse until we have
 * committed the delete transaction.
 *
 * If we didn't do this, then deleting something and reallocating it as
 * data would allow the old block to be overwritten before the
 * transaction committed (because we force data to disk before commit).
 * This would lead to corruption if we crashed between overwriting the
 * data and committing the delete.
 *
 * @@@ We may want to make this allocation behaviour conditional on
 * data-writes at some point, and disable it for metadata allocations or
 * sync-data inodes."
 *
 * Note: OCFS2 already does this differently for metadata vs data
 * allocations, as those bitmaps are seperate and undo access is never
 * called on a metadata group descriptor.
 */
static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
					 int nr)
{
	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;

	if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap))
		return 0;
	if (!buffer_jbd(bg_bh) || !bh2jh(bg_bh)->b_committed_data)
		return 1;

	bg = (struct ocfs2_group_desc *) bh2jh(bg_bh)->b_committed_data;
	return !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap);
}
static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh,
				    int *goal_bit, u32 move_len, u32 max_hop,
				    u32 *phys_cpos)
{
	int i, used, last_free_bits = 0, base_bit = *goal_bit;
	struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
	u32 base_cpos = ocfs2_blocks_to_clusters(inode->i_sb,
						 le64_to_cpu(gd->bg_blkno));

	for (i = base_bit; i < le16_to_cpu(gd->bg_bits); i++) {

		used = ocfs2_test_bit(i, (unsigned long *)gd->bg_bitmap);
		if (used) {
			if ((i - base_bit) > max_hop) {
				*phys_cpos = 0;
				break;
			}

			if (last_free_bits)
				last_free_bits = 0;

			continue;
		} else
			last_free_bits++;

		if (last_free_bits == move_len) {
			*goal_bit = i;
			*phys_cpos = base_cpos + i;
			break;
		}
	}

	mlog(0, "found phys_cpos: %u to fit the wanted moving.\n", *phys_cpos);
}
Exemple #3
0
/*
 * Like ocfs2_hamming_encode(), this can handle hunks.  nr is the bit
 * offset of the current hunk.  If bit to be fixed is not part of the
 * current hunk, this does nothing.
 *
 * If you only have one hunk, use ocfs2_hamming_fix_block().
 */
void ocfs2_hamming_fix(void *data, unsigned int d, unsigned int nr,
		       unsigned int fix)
{
	unsigned int i, b;

	BUG_ON(!d);

	/*
	 * If the bit to fix has an hweight of 1, it's a parity bit.  One
	 * busted parity bit is its own error.  Nothing to do here.
	 */
	if (hweight32(fix) == 1)
		return;

	/*
	 * nr + d is the bit right past the data hunk we're looking at.
	 * If fix after that, nothing to do
	 */
	if (fix >= calc_code_bit(nr + d, NULL))
		return;

	/*
	 * nr is the offset in the data hunk we're starting at.  Let's
	 * start b at the offset in the code buffer.  See hamming_encode()
	 * for a more detailed description of 'b'.
	 */
	b = calc_code_bit(nr, NULL);
	/* If the fix is before this hunk, nothing to do */
	if (fix < b)
		return;

	for (i = 0; i < d; i++, b++)
	{
		/* Skip past parity bits */
		while (hweight32(b) == 1)
			b++;

		/*
		 * i is the offset in this data hunk.
		 * nr + i is the offset in the total data buffer.
		 * b is the offset in the total code buffer.
		 *
		 * Thus, when b == fix, bit i in the current hunk needs
		 * fixing.
		 */
		if (b == fix)
		{
			if (ocfs2_test_bit(i, data))
				ocfs2_clear_bit(i, data);
			else
				ocfs2_set_bit(i, data);
			break;
		}
	}
}
Exemple #4
0
/*
 * More or less lifted from ext3. I'll leave their description below:
 *
 * "For ext3 allocations, we must not reuse any blocks which are
 * allocated in the bitmap buffer's "last committed data" copy.  This
 * prevents deletes from freeing up the page for reuse until we have
 * committed the delete transaction.
 *
 * If we didn't do this, then deleting something and reallocating it as
 * data would allow the old block to be overwritten before the
 * transaction committed (because we force data to disk before commit).
 * This would lead to corruption if we crashed between overwriting the
 * data and committing the delete.
 *
 * @@@ We may want to make this allocation behaviour conditional on
 * data-writes at some point, and disable it for metadata allocations or
 * sync-data inodes."
 *
 * Note: OCFS2 already does this differently for metadata vs data
 * allocations, as those bitmaps are separate and undo access is never
 * called on a metadata group descriptor.
 */
static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
					 int nr)
{
	struct ocfs2_group_desc *bg = (struct ocfs2_group_desc *) bg_bh->b_data;
	int ret;

	if (ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap))
		return 0;

	if (!buffer_jbd(bg_bh))
		return 1;

	jbd_lock_bh_state(bg_bh);
	bg = (struct ocfs2_group_desc *) bh2jh(bg_bh)->b_committed_data;
	if (bg)
		ret = !ocfs2_test_bit(nr, (unsigned long *)bg->bg_bitmap);
	else
		ret = 1;
	jbd_unlock_bh_state(bg_bh);

	return ret;
}
Exemple #5
0
uint64_t ocfs2_image_get_blockno(ocfs2_filesys *ofs, uint64_t blkno)
{
	struct ocfs2_image_state *ost = ofs->ost;
	uint64_t ret_blk;
	int bitmap_blk;
	int i, bit;

	bit = blkno % OCFS2_IMAGE_BITS_IN_BLOCK;
	bitmap_blk = blkno / OCFS2_IMAGE_BITS_IN_BLOCK;

	if (ocfs2_test_bit(bit, ost->ost_bmparr[bitmap_blk].arr_map)) {
		ret_blk = ost->ost_bmparr[bitmap_blk].arr_set_bit_cnt + 1;

		/* add bits set in this block before the block no */
		for (i = 0; i < bit; i++)
			if (ocfs2_test_bit(i,
					   ost->ost_bmparr[bitmap_blk].arr_map))
				ret_blk++;
	} else
		ret_blk = -1;

	return ret_blk;
}
Exemple #6
0
int ocfs2_image_test_bit(ocfs2_filesys *ofs, uint64_t blkno)
{
	struct ocfs2_image_state *ost = ofs->ost;
	int bitmap_blk;
	int bit;

	bit = blkno % OCFS2_IMAGE_BITS_IN_BLOCK;
	bitmap_blk = blkno / OCFS2_IMAGE_BITS_IN_BLOCK;

	if (ocfs2_test_bit(bit, ost->ost_bmparr[bitmap_blk].arr_map))
		return 1;
	else
		return 0;
}
Exemple #7
0
/* turn this on and uncomment below to aid debugging window shifts. */
static void ocfs2_verify_zero_bits(unsigned long *bitmap,
				   unsigned int start,
				   unsigned int count)
{
	unsigned int tmp = count;
	while(tmp--) {
		if (ocfs2_test_bit(start + tmp, bitmap)) {
			printk("ocfs2_verify_zero_bits: start = %u, count = "
			       "%u\n", start, count);
			printk("ocfs2_verify_zero_bits: bit %u is set!",
			       start + tmp);
			BUG();
		}
	}
}
Exemple #8
0
static int ocfs2_info_freefrag_scan_chain(struct ocfs2_super *osb,
					  struct inode *gb_inode,
					  struct ocfs2_dinode *gb_dinode,
					  struct ocfs2_chain_rec *rec,
					  struct ocfs2_info_freefrag *ffg,
					  u32 chunks_in_group)
{
	int status = 0, used;
	u64 blkno;

	struct buffer_head *bh = NULL;
	struct ocfs2_group_desc *bg = NULL;

	unsigned int max_bits, num_clusters;
	unsigned int offset = 0, cluster, chunk;
	unsigned int chunk_free, last_chunksize = 0;

	if (!le32_to_cpu(rec->c_free))
		goto bail;

	do {
		if (!bg)
			blkno = le64_to_cpu(rec->c_blkno);
		else
			blkno = le64_to_cpu(bg->bg_next_group);

		if (bh) {
			brelse(bh);
			bh = NULL;
		}

		if (o2info_coherent(&ffg->iff_req))
			status = ocfs2_read_group_descriptor(gb_inode,
							     gb_dinode,
							     blkno, &bh);
		else
			status = ocfs2_read_blocks_sync(osb, blkno, 1, &bh);

		if (status < 0) {
			mlog(ML_ERROR, "Can't read the group descriptor # "
			     "%llu from device.", (unsigned long long)blkno);
			status = -EIO;
			goto bail;
		}

		bg = (struct ocfs2_group_desc *)bh->b_data;

		if (!le16_to_cpu(bg->bg_free_bits_count))
			continue;

		max_bits = le16_to_cpu(bg->bg_bits);
		offset = 0;

		for (chunk = 0; chunk < chunks_in_group; chunk++) {
			/*
			 * last chunk may be not an entire one.
			 */
			if ((offset + ffg->iff_chunksize) > max_bits)
				num_clusters = max_bits - offset;
			else
				num_clusters = ffg->iff_chunksize;

			chunk_free = 0;
			for (cluster = 0; cluster < num_clusters; cluster++) {
				used = ocfs2_test_bit(offset,
						(unsigned long *)bg->bg_bitmap);
				/*
				 * - chunk_free counts free clusters in #N chunk.
				 * - last_chunksize records the size(in) clusters
				 *   for the last real free chunk being counted.
				 */
				if (!used) {
					last_chunksize++;
					chunk_free++;
				}

				if (used && last_chunksize) {
					ocfs2_info_update_ffg(ffg,
							      last_chunksize);
					last_chunksize = 0;
				}

				offset++;
			}

			if (chunk_free == ffg->iff_chunksize)
				ffg->iff_ffs.ffs_free_chunks++;
		}

		/*
		 * need to update the info for last free chunk.
		 */
		if (last_chunksize)
			ocfs2_info_update_ffg(ffg, last_chunksize);

	} while (le64_to_cpu(bg->bg_next_group));

bail:
	brelse(bh);

	return status;
}
Exemple #9
0
/*
 * This routine loads bitmap blocks from an o2image image file into memory.
 * This process happens during file open. bitmap blocks reside towards
 * the end of the imagefile.
 */
errcode_t ocfs2_image_load_bitmap(ocfs2_filesys *ofs)
{
	struct ocfs2_image_state *ost;
	struct ocfs2_image_hdr *hdr;
	uint64_t blk_off, bits_set;
	int i, j, fd;
	ssize_t count;
	errcode_t ret;
	char *blk;

	ret = ocfs2_malloc0(sizeof(struct ocfs2_image_state), &ofs->ost);
	if (ret)
		return ret;

	ost = ofs->ost;
	ret = ocfs2_malloc_block(ofs->fs_io, &blk);
	if (ret)
		return ret;

	/* read ocfs2 image header */
	ret = io_read_block(ofs->fs_io, 0, 1, blk);
	if (ret)
		goto out;

	hdr = (struct ocfs2_image_hdr *)blk;
	ocfs2_image_swap_header(hdr);

	ret = OCFS2_ET_BAD_MAGIC;
	if (hdr->hdr_magic != OCFS2_IMAGE_MAGIC)
		goto out;

	if (memcmp(hdr->hdr_magic_desc, OCFS2_IMAGE_DESC,
		   sizeof(OCFS2_IMAGE_DESC)))
		goto out;

	ret = OCFS2_ET_OCFS_REV;
	if (hdr->hdr_version > OCFS2_IMAGE_VERSION)
		goto out;

	ost->ost_fsblkcnt 	= hdr->hdr_fsblkcnt;
	ost->ost_fsblksz 	= hdr->hdr_fsblksz;
	ost->ost_imgblkcnt 	= hdr->hdr_imgblkcnt;
	ost->ost_bmpblksz 	= hdr->hdr_bmpblksz;

	ret = ocfs2_image_alloc_bitmap(ofs);
	if (ret)
		return ret;

	/* load bitmap blocks ocfs2 image state */
	bits_set = 0;
	fd 	= io_get_fd(ofs->fs_io);
	blk_off = (ost->ost_imgblkcnt + 1) * ost->ost_fsblksz;

	for (i = 0; i < ost->ost_bmpblks; i++) {
		ost->ost_bmparr[i].arr_set_bit_cnt = bits_set;
		/*
		 * we don't use io_read_block as ocfs2 image bitmap block size
		 * could be different from filesystem block size
		 */
		count = pread64(fd, ost->ost_bmparr[i].arr_map,
				ost->ost_bmpblksz, blk_off);
		if (count < 0) {
			ret = OCFS2_ET_IO;
			goto out;
		}

		/* add bits set in this bitmap */
		for (j = 0; j < (ost->ost_bmpblksz * 8); j++)
			if (ocfs2_test_bit(j, ost->ost_bmparr[i].arr_map))
				bits_set++;

		blk_off += ost->ost_bmpblksz;
	}

out:
	if (blk)
		ocfs2_free(&blk);
	return ret;
}