if (checkPermissions(this->secCtx_, meta.acl, meta.stat, S_IWRITE) != 0)
vfsThrow(EACCES, "not enough permissions for '%s' to add replica '%s'", clientName.c_str(), path.c_str());
+ // new replica ID
replicaid = 0;
do {
replicaid++;
} while (meta.hasField(attr1));
attr2 = std::string(VFS_XATTR "repattrs.") + buf;
+ // check duplicity of RFN
+ for (Extensible::const_iterator it = meta.begin(); it != meta.end(); it++) {
+ std::string key, value;
+ Replica rep;
+
+ key = it->first;
+ value = Extensible::anyToString(it->second);
+ if (key.compare(0, VFS_XATTR_LENGTH + 8, VFS_XATTR "replica.") == 0) {
+ rep = replicaDeserialize(value, "");
+ if (rep.rfn.compare(replica.rfn) == 0) {
+ vfsThrow(EEXIST, "RFN '%s' already exists on '%s'", replica.rfn.c_str(), path.c_str());
+ }
+ }
+ }
+
replicaSerialize(replica, attrval1, attrval2);
vfsSetXattr(path, getLocalPath(path), attr1, attrval1, ATTR_CREATE);
vfsThrow(DMLITE_NO_SUCH_REPLICA, "replica %lu of '%s' doesn't exist", replica.replicaid, path.c_str());
attr2 = std::string(VFS_XATTR "repattrs.") + buf;
+ // check duplicity of RFN
+ for (Extensible::const_iterator it = meta.begin(); it != meta.end(); it++) {
+ std::string key, value;
+ Replica rep;
+ int64_t repid;
+
+ key = it->first;
+ value = Extensible::anyToString(it->second);
+ if (key.compare(0, VFS_XATTR_LENGTH + 8, VFS_XATTR "replica.") == 0) {
+ repid = atoll(key.c_str() + VFS_XATTR_LENGTH + 8);
+ // skip the currently updated replica (RFN may be the same)
+ if (repid == replica.replicaid) continue;
+ rep = replicaDeserialize(value, "");
+ if (rep.rfn.compare(replica.rfn) == 0) {
+ vfsThrow(EEXIST, "RFN '%s' already exists on '%s'", replica.rfn.c_str(), path.c_str());
+ }
+ }
+ }
+
replicaSerialize(replica, attrval1, attrval2);
vfsSetXattr(path, getLocalPath(path), attr1, attrval1, ATTR_REPLACE);
if (attrval2.empty()) {