From 76eee24595b710b461e19e33b2fb7f3e480ef832 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Franti=C5=A1ek=20Dvo=C5=99=C3=A1k?= Date: Sun, 1 Dec 2013 21:41:50 +0100 Subject: [PATCH] Check duplicity of RFN during adding or updating replicas. --- src/VfsNs.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/VfsNs.cpp b/src/VfsNs.cpp index 0bf63b9..6e5f8a2 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -450,6 +450,7 @@ void VfsCatalog::addReplica(const Replica& replica) throw (DmException) 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++; @@ -458,6 +459,21 @@ void VfsCatalog::addReplica(const Replica& replica) throw (DmException) } 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); @@ -1389,6 +1405,25 @@ void VfsCatalog::updateReplica(const Replica& replica) throw (DmException) 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()) { -- 1.8.2.3