예제 #1
0
/** 
  Apply the transform to a buffer starting at "data". That buffer MUST be ROZOFS_BSIZE
  aligned.
  The first_block_idx is the index of a ROZOFS_BSIZE array in the output buffer
  The number_of_blocks is the number of ROZOFS_BSIZE that must be transform
  Notice that the first_block_idx offset applies to the output transform buffer only
  not to the input buffer pointed by "data".
  
 * 
 * @param *prj_ctx_p: pointer to the working array of the projection
 * @param first_block_idx: index of the first block to transform
 * @param number_of_blocks: number of blocks to write
 * @param *data: pointer to the source data that must be transformed
   @param *number_of_blocks_p: pointer to the array where the function returns number of blocks on which the transform was applied
  @param *rozofs_storcli_prj_idx_table: pointer to the array used for storing the projections index for inverse process
 *
 * @return: the length written on success, -1 otherwise (errno is set)
 */
 int rozofs_storcli_transform_inverse(rozofs_storcli_projection_ctx_t *prj_ctx_p,  
                                       uint8_t layout, uint32_t bsize,
                                       uint32_t first_block_idx, 
                                       uint32_t number_of_blocks, 
                                       rozofs_storcli_inverse_block_t *block_ctx_p,
                                       char *data,
                                       uint32_t *number_of_blocks_p,
				       uint8_t  *rozofs_storcli_prj_idx_table) 

 {

    int block_idx;
    uint16_t projection_id = 0;
    int prj_ctx_idx;
    *number_of_blocks_p = 0;    
    uint8_t rozofs_inverse = rozofs_get_rozofs_inverse(layout);
    uint8_t rozofs_forward = rozofs_get_rozofs_forward(layout);
    uint8_t rozofs_safe = rozofs_get_rozofs_safe(layout);        
    uint32_t bbytes = ROZOFS_BSIZE_BYTES(bsize);

    int prj_size_in_msg = rozofs_get_max_psize_in_msg(layout,bsize);

    /*
    ** Proceed the inverse data transform for the nb_projections2read blocks.
    */
    for (block_idx = 0; block_idx < number_of_blocks; block_idx++) {
        if (block_ctx_p[block_idx].state == ROZOFS_BLK_TRANSFORM_DONE)
        {
          /*
          ** transformation has already been done for that block of ROZOFS_BSIZE siz
          ** check the next one
          */
          continue;        
        }
        /*
        ** Check the case of the file that has no data (there is a hole in the file), this is indicated by
        ** reporting a timestamp of 0
        */
        if ((block_ctx_p[block_idx].timestamp == 0)  && (block_ctx_p[block_idx].effective_length == bbytes ))
        {
          /*
          ** clear the memory
          */
          ROZOFS_STORCLI_STATS(ROZOFS_STORCLI_EMPTY_READ);
          memset( data + (bbytes * (first_block_idx + block_idx)),0,bbytes);
          block_ctx_p[block_idx].state = ROZOFS_BLK_TRANSFORM_DONE;
          continue;
        
        }	                                                              
        if ((block_ctx_p[block_idx].timestamp == 0)  && (block_ctx_p[block_idx].effective_length == 0 ))
        {
          /*
          ** we have reached end of file
          */
          block_ctx_p[block_idx].state = ROZOFS_BLK_TRANSFORM_DONE;
          *number_of_blocks_p = (block_idx++);
          
          return 0;        
        }      
	
        /*
        ** Here we have to take care, since the index of the projection_id use to address
        ** prj_ctx_p is NOT the real projection_id. The projection ID is found in the header of
        ** each bins, so for a set of projections pointed by bins, we might have a different
        ** projection id in the header of the projections contains in the bins array that has
        ** been read!!
        */
	transform_inverse_proc(&rozofs_storcli_prj_idx_table[ROZOFS_SAFE_MAX_STORCLI*block_idx],
			       prj_ctx_p,
			       prj_size_in_msg,
			       layout,
			       bbytes,
			       first_block_idx,
			       block_idx,
			       data);
        /*
        ** indicate that transform has been done for the projection
        */
        block_ctx_p[block_idx].state = ROZOFS_BLK_TRANSFORM_DONE;
        /*
        ** check the case of a block that is not full: need to zero's that part
        */
        if (block_ctx_p[block_idx].effective_length < bbytes)
        {
           /*
           ** clear the memory
           */
           char *raz_p = data + (bbytes * (first_block_idx + block_idx)) + block_ctx_p[block_idx].effective_length;
           memset( raz_p,0,(bbytes-block_ctx_p[block_idx].effective_length) );
        }
    }
    /*
    ** now the inverse transform is finished, release the allocated ressources used for
    ** rebuild
    */
    *number_of_blocks_p = number_of_blocks;
    
    /*
    ** Check whether a block should be repaired
    */
    rozofs_storcli_check_block_2_repair(prj_ctx_p, rozofs_inverse, rozofs_forward, rozofs_safe, prj_size_in_msg, number_of_blocks, block_ctx_p);
    
    return 0;   
}
예제 #2
0
/** 
  Apply the transform to a buffer starting at "data". That buffer MUST be ROZOFS_BSIZE
  aligned.
  The first_block_idx is the index of a ROZOFS_BSIZE array in the output buffer
  The number_of_blocks is the number of ROZOFS_BSIZE that must be transform
  Notice that the first_block_idx offset applies to the output transform buffer only
  not to the input buffer pointed by "data".
  
 * 
 * @param *working_ctx_p: storcli working context
 * @param number_of_blocks: number of blocks to write
 * @param *data: pointer to the source data that must be transformed
 *
 * @return: the length written on success, -1 otherwise (errno is set)
 */
 void rozofs_storcli_transform_forward_repair(rozofs_storcli_ctx_t *working_ctx_p,
                                	      uint8_t layout,
                                	      uint32_t number_of_blocks,
                                	      char *data) 
 {
    projection_t rozofs_fwd_projections[ROZOFS_SAFE_MAX_STORCLI];
    projection_t *projections; // Table of projections used to transform data
    uint16_t projection_id = 0;
    uint32_t i = 0;    
    uint8_t rozofs_forward = rozofs_get_rozofs_forward(layout);
    uint8_t rozofs_safe    = rozofs_get_rozofs_forward(layout);
    uint8_t rozofs_inverse = rozofs_get_rozofs_inverse(layout);
    rozofs_storcli_projection_ctx_t *prj_ctx_p = &working_ctx_p->prj_ctx[0];
    int empty_block = 0;
    uint8_t sid;
    int moj_prj_id;
    int block_idx;
    int k;
    storcli_read_arg_t *storcli_read_rq_p = (storcli_read_arg_t*)&working_ctx_p->storcli_read_arg;
    uint8_t  bsize  = storcli_read_rq_p->bsize;
    uint32_t bbytes = ROZOFS_BSIZE_BYTES(bsize);
    int prj_size_in_msg = rozofs_get_max_psize_in_msg(layout,bsize);
              
    projections = rozofs_fwd_projections;

    // For each projection
    for (projection_id = 0; projection_id < rozofs_forward; projection_id++) {
        projections[projection_id].angle.p =  rozofs_get_angles_p(layout,projection_id);
        projections[projection_id].angle.q =  rozofs_get_angles_q(layout,projection_id);
        projections[projection_id].size    =  rozofs_get_128bits_psizes(layout,bsize,projection_id);
    }
    /*
    ** now go through all projection set to find out if there is something to regenerate
    */
    for (k = 0; k < rozofs_safe; k++)
    {
	block_idx = 0;
       if (ROZOFS_BITMAP64_TEST_ALL0(prj_ctx_p[k].crc_err_bitmap)) continue;
       /*
       **  Get the sid associated with the projection context
       */
       sid = (uint8_t) rozofs_storcli_lbg_prj_get_sid(working_ctx_p->lbg_assoc_tb,
                                                      prj_ctx_p[k].stor_idx);
       /*
       ** Get the reference of the Mojette projection_id
       */
       moj_prj_id = rozofs_storcli_get_mojette_proj_id(storcli_read_rq_p->dist_set,sid,rozofs_forward);
       if  (moj_prj_id < 0)
       {
          /*
	  ** it is the reference of a spare sid, so go to the next projection context
	  */
	  continue;
       }
       for (i = 0; i < number_of_blocks; i++) 
       {
          if (ROZOFS_BITMAP64_TEST0(i,prj_ctx_p[k].crc_err_bitmap)) 
	  {
	    /*
	    ** nothing to generate for that block
	    */
	    continue;
	  }
	  /*
	  ** check for empty block
	  */
          empty_block = rozofs_data_block_check_empty(data + (i * bbytes), bbytes);
	  /**
	  * regenerate the projection for the block for which a crc error has been detected
	  */
//CRC     projections[moj_prj_id].bins = prj_ctx_p[moj_prj_id].bins + 
          projections[moj_prj_id].bins = prj_ctx_p[k].bins + 
                                         (prj_size_in_msg/sizeof(bin_t)* (0+block_idx));
          rozofs_stor_bins_hdr_t *rozofs_bins_hdr_p = (rozofs_stor_bins_hdr_t*)projections[moj_prj_id].bins;
          /*
          ** check if the user data block is empty: if the data block is empty no need to transform
          */
          if (empty_block)
          {
            rozofs_bins_hdr_p->s.projection_id = 0;
            rozofs_bins_hdr_p->s.timestamp     = 0;          
            rozofs_bins_hdr_p->s.effective_length = 0;    
            rozofs_bins_hdr_p->s.filler = 0;    
            rozofs_bins_hdr_p->s.version = 0;
	    block_idx++;    
            continue;   
          }	 
          /*
          ** fill the header of the projection
          */
          rozofs_bins_hdr_p->s.projection_id     = moj_prj_id;
//CRC     rozofs_bins_hdr_p->s.timestamp         = working_ctx_p->block_ctx_table[block_idx].timestamp;       
          rozofs_bins_hdr_p->s.timestamp         = working_ctx_p->block_ctx_table[i].timestamp; 
//CRC     rozofs_bins_hdr_p->s.effective_length  = working_ctx_p->block_ctx_table[block_idx].effective_length;
          rozofs_bins_hdr_p->s.effective_length  = working_ctx_p->block_ctx_table[i].effective_length;
          rozofs_bins_hdr_p->s.filler = 0;    
          rozofs_bins_hdr_p->s.version = 0;    	 
          /*
          ** update the pointer to point out the first bins
          */
          projections[moj_prj_id].bins += sizeof(rozofs_stor_bins_hdr_t)/sizeof(bin_t);
          /*
          ** do not apply transform for empty block
          */
          if (empty_block == 0)
          {
	  	    
            /*
            ** Apply the erasure code transform for the block i
            */
            transform128_forward_one_proj((pxl_t *) (data + (i * bbytes)),
                    rozofs_inverse,
                    bbytes / rozofs_inverse / sizeof (pxl_t),
                    moj_prj_id, projections);
            /*
	    ** add the footer at the end of the repaired projection
	    */
            rozofs_stor_bins_footer_t *rozofs_bins_foot_p;
            rozofs_bins_foot_p = (rozofs_stor_bins_footer_t*) (projections[moj_prj_id].bins
	                                                      + rozofs_get_psizes(layout,bsize,moj_prj_id));
//CRC       rozofs_bins_foot_p->timestamp      = working_ctx_p->block_ctx_table[block_idx].timestamp;
            rozofs_bins_foot_p->timestamp      = rozofs_bins_hdr_p->s.timestamp;	
          }
	  block_idx++;    	  
        }
    }
}
예제 #3
0
/** 
  Apply the transform to a buffer starting at "data". That buffer MUST be ROZOFS_BSIZE
  aligned.
  The first_block_idx is the index of a ROZOFS_BSIZE array in the output buffer
  The number_of_blocks is the number of ROZOFS_BSIZE that must be transform
  Notice that the first_block_idx offset applies to the output transform buffer only
  not to the input buffer pointed by "data".
  
 * 
 * @param *prj_ctx_p: pointer to the working array of the projection
 * @param first_block_idx: index of the first block to transform
 * @param number_of_blocks: number of blocks to write
 * @param timestamp: date in microseconds
   @param last_block_size: effective length of the last block
 * @param *data: pointer to the source data that must be transformed
 *
 * @return: the length written on success, -1 otherwise (errno is set)
 */
 int rozofs_storcli_transform_forward(rozofs_storcli_projection_ctx_t *prj_ctx_p,  
                                       uint8_t layout,uint32_t bsize,
                                       uint32_t first_block_idx, 
                                       uint32_t number_of_blocks,
                                       uint64_t timestamp, 
                                       uint16_t last_block_size,
                                       char *data) 
 {

    projection_t rozofs_fwd_projections[ROZOFS_SAFE_MAX_STORCLI];
    projection_t *projections; // Table of projections used to transform data
    uint16_t projection_id = 0;
    uint32_t i = 0;    
    uint8_t rozofs_forward = rozofs_get_rozofs_forward(layout);
    uint8_t rozofs_inverse = rozofs_get_rozofs_inverse(layout);
    int empty_block = 0;
    uint32_t bbytes = ROZOFS_BSIZE_BYTES(bsize);

    projections = rozofs_fwd_projections;
    int prj_size_in_msg = rozofs_get_max_psize_in_msg(layout,bsize);
    
    /* Transform the data */
    // For each block to send
    for (i = 0; i < number_of_blocks; i++) 
    {
         empty_block = rozofs_data_block_check_empty(data + (i * bbytes), bbytes);

        // seek bins for each projection
        for (projection_id = 0; projection_id < rozofs_forward; projection_id++) 
        {
          /*
          ** Indicates the memory area where the transformed data must be stored
          */
          projections[projection_id].bins = prj_ctx_p[projection_id].bins 
	                                  + (prj_size_in_msg/sizeof(bin_t)) * (first_block_idx+i);
          rozofs_stor_bins_hdr_t *rozofs_bins_hdr_p = (rozofs_stor_bins_hdr_t*)projections[projection_id].bins;
          rozofs_stor_bins_footer_t *rozofs_bins_foot_p = (rozofs_stor_bins_footer_t*)
	                                                  ((bin_t*)(rozofs_bins_hdr_p+1)+
							  rozofs_get_psizes(layout,bsize,projection_id));
          /*
          ** check if the user data block is empty: if the data block is empty no need to transform
          */
          if (empty_block)
          {
            rozofs_bins_hdr_p->s.projection_id = 0;
            rozofs_bins_hdr_p->s.timestamp     = 0;          
            rozofs_bins_hdr_p->s.effective_length = 0;    
            rozofs_bins_hdr_p->s.filler = 0;    
            rozofs_bins_hdr_p->s.version = 0;    
            continue;   
          }
          /*
          ** fill the header of the projection
          */
          rozofs_bins_hdr_p->s.projection_id = projection_id;
          rozofs_bins_hdr_p->s.timestamp     = timestamp;
          rozofs_bins_hdr_p->s.filler = 0;    
          rozofs_bins_hdr_p->s.version = 0;   
	  /*
          ** set the effective size of the block. It is always ROZOFS_BSIZE except for the last block
          */
          if (i == (number_of_blocks-1))
          {
            rozofs_bins_hdr_p->s.effective_length = last_block_size;
          }
          else
          {
            rozofs_bins_hdr_p->s.effective_length = bbytes;          
          } 
          /*
          ** update the pointer to point out the first bins
          */
          projections[projection_id].bins += sizeof(rozofs_stor_bins_hdr_t)/sizeof(bin_t);
	  rozofs_bins_foot_p = (rozofs_stor_bins_footer_t*) (projections[projection_id].bins
	                                                      + rozofs_get_psizes(layout,bsize,projection_id));
          rozofs_bins_foot_p->timestamp      = timestamp;                                                     
        }
        /*
        ** do not apply transform for empty block
        */
        if (empty_block == 0)
        {
	  transform_forward_proc(layout,data + (i * bbytes),bbytes,projections);
	} 

    }
    return 0;
}
예제 #4
0
int export_unlink_multiple(export_t * e, fid_t parent, char *name, fid_t fid,mattr_t * pattrs,lv2_entry_t *plv2) {
    int status = -1;
    lv2_entry_t *lv2=NULL;
    fid_t child_fid;
    uint32_t child_type;
    uint16_t nlink = 0;
    int fdp = -1;
    int ret;
    rozofs_inode_t *fake_inode_p;
    rmfentry_disk_t trash_entry;
    int root_dirent_mask = 0;
    int unknown_fid = 0;
    int deleted_fid_count = 0;
    char filename[1024];
    char *basename;
    int filecount;
    char *filename_p;
    int k;    

    /*
    ** search for rozofs key in the filename
    */
    if (strncmp(name,".@rozofs-mf@",12) == 0)
    {
      ret = rozofs_parse_object_name((char*)(name+12),&basename,&filecount);
      if (ret < 0)
      {
	errno = ENOTSUP;
	goto error;
      }
    }
    /*
    ** load the root_idx bitmap of the old parent
    */
    export_dir_load_root_idx_bitmap(e,parent,plv2);
    /*
    ** set global variables associated with the export
    */
    fdp = export_open_parent_directory(e,parent);
    if (get_mdirentry(plv2->dirent_root_idx_p,fdp, parent, name, child_fid, &child_type,&root_dirent_mask) != 0)
        goto out;

    if (S_ISDIR(child_type)) {
        errno = EISDIR;
        goto out;
    }
    /*
    ** do a loop on the file count
    */
    for (k = 0; k < filecount ; k++)
    {
      sprintf(filename,"%s.%d",basename,k);
      filename_p = filename;
      // Delete the mdirentry if exist
      ret =del_mdirentry(plv2->dirent_root_idx_p,fdp, parent, name, child_fid, &child_type,root_dirent_mask);
      if (ret != 0)
      {
	  if (errno != ENOENT) goto out;
	  /*
	  ** check the next entry
	  */
	  continue;
      }
      // Get mattrs of child to delete
      if (!(lv2 = export_lookup_fid(e->trk_tb_p,e->lv2_cache, child_fid)))
      {
	    unknown_fid++;
	    /*
	    ** check the next entry
	    */
	    continue;
      }
      deleted_fid_count++;    

      // Compute hash value for this fid
      uint32_t hash = 0;
      uint8_t *c = 0;
      for (c = lv2->attributes.s.attrs.fid; c != lv2->attributes.s.attrs.fid + 16; c++)
	  hash = *c + (hash << 6) + (hash << 16) - hash;
      hash %= RM_MAX_BUCKETS;	    
      /*
      ** prepare the trash entry
      */
      trash_entry.size = lv2->attributes.s.attrs.size;
      memcpy(trash_entry.fid, lv2->attributes.s.attrs.fid, sizeof (fid_t));
      trash_entry.cid = lv2->attributes.s.attrs.cid;
      memcpy(trash_entry.initial_dist_set, lv2->attributes.s.attrs.sids,
              sizeof (sid_t) * ROZOFS_SAFE_MAX);
      memcpy(trash_entry.current_dist_set, lv2->attributes.s.attrs.sids,
              sizeof (sid_t) * ROZOFS_SAFE_MAX);
      fake_inode_p =  (rozofs_inode_t *)parent;   
      ret = exp_trash_entry_create(e->trk_tb_p,fake_inode_p->s.usr_id,&trash_entry); 
      if (ret < 0)
      {
	 /*
	 ** error while inserting entry in trash file
	 */
	 severe("error on trash insertion name %s error %s",name,strerror(errno)); 
      }
      /*
      ** delete the metadata associated with the file
      */
      ret = exp_delete_file(e,lv2);
      /*
      * In case of geo replication, insert a delete request from the 2 sites 
      */
      if (e->volume->georep) 
      {
	/*
	** update the geo replication: set start=end=0 to indicate a deletion 
	*/
	geo_rep_insert_fid(e->geo_replication_tb[0],
                	   lv2->attributes.s.attrs.fid,
			   0/*start*/,0/*end*/,
			   e->layout,
			   lv2->attributes.s.attrs.cid,
			   lv2->attributes.s.attrs.sids);
	/*
	** update the geo replication: set start=end=0 to indicate a deletion 
	*/
	geo_rep_insert_fid(e->geo_replication_tb[1],
                	   lv2->attributes.s.attrs.fid,
			   0/*start*/,0/*end*/,
			   e->layout,
			   lv2->attributes.s.attrs.cid,
			   lv2->attributes.s.attrs.sids);
      }	
      /*
      ** Preparation of the rmfentry
      */
      rmfentry_t *rmfe = xmalloc(sizeof (rmfentry_t));
      export_rm_bins_pending_count++;
      memcpy(rmfe->fid, trash_entry.fid, sizeof (fid_t));
      rmfe->cid = trash_entry.cid;
      memcpy(rmfe->initial_dist_set, trash_entry.initial_dist_set,
              sizeof (sid_t) * ROZOFS_SAFE_MAX);
      memcpy(rmfe->current_dist_set, trash_entry.current_dist_set,
              sizeof (sid_t) * ROZOFS_SAFE_MAX);
      memcpy(rmfe->trash_inode,trash_entry.trash_inode,sizeof(fid_t));
      list_init(&rmfe->list);
      /* Acquire lock on bucket trash list
      */
      if ((errno = pthread_rwlock_wrlock
              (&e->trash_buckets[hash].rm_lock)) != 0) {
	  severe("pthread_rwlock_wrlock failed: %s", strerror(errno));
	  // Best effort
      }
      /*
      ** Check size of file 
      */
      if (lv2->attributes.s.attrs.size >= RM_FILE_SIZE_TRESHOLD) {
	  // Add to front of list
	  list_push_front(&e->trash_buckets[hash].rmfiles, &rmfe->list);
      } else {
	  // Add to back of list
	  list_push_back(&e->trash_buckets[hash].rmfiles, &rmfe->list);
      }

      if ((errno = pthread_rwlock_unlock
              (&e->trash_buckets[hash].rm_lock)) != 0) {
	  severe("pthread_rwlock_unlock failed: %s", strerror(errno));
	  // Best effort
      }
      // Update the nb. of blocks
      if (export_update_blocks(e,
              -(((int64_t) lv2->attributes.s.attrs.size + ROZOFS_BSIZE_BYTES(e->bsize) - 1)
              / ROZOFS_BSIZE_BYTES(e->bsize))) != 0) {
	  severe("export_update_blocks failed: %s", strerror(errno));
	  // Best effort
      }
      // Remove from the cache (will be closed and freed)
      lv2_cache_del(e->lv2_cache, child_fid);
    }  
    /*
    ** al the subfile have been deleted so  Update export files
    */
    if (export_update_files(e, 0-deleted_fid_count) != 0)
      goto out;

    // Update parent
    plv2->attributes.s.attrs.mtime = plv2->attributes.s.attrs.ctime = time(NULL);
    plv2->attributes.s.attrs.children--;

    // Write attributes of parents
    if (export_lv2_write_attributes(e->trk_tb_p,plv2) != 0)
        goto out;
    /*
    ** return the parent attributes
    */
    memcpy(pattrs, &plv2->attributes.s.attrs, sizeof (mattr_t));
    status = 0;

out:
    /*
    ** check if parent root idx bitmap must be updated
    */
    if (plv2 != NULL) export_dir_flush_root_idx_bitmap(e,parent,plv2->dirent_root_idx_p);
    
    if(fdp != -1) close(fdp);
    return status;
}
예제 #5
0
/**
* callback for the internal read request triggered by a truncate

 potential failure case:
  - socket_ref is out of range
  - connection is down
  
 @param buffer : pointer to the ruc_buffer that cointains the response
 @param socket_ref : non significant
 @param user_param_p : pointer to the root context
 
 
 @retval 0 : successfully submitted to the transport layer
 @retval < 0 error, the caller is intended to release the buffer
 */
