Esempio n. 1
0
errcode_t ocfs2_malloc_blocks(io_channel *channel, int num_blocks,
			      void *ptr)
{
	errcode_t ret;
	int blksize;
	size_t bytes;
	void **pp = (void **)ptr;
	void *tmp;

	blksize = io_get_blksize(channel);
	if (((unsigned long long)num_blocks * blksize) > SIZE_MAX)
		return OCFS2_ET_NO_MEMORY;
	bytes = (unsigned long long)num_blocks * blksize;

	/*
	 * Older glibcs abort when they can't memalign() something.
	 * Ugh!  Check with malloc() first.
	 */
	tmp = malloc(bytes);
	if (!tmp)
		return OCFS2_ET_NO_MEMORY;
	free(tmp);

	ret = posix_memalign(pp, blksize, bytes);
	if (!ret)
		return 0;
	if (errno == ENOMEM)
		return OCFS2_ET_NO_MEMORY;
	/* blksize better be valid */
	abort();
}
Esempio n. 2
0
void o2fsck_print_resource_track(char *pass, o2fsck_state *ost,
                                 struct o2fsck_resource_track *rt,
                                 io_channel *channel)
{
    struct ocfs2_io_stats *rtio = &rt->rt_io_stats;
    uint64_t total_io, cache_read;
    float rtime_s, utime_s, stime_s, walltime;
    uint32_t rtime_m, utime_m, stime_m;

    if (!ost->ost_show_stats)
        return ;

    if (pass && !ost->ost_show_extended_stats)
        return;

#define split_time(_t, _m, _s)			\
	do {					\
		(_s) = timeval_in_secs(&_t);	\
		(_m) = (_s) / 60;		\
		(_s) -= ((_m) * 60);		\
	} while (0);

    split_time(rt->rt_real_time, rtime_m, rtime_s);
    split_time(rt->rt_user_time, utime_m, utime_s);
    split_time(rt->rt_sys_time, stime_m, stime_s);

    walltime = timeval_in_secs(&rt->rt_real_time) -
               timeval_in_secs(&rt->rt_user_time);

    /* TODO: Investigate why user time is sometimes > wall time*/
    if (walltime < 0)
        walltime = 0;

    cache_read = (uint64_t)rtio->is_cache_hits * io_get_blksize(channel);
    total_io = rtio->is_bytes_read + rtio->is_bytes_written;

    if (!pass)
        printf("  Cache size: %luMB\n",
               mbytes(io_get_cache_size(channel)));

    printf("  I/O read disk/cache: %"PRIu64"MB / %"PRIu64"MB, "
           "write: %"PRIu64"MB, rate: %.2fMB/s\n",
           mbytes(rtio->is_bytes_read),
           mbytes(cache_read), mbytes(rtio->is_bytes_written),
           (double)(mbytes(total_io) / walltime));

    printf("  Times real: %dm%.3fs, user: %dm%.3fs, sys: %dm%.3fs\n",
           rtime_m, rtime_s, utime_m, utime_s, stime_m, stime_s);
}
Esempio n. 3
0
File: memory.c Progetto: colyli/cmfs
errcode_t cmfs_malloc_blocks(io_channel *channel,
			     int num_blocks,
			     void *ptr)
{
	errcode_t ret;
	int blksize;
	size_t bytes;
	void **pp = (void **)ptr;

	blksize = io_get_blksize(channel);
	if (((unsigned long long)num_blocks * blksize) > SIZE_MAX)
		return CMFS_ET_NO_MEMORY;

	bytes = num_blocks * blksize;
	ret = posix_memalign(pp, blksize, bytes); 
	if (!ret)
		return 0;
	if (errno == ENOMEM)
		return CMFS_ET_NO_MEMORY;
	abort();
}
Esempio n. 4
0
static errcode_t io_validate_o_direct(io_channel *channel)
{
	errcode_t ret = OCFS2_ET_UNEXPECTED_BLOCK_SIZE;
	int block_size;
	char *blk;

	for (block_size = io_get_blksize(channel);
	     block_size <= OCFS2_MAX_BLOCKSIZE;
	     block_size <<= 1) {
		io_set_blksize(channel, block_size);
		ret = ocfs2_malloc_block(channel, &blk);
		if (ret)
			break;

		ret = unix_io_read_block(channel, 0, 1, blk);
		ocfs2_free(&blk);
		if (!ret)
			break;
	}

	return ret;
}
Esempio n. 5
0
errcode_t ocfs2_open(const char *name, int flags,
		     unsigned int superblock, unsigned int block_size,
		     ocfs2_filesys **ret_fs)
{
	ocfs2_filesys *fs;
	errcode_t ret;
	int i, len;
	char *ptr;
	unsigned char *raw_uuid;

	ret = ocfs2_malloc0(sizeof(ocfs2_filesys), &fs);
	if (ret)
		return ret;

	fs->fs_flags = flags;
	fs->fs_umask = 022;

	ret = io_open(name, (flags & (OCFS2_FLAG_RO | OCFS2_FLAG_RW |
				      OCFS2_FLAG_BUFFERED)),
		      &fs->fs_io);
	if (ret)
		goto out;

	ret = ocfs2_malloc(strlen(name)+1, &fs->fs_devname);
	if (ret)
		goto out;
	strcpy(fs->fs_devname, name);

	/*
	 * If OCFS2_FLAG_IMAGE_FILE is specified, it needs to be handled
	 * differently
	 */
	if (flags & OCFS2_FLAG_IMAGE_FILE) {
		ret = ocfs2_image_load_bitmap(fs);
		if (ret)
			goto out;
		if (!superblock)
			superblock = fs->ost->ost_superblocks[0];
		if (!block_size)
			block_size = fs->ost->ost_fsblksz;
	}

	/* image file is not a device */
	if (!(flags & OCFS2_FLAG_IMAGE_FILE)) {
		if (io_is_device_readonly(fs->fs_io))
			fs->fs_flags |= OCFS2_FLAG_HARD_RO;
	}

	/*
	 * If OCFS2_FLAG_NO_REV_CHECK is specified, fsck (or someone
	 * like it) is asking to ignore the OCFS vol_header at
	 * block 0.
	 */
	if (!(flags & OCFS2_FLAG_NO_REV_CHECK)) {
		ret = ocfs2_validate_ocfs1_header(fs);
		if (ret)
			goto out;
	}

	if (superblock) {
		ret = OCFS2_ET_INVALID_ARGUMENT;
		if (!block_size)
			goto out;
		io_set_blksize(fs->fs_io, block_size);
		ret = ocfs2_read_super(fs, (uint64_t)superblock, NULL);
	} else {
		superblock = OCFS2_SUPER_BLOCK_BLKNO;
		if (block_size) {
			io_set_blksize(fs->fs_io, block_size);
			ret = ocfs2_read_super(fs, (uint64_t)superblock, NULL);
		} else {
			for (block_size = io_get_blksize(fs->fs_io);
			     block_size <= OCFS2_MAX_BLOCKSIZE;
			     block_size <<= 1) {
				io_set_blksize(fs->fs_io, block_size);
				ret = ocfs2_read_super(fs, (uint64_t)superblock,
						       NULL);
				if ((ret == OCFS2_ET_BAD_MAGIC) ||
				    (ret == OCFS2_ET_IO))
					continue;
				break;
			}
		}
	}
	if (ret)
		goto out;

	fs->fs_blocksize = block_size;
	if (superblock == OCFS2_SUPER_BLOCK_BLKNO) {
		ret = ocfs2_malloc_block(fs->fs_io, &fs->fs_orig_super);
		if (ret)
			goto out;
		memcpy((char *)fs->fs_orig_super,
		       (char *)fs->fs_super, fs->fs_blocksize);
	}

#if 0
	ret = OCFS2_ET_REV_TOO_HIGH;
	if (fs->fs_super->id2.i_super.s_major_rev_level >
	    OCFS2_LIB_CURRENT_REV)
		goto out;
#endif

	if (flags & OCFS2_FLAG_STRICT_COMPAT_CHECK) {
		ret = OCFS2_ET_UNSUPP_FEATURE;
		if (OCFS2_RAW_SB(fs->fs_super)->s_feature_compat &
		    ~OCFS2_LIB_FEATURE_COMPAT_SUPP)
			    goto out;

		/* We need to check s_tunefs_flag also to make sure
		 * fsck.ocfs2 won't try to clean up an aborted tunefs
		 * that it doesn't know.
		 */
		if (OCFS2_HAS_INCOMPAT_FEATURE(OCFS2_RAW_SB(fs->fs_super),
					OCFS2_FEATURE_INCOMPAT_TUNEFS_INPROG) &&
		    (OCFS2_RAW_SB(fs->fs_super)->s_tunefs_flag &
		     ~OCFS2_LIB_ABORTED_TUNEFS_SUPP))
			goto out;
	}

	ret = OCFS2_ET_UNSUPP_FEATURE;
	if (OCFS2_RAW_SB(fs->fs_super)->s_feature_incompat &
	    ~OCFS2_LIB_FEATURE_INCOMPAT_SUPP)
		goto out;

	ret = OCFS2_ET_RO_UNSUPP_FEATURE;
	if ((flags & OCFS2_FLAG_RW) &&
	    (OCFS2_RAW_SB(fs->fs_super)->s_feature_ro_compat &
	     ~OCFS2_LIB_FEATURE_RO_COMPAT_SUPP))
		goto out;

	ret = OCFS2_ET_UNSUPP_FEATURE;
	if (!(flags & OCFS2_FLAG_HEARTBEAT_DEV_OK) &&
	    (OCFS2_RAW_SB(fs->fs_super)->s_feature_incompat &
	     OCFS2_FEATURE_INCOMPAT_HEARTBEAT_DEV))
		goto out;

	ret = OCFS2_ET_CORRUPT_SUPERBLOCK;
	if (!OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits)
		goto out;
	if (fs->fs_super->i_blkno != superblock)
		goto out;
	if ((OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits < 12) ||
	    (OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits > 20))
		goto out;
	if (!OCFS2_RAW_SB(fs->fs_super)->s_root_blkno ||
	    !OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno)
		goto out;
	if (OCFS2_RAW_SB(fs->fs_super)->s_max_slots > OCFS2_MAX_SLOTS)
		goto out;

	ret = ocfs2_malloc0(OCFS2_RAW_SB(fs->fs_super)->s_max_slots *
			    sizeof(ocfs2_cached_inode *), 
			    &fs->fs_inode_allocs);
	if (ret)
		goto out;

	ret = ocfs2_malloc0(OCFS2_RAW_SB(fs->fs_super)->s_max_slots *
			    sizeof(ocfs2_cached_inode *), 
			    &fs->fs_eb_allocs);
	if (ret)
		goto out;

	ret = OCFS2_ET_UNEXPECTED_BLOCK_SIZE;
	if (block_size !=
	    (1U << OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits))
		goto out;

	fs->fs_clustersize =
		1 << OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;

	/* FIXME: Read the system dir */
	
	fs->fs_root_blkno =
		OCFS2_RAW_SB(fs->fs_super)->s_root_blkno;
	fs->fs_sysdir_blkno =
		OCFS2_RAW_SB(fs->fs_super)->s_system_dir_blkno;

	fs->fs_clusters = fs->fs_super->i_clusters;
	fs->fs_blocks = ocfs2_clusters_to_blocks(fs, fs->fs_clusters);
	fs->fs_first_cg_blkno = 
		OCFS2_RAW_SB(fs->fs_super)->s_first_cluster_group;

	raw_uuid = OCFS2_RAW_SB(fs->fs_super)->s_uuid;
	for (i = 0, ptr = fs->uuid_str; i < OCFS2_VOL_UUID_LEN; i++) {
		/* print with null */
		len = snprintf(ptr, 3, "%02X", raw_uuid[i]);
		if (len != 2) {
			ret = OCFS2_ET_INTERNAL_FAILURE;
			goto out;
		}
		/* then only advace past the last char */
		ptr += 2;
	}

	*ret_fs = fs;
	return 0;

out:
	if (fs->fs_inode_allocs)
		ocfs2_free(&fs->fs_inode_allocs);

	ocfs2_freefs(fs);

	return ret;
}
Esempio n. 6
0
errcode_t ocfs2_read_super(ocfs2_filesys *fs, uint64_t superblock, char *sb)
{
	errcode_t ret;
	char *blk, *swapblk;
	struct ocfs2_dinode *di, *orig_super;
	int orig_blocksize;
	int blocksize = io_get_blksize(fs->fs_io);

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

	ret = ocfs2_read_blocks(fs, superblock, 1, blk);
	if (ret)
		goto out_blk;

	di = (struct ocfs2_dinode *)blk;

	ret = OCFS2_ET_BAD_MAGIC;
	if (memcmp(di->i_signature, OCFS2_SUPER_BLOCK_SIGNATURE,
		   strlen(OCFS2_SUPER_BLOCK_SIGNATURE)))
		goto out_blk;

	/*
	 * We want to use the latest superblock to validate.  We need
	 * a local-endian copy in fs->fs_super, and the unswapped copy to
	 * check in blk.  ocfs2_validate_meta_ecc() uses fs->fs_super and
	 * fs->fs_blocksize.
	 */
	ret = ocfs2_malloc_block(fs->fs_io, &swapblk);
	if (ret)
		goto out_blk;

	memcpy(swapblk, blk, blocksize);
	orig_super = fs->fs_super;
	orig_blocksize = fs->fs_blocksize;
	fs->fs_super = (struct ocfs2_dinode *)swapblk;
	fs->fs_blocksize = blocksize;
	ocfs2_swap_inode_to_cpu(fs, fs->fs_super);

	ret = ocfs2_validate_meta_ecc(fs, blk, &di->i_check);

	fs->fs_super = orig_super;
	fs->fs_blocksize = orig_blocksize;
	ocfs2_free(&swapblk);

	if (ret)
		goto out_blk;

	ocfs2_swap_inode_to_cpu(fs, di);
	if (!sb)
		fs->fs_super = di;
	else {
		memcpy(sb, blk, fs->fs_blocksize);
		ocfs2_free(&blk);
	}

	return 0;

out_blk:
	ocfs2_free(&blk);

	return ret;
}
Esempio n. 7
0
/*
 * allocate ocfs2_image_bitmap_arr and ocfs2 image bitmap blocks. o2image bitmap
 * block is of size OCFS2_IMAGE_BITMAP_BLOCKSIZE and ocfs2_image_bitmap_arr
 * tracks the bitmap blocks
 */
