Ejemplo n.º 1
0
/* Fill first wander record (tx head) in accordance with supplied given data */
static void format_tx_head(struct commit_handle *ch)
{
	jnode *tx_head;
	jnode *next;
	struct tx_header *header;

	tx_head = list_entry(ch->tx_list.next, jnode, capture_link);
	assert("zam-692", &ch->tx_list != &tx_head->capture_link);

	next = list_entry(tx_head->capture_link.next, jnode, capture_link);
	if (&ch->tx_list == &next->capture_link)
		next = tx_head;

	header = (struct tx_header *)jdata(tx_head);

	assert("zam-460", header != NULL);
	assert("zam-462", ch->super->s_blocksize >= sizeof(struct tx_header));

	memset(jdata(tx_head), 0, (size_t) ch->super->s_blocksize);
	memcpy(jdata(tx_head), TX_HEADER_MAGIC, TX_HEADER_MAGIC_SIZE);

	put_unaligned(cpu_to_le32(ch->tx_size), &header->total);
	put_unaligned(cpu_to_le64(get_super_private(ch->super)->last_committed_tx),
		      &header->prev_tx);
	put_unaligned(cpu_to_le64(*jnode_get_block(next)), &header->next_block);
	put_unaligned(cpu_to_le64(ch->free_blocks), &header->free_blocks);
	put_unaligned(cpu_to_le64(ch->nr_files), &header->nr_files);
	put_unaligned(cpu_to_le64(ch->next_oid), &header->next_oid);
}
Ejemplo n.º 2
0
/* fill journal footer block data */
static void format_journal_footer(struct commit_handle *ch)
{
	struct reiser4_super_info_data *sbinfo;
	struct journal_footer *footer;
	jnode *tx_head;

	sbinfo = get_super_private(ch->super);

	tx_head = list_entry(ch->tx_list.next, jnode, capture_link);

	assert("zam-493", sbinfo != NULL);
	assert("zam-494", sbinfo->journal_header != NULL);

	check_me("zam-691", jload(sbinfo->journal_footer) == 0);

	footer = (struct journal_footer *)jdata(sbinfo->journal_footer);
	assert("zam-495", footer != NULL);

	put_unaligned(cpu_to_le64(*jnode_get_block(tx_head)),
		      &footer->last_flushed_tx);
	put_unaligned(cpu_to_le64(ch->free_blocks), &footer->free_blocks);

	put_unaligned(cpu_to_le64(ch->nr_files), &footer->nr_files);
	put_unaligned(cpu_to_le64(ch->next_oid), &footer->next_oid);

	jrelse(sbinfo->journal_footer);
}
Ejemplo n.º 3
0
/**
 * reiser4_init_ktxnmgrd - initialize ktxnmgrd context and start kernel daemon
 * @super: pointer to super block
 *
 * Allocates and initializes ktxnmgrd_context, attaches it to transaction
 * manager. Starts kernel txnmgr daemon. This is called on mount.
 */
int reiser4_init_ktxnmgrd(struct super_block *super)
{
	txn_mgr *mgr;
	ktxnmgrd_context *ctx;

	mgr = &get_super_private(super)->tmgr;

	assert("zam-1014", mgr->daemon == NULL);

	ctx = kzalloc(sizeof(ktxnmgrd_context), reiser4_ctx_gfp_mask_get());
	if (!ctx)
		return RETERR(-ENOMEM);

	assert("nikita-2442", ctx != NULL);

	init_waitqueue_head(&ctx->wait);

	/*kcond_init(&ctx->startup);*/
	spin_lock_init(&ctx->guard);
	ctx->timeout = REISER4_TXNMGR_TIMEOUT;
	ctx->rescan = 1;
	mgr->daemon = ctx;

	ctx->tsk = kthread_run(ktxnmgrd, super, "ktxnmgrd");
	if (IS_ERR(ctx->tsk)) {
		int ret = PTR_ERR(ctx->tsk);
		mgr->daemon = NULL;
		kfree(ctx);
		return RETERR(ret);
	}
	return 0;
}
Ejemplo n.º 4
0
/**
 * ktxnmgrd - kernel txnmgr daemon
 * @arg: pointer to super block
 *
 * The background transaction manager daemon, started as a kernel thread during
 * reiser4 initialization.
 */