int rozofs_storcli_internal_read_before_truncate_rsp_cbk(void *buffer,uint32_t socket_ref,void *user_param)
{

   int errcode = 0; 
   rozofs_storcli_ctx_t                *working_ctx_p = (rozofs_storcli_ctx_t*)user_param;
   storcli_truncate_arg_t * storcli_truncate_rq_p = (storcli_truncate_arg_t*)&working_ctx_p->storcli_truncate_arg;

   XDR       xdrs;       
   uint8_t  *payload;
   char     *data;
   int       position;
   int      bufsize;   
   struct rpc_msg  rpc_reply;
   storcli_status_ret_t rozofs_status;
   int  data_len; 
   int error;  
   rpc_reply.acpted_rply.ar_results.proc = NULL;
   uint32_t bsize = storcli_truncate_rq_p->bsize;
   uint32_t bbytes = ROZOFS_BSIZE_BYTES(bsize);
   

   /*
   ** decode the read internal read reply
   */
   payload  = (uint8_t*) ruc_buf_getPayload(buffer);
   payload += sizeof(uint32_t); /* skip length*/  
   
   /*
   ** OK now decode the received message
   */
   bufsize = ruc_buf_getPayloadLen(buffer);
   bufsize -= sizeof(uint32_t); /* skip length*/
   xdrmem_create(&xdrs,(char*)payload,bufsize,XDR_DECODE);   
   error = 0;
   while (1)
   {
     /*
     ** decode the rpc part
     */
     if (rozofs_xdr_replymsg(&xdrs,&rpc_reply) != TRUE)
     {
       errno = EPROTO;
       error = 1;
       break;
     }
     
     /*
     ** decode the status of the operation
     */
     if (xdr_storcli_status_ret_t(&xdrs,&rozofs_status)!= TRUE)
     {
       errno = EPROTO;
       error = 1;
       break;    
     }
     /*
     ** check th estatus of the operation
     */
     if ( rozofs_status.status != STORCLI_SUCCESS )
     {
       error = 0;
       break;    
     }
     {
       int alignment;
       int k;
       /*
       ** skip the alignment
       */
       for (k=0; k<3; k++) 
       {
	 if (xdr_int(&xdrs, &alignment) != TRUE)
	 {
           errno = EPROTO;
           STORCLI_ERR_PROF(read_prj_err);       
           error = 1;
           break;          
	 }
       }
       if (error==1) break;
     }
     /*
     ** Now get the length of the part that has been read
     */
     if (xdr_int(&xdrs, &data_len) != TRUE)
     {
       errno = EPROTO;
       error = 1;
       break;          
     }
     break;
   }
   if (error)
   {
     severe("error while decoding rpc reply");  
     goto failure;  
   }   

   position = XDR_GETPOS(&xdrs);
   data     = (char*)(payload+position);

   /*
   ** check the status of the read operation
   */
   if (rozofs_status.status != STORCLI_SUCCESS)
   {
     data = NULL;
   }
   else {
     /*, 
     ** No data returned
     */
     if (data_len == 0) {
       data = NULL;
     }
     else if (storcli_truncate_rq_p->last_seg <= data_len) {
       memset(data+storcli_truncate_rq_p->last_seg, 0, bbytes-storcli_truncate_rq_p->last_seg);       
     }
     else {
       memset(data+data_len, 0, bbytes-data_len);     
     }
   }
   rozofs_storcli_truncate_req_processing_exec(working_ctx_p, data);
   ruc_buf_freeBuffer(buffer);
   return 0 ;   


failure:
   ruc_buf_freeBuffer(buffer);
   /*
   ** check if the lock is asserted to prevent direct call to callback
   */
   if (working_ctx_p->write_ctx_lock == 1) return 0;
   /*
   ** write failure
   */
   rozofs_storcli_write_reply_error(working_ctx_p,errcode);

   /*
   ** release the transaction root context
   */
   working_ctx_p->xmitBuf = NULL;
   STORCLI_STOP_NORTH_PROF(working_ctx_p,truncate,0);  
   rozofs_storcli_release_context(working_ctx_p);
   return 0 ;

}
예제 #6
0
void read_chunk_file(uuid_t fid, char * path, rozofs_stor_bins_file_hdr_vall_t * hdr, int spare, uint64_t firstBlock) {
  uint16_t rozofs_disk_psize;
  int      fd;
  rozofs_stor_bins_hdr_t * pH;
  int      nb_read;
  uint32_t bbytes = ROZOFS_BSIZE_BYTES(hdr->v0.bsize);
  char     crc32_string[32];
  uint64_t offset;
  
  if (dump_data == 0) {
    printf ("+------------+------------------+------------+----+------+-------+--------------------------------------------\n");
    printf ("| %10s | %16s | %10s | %2s | %4s | %5s | %s\n", "block#","file offset", "prj offset", "pj", "size", "crc32", "date");
    printf ("+------------+------------------+------------+----+------+-------+--------------------------------------------\n");
  }

  // Open bins file
  fd = open(path, ROZOFS_ST_NO_CREATE_FILE_FLAG, ROZOFS_ST_BINS_FILE_MODE_RO);
  if (fd < 0) {
    printf("open(%s) %s\n",path,strerror(errno));
    return;	
  }

  /*
  ** Retrieve the projection size on disk
  */
  rozofs_disk_psize = rozofs_get_max_psize_in_msg(hdr->v0.layout,hdr->v0.bsize);
  if (spare==0) {
  
    /* Header version 1. Find the sid in  the distribution */
    if (hdr->v0.version == 2) {
      int fwd = rozofs_get_rozofs_forward(hdr->v2.layout);
      int idx;
      for (idx=0; idx< fwd;idx++) {
	if (hdr->v2.distrib[idx] != hdr->v2.sid) continue;
	rozofs_disk_psize = rozofs_get_psizes_on_disk(hdr->v2.layout,hdr->v2.bsize,idx);
	break; 
      }
    }  
    else if (hdr->v0.version == 1) {
      int fwd = rozofs_get_rozofs_forward(hdr->v1.layout);
      int idx;
      for (idx=0; idx< fwd;idx++) {
	if (hdr->v1.dist_set_current[idx] != hdr->v1.sid) continue;
	rozofs_disk_psize = rozofs_get_psizes_on_disk(hdr->v1.layout,hdr->v1.bsize,idx);
	break; 
      }
    }  
    /* Projection id given as parameter */
    else if (prjid != -1) {
      rozofs_disk_psize = rozofs_get_psizes_on_disk(hdr->v0.layout,hdr->v0.bsize,prjid);
    }
    
    /*�Version 0 without projection given as parameter*/
    else {
      // Read 1rst block
      nb_read = pread(fd, buffer, sizeof(rozofs_stor_bins_hdr_t), 0);
      if (nb_read<0) {
	printf("pread(%s) %s\n",path,strerror(errno));
	return;      
      }
      pH = (rozofs_stor_bins_hdr_t*)buffer;
      if (pH->s.timestamp == 0) {
	printf("Can not tell projection id\n");
	return;            
      }
      rozofs_disk_psize = rozofs_get_psizes_on_disk(hdr->v0.layout,hdr->v0.bsize,pH->s.projection_id);
    }
  }
  

  /*
  ** Where to start reading from 
  */
  if (first == 0) { 
    offset = 0;
  }
  else {
    if (first <= firstBlock) {
      offset = 0;
    }
    else {
      offset = (first-firstBlock)*rozofs_disk_psize;
    }
  }
  
  int idx;
  nb_read = 1;
  uint64_t bid;
  
  /*
  ** Reading blocks
  */  
  while (nb_read) {
  
    // Read nb_proj * (projection + header)
    nb_read = pread(fd, buffer, rozofs_disk_psize*32, offset);
    if (nb_read<0) {
      printf("pread(%s) %s\n",path,strerror(errno));
      close(fd);
      return;         
    }
    
    nb_read = (nb_read / rozofs_disk_psize);
    
    pH = (rozofs_stor_bins_hdr_t*) buffer;
    for (idx=0; idx<nb_read; idx++) {
    
      pH = (rozofs_stor_bins_hdr_t*) &buffer[idx*rozofs_disk_psize];
      
      bid = (offset/rozofs_disk_psize)+idx+firstBlock;
      
      if (bid < first) continue;
      if (bid > last)  break;
     
      uint32_t save_crc32 = pH->s.filler;
      pH->s.filler = 0;
      uint32_t crc32=0;

      if (save_crc32 == 0) {
        sprintf(crc32_string,"NONE");
      }
      else {
        crc32 = fid2crc32((uint32_t *)fid)+bid-firstBlock;
        crc32 = crc32c(crc32,(char *) pH, rozofs_disk_psize);
	if (crc32 != save_crc32) sprintf(crc32_string,"ERROR");
	else                     sprintf(crc32_string,"OK");
	
      }
      pH->s.filler = save_crc32;
      	
      if (dump_data == 0) {
      
	printf ("| %10llu | %16llu | %10llu | %2d | %4d | %5s | %s\n",
        	(long long unsigned int)bid,
        	(long long unsigned int)bbytes * bid,
        	(long long unsigned int)offset+(idx*rozofs_disk_psize),
		pH->s.projection_id,
		pH->s.effective_length, 
		crc32_string,  
		ts2string(pH->s.timestamp));
       }		
       else {
	printf("_________________________________________________________________________________________\n");
	printf("Block# %llu / file offset %llu / projection offset %llu\n", 
        	(unsigned long long)bid, (unsigned long long)(bbytes * bid), (unsigned long long)(offset+(idx*rozofs_disk_psize)));
	printf("prj id %d / length %d / CRC %s / time stamp %s\n", 
        	pH->s.projection_id,pH->s.effective_length,crc32_string, ts2string(pH->s.timestamp)); 	
	printf("_________________________________________________________________________________________\n");
	if ((pH->s.projection_id == 0)&&(pH->s.timestamp==0)) continue;
	hexdump(pH, (offset+(idx*rozofs_disk_psize)), rozofs_disk_psize);      	            
      }
    }
    offset += (nb_read*rozofs_disk_psize);
  }
  if (dump_data == 0) {
    printf ("+------------+------------------+------------+----+------+-------+--------------------------------------------\n");
  }
  close(fd);
}    
예제 #7
0
int main(int argc, char *argv[]) {
    int c;
    
    static struct option long_options[] = {
        { "help", no_argument, 0, 'h'},
        { "file", required_argument, 0, 'f'},	
        { "layout", required_argument, 0, 'l'},	
        { "bsize", required_argument, 0, 'b'},	
        { "chunk", required_argument, 0, 'c'},	
        { "blockNumber", required_argument, 0, 'n'},	
        { 0, 0, 0, 0}
    };

    // Get utility name
    utility_name = basename(argv[0]);   

    rozofs_layout_initialize();
   
    while (1) {

        int option_index = 0;
        c = getopt_long(argc, argv, "hH:f:l:b:c:n:", long_options, &option_index);

        if (c == -1)
            break;

        switch (c) {

            case 'h':
                usage();
                exit(EXIT_SUCCESS);
                break;
                break;
            case 'f':
	        filename[nb_file++] = optarg;
                break;	
            case 'l':
	        {
		  int ret;
                  ret = sscanf(optarg,"%d", &layout);
                  if (ret <= 0) { 
                      fprintf(stderr, "dataReader failed. Bad layout: %s %s\n", optarg,
                              strerror(errno));
                      exit(EXIT_FAILURE);
                  }
		}
		break;
            case 'c':
	        {
		  int ret;
                  ret = sscanf(optarg,"%d", &firstBlock);
                  if (ret <= 0) { 
                      fprintf(stderr, "dataReader failed. Bad chunk number: %s %s\n", optarg,
                              strerror(errno));
                      exit(EXIT_FAILURE);
                  }
		}
		break;		
            case 'n':
	        {
		  int ret;
                  ret = sscanf(optarg,"%d", &block_number);
                  if (ret < 0) { 
                      fprintf(stderr, "dataReader failed. Bad block number: %s %s\n", optarg,
                              strerror(errno));
                      exit(EXIT_FAILURE);
                  }
		}	
		break;	
            case 'b':
	        {
		  int ret;
                  ret = sscanf(optarg,"%d", &bsize);
                  if (ret < 0) { 
                      fprintf(stderr, "dataReader failed. Bad block size: %s %s\n", optarg,
                              strerror(errno));
                      exit(EXIT_FAILURE);
                  }
		}	
		break;				
	    case '?':
                usage();
                exit(EXIT_SUCCESS);
                break;
            default:
                usage();
                exit(EXIT_FAILURE);
                break;
        }
    }
    openlog("dataReader", LOG_PID, LOG_DAEMON);
    
    
    /*
    ** Check parameter consistency
    */
    if (nb_file == 0){
        fprintf(stderr, "dataReader failed. Missing --file option.\n");
        exit(EXIT_FAILURE);
    }  
 
    bbytes = ROZOFS_BSIZE_BYTES(bsize);
    if (bbytes < 0) {
        fprintf(stderr, "bad block size: %d\n", bsize);
        exit(EXIT_FAILURE);
    }
    firstBlock *= ROZOFS_STORAGE_NB_BLOCK_PER_CHUNK(bsize);

    // Start rebuild storage   
    if (read_data_file() != 0) goto error;
    exit(EXIT_SUCCESS);
    
error:
    exit(EXIT_FAILURE);
}