"Fossies" - the Fresh Open Source Software Archive

Member "glusterfs-8.2/xlators/cluster/ec/src/ec-helpers.h" (16 Sep 2020, 5437 Bytes) of package /linux/misc/glusterfs-8.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ec-helpers.h" see the Fossies "Dox" file reference documentation.

    1 /*
    2   Copyright (c) 2012-2014 DataLab, s.l. <http://www.datalab.es>
    3   This file is part of GlusterFS.
    4 
    5   This file is licensed to you under your choice of the GNU Lesser
    6   General Public License, version 3 or any later version (LGPLv3 or
    7   later), or the GNU General Public License, version 2 (GPLv2), in all
    8   cases as published by the Free Software Foundation.
    9 */
   10 
   11 #ifndef __EC_HELPERS_H__
   12 #define __EC_HELPERS_H__
   13 
   14 #include "ec-types.h"
   15 
   16 #define EC_ERR(_x) ((void *)-(intptr_t)(_x))
   17 #define EC_IS_ERR(_x) (((uintptr_t)(_x) & ~0xfffULL) == ~0xfffULL)
   18 #define EC_GET_ERR(_x) ((int32_t)(intptr_t)(_x))
   19 
   20 #define EC_ALIGN_CHECK(_ptr, _align) ((((uintptr_t)(_ptr)) & ((_align)-1)) == 0)
   21 
   22 const char *
   23 ec_bin(char *str, size_t size, uint64_t value, int32_t digits);
   24 const char *
   25 ec_fop_name(int32_t id);
   26 void
   27 ec_trace(const char *event, ec_fop_data_t *fop, const char *fmt, ...);
   28 int32_t
   29 ec_bits_consume(uint64_t *n);
   30 size_t
   31 ec_iov_copy_to(void *dst, struct iovec *vector, int32_t count, off_t offset,
   32                size_t size);
   33 int32_t
   34 ec_buffer_alloc(xlator_t *xl, size_t size, struct iobref **piobref, void **ptr);
   35 int32_t
   36 ec_dict_set_array(dict_t *dict, char *key, uint64_t *value, int32_t size);
   37 int32_t
   38 ec_dict_get_array(dict_t *dict, char *key, uint64_t value[], int32_t size);
   39 
   40 int32_t
   41 ec_dict_del_array(dict_t *dict, char *key, uint64_t *value, int32_t size);
   42 int32_t
   43 ec_dict_set_number(dict_t *dict, char *key, uint64_t value);
   44 int32_t
   45 ec_dict_del_number(dict_t *dict, char *key, uint64_t *value);
   46 int32_t
   47 ec_dict_set_config(dict_t *dict, char *key, ec_config_t *config);
   48 int32_t
   49 ec_dict_del_config(dict_t *dict, char *key, ec_config_t *config);
   50 
   51 int32_t
   52 ec_loc_parent(xlator_t *xl, loc_t *loc, loc_t *parent);
   53 int32_t
   54 ec_loc_update(xlator_t *xl, loc_t *loc, inode_t *inode, struct iatt *iatt);
   55 
   56 int32_t
   57 ec_loc_from_fd(xlator_t *xl, loc_t *loc, fd_t *fd);
   58 int32_t
   59 ec_loc_from_loc(xlator_t *xl, loc_t *dst, loc_t *src);
   60 
   61 void
   62 ec_owner_set(call_frame_t *frame, void *owner);
   63 void
   64 ec_owner_copy(call_frame_t *frame, gf_lkowner_t *owner);
   65 
   66 ec_inode_t *
   67 __ec_inode_get(inode_t *inode, xlator_t *xl);
   68 ec_inode_t *
   69 ec_inode_get(inode_t *inode, xlator_t *xl);
   70 ec_fd_t *
   71 __ec_fd_get(fd_t *fd, xlator_t *xl);
   72 ec_fd_t *
   73 ec_fd_get(fd_t *fd, xlator_t *xl);
   74 
   75 static inline uint32_t
   76 ec_adjust_size_down(ec_t *ec, uint64_t *value, gf_boolean_t scale)
   77 {
   78     uint64_t head, tmp;
   79 
   80     tmp = *value;
   81     head = tmp % ec->stripe_size;
   82     tmp -= head;
   83 
   84     if (scale) {
   85         tmp /= ec->fragments;
   86     }
   87 
   88     *value = tmp;
   89 
   90     return (uint32_t)head;
   91 }
   92 
   93 /* This function can cause an overflow if the passed value is too near to the
   94  * uint64_t limit. If this happens, it returns the tail in negative form and
   95  * the value is set to UINT64_MAX. */
   96 static inline int32_t
   97 ec_adjust_size_up(ec_t *ec, uint64_t *value, gf_boolean_t scale)
   98 {
   99     uint64_t tmp;
  100     int32_t tail;
  101 
  102     tmp = *value;
  103     /* We first adjust the value down. This never causes overflow. */
  104     tail = ec_adjust_size_down(ec, &tmp, scale);
  105 
  106     /* If the value was already aligned, tail will be 0 and nothing else
  107      * needs to be done. */
  108     if (tail != 0) {
  109         /* Otherwise, we need to compute the real tail and adjust the
  110          * returned value to the next stripe. */
  111         tail = ec->stripe_size - tail;
  112         if (scale) {
  113             tmp += ec->fragment_size;
  114         } else {
  115             tmp += ec->stripe_size;
  116             /* If no scaling is requested there's a possibility of
  117              * overflow. */
  118             if (tmp < ec->stripe_size) {
  119                 tmp = UINT64_MAX;
  120                 tail = -tail;
  121             }
  122         }
  123     }
  124 
  125     *value = tmp;
  126 
  127     return tail;
  128 }
  129 
  130 /* This function is equivalent to ec_adjust_size_down() but with a potentially
  131  * different parameter size (off_t vs uint64_t). */
  132 static inline uint32_t
  133 ec_adjust_offset_down(ec_t *ec, off_t *value, gf_boolean_t scale)
  134 {
  135     off_t head, tmp;
  136 
  137     tmp = *value;
  138     head = tmp % ec->stripe_size;
  139     tmp -= head;
  140 
  141     if (scale) {
  142         tmp /= ec->fragments;
  143     }
  144 
  145     *value = tmp;
  146 
  147     return (uint32_t)head;
  148 }
  149 
  150 /* This function is equivalent to ec_adjust_size_up() but with a potentially
  151  * different parameter size (off_t vs uint64_t). */
  152 static inline int32_t
  153 ec_adjust_offset_up(ec_t *ec, off_t *value, gf_boolean_t scale)
  154 {
  155     uint64_t tail, tmp;
  156 
  157     /* An offset is a signed type that can only have positive values, so
  158      * we take advantage of this to avoid overflows. We simply convert it
  159      * to an unsigned integer and operate normally. This won't cause an
  160      * overflow. Overflow is only checked when converting back to an
  161      * off_t. */
  162     tmp = *value;
  163     tail = ec->stripe_size;
  164     tail -= (tmp + tail - 1) % tail + 1;
  165     tmp += tail;
  166     if (scale) {
  167         /* If we are scaling, we'll never get an overflow. */
  168         tmp /= ec->fragments;
  169     } else {
  170         /* Check if there has been an overflow. */
  171         if ((off_t)tmp < 0) {
  172             tmp = GF_OFF_MAX;
  173             tail = -tail;
  174         }
  175     }
  176 
  177     *value = (off_t)tmp;
  178 
  179     return (int32_t)tail;
  180 }
  181 
  182 static inline int32_t
  183 ec_is_power_of_2(uint32_t value)
  184 {
  185     return (value != 0) && ((value & (value - 1)) == 0);
  186 }
  187 
  188 gf_boolean_t
  189 ec_is_internal_xattr(dict_t *dict, char *key, data_t *value, void *data);
  190 
  191 void
  192 ec_filter_internal_xattrs(dict_t *xattr);
  193 
  194 gf_boolean_t
  195 ec_is_data_fop(glusterfs_fop_t fop);
  196 
  197 int32_t
  198 ec_launch_replace_heal(ec_t *ec);
  199 
  200 #endif /* __EC_HELPERS_H__ */