Skip to content

Commit 0ffefcd

Browse files
itsXuStwangrong1069
authored andcommitted
fix: Improve ext* filesystem usage display logic
Changes: 1. Reserved space handling - Now counts reserved blocks as used space for ext2/3/4 filesystems - Matches behavior of standard tools like df 2. Mounted device detection - Uses stat-based calculation for accurate free space on mounted devices - Falls back to previous method for unmounted devices Technical Impact: - Fixes discrepancy between displayed and actual available space - Provides more consistent behavior with system utilities Log: Improved ext* filesystem space calculation accuracy Bug: https://pms.uniontech.com/bug-view-323359.html
1 parent 06390a6 commit 0ffefcd

3 files changed

Lines changed: 82 additions & 57 deletions

File tree

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
*.user
22
.build
3+
build
34
.qmake.stash
45
*.qm
6+
.cache/*
7+
.claude/*
58
.vscode
69

710
# AI

basestruct/utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -510,8 +510,8 @@ int Utils::getMountedFileSystemUsage(const QString &mountpoint, Byte_Value &file
510510
int ret;
511511
ret = statvfs(mountpoint.toStdString().c_str(), &sfs);
512512
if (ret == 0) {
513-
fileSystemSize = static_cast<Byte_Value>(sfs.f_blocks) * sfs.f_frsize;
514-
fileSystemFree = static_cast<Byte_Value>(sfs.f_bfree) * sfs.f_bsize;
513+
fileSystemSize = static_cast<Byte_Value>(sfs.f_blocks) * sfs.f_bsize;
514+
fileSystemFree = static_cast<Byte_Value>(sfs.f_bavail) * sfs.f_bsize;
515515
} else {
516516
qWarning() << "Utils::getMountedFileSystemUsage - Failed for:" << mountpoint << "Error:" << errno;
517517
QString errorMessage("statvfs(\"%1\"):%2 "); // = "statvfs(\"" + mountpoint + "\"): " + Glib::strerror(errno) ;

service/diskoperation/filesystems/ext2.cpp

Lines changed: 77 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -137,73 +137,95 @@ FS EXT2::getFilesystemSupport()
137137
void EXT2::setUsedSectors(Partition &partition)
138138
{
139139
qDebug() << "Setting used sectors for ext2/3/4 partition:" << partition.getPath();
140-
QString output, error, strmatch, strcmd;
141-
m_blocksSize = m_numOfFreeOrUsedBlocks = m_totalNumOfBlock = -1;
140+
QString output, error, strcmd;
142141
strcmd = QString("dumpe2fs -h %1").arg(partition.getPath());
142+
143+
qDebug() << "Executing dumpe2fs command to get filesystem information";
143144
if (!Utils::executCmd(strcmd, output, error)) {
144-
strmatch = ("Block count:");
145+
long long blockCount = -1;
146+
long long blockSize = -1;
147+
long long freeBlocks = -1;
148+
long long reservedBlocks = 0;
149+
150+
// 获取总块数
151+
QString strmatch = "Block count:";
145152
int index = output.indexOf(strmatch);
146153
if (index >= 0 && index < output.length()) {
147-
qDebug() << "Found block count";
148-
m_totalNumOfBlock = Utils::regexpLabel(output, QString("(?<=Block count:).*(?=\n)")).trimmed().toLong();
154+
qDebug() << "Found block count information";
155+
blockCount = Utils::regexpLabel(output, QString("(?<=Block count:).*(?=\n)")).trimmed().toLong();
149156
}
150-
// qDebug() << output;
151-
// qDebug() << output.mid(index, strmatch.length()).toLatin1() << m_totalNumOfBlock;
152-
strmatch = ("Block size:");
157+
158+
// 获取块大小
159+
strmatch = "Block size:";
153160
index = output.indexOf(strmatch);
154161
if (index >= 0 && index < output.length()) {
155-
qDebug() << "Found block size";
156-
m_blocksSize = Utils::regexpLabel(output, QString("(?<=Block size:).*(?=\n)")).trimmed().toLong();
162+
qDebug() << "Found block size information";
163+
blockSize = Utils::regexpLabel(output, QString("(?<=Block size:).*(?=\n)")).trimmed().toLong();
157164
}
158-
// qDebug() << output << output.mid(index, strmatch.length()).toLatin1() << m_blocksSize;
159-
160-
if (partition.m_busy) {
161-
qDebug() << "Partition is busy, getting usage from mounted filesystem";
162-
Byte_Value fs_all;
163-
Byte_Value fs_free;
164-
if (Utils::getMountedFileSystemUsage(partition.getMountPoint(), fs_all, fs_free) == 0) {
165-
qDebug() << "Successfully got mounted filesystem usage";
166-
partition.setSectorUsage(qRound64(fs_all / double(partition.m_sectorSize)), qRound64(fs_free / double(partition.m_sectorSize)));
167-
partition.m_fsBlockSize = m_blocksSize;
168-
}
169-
} else {
170-
qDebug() << "Partition is not busy, estimating minimum size";
171-
// Resize2fs won't shrink a file system smaller than it's own
172-
// estimated minimum size, so use that to derive the free space.
173-
m_numOfFreeOrUsedBlocks = -1;
174-
if (!Utils::executCmd(QString("resize2fs -P %1").arg(partition.getPath()), output, error)) {
175-
qDebug() << "resize2fs -P successful";
176-
if (sscanf(output.toLatin1(), "Estimated minimum size of the filesystem: %lld", &m_numOfFreeOrUsedBlocks) == 1
177-
|| sscanf(output.toStdString().c_str(), "预计文件系统的最小尺寸:%lld", &m_numOfFreeOrUsedBlocks) == 1) {
178-
qDebug() << "Parsed estimated minimum size";
179-
m_numOfFreeOrUsedBlocks = m_totalNumOfBlock - m_numOfFreeOrUsedBlocks;
180-
}
181-
}
182-
// Resize2fs can fail reporting please run fsck first. Fall back
183-
// to reading dumpe2fs output for free space.
184-
if (m_numOfFreeOrUsedBlocks == -1) {
185-
qDebug() << "resize2fs -P failed or did not provide minimum size, falling back to dumpe2fs";
186-
strmatch = "Free blocks:";
187-
index = output.indexOf(strmatch);
188-
if (index < output.length()) {
189-
qDebug() << "Found free blocks in dumpe2fs output";
190-
sscanf(output.mid(index, strmatch.length()).toLatin1(), "Free blocks: %lld", &m_numOfFreeOrUsedBlocks);
165+
166+
// 获取空闲块数
167+
strmatch = "Free blocks:";
168+
index = output.indexOf(strmatch);
169+
if (index >= 0 && index < output.length()) {
170+
qDebug() << "Found free blocks information";
171+
freeBlocks = Utils::regexpLabel(output, QString("(?<=Free blocks:).*(?=\n)")).trimmed().toLong();
172+
}
173+
174+
// 获取保留块数
175+
strmatch = "Reserved block count:";
176+
index = output.indexOf(strmatch);
177+
if (index >= 0 && index < output.length()) {
178+
qDebug() << "Found reserved blocks information";
179+
reservedBlocks = Utils::regexpLabel(output, QString("(?<=Reserved block count:).*(?=\n)")).trimmed().toLong();
180+
}
181+
182+
// 验证数据有效性并计算扇区使用情况
183+
if (blockCount > 0 && blockSize > 0 && freeBlocks >= 0 && reservedBlocks >= 0) {
184+
qDebug() << "Filesystem information validation successful, calculating sector usage";
185+
186+
// 计算用户实际可用的空闲块数:可用 = (freeBlocks - reservedBlocks)
187+
long long userAvailableBlocks = (freeBlocks > reservedBlocks) ? (freeBlocks - reservedBlocks) : 0;
188+
189+
// 转换为扇区数
190+
Sector totalSectors = qRound64(blockCount * (blockSize / double(partition.m_sectorSize)));
191+
Sector availableSectors = qRound64(userAvailableBlocks * (blockSize / double(partition.m_sectorSize)));
192+
193+
qDebug() << "EXT* usage calculation: blockCount=" << blockCount
194+
<< "blockSize=" << blockSize
195+
<< "freeBlocks=" << freeBlocks
196+
<< "reservedBlocks=" << reservedBlocks
197+
<< "userAvailableBlocks=" << userAvailableBlocks
198+
<< "totalSectors=" << totalSectors
199+
<< "availableSectors=" << availableSectors;
200+
201+
// 如果分区已挂载,使用 stat 获取更准确的可用块数
202+
if (partition.m_busy && !partition.getMountPoints().empty()) {
203+
qDebug() << "Partition is mounted, using stat for more accurate available space calculation";
204+
Byte_Value statTotalSize, statAvailableSize;
205+
if (Utils::getMountedFileSystemUsage(partition.getMountPoint(), statTotalSize, statAvailableSize) == 0) {
206+
// 使用 stat 获取的可用空间(已经排除了保留空间)
207+
Sector statAvailableSectors = qRound64(statAvailableSize / double(partition.m_sectorSize));
208+
qDebug() << "Using stat data for mounted partition: statAvailableSectors=" << statAvailableSectors;
209+
partition.setSectorUsage(totalSectors, statAvailableSectors);
210+
qDebug() << "Sector usage set successfully using stat data";
211+
} else {
212+
qDebug() << "Failed to get mounted filesystem usage, using calculated available sectors";
213+
partition.setSectorUsage(totalSectors, availableSectors);
214+
qDebug() << "Sector usage set successfully using calculated data";
191215
}
216+
} else {
217+
qDebug() << "Partition is not mounted, using calculated available sectors";
218+
partition.setSectorUsage(totalSectors, availableSectors);
219+
qDebug() << "Sector usage set successfully";
192220
}
193-
194-
if (m_totalNumOfBlock > -1 && m_numOfFreeOrUsedBlocks > -1 && m_blocksSize > -1) {
195-
qDebug() << "Calculating and setting sector usage from block counts";
196-
m_totalNumOfBlock = qRound64(m_totalNumOfBlock * (m_blocksSize / double(partition.m_sectorSize)));
197-
m_numOfFreeOrUsedBlocks = qRound64(m_numOfFreeOrUsedBlocks * (m_blocksSize / double(partition.m_sectorSize)));
198-
qDebug() << "111111111111111111111111" << m_totalNumOfBlock << m_numOfFreeOrUsedBlocks << m_blocksSize;
199-
partition.setSectorUsage(m_totalNumOfBlock, m_numOfFreeOrUsedBlocks);
200-
partition.m_fsBlockSize = m_blocksSize;
201-
}
221+
partition.m_fsBlockSize = blockSize;
222+
qDebug() << "Filesystem block size set to:" << blockSize;
223+
} else {
224+
qDebug() << "Filesystem information validation failed, invalid parameters detected";
202225
}
203-
204-
205226
} else {
206-
qDebug() << __FUNCTION__ << "dumpe2fs -h failed :" << output << error;
227+
qDebug() << "dumpe2fs command execution failed, error:" << error;
228+
qDebug() << "Failed to set used sectors for partition:" << partition.getPath();
207229
}
208230
}
209231

0 commit comments

Comments
 (0)