static int ktxnmgrd(void *arg)
{
	struct super_block *super;
	ktxnmgrd_context *ctx;
	txn_mgr *mgr;
	int done = 0;

	super = arg;
	mgr = &get_super_private(super)->tmgr;

	/*
	 * do_fork() just copies task_struct into the new thread. ->fs_context
	 * shouldn't be copied of course. This shouldn't be a problem for the
	 * rest of the code though.
	 */
	current->journal_info = NULL;
	ctx = mgr->daemon;
	while (1) {
		try_to_freeze();
		set_comm("wait");
		{
			DEFINE_WAIT(__wait);

			prepare_to_wait(&ctx->wait, &__wait,
					TASK_INTERRUPTIBLE);
			if (kthread_should_stop())
				done = 1;
			else
				schedule_timeout(ctx->timeout);
			finish_wait(&ctx->wait, &__wait);
		}
		if (done)
			break;
		set_comm("run");
		spin_lock(&ctx->guard);
		/*
		 * wait timed out or ktxnmgrd was woken up by explicit request
		 * to commit something. Scan list of atoms in txnmgr and look
		 * for too old atoms.
		 */
		do {
			ctx->rescan = 0;
			scan_mgr(super);
			spin_lock(&ctx->guard);
			if (ctx->rescan) {
				/*
				 * the list could be modified while ctx
				 * spinlock was released, we have to repeat
				 * scanning from the beginning
				 */
				break;
			}
		} while (ctx->rescan);
		spin_unlock(&ctx->guard);
	}
	return 0;
}
Ejemplo n.º 5
0
/**
 * reiser4_init_super_d_info - initialize per-super-block d_cursor resources
 * @super: super block to initialize
 *
 * Initializes per-super-block d_cursor's hash table and radix tree. It is part
 * of mount.
 */
int reiser4_init_super_d_info(struct super_block *super)
{
	struct d_cursor_info *p;

	p = &get_super_private(super)->d_info;

	INIT_RADIX_TREE(&p->tree, reiser4_ctx_gfp_mask_get());
	return d_cursor_hash_init(&p->table, D_CURSOR_TABLE_SIZE);
}
Ejemplo n.º 6
0
void reiser4_release_reserved(struct super_block *super)
{
	reiser4_super_info_data *info;

	info = get_super_private(super);
	if (info->delete_mutex_owner == current) {
		info->delete_mutex_owner = NULL;
		mutex_unlock(&info->delete_mutex);
	}
}
Ejemplo n.º 7
0
void fake_allocated2free(__u64 count, reiser4_ba_flags_t flags)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	fake_allocated2grabbed(ctx, sbinfo, count, flags);
	grabbed2free(ctx, sbinfo, count);
}
Ejemplo n.º 8
0
void cluster_reserved2free(int count)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	cluster_reserved2grabbed(count);
	grabbed2free(ctx, sbinfo, count);
}
Ejemplo n.º 9
0
/**
 * reiser4_done_ktxnmgrd - stop kernel thread and frees ktxnmgrd context
 * @mgr:
 *
 * This is called on umount. Stops ktxnmgrd and free t
 */
void reiser4_done_ktxnmgrd(struct super_block *super)
{
	txn_mgr *mgr;

	mgr = &get_super_private(super)->tmgr;
	assert("zam-1012", mgr->daemon != NULL);

	kthread_stop(mgr->daemon->tsk);
	kfree(mgr->daemon);
	mgr->daemon = NULL;
}
Ejemplo n.º 10
0
/**
 * scan_mgr - commit atoms which are to be committed
 * @super: super block to commit atoms of
 *
 * Commits old atoms.
 */
static int scan_mgr(struct super_block *super)
{
	int ret;
	reiser4_context ctx;

	init_stack_context(&ctx, super);

	ret = commit_some_atoms(&get_super_private(super)->tmgr);

	reiser4_exit_context(&ctx);
	return ret;
}
Ejemplo n.º 11
0
/**
 * reiser4_done_super_d_info - release per-super-block d_cursor resources
 * @super: super block being umounted
 *
 * It is called on umount. Kills all directory cursors attached to suoer block.
 */
void reiser4_done_super_d_info(struct super_block *super)
{
	struct d_cursor_info *d_info;
	dir_cursor *cursor, *next;

	d_info = &get_super_private(super)->d_info;
	for_all_in_htable(&d_info->table, d_cursor, cursor, next)
		kill_cursor(cursor);

	BUG_ON(d_info->tree.rnode != NULL);
	d_cursor_hash_done(&d_info->table);
}
Ejemplo n.º 12
0
void grabbed2free_mark(__u64 mark)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	assert("nikita-3007", (__s64) mark >= 0);
	assert("nikita-3006", ctx->grabbed_blocks >= mark);
	grabbed2free(ctx, sbinfo, ctx->grabbed_blocks - mark);
}
Ejemplo n.º 13
0
static reiser4_super_info_data *grabbed2fake_allocated_head(int count)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	ctx = get_current_context();
	sub_from_ctx_grabbed(ctx, count);

	sbinfo = get_super_private(ctx->super);
	spin_lock_reiser4_super(sbinfo);

	sub_from_sb_grabbed(sbinfo, count);
	/* return sbinfo locked */
	return sbinfo;
}
Ejemplo n.º 14
0
static int
reiser4_grab(reiser4_context * ctx, __u64 count, reiser4_ba_flags_t flags)
{
	__u64 free_blocks;
	int ret = 0, use_reserved = flags & BA_RESERVED;
	reiser4_super_info_data *sbinfo;

	assert("vs-1276", ctx == get_current_context());

	/* Do not grab anything on ro-mounted fs. */
	if (rofs_super(ctx->super)) {
		ctx->grab_enabled = 0;
		return 0;
	}

	sbinfo = get_super_private(ctx->super);

	spin_lock_reiser4_super(sbinfo);

	free_blocks = sbinfo->blocks_free;

	if ((use_reserved && free_blocks < count) ||
	    (!use_reserved && free_blocks < count + sbinfo->blocks_reserved)) {
		ret = RETERR(-ENOSPC);
		goto unlock_and_ret;
	}

	add_to_ctx_grabbed(ctx, count);

	sbinfo->blocks_grabbed += count;
	sbinfo->blocks_free -= count;

#if REISER4_DEBUG
	if (ctx->grabbed_initially == 0)
		ctx->grabbed_initially = count;
#endif

	assert("nikita-2986", reiser4_check_block_counters(ctx->super));

	/* disable grab space in current context */
	ctx->grab_enabled = 0;

unlock_and_ret:
	spin_unlock_reiser4_super(sbinfo);

	return ret;
}
Ejemplo n.º 15
0
void cluster_reserved2grabbed(int count)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	ctx = get_current_context();

	sbinfo = get_super_private(ctx->super);
	spin_lock_reiser4_super(sbinfo);

	sub_from_cluster_reserved(sbinfo, count);
	sbinfo->blocks_grabbed += count;

	assert("edward-505", reiser4_check_block_counters(ctx->super));

	spin_unlock_reiser4_super(sbinfo);
	add_to_ctx_grabbed(ctx, count);
}
Ejemplo n.º 16
0
/* update the per fs  blocknr hint default value. */
void
update_blocknr_hint_default(const struct super_block *s,
			    const reiser4_block_nr * block)
{
	reiser4_super_info_data *sbinfo = get_super_private(s);

	assert("nikita-3342", !reiser4_blocknr_is_fake(block));

	spin_lock_reiser4_super(sbinfo);
	if (*block < sbinfo->block_count) {
		sbinfo->blocknr_hint_default = *block;
	} else {
		warning("zam-676",
			"block number %llu is too large to be used in a blocknr hint\n",
			(unsigned long long)*block);
		dump_stack();
		DEBUGON(1);
	}
	spin_unlock_reiser4_super(sbinfo);
}
Ejemplo n.º 17
0
/* fill journal header block data  */
static void format_journal_header(struct commit_handle *ch)
{
	struct reiser4_super_info_data *sbinfo;
	struct journal_header *header;
	jnode *txhead;

	sbinfo = get_super_private(ch->super);
	assert("zam-479", sbinfo != NULL);
	assert("zam-480", sbinfo->journal_header != NULL);

	txhead = list_entry(ch->tx_list.next, jnode, capture_link);

	jload(sbinfo->journal_header);

	header = (struct journal_header *)jdata(sbinfo->journal_header);
	assert("zam-484", header != NULL);

	put_unaligned(cpu_to_le64(*jnode_get_block(txhead)),
		      &header->last_committed_tx);

	jrelse(sbinfo->journal_header);
}
Ejemplo n.º 18
0
void grabbed2flush_reserved_nolock(txn_atom * atom, __u64 count)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	assert("vs-1095", atom);

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	sub_from_ctx_grabbed(ctx, count);

	add_to_atom_flush_reserved_nolock(atom, count);

	spin_lock_reiser4_super(sbinfo);

	sbinfo->blocks_flush_reserved += count;
	sub_from_sb_grabbed(sbinfo, count);

	assert("vpf-292", reiser4_check_block_counters(ctx->super));

	spin_unlock_reiser4_super(sbinfo);
}
Ejemplo n.º 19
0
void flush_reserved2grabbed(txn_atom * atom, __u64 count)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	assert("nikita-2788", atom != NULL);
	assert_spin_locked(&(atom->alock));

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	add_to_ctx_grabbed(ctx, count);

	sub_from_atom_flush_reserved_nolock(atom, (__u32) count);

	spin_lock_reiser4_super(sbinfo);

	sbinfo->blocks_grabbed += count;
	sub_from_sb_flush_reserved(sbinfo, count);

	assert("vpf-292", reiser4_check_block_counters(ctx->super));

	spin_unlock_reiser4_super(sbinfo);
}
Ejemplo n.º 20
0
int reiser4_grab_reserved(struct super_block *super,
			  __u64 count, reiser4_ba_flags_t flags)
{
	reiser4_super_info_data *sbinfo = get_super_private(super);

	assert("nikita-3175", flags & BA_CAN_COMMIT);

	/* Check the delete mutex already taken by us, we assume that
	 * reading of machine word is atomic. */
	if (sbinfo->delete_mutex_owner == current) {
		if (reiser4_grab_space
		    (count, (flags | BA_RESERVED) & ~BA_CAN_COMMIT)) {
			warning("zam-1003",
				"nested call of grab_reserved fails count=(%llu)",
				(unsigned long long)count);
			reiser4_release_reserved(super);
			return RETERR(-ENOSPC);
		}
		return 0;
	}

	if (reiser4_grab_space(count, flags)) {
		mutex_lock(&sbinfo->delete_mutex);
		assert("nikita-2929", sbinfo->delete_mutex_owner == NULL);
		sbinfo->delete_mutex_owner = current;

		if (reiser4_grab_space(count, flags | BA_RESERVED)) {
			warning("zam-833",
				"reserved space is not enough (%llu)",
				(unsigned long long)count);
			reiser4_release_reserved(super);
			return RETERR(-ENOSPC);
		}
	}
	return 0;
}
Ejemplo n.º 21
0
	sa_pre_commit_hook();
	return 0;
}

