From: František Dvořák Date: Sun, 1 Dec 2013 20:41:50 +0000 (+0100) Subject: Check duplicity of RFN during adding or updating replicas. X-Git-Url: http://scientific.zcu.cz/git/?a=commitdiff_plain;h=76eee24595b710b461e19e33b2fb7f3e480ef832;p=dmlite-plugins-vfs.git Check duplicity of RFN during adding or updating replicas. --- 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()) {