errcode_t ocfs2_image_alloc_bitmap(ocfs2_filesys *ofs)
{
	uint64_t blks, allocsize, leftsize;
	struct ocfs2_image_state *ost = ofs->ost;
	int indx, i, n;
	errcode_t ret;
	char *buf;

	ost->ost_bmpblks =
		((ost->ost_fsblkcnt - 1) / (OCFS2_IMAGE_BITS_IN_BLOCK)) + 1;
	ost->ost_bmpblksz = OCFS2_IMAGE_BITMAP_BLOCKSIZE;
	blks = ost->ost_bmpblks;

	/* allocate memory for an array to track bitmap blocks */
	ret = ocfs2_malloc0((blks * sizeof(ocfs2_image_bitmap_arr)),
			    &ost->ost_bmparr);
	if (ret)
		return ret;

	allocsize = blks * OCFS2_IMAGE_BITMAP_BLOCKSIZE;
	leftsize = allocsize;
	indx = 0;

	/* allocate bitmap blocks and assign blocks to above array */
	while (leftsize) {
		ret = ocfs2_malloc_blocks(ofs->fs_io,
					  allocsize/io_get_blksize(ofs->fs_io),
					  &buf);
		if (ret && (ret != -ENOMEM))
			goto out;

		if (ret == -ENOMEM) {
			if (allocsize == OCFS2_IMAGE_BITMAP_BLOCKSIZE)
				goto out;
			allocsize >>= 1;
			if (allocsize % OCFS2_IMAGE_BITMAP_BLOCKSIZE) {
				allocsize /= OCFS2_IMAGE_BITMAP_BLOCKSIZE;
				allocsize *= OCFS2_IMAGE_BITMAP_BLOCKSIZE;
			}
			continue;
		}

		n = allocsize / OCFS2_IMAGE_BITMAP_BLOCKSIZE;
		for (i = 0; i < n; i++) {
			ost->ost_bmparr[indx].arr_set_bit_cnt = 0;
			ost->ost_bmparr[indx].arr_map =
				((char *)buf + (i *
						OCFS2_IMAGE_BITMAP_BLOCKSIZE));

			/* remember buf address to free it later */
			if (!i)
				ost->ost_bmparr[indx].arr_self = buf;
			indx++;
		}
		leftsize -= allocsize;
		if (leftsize <= allocsize)
			allocsize = leftsize;
	}
out:
	/* If allocation failed free and return error */
	if (leftsize) {
		for (i = 0; i < indx; i++)
			if (ost->ost_bmparr[i].arr_self)
				ocfs2_free(&ost->ost_bmparr[i].arr_self);
		ocfs2_free(&ost->ost_bmparr);
	}

	return ret;
}