Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/mds/common/helper.cc
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ std::string Helper::ToLowerCase(const std::string& str) {
bool Helper::StringToBool(const std::string& str) { return !(str == "0" || str == "false"); }
int32_t Helper::StringToInt32(const std::string& str) { return std::strtol(str.c_str(), nullptr, 10); }
int64_t Helper::StringToInt64(const std::string& str) { return std::strtoll(str.c_str(), nullptr, 10); }
uint64_t Helper::StringToUint64(const std::string& str) { return std::strtoull(str.c_str(), nullptr, 10); }
float Helper::StringToFloat(const std::string& str) { return std::strtof(str.c_str(), nullptr); }
double Helper::StringToDouble(const std::string& str) { return std::strtod(str.c_str(), nullptr); }

Expand Down
1 change: 1 addition & 0 deletions src/mds/common/helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class Helper {
static bool StringToBool(const std::string& str);
static int32_t StringToInt32(const std::string& str);
static int64_t StringToInt64(const std::string& str);
static uint64_t StringToUint64(const std::string& str);
static float StringToFloat(const std::string& str);
static double StringToDouble(const std::string& str);

Expand Down
43 changes: 41 additions & 2 deletions src/mds/filesystem/fs_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,11 @@ Status FsUtils::GenRootDirJsonString(std::string& output) {
nlohmann::json doc = nlohmann::json::array();

nlohmann::json item;
item["ino"] = attr.ino();
// Emit ino as a JSON string: trash-realm inos (kTrashInodeId,
// kTrashSubInodeStart+) exceed 2^53 and lose precision when parsed as a
// JSON number by the dashboard JS, which then sends a wrong-parent URL
// back. Stringifying all inos keeps the wire format uniform.
item["ino"] = std::to_string(attr.ino());
item["name"] = "/";
item["type"] = "directory";
if (fs_info_.partition_policy().type() == pb::mds::PartitionType::MONOLITHIC_PARTITION) {
Expand Down Expand Up @@ -336,9 +340,16 @@ Status FsUtils::GenDirJsonString(Ino parent, std::string& output) {
const auto& attr = it->second;

nlohmann::json item;
item["ino"] = dentry.ino();
item["ino"] = std::to_string(dentry.ino());
item["name"] = dentry.name();
item["type"] = dentry.type() == pb::mds::FileType::DIRECTORY ? "directory" : "file";
// Hour-bucket sub-trash directories live in the trash ino range and have
// no persistent partition (every request builds a request-local
// ShardPartition; see mds/common/trash.h). Suppress the dashboard shard
// link for them, matching the synthesized `.trash` row above.
if (IsTrashInode(dentry.ino())) {
item["no_shard"] = true;
}
if (fs_info_.partition_policy().type() == pb::mds::PartitionType::MONOLITHIC_PARTITION) {
item["node"] = fs_info_.partition_policy().mono().mds_id();
} else {
Expand All @@ -355,6 +366,34 @@ Status FsUtils::GenDirJsonString(Ino parent, std::string& output) {
doc.push_back(item);
}

// Synthesize the virtual `.trash` directory under root. kTrashInodeId has
// no KV dentry — it is built on demand via BuildTrashInodeAttr (see
// mds/common/trash.h), so the ScanDentryOperation above never returns it.
// Gated on trash_days > 0 to mirror the GC enabled check
// (mds/background/gc.cc:1100) and the client-visible behavior.
if (parent == kRootIno && fs_info_.trash_days() > 0) {
const auto attr =
BuildTrashInodeAttr(fs_info_.fs_id(), fs_info_.create_time_s() * 1000000000ULL);
nlohmann::json item;
item["ino"] = std::to_string(attr.ino());
item["name"] = kTrashName;
item["type"] = "directory";
// .trash is a virtual root; it has no on-disk partition, so suppress
// the shard link in the dashboard JS.
item["no_shard"] = true;
if (fs_info_.partition_policy().type() == pb::mds::PartitionType::MONOLITHIC_PARTITION) {
item["node"] = fs_info_.partition_policy().mono().mds_id();
} else {
item["node"] = hash_router_->GetMDS(attr.ino());
}
item["description"] = fmt::format(
"{},{}/{},{},{},{},{},{},{},{}", attr.version(), attr.mode(),
Helper::FsModeToString(attr.mode()), attr.nlink(), attr.uid(), attr.gid(),
attr.length(), FormatTime(attr.ctime()), FormatTime(attr.mtime()),
FormatTime(attr.atime()));
doc.push_back(item);
}

output = doc.dump();

return Status::OK();
Expand Down
28 changes: 17 additions & 11 deletions src/mds/service/fsstat_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ static void RenderFsInfo(const std::vector<pb::mds::FsInfo>& fs_infoes, butil::I
os << "<th>Owner</th>";
os << "<th>Navigation</th>";
os << "<th>Time</th>";
os << "<th>Trash</th>";
os << "<th>RecycleTime</th>";
os << "<th>MountPoint</th>";
os << "<th>Storage</th>";
Expand All @@ -271,6 +272,10 @@ static void RenderFsInfo(const std::vector<pb::mds::FsInfo>& fs_infoes, butil::I
os << "<td>" << fs_info.owner() << "</td>";
os << "<td>" << render_navigation_func(fs_info) << "</td>";
os << "<td>" << render_time_func(fs_info) << "</td>";
os << "<td>"
<< fmt::format("trash_days: {}<br>immediate_trash_quota: {}", fs_info.trash_days(),
fs_info.immediate_trash_quota() ? "true" : "false")
<< "</td>";
os << "<td>" << fmt::format("{}hour", fs_info.recycle_time_hour()) << "</td>";
os << fmt::format(R"(<td><a href="FsStatService/mountpoint/{}" target="_blank">Goto</a>&nbsp;[{}]</td>)",
fs_info.fs_name(), fs_info.mount_points_size());
Expand Down Expand Up @@ -1149,15 +1154,16 @@ body {
info.className = 'info';
info.textContent = `[${item.ino},${item.description}][${item.node}]`;

const shard_link = document.createElement('a');
shard_link.href = `shard/${fs_id}/${item.ino}`;
shard_link.target = '_blank';
shard_link.textContent = 'shard';

folderDiv.appendChild(icon);
folderDiv.appendChild(folderName);
folderDiv.appendChild(info);
folderDiv.appendChild(shard_link);
if (!item.no_shard) {
const shard_link = document.createElement('a');
shard_link.href = `shard/${fs_id}/${item.ino}`;
shard_link.target = '_blank';
shard_link.textContent = 'shard';
folderDiv.appendChild(shard_link);
}

// 只给目录名添加点击事件
folderName.addEventListener('click', async function(e) {
Expand Down Expand Up @@ -1850,7 +1856,7 @@ void FsStatServiceImpl::default_method(::google::protobuf::RpcController* contro
// /FsStatService/delfiles/{fs_id}/{ino}

uint32_t fs_id = Helper::StringToInt32(params[1]);
uint64_t ino = Helper::StringToInt64(params[2]);
uint64_t ino = Helper::StringToUint64(params[2]);

auto file_system_set = Server::GetInstance().GetFileSystemSet();
auto file_system = file_system_set->GetFileSystem(fs_id);
Expand Down Expand Up @@ -1912,7 +1918,7 @@ void FsStatServiceImpl::default_method(::google::protobuf::RpcController* contro
// /FsStatService/{fs_id}/{ino}

uint32_t fs_id = Helper::StringToInt32(params[0]);
uint64_t ino = Helper::StringToInt64(params[1]);
uint64_t ino = Helper::StringToUint64(params[1]);

auto file_system_set = Server::GetInstance().GetFileSystemSet();
auto file_system = file_system_set->GetFileSystem(fs_id);
Expand All @@ -1934,7 +1940,7 @@ void FsStatServiceImpl::default_method(::google::protobuf::RpcController* contro
// /FsStatService/partition/{fs_id}/{ino}

uint32_t fs_id = Helper::StringToInt32(params[1]);
uint64_t ino = Helper::StringToInt64(params[2]);
uint64_t ino = Helper::StringToUint64(params[2]);

LOG(INFO) << fmt::format("Get dir json, fs_id: {}, ino: {}", fs_id, ino);

Expand All @@ -1961,7 +1967,7 @@ void FsStatServiceImpl::default_method(::google::protobuf::RpcController* contro
// /FsStatService/chunk/{fs_id}/{ino}

uint32_t fs_id = Helper::StringToInt32(params[1]);
uint64_t ino = Helper::StringToInt64(params[2]);
uint64_t ino = Helper::StringToUint64(params[2]);

FsUtils fs_utils(Server::GetInstance().GetOperationProcessor());

Expand All @@ -1978,7 +1984,7 @@ void FsStatServiceImpl::default_method(::google::protobuf::RpcController* contro
// /FsStatService/shard/{fs_id}/{ino}

uint32_t fs_id = Helper::StringToInt32(params[1]);
uint64_t ino = Helper::StringToInt64(params[2]);
uint64_t ino = Helper::StringToUint64(params[2]);

auto file_system_set = Server::GetInstance().GetFileSystemSet();
auto file_system = file_system_set->GetFileSystem(fs_id);
Expand Down
Loading