home *** CD-ROM | disk | FTP | other *** search
/ ftp.parl.clemson.edu / 2015-02-07.ftp.parl.clemson.edu.tar / ftp.parl.clemson.edu / pub / pvfs2 / orangefs-2.8.3-20110323.tar.gz / orangefs-2.8.3-20110323.tar / orangefs / src / io / description / dist-varstrip.c < prev    next >
C/C++ Source or Header  |  2010-12-21  |  15KB  |  476 lines

  1. /*
  2.  * (C) 2005 Tobias Eberle <tobias.eberle@gmx.de>
  3.  *
  4.  * See COPYING in top-level directory.
  5.  */       
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <string.h>
  10. #define __PINT_REQPROTO_ENCODE_FUNCS_C
  11. #include "pint-distribution.h"
  12. #include "pint-dist-utils.h"
  13. #include "pvfs2-dist-varstrip.h"
  14. #include "dist-varstrip-parser.h"
  15.  
  16. #include "pvfs2-debug.h"
  17. #include "gossip.h"
  18.  
  19. static PVFS_offset logical_to_physical_offset(void* params,
  20.                                               PINT_request_file_data* fd,
  21.                                               PVFS_offset logical_offset)
  22. {
  23.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  24.     /* parse parameter */
  25.     PINT_dist_strips *strips;
  26.     uint32_t ui_count, ii, ui_stripe_nr;
  27.     PVFS_size ui_stripe_size;
  28.     int32_t server_nr = fd->server_nr;
  29.     
  30.     if (PINT_dist_strips_parse(
  31.             varstrip_params->strips, &strips, &ui_count) == -1)
  32.     {
  33.         return -1;
  34.     }
  35.     
  36.     /* stripe size */
  37.     ui_stripe_size = strips[ui_count - 1].offset + 
  38.         strips[ui_count - 1].size;
  39.     ui_stripe_nr = logical_offset / ui_stripe_size;
  40.     /* search my strips */
  41.     for(ii = 0; ii < ui_count; ii++)
  42.     {
  43.         if (strips[ii].server_nr == server_nr)
  44.         {
  45.             if ((logical_offset >= (ui_stripe_nr * ui_stripe_size) + 
  46.                                    strips[ii].offset) &&
  47.                 (logical_offset <= (ui_stripe_nr * ui_stripe_size) + 
  48.                                    strips[ii].offset + strips[ii].size - 1))
  49.             {
  50.                 unsigned int jj;
  51.                 PVFS_offset ui_offset_in_strips;
  52.                 
  53.                 /* get size of all strips in the stripe of this server */
  54.                 /* and get the size of all strips of this server that are */
  55.                 /* before the current Strips */
  56.                 PVFS_size ui_size_of_all_my_strips_in_stripe = 0;
  57.                 PVFS_size ui_size_of_my_strips_before_current = 0;
  58.                 for (jj = 0; jj < ui_count; jj++)
  59.                 {
  60.                     if (strips[jj].server_nr == server_nr)
  61.                     {
  62.                         ui_size_of_all_my_strips_in_stripe += strips[jj].size;
  63.                         if (jj < ii)
  64.                         {
  65.                             ui_size_of_my_strips_before_current += 
  66.                                 strips[jj].size;
  67.                         }
  68.                     }
  69.                 }
  70.                 
  71.                 ui_offset_in_strips = logical_offset - 
  72.                     (ui_stripe_nr * ui_stripe_size) - strips[ii].offset;
  73.                 
  74.                 PINT_dist_strips_free_mem(&strips);
  75.                 return ui_stripe_nr * ui_size_of_all_my_strips_in_stripe + 
  76.                        ui_size_of_my_strips_before_current + 
  77.                        ui_offset_in_strips;
  78.             }
  79.         }
  80.         /* try next */
  81.     }
  82.     gossip_err("logical_to_physical: todo\n");
  83.     /*
  84.      * todo: logical offsets that do not belong to the current server
  85.      *       I dont know if it is really neccessary to implement this.
  86.      *       In practice I have never seen this error string.
  87.      */
  88.     PINT_dist_strips_free_mem(&strips);
  89.     return 0;
  90. }
  91.  
  92. static PVFS_offset physical_to_logical_offset(void* params,
  93.                                               PINT_request_file_data* fd,
  94.                                               PVFS_offset physical_offset)
  95. {
  96.     /* parse parameter */
  97.     PINT_dist_strips *strips;
  98.     unsigned int ui_count, jj, ui_stripe_nr, ii;
  99.     uint32_t server_nr = fd->server_nr;
  100.     PVFS_size ui_size_of_strips_in_stripe = 0;
  101.     PVFS_offset ui_physical_offset_in_stripe;
  102.     PVFS_offset ui_offset_in_stripe = 0;
  103.  
  104.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  105.  
  106.     if (PINT_dist_strips_parse(
  107.             varstrip_params->strips, &strips, &ui_count) == -1)
  108.     {
  109.         return -1;
  110.     }
  111.     
  112.     /* to what stripe belongs that physical offset? */
  113.     /* must get size of strips of this server in one stripe first */
  114.     for (jj = 0; jj < ui_count; jj++)
  115.     {
  116.         if (strips[jj].server_nr == server_nr)
  117.         {
  118.             ui_size_of_strips_in_stripe += strips[jj].size;
  119.         }
  120.     }
  121.     ui_stripe_nr = physical_offset / ui_size_of_strips_in_stripe;
  122.  
  123.     /* now get the Strips number in the 
  124.      * stripe the physical offset belongs to */
  125.     ui_physical_offset_in_stripe = 
  126.         physical_offset - ui_stripe_nr * ui_size_of_strips_in_stripe;
  127.     for(ii = 0; ii < ui_count; ii++)
  128.     {
  129.         if (strips[ii].server_nr == server_nr)
  130.         {
  131.             if (ui_physical_offset_in_stripe < 
  132.                 ui_offset_in_stripe + strips[ii].size)
  133.             {
  134.                 /* found! */
  135.                 PVFS_offset logical_offset = ui_stripe_nr * 
  136.                     (strips[ui_count - 1].offset + strips[ui_count - 1].size) + 
  137.                     strips[ii].offset + 
  138.                     (ui_physical_offset_in_stripe - ui_offset_in_stripe);
  139.                 PINT_dist_strips_free_mem(&strips);
  140.                 return logical_offset;
  141.             }
  142.             else
  143.             {
  144.                 ui_offset_in_stripe += strips[ii].size;
  145.             }
  146.         }
  147.         /* try next */
  148.     }
  149.     /* error! */
  150.     gossip_err("ERROR in varstrip distribution in "
  151.                "function physical_to_logical: no fitting strip found!\n");
  152.     PINT_dist_strips_free_mem(&strips);
  153.     return -1;
  154. }
  155.  
  156. static PVFS_offset next_mapped_offset(void* params,
  157.                                       PINT_request_file_data* fd,
  158.                                       PVFS_offset logical_offset)
  159. {
  160.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  161.     /* parse parameter */
  162.     PINT_dist_strips *strips;
  163.     unsigned int ui_count, ii, ui_stripe_nr;
  164.     uint32_t server_nr = fd->server_nr;
  165.     PVFS_size ui_stripe_size;
  166.     PVFS_offset ui_offset_in_stripe;
  167.  
  168.     if (PINT_dist_strips_parse(
  169.             varstrip_params->strips, &strips, &ui_count) == -1)
  170.     {
  171.         return -1;
  172.     }
  173.  
  174.     /* get number of stripes */
  175.     ui_stripe_size = 
  176.         strips[ui_count - 1].offset +
  177.         strips[ui_count - 1].size;
  178.     ui_stripe_nr = logical_offset / ui_stripe_size;
  179.  
  180.     /* get offset in stripe */
  181.     ui_offset_in_stripe = 
  182.         logical_offset - (ui_stripe_nr * ui_stripe_size);
  183.  
  184.     /* get Strips number */
  185.     ii = 0;
  186.     for(ii = 0; ii < ui_count; ii++)
  187.     {
  188.         if ((ui_offset_in_stripe >= strips[ii].offset) &&
  189.             (ui_offset_in_stripe <= strips[ii].offset + strips[ii].size - 1))
  190.         {
  191.             /* found! */
  192.             break;
  193.         }
  194.     }
  195.     if (strips[ii].server_nr == server_nr)
  196.     {
  197.         /* logical offset is part of my Strips */
  198.         PINT_dist_strips_free_mem(&strips);
  199.         return logical_offset;
  200.     }
  201.     else
  202.     {
  203.         /* search my next Strips */
  204.         unsigned int jj;
  205.         for (jj = ii + 1; jj < ui_count; jj++)
  206.         {
  207.             if (strips[jj].server_nr == server_nr)
  208.             {
  209.                 /* found! */
  210.                 PVFS_offset ui_next_mapped_offset = 
  211.                     ui_stripe_nr * ui_stripe_size + strips[jj].offset;
  212.                 PINT_dist_strips_free_mem(&strips);
  213.                 return ui_next_mapped_offset;
  214.             }
  215.         }
  216.         /* not found! */
  217.         /* -> next stripe */
  218.         ui_stripe_nr++;
  219.         for (jj = 0; jj < ui_count; jj++)
  220.         {
  221.             if (strips[jj].server_nr == server_nr)
  222.             {
  223.                 PVFS_offset ui_next_mapped_offset = 
  224.                     ui_stripe_nr * ui_stripe_size + strips[jj].offset;
  225.                 PINT_dist_strips_free_mem(&strips);
  226.                 return ui_next_mapped_offset;
  227.             }
  228.         }
  229.     }
  230.     /* huh? this is an error */
  231.     PINT_dist_strips_free_mem(&strips);
  232.     gossip_err("ERROR in varstrip distribution in "
  233.                "next_mapped_offset: Did not find my next offset\n");
  234.     return -1;
  235. }
  236.  
  237. static PVFS_size contiguous_length(void* params,
  238.                                    PINT_request_file_data* fd,
  239.                                    PVFS_offset physical_offset)
  240. {
  241.     PVFS_varstrip_params* varstrip_params;
  242.     /* convert to a logical offset */
  243.      
  244.     /* parse parameter */
  245.     PINT_dist_strips *strips;
  246.     PVFS_offset ui_offset_in_stripe, logical_offset;
  247.     unsigned int ui_count, ii, ui_stripe_nr, ui_stripe_size;
  248.  
  249.     logical_offset = physical_to_logical_offset(
  250.         params, fd, physical_offset);
  251.     
  252.     varstrip_params = (PVFS_varstrip_params*)params;
  253.  
  254.     if (PINT_dist_strips_parse(
  255.             varstrip_params->strips, &strips, &ui_count) == -1)
  256.     {
  257.         return -1;
  258.     }
  259.     
  260.     /* get number of stripes */
  261.     ui_stripe_size = strips[ui_count - 1].offset +
  262.         strips[ui_count - 1].size;
  263.     ui_stripe_nr = logical_offset / ui_stripe_size;
  264.     /* get offset in stripe */
  265.     ui_offset_in_stripe = logical_offset - (ui_stripe_nr * ui_stripe_size);
  266.     /* get Strips */
  267.     for(ii = 0; ii < ui_count; ii++)
  268.     {
  269.         if ((ui_offset_in_stripe >= strips[ii].offset) &&
  270.             (ui_offset_in_stripe <= strips[ii].offset + strips[ii].size - 1))
  271.         {
  272.             /* found! */
  273.             PVFS_size ui_contiguous_length = strips[ii].offset + 
  274.                 strips[ii].size - ui_offset_in_stripe;
  275.             PINT_dist_strips_free_mem(&strips);
  276.             
  277.             return ui_contiguous_length;
  278.         }
  279.     }
  280.     /* error! */
  281.     gossip_err("ERROR in varstrip distribution in "
  282.                "function contiguous_length: no fitting strip found\n");
  283.     PINT_dist_strips_free_mem(&strips);
  284.     return 0;
  285. }
  286.  
  287. static PVFS_size logical_file_size(void* params,
  288.                                    uint32_t server_ct,
  289.                                    PVFS_size *psizes)
  290. {
  291.     PVFS_size ui_file_size = 0;
  292.     uint32_t ii;
  293.     
  294.     if (!psizes)
  295.         return -1;
  296.     for (ii = 0; ii < server_ct; ii++)
  297.     {
  298.         ui_file_size += psizes[ii];
  299.     }
  300.     return ui_file_size;
  301. }
  302.  
  303. static int get_num_dfiles(void* params,
  304.                           uint32_t num_servers_requested,
  305.                           uint32_t num_dfiles_requested)
  306. {
  307.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  308.     /* parse parameter */
  309.     PINT_dist_strips *strips;
  310.     unsigned int i_highest_data_file_number = 0;
  311.     unsigned int ii, ui_count;
  312.  
  313.     if (PINT_dist_strips_parse(
  314.             varstrip_params->strips, &strips, &ui_count) == -1)
  315.     {
  316.         /* error */
  317.         return -1;
  318.     }
  319.     /* get highest requested data file number */
  320.     for (ii = 0; ii < ui_count; ii++)
  321.     {
  322.         if (strips[ii].server_nr > i_highest_data_file_number)
  323.         {
  324.             i_highest_data_file_number = strips[ii].server_nr;
  325.         }
  326.     }
  327.     /* are all data file numbers available in string? */
  328.     for (ii = 0; ii < i_highest_data_file_number; ii++)
  329.     {
  330.         int b_found = 0;
  331.         unsigned int jj;
  332.         for (jj = 0; jj < ui_count; jj++)
  333.         {
  334.             if (strips[jj].server_nr == ii)
  335.             {
  336.                 b_found = 1;
  337.                 break;
  338.             }
  339.         }
  340.         if (!b_found)
  341.         {
  342.             gossip_err("ERROR in varstrip distribution: The strip "
  343.                        "partitioning string must contain all data "
  344.                        "file numbers from 0 to the highest one specified!\n");
  345.             return -1;
  346.         }
  347.     }
  348.     PINT_dist_strips_free_mem(&strips);
  349.     i_highest_data_file_number++;
  350.     if (i_highest_data_file_number > num_servers_requested)
  351.     {
  352.         gossip_err("ERROR in varstrip distribution: There are more "
  353.                    "data files specified in strip partitioning string "
  354.                    "than servers available!\n");
  355.         return -1;
  356.     }
  357.     return i_highest_data_file_number;
  358. }
  359.  
  360. /* its like the default one but assures that last character is \0
  361.  * we need null terminated strings!
  362.  */
  363. static int set_param(const char* dist_name, void* params,
  364.                     const char* param_name, void* value)
  365. {
  366.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  367.     if (strcmp(param_name, "strips") == 0)
  368.     {
  369.         if (strlen((char *)value) == 0)
  370.         {
  371.             gossip_err("ERROR: Parameter 'strips' empty!\n");
  372.         }
  373.         else
  374.         {
  375.             if (strlen((char *)value) > 
  376.                 PVFS_DIST_VARSTRIP_MAX_STRIPS_STRING_LENGTH)
  377.             {
  378.                 gossip_err("ERROR: Parameter 'strips' too long!\n");
  379.             }
  380.             else
  381.             {
  382.                 strcpy(varstrip_params->strips, (char *)value);
  383.             }
  384.         }
  385.     }
  386.     return 0;
  387. }
  388.  
  389.  
  390. static void encode_params(char **pptr, void* params)
  391. {
  392.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  393.     encode_string(pptr, &varstrip_params->strips);
  394. }
  395.  
  396. static void decode_params(char **pptr, void* params)
  397. {
  398.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  399.     decode_here_string(pptr, varstrip_params->strips);
  400. }
  401.  
  402. static void registration_init(void* params)
  403. {
  404.     PINT_dist_register_param(PVFS_DIST_VARSTRIP_NAME, "strips",
  405.             PVFS_varstrip_params, strips);
  406. }
  407.  
  408. static void unregister(void)
  409. {
  410.     PINT_dist_unregister_param(PVFS_DIST_VARSTRIP_NAME, "strips");
  411. }
  412.  
  413. static char *params_string(void *params)
  414. {
  415.     PVFS_varstrip_params* dparam = (PVFS_varstrip_params*)params;
  416.  
  417.     return strdup(dparam->strips);
  418. }
  419.  
  420. static PVFS_size get_blksize(void* params)
  421. {
  422.     PVFS_varstrip_params* varstrip_params = (PVFS_varstrip_params*)params;
  423.     PINT_dist_strips *strips;
  424.     uint32_t ui_count;
  425.     PVFS_size blksize;
  426.  
  427.     if (PINT_dist_strips_parse(
  428.             varstrip_params->strips, &strips, &ui_count) == -1)
  429.     {
  430.         return -1;
  431.     }
  432.  
  433.     /* report the first trip size in the set as the block size */
  434.     blksize = strips[0].size;
  435.  
  436.     PINT_dist_strips_free_mem(&strips);
  437.  
  438.     return(blksize);
  439. }
  440.  
  441. static PVFS_varstrip_params varstrip_params = { "\0" };
  442.  
  443. static PINT_dist_methods varstrip_methods = {
  444.     logical_to_physical_offset,
  445.     physical_to_logical_offset,
  446.     next_mapped_offset,
  447.     contiguous_length,
  448.     logical_file_size,
  449.     get_num_dfiles,
  450.     set_param,
  451.     get_blksize,
  452.     encode_params,
  453.     decode_params,
  454.     registration_init,
  455.     unregister,
  456.     params_string
  457. };
  458.  
  459. PINT_dist varstrip_dist = {
  460.     .dist_name = PVFS_DIST_VARSTRIP_NAME,
  461.     .name_size = roundup8(PVFS_DIST_VARSTRIP_NAME_SIZE), /* name size */
  462.     .param_size = roundup8(sizeof(PVFS_varstrip_params)), /* param size */
  463.     .params = &varstrip_params,
  464.     .methods = &varstrip_methods
  465. };
  466.  
  467. /*
  468.  * Local variables:
  469.  *  mode: c
  470.  *  c-indent-level: 4
  471.  *  c-varstrip-offset: 4
  472.  * End:
  473.  *
  474.  * vim: ft=c ts=8 sts=4 sw=4 expandtab
  475.  */
  476.