summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--xlators/cluster/ec/src/ec-common.c283
-rw-r--r--xlators/cluster/ec/src/ec-common.h1
-rw-r--r--xlators/cluster/ec/src/ec-data.h2
-rw-r--r--xlators/cluster/ec/src/ec-generic.c30
-rw-r--r--xlators/cluster/ec/src/ec-heal.c93
-rw-r--r--xlators/cluster/ec/src/ec-inode-read.c4
-rw-r--r--xlators/cluster/ec/src/ec-inode-write.c4
-rw-r--r--xlators/cluster/ec/src/ec.h1
8 files changed, 297 insertions, 121 deletions
diff --git a/xlators/cluster/ec/src/ec-common.c b/xlators/cluster/ec/src/ec-common.c
index fcae083aa84..92f7657cd75 100644
--- a/xlators/cluster/ec/src/ec-common.c
+++ b/xlators/cluster/ec/src/ec-common.c
@@ -936,78 +936,77 @@ void ec_lock(ec_fop_data_t * fop)
}
}
+gf_boolean_t
+ec_config_check (ec_fop_data_t *fop, dict_t *xdata)
+{
+ ec_t *ec;
+
+ if (ec_dict_del_config(xdata, EC_XATTR_CONFIG, &fop->config) < 0) {
+ gf_log(fop->xl->name, GF_LOG_ERROR, "Failed to get a valid "
+ "config");
+
+ ec_fop_set_error(fop, EIO);
+
+ return _gf_false;
+ }
+
+ ec = fop->xl->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(fop->xl->name, GF_LOG_ERROR, "Invalid or corrupted config");
+ } else {
+ gf_log(fop->xl->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 _gf_false;
+ }
+
+ return _gf_true;
+}
+
int32_t ec_get_size_version_set(call_frame_t * frame, void * cookie,
xlator_t * this, int32_t op_ret,
int32_t op_errno, inode_t * inode,
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 = NULL;
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;
- }
+ if ((buf->ia_type == IA_IFREG) && !ec_config_check(fop, xdata)) {
+ return 0;
}
LOCK(&inode->lock);
@@ -1053,6 +1052,58 @@ int32_t ec_get_size_version_set(call_frame_t * frame, void * cookie,
return 0;
}
+int32_t ec_prepare_update_cbk(call_frame_t *frame, void *cookie,
+ xlator_t *this, int32_t op_ret, int32_t op_errno,
+ dict_t *dict, dict_t *xdata)
+{
+ ec_fop_data_t *fop = cookie, *parent;
+ ec_lock_t *lock = NULL;
+
+ if (op_ret >= 0) {
+ parent = fop->parent;
+ while ((parent != NULL) && (parent->locks[0].lock == NULL)) {
+ parent = parent->parent;
+ }
+ if (parent == NULL) {
+ return 0;
+ }
+
+ lock = parent->locks[0].lock;
+ lock->is_dirty = _gf_true;
+
+ if (!ec_config_check(fop, dict)) {
+ return 0;
+ }
+
+ LOCK(&lock->loc.inode->lock);
+
+ if ((ec_dict_del_number(dict, EC_XATTR_VERSION, &lock->version) != 0) ||
+ (ec_dict_del_number(dict, EC_XATTR_SIZE, &lock->size) != 0)) {
+ UNLOCK(&lock->loc.inode->lock);
+
+ ec_fop_set_error(fop, EIO);
+
+ return 0;
+ }
+
+ lock->have_size = 1;
+
+ UNLOCK(&lock->loc.inode->lock);
+
+ fop->parent->mask &= fop->good;
+
+ fop->parent->pre_size = fop->parent->post_size = lock->size;
+ fop->parent->have_size = 1;
+ } else {
+ gf_log(this->name, GF_LOG_WARNING,
+ "Failed to get size and version (error %d: %s)", op_errno,
+ strerror (op_errno));
+ ec_fop_set_error(fop, op_errno);
+ }
+
+ return 0;
+}
+
void ec_get_size_version(ec_fop_data_t * fop)
{
loc_t loc;
@@ -1085,7 +1136,8 @@ void ec_get_size_version(ec_fop_data_t * fop)
}
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_CONFIG, 0) != 0))
+ (dict_set_uint64(xdata, EC_XATTR_CONFIG, 0) != 0) ||
+ (dict_set_uint64(xdata, EC_XATTR_DIRTY, 0) != 0))
{
goto out;
}
@@ -1141,7 +1193,84 @@ out:
dict_unref(xdata);
}
- ec_fop_set_error(fop, error);
+ if (error != 0) {
+ ec_fop_set_error(fop, error);
+ }
+}
+
+void ec_prepare_update(ec_fop_data_t *fop)
+{
+ loc_t loc;
+ dict_t *xdata;
+ ec_fop_data_t *tmp;
+ ec_lock_t *lock;
+ uid_t uid;
+ gid_t gid;
+ int32_t error = ENOMEM;
+
+ tmp = fop;
+ while ((tmp != NULL) && (tmp->locks[0].lock == NULL)) {
+ tmp = tmp->parent;
+ }
+ if ((tmp != NULL) && tmp->locks[0].lock->is_dirty) {
+ lock = tmp->locks[0].lock;
+
+ fop->pre_size = fop->post_size = lock->size;
+ fop->have_size = 1;
+
+ return;
+ }
+
+ memset(&loc, 0, sizeof(loc));
+
+ xdata = dict_new();
+ if (xdata == NULL) {
+ goto out;
+ }
+ if ((ec_dict_set_number(xdata, EC_XATTR_VERSION, 0) != 0) ||
+ (ec_dict_set_number(xdata, EC_XATTR_SIZE, 0) != 0) ||
+ (ec_dict_set_number(xdata, EC_XATTR_CONFIG, 0) != 0) ||
+ (ec_dict_set_number(xdata, EC_XATTR_DIRTY, 1) != 0)) {
+ goto out;
+ }
+
+ uid = fop->frame->root->uid;
+ gid = fop->frame->root->gid;
+
+ fop->frame->root->uid = 0;
+ fop->frame->root->gid = 0;
+
+ error = EIO;
+
+ if (!fop->use_fd) {
+ if (ec_loc_from_loc(fop->xl, &loc, &fop->loc[0]) != 0) {
+ goto out;
+ }
+
+ ec_xattrop(fop->frame, fop->xl, fop->mask, fop->minimum,
+ ec_prepare_update_cbk, NULL, &loc, GF_XATTROP_ADD_ARRAY64,
+ xdata, NULL);
+ } else {
+ ec_fxattrop(fop->frame, fop->xl, fop->mask, fop->minimum,
+ ec_prepare_update_cbk, NULL, fop->fd,
+ GF_XATTROP_ADD_ARRAY64, xdata, NULL);
+ }
+
+ fop->frame->root->uid = uid;
+ fop->frame->root->gid = gid;
+
+ error = 0;
+
+out:
+ loc_wipe(&loc);
+
+ if (xdata != NULL) {
+ dict_unref(xdata);
+ }
+
+ if (error != 0) {
+ ec_fop_set_error(fop, error);
+ }
}
int32_t ec_unlocked(call_frame_t *frame, void *cookie, xlator_t *this,
@@ -1221,7 +1350,7 @@ int32_t ec_update_size_version_done(call_frame_t * frame, void * cookie,
}
void ec_update_size_version(ec_fop_data_t *fop, loc_t *loc, uint64_t version,
- uint64_t size, ec_lock_t *lock)
+ uint64_t size, gf_boolean_t dirty, ec_lock_t *lock)
{
dict_t * dict;
uid_t uid;
@@ -1234,7 +1363,8 @@ void ec_update_size_version(ec_fop_data_t *fop, loc_t *loc, uint64_t version,
return;
}
- ec_trace("UPDATE", fop, "version=%ld, size=%ld", version, size);
+ ec_trace("UPDATE", fop, "version=%ld, size=%ld, dirty=%u", version, size,
+ dirty);
dict = dict_new();
if (dict == NULL)
@@ -1242,14 +1372,18 @@ void ec_update_size_version(ec_fop_data_t *fop, loc_t *loc, uint64_t version,
goto out;
}
- if (ec_dict_set_number(dict, EC_XATTR_VERSION, version) != 0)
- {
- goto out;
+ if (version != 0) {
+ if (ec_dict_set_number(dict, EC_XATTR_VERSION, version) != 0) {
+ goto out;
+ }
}
- if (size != 0)
- {
- if (ec_dict_set_number(dict, EC_XATTR_SIZE, size) != 0)
- {
+ if (size != 0) {
+ if (ec_dict_set_number(dict, EC_XATTR_SIZE, size) != 0) {
+ goto out;
+ }
+ }
+ if (dirty) {
+ if (ec_dict_set_number(dict, EC_XATTR_DIRTY, -1) != 0) {
goto out;
}
}
@@ -1286,9 +1420,9 @@ void ec_unlock_now(ec_fop_data_t *fop, ec_lock_t *lock)
{
ec_trace("UNLOCK_NOW", fop, "lock=%p", lock);
- if (lock->version_delta != 0) {
+ if ((lock->version_delta != 0) || lock->is_dirty) {
ec_update_size_version(fop, &lock->loc, lock->version_delta,
- lock->size_delta, lock);
+ lock->size_delta, lock->is_dirty, lock);
} else {
ec_unlock_lock(fop, lock);
}
@@ -1413,7 +1547,8 @@ void ec_flush_size_version(ec_fop_data_t * fop)
if (version > 0)
{
- ec_update_size_version(fop, &lock->loc, version, delta, NULL);
+ ec_update_size_version(fop, &lock->loc, version, delta, _gf_false,
+ NULL);
}
}
diff --git a/xlators/cluster/ec/src/ec-common.h b/xlators/cluster/ec/src/ec-common.h
index 2b1d9574cdf..aaae16e71c3 100644
--- a/xlators/cluster/ec/src/ec-common.h
+++ b/xlators/cluster/ec/src/ec-common.h
@@ -84,6 +84,7 @@ void ec_lock_reuse(ec_fop_data_t *fop);
void ec_unlock(ec_fop_data_t * fop);
void ec_get_size_version(ec_fop_data_t * fop);
+void ec_prepare_update(ec_fop_data_t *fop);
void ec_flush_size_version(ec_fop_data_t * fop);
void ec_dispatch_all(ec_fop_data_t * fop);
diff --git a/xlators/cluster/ec/src/ec-data.h b/xlators/cluster/ec/src/ec-data.h
index 35c84254550..b17f197837b 100644
--- a/xlators/cluster/ec/src/ec-data.h
+++ b/xlators/cluster/ec/src/ec-data.h
@@ -152,6 +152,7 @@ struct _ec_lock
entrylk_type type;
struct gf_flock flock;
};
+ gf_boolean_t is_dirty;
};
struct _ec_lock_link
@@ -253,6 +254,7 @@ struct _ec_cbk_data
struct gf_flock flock;
struct iovec * vector;
struct iobref * buffers;
+ gf_boolean_t dirty;
};
struct _ec_heal
diff --git a/xlators/cluster/ec/src/ec-generic.c b/xlators/cluster/ec/src/ec-generic.c
index bccbc009457..73df0d89db8 100644
--- a/xlators/cluster/ec/src/ec-generic.c
+++ b/xlators/cluster/ec/src/ec-generic.c
@@ -753,16 +753,17 @@ void ec_lookup_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk)
for (i = 0, ans = cbk; (ans != NULL) && (i < ec->fragments);
ans = ans->next)
{
- data = dict_get(ans->xdata, GF_CONTENT_KEY);
- if (data != NULL)
- {
- values[i] = ans->idx;
- blocks[i] = (uint8_t *)data->data;
- if (size > data->len)
+ if (!ans->dirty) {
+ data = dict_get(ans->xdata, GF_CONTENT_KEY);
+ if (data != NULL)
{
- size = data->len;
+ values[i] = ans->idx;
+ blocks[i] = (uint8_t *)data->data;
+ if (size > data->len) {
+ size = data->len;
+ }
+ i++;
}
- i++;
}
}
@@ -871,6 +872,8 @@ int32_t ec_lookup_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
}
if (xdata != NULL)
{
+ uint64_t dirty;
+
cbk->xdata = dict_ref(xdata);
if (cbk->xdata == NULL)
{
@@ -879,6 +882,9 @@ int32_t ec_lookup_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
goto out;
}
+ if (ec_dict_del_number(cbk->xdata, EC_XATTR_DIRTY, &dirty) == 0) {
+ cbk->dirty = dirty != 0;
+ }
}
ec_combine(cbk, ec_combine_lookup);
@@ -938,7 +944,8 @@ int32_t ec_manager_lookup(ec_fop_data_t * fop, int32_t state)
}
}
if ((dict_set_uint64(fop->xdata, EC_XATTR_SIZE, 0) != 0) ||
- (dict_set_uint64(fop->xdata, EC_XATTR_VERSION, 0) != 0))
+ (dict_set_uint64(fop->xdata, EC_XATTR_VERSION, 0) != 0) ||
+ (dict_set_uint64(fop->xdata, EC_XATTR_DIRTY, 0) != 0))
{
gf_log(fop->xl->name, GF_LOG_ERROR, "Unable to prepare lookup "
"request");
@@ -1339,6 +1346,8 @@ int32_t ec_xattrop_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
}
if (xdata != NULL)
{
+ uint64_t dirty;
+
cbk->xdata = dict_ref(xdata);
if (cbk->xdata == NULL)
{
@@ -1347,6 +1356,9 @@ int32_t ec_xattrop_cbk(call_frame_t * frame, void * cookie, xlator_t * this,
goto out;
}
+ if (ec_dict_del_number(cbk->xdata, EC_XATTR_DIRTY, &dirty) == 0) {
+ cbk->dirty = dirty != 0;
+ }
}
ec_combine(cbk, ec_combine_xattrop);
diff --git a/xlators/cluster/ec/src/ec-heal.c b/xlators/cluster/ec/src/ec-heal.c
index c49ccf3fd72..a121bb43e5c 100644
--- a/xlators/cluster/ec/src/ec-heal.c
+++ b/xlators/cluster/ec/src/ec-heal.c
@@ -868,6 +868,28 @@ int32_t ec_heal_open_others(ec_heal_t * heal)
return (open != 0);
}
+uintptr_t ec_heal_needs_data_rebuild(ec_heal_t *heal)
+{
+ ec_fop_data_t *fop = heal->lookup;
+ ec_cbk_data_t *cbk = NULL;
+ uintptr_t bad = 0;
+
+ if ((heal->fop->error != 0) || (heal->good == 0) ||
+ (heal->iatt.ia_type != IA_IFREG)) {
+ return 0;
+ }
+
+ list_for_each_entry(cbk, &fop->cbk_list, list) {
+ if ((cbk->op_ret >= 0) &&
+ ((cbk->size != heal->raw_size) ||
+ (cbk->version != heal->version))) {
+ bad |= cbk->mask;
+ }
+ }
+
+ return bad;
+}
+
void ec_heal_setxattr_others(ec_heal_t * heal)
{
ec_cbk_data_t * cbk;
@@ -892,9 +914,12 @@ void ec_heal_setxattr_others(ec_heal_t * heal)
}
if (cbk->iatt[0].ia_type == IA_IFREG)
{
- if (ec_dict_set_number(xdata, EC_XATTR_SIZE,
- cbk->iatt[0].ia_size) != 0)
- {
+ uint64_t dirty;
+
+ dirty = ec_heal_needs_data_rebuild(heal) != 0;
+ if ((ec_dict_set_number(xdata, EC_XATTR_SIZE,
+ cbk->iatt[0].ia_size) != 0) ||
+ (ec_dict_set_number(xdata, EC_XATTR_DIRTY, dirty) != 0)) {
goto out;
}
}
@@ -968,40 +993,10 @@ void ec_heal_attr(ec_heal_t * heal)
}
}
-int32_t ec_heal_needs_data_rebuild(ec_heal_t * heal)
-{
- ec_fop_data_t * fop = heal->lookup;
- ec_cbk_data_t * cbk = NULL;
- uintptr_t bad = 0;
-
- if ((heal->fop->error != 0) || (heal->good == 0) ||
- (heal->iatt.ia_type != IA_IFREG))
- {
- return 0;
- }
-
- list_for_each_entry(cbk, &fop->cbk_list, list)
- {
- if ((cbk->op_ret >= 0) &&
- ((cbk->size != heal->raw_size) || (cbk->version != heal->version)))
- {
- bad |= cbk->mask;
- }
- }
-
- /* This function can only be called concurrently with entrylk, which do
- * not modify heal structure, so it's safe to access heal->bad without
- * acquiring any lock.
- */
- heal->bad = bad;
-
- return (bad != 0);
-}
-
void ec_heal_open(ec_heal_t * heal)
{
- if (!ec_heal_needs_data_rebuild(heal))
- {
+ heal->bad = ec_heal_needs_data_rebuild(heal);
+ if (heal->bad == 0) {
return;
}
@@ -1115,6 +1110,30 @@ void ec_heal_data(ec_heal_t * heal)
}
}
+void ec_heal_update_dirty(ec_heal_t *heal, uintptr_t mask)
+{
+ dict_t *dict;
+
+ dict = dict_new();
+ if (dict == NULL) {
+ ec_fop_set_error(heal->fop, EIO);
+
+ return;
+ }
+
+ if (ec_dict_set_number(dict, EC_XATTR_DIRTY, -1) != 0) {
+ dict_unref(dict);
+ ec_fop_set_error(heal->fop, EIO);
+
+ return;
+ }
+
+ ec_fxattrop(heal->fop->frame, heal->xl, mask, EC_MINIMUM_ONE, NULL, NULL,
+ heal->fd, GF_XATTROP_ADD_ARRAY64, dict, NULL);
+
+ dict_unref(dict);
+}
+
void ec_heal_dispatch(ec_heal_t *heal)
{
ec_fop_data_t *fop;
@@ -1347,7 +1366,8 @@ int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state)
case EC_STATE_HEAL_UNLOCK_ENTRY:
ec_heal_entrylk(heal, ENTRYLK_UNLOCK);
- if (ec_heal_needs_data_rebuild(heal))
+ heal->bad = ec_heal_needs_data_rebuild(heal);
+ if (heal->bad != 0)
{
return EC_STATE_HEAL_DATA_LOCK;
}
@@ -1385,6 +1405,7 @@ int32_t ec_manager_heal(ec_fop_data_t * fop, int32_t state)
case EC_STATE_HEAL_POST_INODE_LOOKUP:
heal->fixed = heal->bad;
+ ec_heal_update_dirty(heal, heal->bad);
ec_heal_lookup(heal, heal->good);
return EC_STATE_HEAL_SETATTR;
diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c
index 3483dfb3354..d126d48eb12 100644
--- a/xlators/cluster/ec/src/ec-inode-read.c
+++ b/xlators/cluster/ec/src/ec-inode-read.c
@@ -1182,6 +1182,10 @@ out:
int32_t ec_combine_readv(ec_fop_data_t * fop, ec_cbk_data_t * dst,
ec_cbk_data_t * src)
{
+ if (src->dirty) {
+ return 0;
+ }
+
if (!ec_vector_compare(dst->vector, dst->int32, src->vector, src->int32))
{
gf_log(fop->xl->name, GF_LOG_NOTICE, "Mismatching vector in "
diff --git a/xlators/cluster/ec/src/ec-inode-write.c b/xlators/cluster/ec/src/ec-inode-write.c
index 140d59f5f20..ffca89c5f14 100644
--- a/xlators/cluster/ec/src/ec-inode-write.c
+++ b/xlators/cluster/ec/src/ec-inode-write.c
@@ -1374,7 +1374,7 @@ int32_t ec_manager_truncate(ec_fop_data_t * fop, int32_t state)
return EC_STATE_GET_SIZE_AND_VERSION;
case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
+ ec_prepare_update(fop);
return EC_STATE_DISPATCH;
@@ -2016,7 +2016,7 @@ int32_t ec_manager_writev(ec_fop_data_t * fop, int32_t state)
return EC_STATE_GET_SIZE_AND_VERSION;
case EC_STATE_GET_SIZE_AND_VERSION:
- ec_get_size_version(fop);
+ ec_prepare_update(fop);
return EC_STATE_DISPATCH;
diff --git a/xlators/cluster/ec/src/ec.h b/xlators/cluster/ec/src/ec.h
index e5b54b02966..b6a95a11b18 100644
--- a/xlators/cluster/ec/src/ec.h
+++ b/xlators/cluster/ec/src/ec.h
@@ -19,6 +19,7 @@
#define EC_XATTR_SIZE EC_XATTR_PREFIX"size"
#define EC_XATTR_VERSION EC_XATTR_PREFIX"version"
#define EC_XATTR_HEAL EC_XATTR_PREFIX"heal"
+#define EC_XATTR_DIRTY EC_XATTR_PREFIX"dirty"
struct _ec;
typedef struct _ec ec_t;