Commit 94cfdc7c authored by Georgios Bitzes's avatar Georgios Bitzes

NS: Extract core quotanode logic into separate, standalone class

parent 5bdfaa1f
Pipeline #470961 passed with stages
in 41 minutes 49 seconds
......@@ -43,6 +43,9 @@ add_library(
Prefetcher.cc Prefetcher.hh
Resolver.cc Resolver.hh
# Common helper classes, common to both namespaces
common/QuotaNodeCore.cc common/QuotaNodeCore.hh
# Namespace interface
interface/IView.hh
interface/IFsView.hh
......
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
#include "namespace/common/QuotaNodeCore.hh"
EOSNSNAMESPACE_BEGIN
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given user
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getUsedSpaceByUser(uid_t uid) {
auto it = mUserInfo.find(uid);
if(it == mUserInfo.end()) {
return 0;
}
return it->second.space;
}
//------------------------------------------------------------------------------
//! Get the amount of space occupied by the given group
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getUsedSpaceByGroup(gid_t gid) {
auto it = mGroupInfo.find(gid);
if(it == mGroupInfo.end()) {
return 0;
}
return it->second.space;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given user
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getPhysicalSpaceByUser(uid_t uid) {
auto it = mUserInfo.find(uid);
if(it == mUserInfo.end()) {
return 0;
}
return it->second.physicalSpace;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given group
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getPhysicalSpaceByGroup(gid_t gid) {
auto it = mGroupInfo.find(gid);
if(it == mGroupInfo.end()) {
return 0;
}
return it->second.physicalSpace;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given user
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getNumFilesByUser(uid_t uid) {
auto it = mUserInfo.find(uid);
if(it == mUserInfo.end()) {
return 0;
}
return it->second.files;
}
//------------------------------------------------------------------------------
// Get the amount of space occupied by the given group
//------------------------------------------------------------------------------
uint64_t QuotaNodeCore::getNumFilesByGroup(gid_t gid) {
auto it = mGroupInfo.find(gid);
if(it == mGroupInfo.end()) {
return 0;
}
return it->second.files;
}
//----------------------------------------------------------------------------
// Account a new file.
//----------------------------------------------------------------------------
void QuotaNodeCore::addFile(uid_t uid, gid_t gid, uint64_t size,
uint64_t physicalSize) {
UsageInfo& user = mUserInfo[uid];
UsageInfo& group = mGroupInfo[gid];
user.physicalSpace += physicalSize;
group.physicalSpace += physicalSize;
user.space += size;
group.space += size;
user.files++;
group.files++;
}
//----------------------------------------------------------------------------
// Remove a file.
//----------------------------------------------------------------------------
void QuotaNodeCore::removeFile(uid_t uid, gid_t gid, uint64_t size,
uint64_t physicalSize) {
UsageInfo& user = mUserInfo[uid];
UsageInfo& group = mGroupInfo[gid];
user.physicalSpace -= physicalSize;
group.physicalSpace -= physicalSize;
user.space -= size;
group.space -= size;
user.files--;
group.files--;
}
EOSNSNAMESPACE_END
/************************************************************************
* EOS - the CERN Disk Storage System *
* Copyright (C) 2018 CERN/Switzerland *
* *
* This program is free software: you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation, either version 3 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>.*
************************************************************************/
//------------------------------------------------------------------------------
//! @author Georgios Bitzes <georgios.bitzes@cern.ch>
//! @brief Quota node core logic, shared between the two namespaces
//------------------------------------------------------------------------------
#include "namespace/Namespace.hh"
#include "namespace/interface/Identifiers.hh"
#include <map>
EOSNSNAMESPACE_BEGIN
//------------------------------------------------------------------------------
//! QuotaNode core logic, which keeps track of user/group volume/inode use for
//! a single quotanode.
//------------------------------------------------------------------------------
class QuotaNodeCore {
public:
struct UsageInfo {
UsageInfo(): space(0), physicalSpace(0), files(0) {}
uint64_t space;
uint64_t physicalSpace;
uint64_t files;
};
//----------------------------------------------------------------------------
//! Constructor. The object is initially empty, no files whatsoever are being
//! accounted.
//----------------------------------------------------------------------------
QuotaNodeCore() {}
//----------------------------------------------------------------------------
//! Get the amount of space occupied by the given user
//----------------------------------------------------------------------------
uint64_t getUsedSpaceByUser(uid_t uid);
//----------------------------------------------------------------------------
//! Get the amount of space occupied by the given group
//----------------------------------------------------------------------------
uint64_t getUsedSpaceByGroup(gid_t gid);
//----------------------------------------------------------------------------
//! Get the amount of space occupied by the given user
//----------------------------------------------------------------------------
uint64_t getPhysicalSpaceByUser(uid_t uid);
//----------------------------------------------------------------------------
//! Get the amount of space occupied by the given group
//----------------------------------------------------------------------------
uint64_t getPhysicalSpaceByGroup(gid_t gid);
//----------------------------------------------------------------------------
//! Get the amount of space occupied by the given user
//----------------------------------------------------------------------------
uint64_t getNumFilesByUser(uid_t uid);
//----------------------------------------------------------------------------
//! Get the amount of space occupied by the given group
//----------------------------------------------------------------------------
uint64_t getNumFilesByGroup(gid_t gid);
//----------------------------------------------------------------------------
//! Account a new file.
//----------------------------------------------------------------------------
void addFile(uid_t uid, gid_t gid, uint64_t size, uint64_t physicalSize);
//----------------------------------------------------------------------------
//! Remove a file.
//----------------------------------------------------------------------------
void removeFile(uid_t uid, gid_t gid, uint64_t size, uint64_t physicalSize);
private:
std::map<uid_t, UsageInfo> mUserInfo;
std::map<gid_t, UsageInfo> mGroupInfo;
};
EOSNSNAMESPACE_END
......@@ -32,6 +32,7 @@
#include "namespace/ns_quarkdb/views/HierarchicalView.hh"
#include "namespace/ns_quarkdb/accounting/FileSystemView.hh"
#include "namespace/ns_quarkdb/flusher/MetadataFlusher.hh"
#include "namespace/common/QuotaNodeCore.hh"
#include "namespace/PermissionHandler.hh"
#include "TestUtils.hh"
#include <folly/futures/Future.h>
......@@ -515,3 +516,34 @@ TEST(SysMask, BasicSanity) {
ASSERT_EQ(0770, PermissionHandler::filterWithSysMask(xattr, 0770));
ASSERT_EQ(0774, PermissionHandler::filterWithSysMask(xattr, 0774));
}
TEST(QuotaNodeCore, BasicSanity) {
QuotaNodeCore qn;
ASSERT_EQ(qn.getNumFilesByUser(12), 0u);
ASSERT_EQ(qn.getNumFilesByGroup(12), 0u);
qn.addFile(12, 13, 1024, 2048);
ASSERT_EQ(qn.getNumFilesByUser(12), 1u);
ASSERT_EQ(qn.getNumFilesByUser(13), 0u);
ASSERT_EQ(qn.getNumFilesByGroup(12), 0u);
ASSERT_EQ(qn.getNumFilesByGroup(13), 1u);
ASSERT_EQ(qn.getPhysicalSpaceByUser(12), 2048);
ASSERT_EQ(qn.getPhysicalSpaceByGroup(12), 0);
ASSERT_EQ(qn.getPhysicalSpaceByGroup(13), 2048);
qn.addFile(12, 12, 1, 2);
ASSERT_EQ(qn.getPhysicalSpaceByUser(12), 2050);
ASSERT_EQ(qn.getPhysicalSpaceByGroup(12), 2);
ASSERT_EQ(qn.getPhysicalSpaceByGroup(13), 2048);
qn.removeFile(12, 13, 1024, 2048);
ASSERT_EQ(qn.getPhysicalSpaceByUser(12), 2);
ASSERT_EQ(qn.getPhysicalSpaceByGroup(12), 2);
ASSERT_EQ(qn.getPhysicalSpaceByGroup(13), 0);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment