Beispiel #1
0
/**
 * reiser4_delete_dir_common - delete_object of file_plugin
 * @inode: inode to be deleted
 *
 * This is common implementation of delete_object method of file_plugin for
 * typical directory. It calls done method of dir_plugin to remove "." and
 * removes stat data and safe-link.
 */
int reiser4_delete_dir_common(struct inode *inode)
{
	int result;
	dir_plugin *dplug;

	assert("", (get_current_context() &&
		    get_current_context()->trans->atom == NULL));

	dplug = inode_dir_plugin(inode);
	assert("vs-1101", dplug && dplug->done);

	/* kill cursors which might be attached to inode */
	reiser4_kill_cursors(inode);

	/* grab space enough for removing two items */
	if (reiser4_grab_space
	    (2 * estimate_one_item_removal(reiser4_tree_by_inode(inode)),
	     BA_RESERVED | BA_CAN_COMMIT))
		return RETERR(-ENOSPC);

	result = dplug->done(inode);
	if (!result)
		result = common_object_delete_no_reserve(inode);
	return result;
}
Beispiel #2
0
/* Intended to be called from interrupt context only */
void
task_trigger_exception (struct task *task, int exception, busword_t textaddr, busword_t data, int code)
{
  DECLARE_CRITICAL_SECTION (except);

  ASSERT (get_current_context () == KERNEL_CONTEXT_INTERRUPT);
  ASSERT (get_current_task () == task);
  
  if (exception < 0 || exception >= EX_MAX)
    FAIL ("exception code unrecognized\n");

  if (task->ts_ex_handlers[exception] == NULL)
  {
    /* Process shall be killed */

    TASK_ATOMIC_ENTER (except);
    
    (void) wake_up (task, TASK_STATE_EXITED, 0);

    task_destroy (task);

    schedule ();
    
    TASK_ATOMIC_LEAVE (except);
  }
  else
    (task->ts_ex_handlers[exception]) (task, exception, textaddr, data, code);
}
Beispiel #3
0
int reiser4_grab_space(__u64 count, reiser4_ba_flags_t flags)
{
	int ret;
	reiser4_context *ctx;

	assert("nikita-2964", ergo(flags & BA_CAN_COMMIT,
				   lock_stack_isclean(get_current_lock_stack
						      ())));
	ctx = get_current_context();
	if (!(flags & BA_FORCE) && !is_grab_enabled(ctx))
		return 0;

	ret = reiser4_grab(ctx, count, flags);
	if (ret == -ENOSPC) {

		/* Trying to commit the all transactions if BA_CAN_COMMIT flag
		   present */
		if (flags & BA_CAN_COMMIT) {
			txnmgr_force_commit_all(ctx->super, 0);
			ctx->grab_enabled = 1;
			ret = reiser4_grab(ctx, count, flags);
		}
	}
	/*
	 * allocation from reserved pool cannot fail. This is severe error.
	 */
	assert("nikita-3005", ergo(flags & BA_RESERVED, ret == 0));
	return ret;
}
/**
 * get_nonexclusive_access - get nonexclusive access to a file
 * @uf_info: unix file specific part of inode to obtain access to
 *
 * Nonexclusive access is obtained on a file before read, write, readpage.
 */
void get_nonexclusive_access(struct unix_file_info *uf_info)
{
	assert("nikita-3029", reiser4_schedulable());
	assert("nikita-3361", get_current_context()->trans->atom == NULL);

	down_read(&uf_info->latch);
	nea_grabbed(uf_info);
}
Beispiel #5
0
RapiContext* rapi_context_current()/*{{{*/
{
	RapiContext *context = NULL;

	context = get_current_context();

	/* If the current context is not initialized, setup
	    a new one and return it
	 */
	if (!context)
	{
		RapiContext *new_context = rapi_context_new();
		set_current_context(new_context);
		context = get_current_context();
	}
	
	return context;

}/*}}}*/
Beispiel #6
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);
}
Beispiel #7
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);
}
Beispiel #8
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);
}
Beispiel #9
0
void rapi_context_set(RapiContext* context)
{
	RapiContext *old_context = NULL;

	/* Get the current context, if any */
	old_context = get_current_context();

	set_current_context(context);

	if (context)
		rapi_context_ref(context);
	if (old_context)
		rapi_context_unref(old_context);
}
Beispiel #10
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;
}
static int do_printenv(struct command *cmdtp, int argc, char *argv[])
{
	struct variable_d *var;
	struct env_context *c, *current_c;

	if (argc == 2) {
		const char *val = getenv(argv[1]);
		if (val) {
			printf("%s=%s\n", argv[1], val);
			return 0;
		}
		printf("## Error: \"%s\" not defined\n", argv[1]);
		return 1;
	}

	current_c = get_current_context();
	var = current_c->local->next;
	printf("locals:\n");
	while (var) {
		printf("%s=%s\n", var_name(var), var_val(var));
		var = var->next;
	}

	printf("globals:\n");
	c = get_current_context();
	while(c) {
		var = c->global->next;
		while (var) {
			printf("%s=%s\n", var_name(var), var_val(var));
			var = var->next;
		}
		c = c->parent;
	}

	return 0;
}
Beispiel #12
0
/* called at the beginning of jnode_flush to register flusher thread with ent
 * daemon */
void reiser4_enter_flush(struct super_block *super)
{
	entd_context *ent;

	assert("zam-1029", super != NULL);
	ent = get_entd_context(super);

	assert("zam-1030", ent != NULL);

	spin_lock(&ent->guard);
	ent->flushers++;
#if REISER4_DEBUG
	list_add(&get_current_context()->flushers_link, &ent->flushers_list);
#endif
	spin_unlock(&ent->guard);
}
Beispiel #13
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;
}
Beispiel #14
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);
}
Beispiel #15
0
static void rapi_context_free(RapiContext* context)/*{{{*/
{
	if (!context)
		return;

	/* check it against the current context,
	 * this should never happen
	 */
	RapiContext* check_context = get_current_context();
	if (check_context == context)
		set_current_context(NULL);

	rapi_buffer_free(context->send_buffer);
	rapi_buffer_free(context->recv_buffer);
	synce_socket_free(context->socket);
	if (context->own_info && context->info)
		synce_info_destroy(context->info);
	free(context);

}/*}}}*/
Beispiel #16
0
/* called at the end of jnode_flush */
void reiser4_leave_flush(struct super_block *super)
{
	entd_context *ent;
	int wake_up_ent;

	assert("zam-1027", super != NULL);
	ent = get_entd_context(super);

	assert("zam-1028", ent != NULL);

	spin_lock(&ent->guard);
	ent->flushers--;
	wake_up_ent = (ent->flushers == 0 && ent->nr_todo_reqs != 0);
#if REISER4_DEBUG
	list_del_init(&get_current_context()->flushers_link);
#endif
	spin_unlock(&ent->guard);
	if (wake_up_ent)
		wake_up_process(ent->tsk);
}
Beispiel #17
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);
}
Beispiel #18
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);
}
Beispiel #19
0
	assert("zam-502", get_current_super_private() != NULL);
	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);
Beispiel #20
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;
}
Beispiel #21
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);
}
Beispiel #22
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;
}