/* an actor which applies delete set to block allocator data */
static int
apply_dset(txn_atom * atom UNUSED_ARG, const reiser4_block_nr * a,
	   const reiser4_block_nr * b, void *data UNUSED_ARG)
{
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	__u64 len = 1;

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	assert("zam-877", atom->stage >= ASTAGE_PRE_COMMIT);
	assert("zam-552", sbinfo != NULL);

	if (b != NULL)
		len = *b;

	if (REISER4_DEBUG) {
		spin_lock_reiser4_super(sbinfo);

		assert("zam-554", *a < reiser4_block_count(ctx->super));
		assert("zam-555", *a + len <= reiser4_block_count(ctx->super));

		spin_unlock_reiser4_super(sbinfo);
	}
Ejemplo n.º 22
0
/*
 * return d_cursor data for the file system @inode is in.
 */
static inline struct d_cursor_info *d_info(struct inode *inode)
{
	return &get_super_private(inode->i_sb)->d_info;
}
Ejemplo n.º 23
0
/* return tree @page is in */
reiser4_tree *reiser4_tree_by_page(const struct page *page/* page to query */)
{
	assert("nikita-2461", page != NULL);
	return &get_super_private(page->mapping->host->i_sb)->tree;
}
Ejemplo n.º 24
0
int
reiser4_dealloc_blocks(const reiser4_block_nr * start,
		       const reiser4_block_nr * len,
		       block_stage_t target_stage, reiser4_ba_flags_t flags)
{
	txn_atom *atom = NULL;
	int ret;
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	if (REISER4_DEBUG) {
		assert("zam-431", *len != 0);
		assert("zam-432", *start != 0);
		assert("zam-558", !reiser4_blocknr_is_fake(start));

		spin_lock_reiser4_super(sbinfo);
		assert("zam-562", *start < sbinfo->block_count);
		spin_unlock_reiser4_super(sbinfo);
	}

	if (flags & BA_DEFER) {
		blocknr_set_entry *bsep = NULL;

		/* storing deleted block numbers in a blocknr set
		   datastructure for further actual deletion */
		do {
			atom = get_current_atom_locked();
			assert("zam-430", atom != NULL);

			ret =
			    blocknr_set_add_extent(atom, &atom->delete_set,
						   &bsep, start, len);

			if (ret == -ENOMEM)
				return ret;

			/* This loop might spin at most two times */
		} while (ret == -E_REPEAT);

		assert("zam-477", ret == 0);
		assert("zam-433", atom != NULL);

		spin_unlock_atom(atom);

	} else {
		assert("zam-425", get_current_super_private() != NULL);
		sa_dealloc_blocks(reiser4_get_space_allocator(ctx->super),
				  *start, *len);

		if (flags & BA_PERMANENT) {
			/* These blocks were counted as allocated, we have to
			 * revert it back if allocation is discarded. */
			txn_atom *atom = get_current_atom_locked();
			atom->nr_blocks_allocated -= *len;
			spin_unlock_atom(atom);
		}

		switch (target_stage) {
		case BLOCK_NOT_COUNTED:
			assert("vs-960", flags & BA_FORMATTED);
			/* VITALY: This is what was grabbed for
			   internal/tx-lists/similar only */
			used2free(sbinfo, *len);
			break;

		case BLOCK_GRABBED:
			used2grabbed(ctx, sbinfo, *len);
			break;

		case BLOCK_UNALLOCATED:
			used2fake_allocated(sbinfo, *len, flags & BA_FORMATTED);
			break;

		case BLOCK_FLUSH_RESERVED:{
				txn_atom *atom;

				atom = get_current_atom_locked();
				used2flush_reserved(sbinfo, atom, *len,
						    flags & BA_FORMATTED);
				spin_unlock_atom(atom);
				break;
			}
		default:
			impossible("zam-532", "wrong block stage");
		}
	}

	return 0;
}
Ejemplo n.º 25
0
/**
 * all_grabbed2free - releases all blocks grabbed in context
 *
 * Decreases context's and super block's grabbed block counters by number of
 * blocks grabbed by current context and increases super block's free block
 * counter correspondingly.
 */
void all_grabbed2free(void)
{
	reiser4_context *ctx = get_current_context();

	grabbed2free(ctx, get_super_private(ctx->super), ctx->grabbed_blocks);
}
Ejemplo n.º 26
0
static void disable_write_barrier(struct super_block * s)
{
	notice("zam-1055", "%s does not support write barriers,"
	       " using synchronous write instead.", s->s_id);
	set_bit((int)REISER4_NO_WRITE_BARRIER, &get_super_private(s)->fs_flags);
}
Ejemplo n.º 27
0
/* Allocate "real" disk blocks by calling a proper space allocation plugin
 * method. Blocks are allocated in one contiguous disk region. The plugin
 * independent part accounts blocks by subtracting allocated amount from grabbed
 * or fake block counter and add the same amount to the counter of allocated
 * blocks.
 *
 * @hint -- a reiser4 blocknr hint object which contains further block
 *          allocation hints and parameters (search start, a stage of block
 *          which will be mapped to disk, etc.),
 * @blk  -- an out parameter for the beginning of the allocated region,
 * @len  -- in/out parameter, it should contain the maximum number of allocated
 *          blocks, after block allocation completes, it contains the length of
 *          allocated disk region.
 * @flags -- see reiser4_ba_flags_t description.
 *
 * @return -- 0 if success, error code otherwise.
 */
int
reiser4_alloc_blocks(reiser4_blocknr_hint * hint, reiser4_block_nr * blk,
		     reiser4_block_nr * len, reiser4_ba_flags_t flags)
{
	__u64 needed = *len;
	reiser4_context *ctx;
	reiser4_super_info_data *sbinfo;
	int ret;

	assert("zam-986", hint != NULL);

	ctx = get_current_context();
	sbinfo = get_super_private(ctx->super);

	/* For write-optimized data we use default search start value, which is
	 * close to last write location. */
	if (flags & BA_USE_DEFAULT_SEARCH_START)
		get_blocknr_hint_default(&hint->blk);

	/* VITALY: allocator should grab this for internal/tx-lists/similar
	   only. */
/* VS-FIXME-HANS: why is this comment above addressed to vitaly (from vitaly)?*/
	if (hint->block_stage == BLOCK_NOT_COUNTED) {
		ret = reiser4_grab_space_force(*len, flags);
		if (ret != 0)
			return ret;
	}

	ret =
	    sa_alloc_blocks(reiser4_get_space_allocator(ctx->super),
			    hint, (int)needed, blk, len);

	if (!ret) {
		assert("zam-680", *blk < reiser4_block_count(ctx->super));
		assert("zam-681",
		       *blk + *len <= reiser4_block_count(ctx->super));

		if (flags & BA_PERMANENT) {
			/* we assume that current atom exists at this moment */
			txn_atom *atom = get_current_atom_locked();
			atom->nr_blocks_allocated += *len;
			spin_unlock_atom(atom);
		}

		switch (hint->block_stage) {
		case BLOCK_NOT_COUNTED:
		case BLOCK_GRABBED:
			grabbed2used(ctx, sbinfo, *len);
			break;
		case BLOCK_UNALLOCATED:
			fake_allocated2used(sbinfo, *len, flags);
			break;
		case BLOCK_FLUSH_RESERVED:
			{
				txn_atom *atom = get_current_atom_locked();
				flush_reserved2used(atom, *len);
				spin_unlock_atom(atom);
			}
			break;
		default:
			impossible("zam-531", "wrong block stage");
		}
	} else {
		assert("zam-821",
		       ergo(hint->max_dist == 0
			    && !hint->backward, ret != -ENOSPC));
		if (hint->block_stage == BLOCK_NOT_COUNTED)
			grabbed2free(ctx, sbinfo, needed);
	}

	return ret;
}