diff options
author | Xavier Hernandez <xhernandez@datalab.es> | 2014-09-18 16:50:47 +0200 |
---|---|---|
committer | Vijay Bellur <vbellur@redhat.com> | 2014-09-23 09:12:32 -0700 |
commit | 5f79d6e08fbb930aa67dd59eb39cbece6f138b59 (patch) | |
tree | e647841e8b8423ef097f529d7cbdf7f11de0aafa /xlators/cluster/ec/src/ec-common.c | |
parent | 933e5bd5a7b32394c7a3c6e84543dc48ed24a732 (diff) |
ec: Add config information in an xattr
To simplify backward compatibility of the ec xlator when some
parameter or the implementation itself is changed, a new xattr
is added to each file with the configuration needed to recover
it.
The new attribute is called 'trusted.ec.config', and it's a 64-bit
value containing the following information:
8 bits: version of the config information (currently always 0)
8 bits: algorithm used to encode the file (currently always 0)
8 bits: size of the galois field (currently always 8)
8 bits: number of bricks
8 bits: redundancy
24 bits: chunk size (currently 512)
This new xattr could allow, in a future version, to have different
configurations per file.
Change-Id: I8c12d40ff546cc201fc66caa367484be3d48aeb4
BUG: 1140861
Signed-off-by: Xavier Hernandez <xhernandez@datalab.es>
Reviewed-on: http://review.gluster.org/8770
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Dan Lambright <dlambrig@redhat.com>
Reviewed-by: Vijay Bellur <vbellur@redhat.com>
Diffstat (limited to 'xlators/cluster/ec/src/ec-common.c')
-rw-r--r-- | xlators/cluster/ec/src/ec-common.c | 67 |
1 files changed, 66 insertions, 1 deletions
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c index 6d4855a9656..a7cf23d24bb 100644 --- a/xlators/cluster/ec/src/ec-common.c +++ b/xlators/cluster/ec/src/ec-common.c @@ -26,6 +26,7 @@ #include "ec-combine.h" #include "ec-common.h" #include "ec-fops.h" +#include "ec-method.h" #include "ec.h" int32_t ec_child_valid(ec_t * ec, ec_fop_data_t * fop, int32_t idx) @@ -992,12 +993,75 @@ int32_t ec_get_size_version_set(call_frame_t * frame, void * cookie, struct iatt * buf, dict_t * xdata, struct iatt * postparent) { + ec_t * ec; ec_fop_data_t * fop = cookie; ec_inode_t * ctx; ec_lock_t * lock; if (op_ret >= 0) { + if (buf->ia_type == IA_IFREG) + { + if (ec_dict_del_config(xdata, EC_XATTR_CONFIG, &fop->config) < 0) + { + gf_log(this->name, GF_LOG_ERROR, "Failed to get a valid " + "config"); + + ec_fop_set_error(fop, EIO); + + return 0; + } + ec = this->private; + if ((fop->config.version != EC_CONFIG_VERSION) || + (fop->config.algorithm != EC_CONFIG_ALGORITHM) || + (fop->config.gf_word_size != EC_GF_BITS) || + (fop->config.bricks != ec->nodes) || + (fop->config.redundancy != ec->redundancy) || + (fop->config.chunk_size != EC_METHOD_CHUNK_SIZE)) + { + uint32_t data_bricks; + + // This combination of version/algorithm requires the following + // values. Incorrect values for these fields are a sign of + // corruption: + // + // redundancy > 0 + // redundancy * 2 < bricks + // gf_word_size must be a power of 2 + // chunk_size (in bits) must be a multiple of gf_word_size * + // (bricks - redundancy) + + data_bricks = fop->config.bricks - fop->config.redundancy; + if ((fop->config.redundancy < 1) || + (fop->config.redundancy * 2 >= fop->config.bricks) || + !ec_is_power_of_2(fop->config.gf_word_size) || + ((fop->config.chunk_size * 8) % (fop->config.gf_word_size * + data_bricks) != 0)) + { + gf_log(this->name, GF_LOG_ERROR, "Invalid or corrupted " + "config (V=%u, A=%u, " + "W=%u, N=%u, R=%u, S=%u)", + fop->config.version, fop->config.algorithm, + fop->config.gf_word_size, fop->config.bricks, + fop->config.redundancy, fop->config.chunk_size); + } + else + { + gf_log(this->name, GF_LOG_ERROR, "Unsupported config " + "(V=%u, A=%u, W=%u, " + "N=%u, R=%u, S=%u)", + fop->config.version, fop->config.algorithm, + fop->config.gf_word_size, fop->config.bricks, + fop->config.redundancy, fop->config.chunk_size); + } + + ec_fop_set_error(fop, EIO); + + return 0; + } + } + + LOCK(&inode->lock); ctx = __ec_inode_get(inode, this); @@ -1065,7 +1129,8 @@ void ec_get_size_version(ec_fop_data_t * fop) goto out; } if ((dict_set_uint64(xdata, EC_XATTR_VERSION, 0) != 0) || - (dict_set_uint64(xdata, EC_XATTR_SIZE, 0) != 0)) + (dict_set_uint64(xdata, EC_XATTR_SIZE, 0) != 0) || + (dict_set_uint64(xdata, EC_XATTR_CONFIG, 0) != 0)) { goto out; } |