summaryrefslogtreecommitdiffstats
path: root/xlators/cluster/ec/src/ec-common.c
diff options
context:
space:
mode:
authorXavier Hernandez <xhernandez@datalab.es>2014-09-18 16:50:47 +0200
committerVijay Bellur <vbellur@redhat.com>2014-09-23 09:12:32 -0700
commit5f79d6e08fbb930aa67dd59eb39cbece6f138b59 (patch)
treee647841e8b8423ef097f529d7cbdf7f11de0aafa /xlators/cluster/ec/src/ec-common.c
parent933e5bd5a7b32394c7a3c6e84543dc48ed24a732 (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.c67
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;
}