From 08b74fd5f5627f8f10f75ce9d12443a0abed86f8 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 524cbc5..2a579cb 100644 --- a/src/VfsNs.cpp +++ b/src/VfsNs.cpp @@ -445,6 +445,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++; @@ -453,6 +454,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); @@ -1384,6 +1400,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