示例#1
0
/*
 * Remove a volume.
 */
int
hammer_ioc_volume_del(hammer_transaction_t trans, hammer_inode_t ip,
		struct hammer_ioc_volume *ioc)
{
	struct hammer_mount *hmp = trans->hmp;
	struct mount *mp = hmp->mp;
	struct hammer_volume_ondisk *ondisk;
	struct bigblock_stat stat;
	hammer_volume_t volume;
	int vol_no;
	int error = 0;

	if (mp->mnt_flag & MNT_RDONLY) {
		hmkprintf(hmp, "Cannot del volume from read-only HAMMER filesystem\n");
		return (EINVAL);
	}

	if (hammer_lock_ex_try(&hmp->volume_lock) != 0) {
		hmkprintf(hmp, "Another volume operation is in progress!\n");
		return (EAGAIN);
	}

	/*
	 * find volume by volname
	 */
	volume = NULL;
	HAMMER_VOLUME_NUMBER_FOREACH(hmp, vol_no) {
		volume = hammer_get_volume(hmp, vol_no, &error);
		KKASSERT(volume != NULL && error == 0);
		if (strcmp(volume->vol_name, ioc->device_name) == 0) {
			break;
		}
		hammer_rel_volume(volume, 0);
		volume = NULL;
	}
示例#2
0
int
hammer_ioc_volume_add(hammer_transaction_t trans, hammer_inode_t ip,
		struct hammer_ioc_volume *ioc)
{
	hammer_mount_t hmp = trans->hmp;
	struct mount *mp = hmp->mp;
	struct hammer_volume_ondisk ondisk;
	hammer_volume_t volume;
	int64_t total_bigblocks, empty_bigblocks;
	int free_vol_no = 0;
	int error;

	if (mp->mnt_flag & MNT_RDONLY) {
		hmkprintf(hmp, "Cannot add volume to read-only HAMMER filesystem\n");
		return (EINVAL);
	}

	if (hammer_lock_ex_try(&hmp->volume_lock) != 0) {
		hmkprintf(hmp, "Another volume operation is in progress!\n");
		return (EAGAIN);
	}

	if (hmp->nvolumes >= HAMMER_MAX_VOLUMES) {
		hammer_unlock(&hmp->volume_lock);
		hmkprintf(hmp, "Max number of HAMMER volumes exceeded\n");
		return (EINVAL);
	}

	/*
	 * Find an unused volume number.
	 */
	while (free_vol_no < HAMMER_MAX_VOLUMES &&
		hammer_volume_number_test(hmp, free_vol_no)) {
		++free_vol_no;
	}
	if (free_vol_no >= HAMMER_MAX_VOLUMES) {
		hmkprintf(hmp, "Max number of HAMMER volumes exceeded\n");
		error = EINVAL;
		goto end;
	}

	error = hammer_format_volume_header(hmp, ioc, &ondisk, free_vol_no);
	if (error)
		goto end;

	error = hammer_install_volume(hmp, ioc->device_name, NULL, &ondisk);
	if (error)
		goto end;

	hammer_sync_lock_sh(trans);
	hammer_lock_ex(&hmp->blkmap_lock);

	volume = hammer_get_volume(hmp, free_vol_no, &error);
	KKASSERT(volume != NULL && error == 0);

	error =	hammer_format_freemap(trans, volume);
	KKASSERT(error == 0);

	error = hammer_count_bigblocks(hmp, volume,
			&total_bigblocks, &empty_bigblocks);
	KKASSERT(error == 0);
	KKASSERT(total_bigblocks == empty_bigblocks);

	hammer_rel_volume(volume, 0);

	++hmp->nvolumes;
	error = hammer_update_volumes_header(trans,
			total_bigblocks, empty_bigblocks);
	KKASSERT(error == 0);

	hammer_unlock(&hmp->blkmap_lock);
	hammer_sync_unlock(trans);

	KKASSERT(error == 0);
end:
	hammer_unlock(&hmp->volume_lock);
	if (error)
		hmkprintf(hmp, "An error occurred: %d\n", error);
	return (error);
}
示例#3
0
/*
 * HAMMER version 4+ conversion support.
 *
 * Convert a HAMMER version < 4 UNDO FIFO area to a 4+ UNDO FIFO area.
 * The 4+ UNDO FIFO area is backwards compatible.  The conversion is
 * needed to initialize the sequence space and place headers on the
 * new 512-byte undo boundary.
 */
int
hammer_upgrade_undo_4(hammer_transaction_t trans)
{
	hammer_mount_t hmp;
	hammer_volume_t root_volume;
	hammer_blockmap_t undomap;
	hammer_buffer_t buffer = NULL;
	hammer_fifo_head_t head;
	hammer_fifo_tail_t tail;
	hammer_off_t next_offset;
	uint32_t seqno;
	int error;
	int bytes;

	hmp = trans->hmp;

	root_volume = trans->rootvol;

	/* no undo recursion */
	hammer_lock_ex(&hmp->undo_lock);
	hammer_modify_volume_noundo(NULL, root_volume);

	/*
	 * Adjust the in-core undomap and the on-disk undomap.
	 */
	next_offset = HAMMER_ENCODE_UNDO(0);
	undomap = &hmp->blockmap[HAMMER_ZONE_UNDO_INDEX];
	undomap->next_offset = next_offset;
	undomap->first_offset = next_offset;

	undomap = &root_volume->ondisk->vol0_blockmap[HAMMER_ZONE_UNDO_INDEX];
	undomap->next_offset = next_offset;
	undomap->first_offset = next_offset;

	/*
	 * Loop over the entire UNDO space creating DUMMY entries.  Sequence
	 * numbers are assigned.
	 */
	seqno = 0;
	bytes = HAMMER_UNDO_ALIGN;

	while (next_offset != undomap->alloc_offset) {
		head = hammer_bnew(hmp, next_offset, &error, &buffer);
		if (error)
			break;
		hammer_modify_buffer_noundo(NULL, buffer);
		tail = (void *)((char *)head + bytes - sizeof(*tail));

		head->hdr_signature = HAMMER_HEAD_SIGNATURE;
		head->hdr_type = HAMMER_HEAD_TYPE_DUMMY;
		head->hdr_size = bytes;
		head->hdr_seq = seqno;
		head->hdr_crc = 0;

		tail = (void *)((char *)head + bytes - sizeof(*tail));
		tail->tail_signature = HAMMER_TAIL_SIGNATURE;
		tail->tail_type = HAMMER_HEAD_TYPE_DUMMY;
		tail->tail_size = bytes;

		hammer_crc_set_fifo_head(head, bytes);
		hammer_modify_buffer_done(buffer);

		hammer_stats_undo += bytes;
		next_offset += HAMMER_UNDO_ALIGN;
		++seqno;
	}

	/*
	 * The sequence number will be the next sequence number to lay down.
	 */
	hmp->undo_seqno = seqno;
	hmkprintf(hmp, "version upgrade seqno start %08x\n", seqno);

	hammer_modify_volume_done(root_volume);
	hammer_unlock(&hmp->undo_lock);

	if (buffer)
		hammer_rel_buffer(buffer, 0);
	return (error);
}