Exemple #1
0
struct mem_node* __get_node(struct mem_node* node, uint32_t loc){
  switch(node->state){
  case LOCKED:
  case SPLIT:
    if(loc < node->loc+(1<<(node->size-1))){
      if(node->left != 0){
	return __get_node(node->left,loc);
      }else{
	return 0;//FIXME
      }
    }else{
      if(node->right != 0){
	return __get_node(node->right,loc);
      }else{
	return 0;//FIXME
      }
    }
  case FREE:
  case FULL:
    return node;

  default:
    return 0;
  }
}
Exemple #2
0
static void recovery_xdata_block(struct hmfs_sb_info *sbi, seg_t src_segno,
				int src_off, struct hmfs_summary *src_sum)
{
	struct gc_move_arg arg;
	struct hmfs_node *last = NULL, *this = NULL;
	struct hmfs_cm_info *cm_i = CM_I(sbi);
	block_t addr_in_par;
	bool modify_vb = false;
	int x_tag;

	prepare_move_argument(&arg, sbi, src_segno, src_off, src_sum,
			TYPE_DATA);

	while (1) {
		this = __get_node(sbi, arg.cp_i, arg.nid);

		if (IS_ERR(this))
			break;

		if (this == last)
			goto next;

		x_tag = le64_to_cpu(XATTR_HDR(arg.src)->h_magic);
		addr_in_par = XBLOCK_ADDR(this, x_tag);
		
		if (addr_in_par != arg.src_addr && is_valid_address(sbi, addr_in_par)) {
			break;
		}
		
		if (addr_in_par != arg.src_addr) {
			hmfs_memcpy_atomic(JUMP(this, x_tag), &arg.src_addr, 8);
		
			if (!modify_vb) {
				arg.dest_sum = get_summary_by_addr(sbi, addr_in_par);
				clear_summary_valid_bit(arg.dest_sum);
				modify_vb = true;
			}
		}

		last = this;

next:
		if (arg.cp_i == cm_i->last_cp_i)
			break;
		arg.cp_i = get_next_checkpoint_info(sbi, arg.cp_i);
	}
}
Exemple #3
0
struct mem_node* _get_node(uint32_t loc){
  return __get_node(root,loc);
}
Exemple #4
0
static void recovery_data_block(struct hmfs_sb_info *sbi, seg_t src_segno,
				int src_off, struct hmfs_summary *src_sum)
{
	struct gc_move_arg args;
	struct hmfs_node *last = NULL, *this = NULL;
	struct hmfs_summary *par_sum;
	struct hmfs_cm_info *cm_i = CM_I(sbi);
	bool modify_vb = false;
	block_t addr_in_par;
	int par_type;

	prepare_move_argument(&args, sbi, src_segno, src_off, src_sum,
			TYPE_DATA);

	while (1) {
		this = __get_node(sbi, args.cp_i, args.nid);

		par_sum = get_summary_by_addr(sbi, L_ADDR(sbi, this));

		if (IS_ERR(this)) {
			/* the node(args.nid) has been deleted */
			break;
		}

		if (this == last)
			goto next;

		par_type = get_summary_type(par_sum);
		if (par_type == SUM_TYPE_INODE) {
			addr_in_par = le64_to_cpu(this->i.i_addr[args.ofs_in_node]);
		} else {
			addr_in_par = le64_to_cpu(this->dn.addr[args.ofs_in_node]);
		}

		/*
		 * In recovery, the address stored in parent node would be
		 * arg.src_addr or an invalid address. Because GC might terminate
		 * in the loop change this address.
		 * Condition addr_in_par != args.src_addr is not sufficient
		 * to terminate recovery. For example, we delete a node in a
		 * checkpoint and reuse it later. And address in reused node
		 * is not equal to args.src_addr but we could not modify it.
		 * Luckly, the child block in that node is valid and we could
		 * judge this case by the value of address.
		 */
		if (addr_in_par != args.src_addr && is_valid_address(sbi, addr_in_par))
			break;
		
		if (addr_in_par != args.src_addr) {
			/* Recover address in parent node */
			if (par_type == SUM_TYPE_INODE) {
				hmfs_memcpy_atomic(&this->i.i_addr[args.ofs_in_node],
						&args.src_addr, 8);
			} else {
				hmfs_memcpy_atomic(&this->dn.addr[args.ofs_in_node],
						&args.src_addr, 8);
			}

			if (!modify_vb) {
				args.dest_sum = get_summary_by_addr(sbi, addr_in_par);
				clear_summary_valid_bit(args.dest_sum);
				modify_vb = true;
			}
		}

		last = this;
next:
		if (args.cp_i == cm_i->last_cp_i)
			break;
		args.cp_i = get_next_checkpoint_info(sbi, args.cp_i);
	}
}