Skip to content

feat: Merge from release/1071#185

Merged
deepin-bot[bot] merged 8 commits intolinuxdeepin:masterfrom
wangrong1069:pr1219
Dec 19, 2025
Merged

feat: Merge from release/1071#185
deepin-bot[bot] merged 8 commits intolinuxdeepin:masterfrom
wangrong1069:pr1219

Conversation

@wangrong1069
Copy link
Contributor

@wangrong1069 wangrong1069 commented Dec 19, 2025

Summary by Sourcery

Improve filesystem usage calculations, broaden platform compatibility, and refine logging and device metadata handling.

Bug Fixes:

  • Correct EXT* partition free-space calculation by using dumpe2fs fields and stat data, properly accounting for reserved blocks and mounted filesystems.
  • Fix mounted filesystem size and free-space reporting by using statvfs block size and available blocks fields instead of fragment size and total free blocks.
  • Resolve incorrect UFS interface labeling by detecting additional spec_version values for UFS 3.0, 3.1, and 4.0.

Enhancements:

  • Refine EXT* filesystem probing to derive sector usage directly from dumpe2fs output and set filesystem block size more robustly.
  • Add a udevadm-based fallback to retrieve disk model information when other methods fail and warn when no model can be determined.
  • Extend logging to handle QtInfoMsg and standardize newline handling in various file outputs.
  • Disable FAT32 support object construction in SupportedFileSystems to prevent use of the FAT16-based implementation.
  • Include missing QDebug headers in components that use debug logging.
  • Adjust authorization logic to allow build-time disabling of DBus caller authentication via a compile-time flag for non-Qt6 builds.

Build:

  • Make the build system automatically select Qt6 when available or fall back to Qt5, defining a flag to bypass DBus caller auth checks under Qt5.
  • Use the appropriate Qt5 or Qt6 translation generation command based on the detected Qt version.

wangrong1069 and others added 7 commits December 18, 2025 21:10
Remove exfat-fuse dependency.

Log: Remove exfat-fuse dependency
Remove support for FAT32 format.

Log: Fix fail to format disk to FAT32
Bug: https://pms.uniontech.com/bug-view-299499.html
cannot obtain model info from either smartctl nor lshw commands, try
with udevadm command to obtain ID_MODEL field.

Log: fix block model missing.

Bug: https://pms.uniontech.com/bug-view-322579.html
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
-- In the special platform, the stroage interface show error.
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 19, 2025

Reviewer's Guide

Refactors ext* filesystem usage calculation to rely purely on dumpe2fs output and statvfs, adjusts device model/interface detection, introduces Qt5/Qt6‑aware build and translation setup plus an optional DBus auth bypass, and makes small logging/formatting and include tweaks.

Sequence diagram for EXT2 setUsedSectors usage calculation

sequenceDiagram
    participant Caller
    participant EXT2
    participant Utils
    participant Partition

    Caller->>EXT2: setUsedSectors(partition)
    EXT2->>Partition: getPath()
    Partition-->>EXT2: path
    EXT2->>Utils: executCmd("dumpe2fs -h path", output, error)
    Utils-->>EXT2: success_or_failure

    alt dumpe2fs_success
        EXT2->>EXT2: parse Block count, Block size, Free blocks, Reserved block count
        EXT2->>EXT2: validate blockCount, blockSize, freeBlocks, reservedBlocks
        alt partition_mounted
            EXT2->>Partition: getMountPoints()
            Partition-->>EXT2: mountPoints
            EXT2->>Partition: getMountPoint()
            Partition-->>EXT2: mountpoint
            EXT2->>Utils: getMountedFileSystemUsage(mountpoint, statTotalSize, statAvailableSize)
            Utils-->>EXT2: rc
            alt stat_success
                EXT2->>EXT2: convert sizes to totalSectors, statAvailableSectors
                EXT2->>Partition: setSectorUsage(totalSectors, statAvailableSectors)
            else stat_failed
                EXT2->>EXT2: compute availableSectors from dumpe2fs
                EXT2->>Partition: setSectorUsage(totalSectors, availableSectors)
            end
        else partition_not_mounted
            EXT2->>EXT2: compute userAvailableBlocks = max(freeBlocks - reservedBlocks, 0)
            EXT2->>EXT2: compute totalSectors, availableSectors
            EXT2->>Partition: setSectorUsage(totalSectors, availableSectors)
        end
        EXT2->>Partition: m_fsBlockSize = blockSize
    else dumpe2fs_failed
        EXT2->>EXT2: log error and skip sector update
    end

    EXT2-->>Caller: return
Loading

Sequence diagram for DiskManagerService authorization with optional bypass

sequenceDiagram
    participant Client
    participant DBus
    participant DiskManagerService
    participant AuthAgent

    Client->>DBus: call disk operation
    DBus->>DiskManagerService: dispatch message

    DiskManagerService->>DiskManagerService: checkAuthorization()

    alt NO_DBUS_CALLER_AUTH_CHECK defined
        DiskManagerService->>DiskManagerService: log "Authorization check was skipped"
        DiskManagerService-->>DBus: authorized
    else NO_DBUS_CALLER_AUTH_CHECK not defined
        DiskManagerService->>DiskManagerService: read message().service()
        DiskManagerService->>AuthAgent: check action com.deepin.pkexec.deepin-diskmanager
        AuthAgent-->>DiskManagerService: allow_or_deny
        alt allow
            DiskManagerService-->>DBus: authorized
        else deny
            DiskManagerService->>DBus: sendErrorReply(AccessDenied)
        end
    end

    DBus-->>Client: reply or error
Loading

Class diagram for updated filesystem and utility interactions

classDiagram
    class Partition {
        +QString m_uuid
        +bool m_busy
        +qulonglong m_sectorSize
        +qulonglong m_fsBlockSize
        +QString getPath()
        +QString getMountPoint()
        +QList~QString~ getMountPoints()
        +void setSectorUsage(Sector totalSectors, Sector freeSectors)
    }

    class EXT2 {
        -long long m_blocksSize
        -long long m_numOfFreeOrUsedBlocks
        -long long m_totalNumOfBlock
        +FS getFilesystemSupport()
        +void setUsedSectors(Partition partition)
    }

    class Utils {
        +bool executCmd(QString command, QString output, QString error)
        +QString regexpLabel(QString text, QString pattern)
        +int getMountedFileSystemUsage(QString mountpoint, Byte_Value fileSystemSize, Byte_Value fileSystemFree)
        +QString readContent(QString path)
    }

    class DeviceStorage {
        +void getDiskInfoModel(QString devicePath, QString model)
        +void getDiskInfoInterface(QString devicePath, QString interface)
    }

    class DiskManagerService {
        +int test()
        +bool checkAuthorization()
    }

    class PartedCore {
        +bool hidePartition()
        +void onRefreshDeviceInfo(int type, bool arg1, QString arg2)
    }

    EXT2 --> Partition : updates_sector_usage
    EXT2 --> Utils : uses_dumpe2fs_and_statvfs
    Utils --> Partition : fills_usage_via_mountpoint
    DeviceStorage --> Utils : reads_sysfs_and_udevadm
    DiskManagerService ..> Utils : affected_by_NO_DBUS_CALLER_AUTH_CHECK
    PartedCore --> Partition : manages_visibility
Loading

File-Level Changes

Change Details Files
Rework EXT2/3/4 used‑sector calculation to parse dumpe2fs output, account for reserved blocks, and use stat data for mounted filesystems.
  • Replace member variables m_blocksSize, m_numOfFreeOrUsedBlocks, and m_totalNumOfBlock with local blockCount, blockSize, freeBlocks, and reservedBlocks when parsing dumpe2fs -h output.
  • Parse Block count, Block size, Free blocks, and Reserved block count via Utils::regexpLabel instead of sscanf on substrings.
  • Compute userAvailableBlocks as freeBlocks minus reservedBlocks (clamped to >=0) and convert block counts to sectors using partition.m_sectorSize.
  • For mounted/busy partitions, prefer Utils::getMountedFileSystemUsage() (statvfs) to derive available sectors; otherwise fall back to calculated availableSectors.
  • Always set partition.m_fsBlockSize to the parsed blockSize when data is valid, and add more detailed qDebug logging and error paths when dumpe2fs fails or data is invalid.
service/diskoperation/filesystems/ext2.cpp
Improve disk model/interface detection and Qt/DBus build configuration for wider platform support.
  • In getDiskInfoModel, add a udevadm info ...
grep ID_MODEL= fallback to derive the disk model if previous methods fail, and log a warning when no model can be obtained.
  • In getDiskInfoInterface, refine UFS spec_version handling to distinguish UFS 3.0, 3.1, and 4.0 based on spec_version contents.
  • In top-level CMakeLists, detect Qt6 via find_package(Qt6 QUIET); if found, set QT_VERSION_MAJOR/DK_VERSION for Qt6, otherwise configure for Qt5 and define NO_DBUS_CALLER_AUTH_CHECK.
  • In application/CMakeLists, use qt_create_translation when building with Qt6 and qt5_create_translation when building with Qt5.
  • Guard DiskManagerService::checkAuthorization with NO_DBUS_CALLER_AUTH_CHECK so that authorization is skipped (and always allowed) when that macro is defined.
  • Adjust filesystem usage helper and logging implementation details for correctness and compatibility.
    • Fix Utils::getMountedFileSystemUsage to use statvfs fields consistently: compute total size using f_blocks * f_bsize and free space using f_bavail * f_bsize.
    • Change QTextStream logging calls to write simple newline characters instead of Qt::endl to avoid flushing overhead and align with Qt6 behavior.
    • Extend customLogMessageHandler to handle QtInfoMsg by mapping it to an "Info:" prefix.
    • Replace one FS_FAT32 registration in SupportedFileSystems with a commented-out line, effectively disabling FAT32 via FAT16 handler construction.
    • Add missing QDebug includes to waterloadingwidget.cpp and deviceinfo.cpp so qDebug() can be used without relying on transitive includes.
    basestruct/utils.cpp
    log/log.cpp
    service/diskoperation/partedcore.cpp
    service/diskoperation/supportedfilesystems.cpp
    application/widgets/customcontrol/waterloadingwidget.cpp
    basestruct/deviceinfo.cpp

    Tips and commands

    Interacting with Sourcery

    • Trigger a new review: Comment @sourcery-ai review on the pull request.
    • Continue discussions: Reply directly to Sourcery's review comments.
    • Generate a GitHub issue from a review comment: Ask Sourcery to create an
      issue from a review comment by replying to it. You can also reply to a
      review comment with @sourcery-ai issue to create an issue from it.
    • Generate a pull request title: Write @sourcery-ai anywhere in the pull
      request title to generate a title at any time. You can also comment
      @sourcery-ai title on the pull request to (re-)generate the title at any time.
    • Generate a pull request summary: Write @sourcery-ai summary anywhere in
      the pull request body to generate a PR summary at any time exactly where you
      want it. You can also comment @sourcery-ai summary on the pull request to
      (re-)generate the summary at any time.
    • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
      request to (re-)generate the reviewer's guide at any time.
    • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
      pull request to resolve all Sourcery comments. Useful if you've already
      addressed all the comments and don't want to see them anymore.
    • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
      request to dismiss all existing Sourcery reviews. Especially useful if you
      want to start fresh with a new review - don't forget to comment
      @sourcery-ai review to trigger a new review!

    Customizing Your Experience

    Access your dashboard to:

    • Enable or disable review features such as the Sourcery-generated pull request
      summary, the reviewer's guide, and others.
    • Change the review language.
    • Add, remove or edit custom review instructions.
    • Adjust other review settings.

    Getting Help

    Copy link

    @sourcery-ai sourcery-ai bot left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Hey there - I've reviewed your changes - here's some feedback:

    • In getDiskInfoInterface(), the sysfs path is hard-coded to /sys/block/sdd/device/spec_version; consider deriving the block device name from devicePath so the UFS interface detection works for arbitrary devices instead of only sdd.
    • The new udevadm model fallback in getDiskInfoModel() builds a shell command with an unquoted devicePath and greps the output; using udevadm info --query=property --name=<device> and parsing key/value lines directly (with proper quoting) would be more robust and safer.
    • Replacing Qt::endl with "\n" in logging changes flushing behavior; if immediate flush after each log line is still desired, consider calling ts.flush() explicitly.
    Prompt for AI Agents
    Please address the comments from this code review:
    
    ## Overall Comments
    - In getDiskInfoInterface(), the sysfs path is hard-coded to `/sys/block/sdd/device/spec_version`; consider deriving the block device name from `devicePath` so the UFS interface detection works for arbitrary devices instead of only `sdd`.
    - The new udevadm model fallback in getDiskInfoModel() builds a shell command with an unquoted `devicePath` and greps the output; using `udevadm info --query=property --name=<device>` and parsing key/value lines directly (with proper quoting) would be more robust and safer.
    - Replacing `Qt::endl` with `"\n"` in logging changes flushing behavior; if immediate flush after each log line is still desired, consider calling `ts.flush()` explicitly.
    
    ## Individual Comments
    
    ### Comment 1
    <location> `service/diskoperation/filesystems/ext2.cpp:186-187` </location>
    <code_context>
    +        if (blockCount > 0 && blockSize > 0 && freeBlocks >= 0 && reservedBlocks >= 0) {
    +            qDebug() << "Filesystem information validation successful, calculating sector usage";
    +
    +            // 计算用户实际可用的空闲块数:可用 = (freeBlocks - reservedBlocks)
    +            long long userAvailableBlocks = (freeBlocks > reservedBlocks) ? (freeBlocks - reservedBlocks) : 0;
    +            
    +            // 转换为扇区数
    </code_context>
    
    <issue_to_address>
    **issue (bug_risk):** Subtracting `reservedBlocks` from `freeBlocks` likely underestimates user-available space for ext*.
    
    On ext2/3/4, `dumpe2fs` typically reports `Free blocks:` with reserved space already excluded, and also exposes `Reserved block count:` separately. Assuming `freeBlocks` includes reserved blocks and subtracting `reservedBlocks` again can double‑count the reservation and under‑report available space. Please confirm the semantics against real `dumpe2fs -h` output and adjust the computation accordingly (e.g., use `freeBlocks` as‑is and keep `reservedBlocks` only as metadata, or derive used space from `blockCount - freeBlocks` while tracking reserved separately).
    </issue_to_address>
    
    ### Comment 2
    <location> `basestruct/utils.cpp:512-515` </location>
    <code_context>
         if (ret == 0) {
    -        fileSystemSize = static_cast<Byte_Value>(sfs.f_blocks) * sfs.f_frsize;
    -        fileSystemFree = static_cast<Byte_Value>(sfs.f_bfree) * sfs.f_bsize;
    +        fileSystemSize = static_cast<Byte_Value>(sfs.f_blocks) * sfs.f_bsize;
    +        fileSystemFree = static_cast<Byte_Value>(sfs.f_bavail) * sfs.f_bsize;
         } else {
             qWarning() << "Utils::getMountedFileSystemUsage - Failed for:" << mountpoint << "Error:" << errno;
    </code_context>
    
    <issue_to_address>
    **suggestion (bug_risk):** Using `f_bsize` for filesystem size may be less correct than `f_frsize`.
    
    `statvfs` typically defines total size as `f_blocks * f_frsize`, while `f_bsize` is only the optimal transfer block size and may differ. The previous use of `f_frsize` for total size followed that convention. I’d keep `fileSystemSize = f_blocks * f_frsize` and only switch free space to `f_bavail * f_bsize` to avoid incorrect total size on filesystems where these fields differ.
    
    ```suggestion
        if (ret == 0) {
            fileSystemSize = static_cast<Byte_Value>(sfs.f_blocks) * sfs.f_frsize;
            fileSystemFree = static_cast<Byte_Value>(sfs.f_bavail) * sfs.f_bsize;
        } else {
    ```
    </issue_to_address>

    Sourcery is free for open source - if you like our reviews please consider sharing them ✨
    Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

    Comment on lines +186 to +187
    // 计算用户实际可用的空闲块数:可用 = (freeBlocks - reservedBlocks)
    long long userAvailableBlocks = (freeBlocks > reservedBlocks) ? (freeBlocks - reservedBlocks) : 0;
    Copy link

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    issue (bug_risk): Subtracting reservedBlocks from freeBlocks likely underestimates user-available space for ext*.

    On ext2/3/4, dumpe2fs typically reports Free blocks: with reserved space already excluded, and also exposes Reserved block count: separately. Assuming freeBlocks includes reserved blocks and subtracting reservedBlocks again can double‑count the reservation and under‑report available space. Please confirm the semantics against real dumpe2fs -h output and adjust the computation accordingly (e.g., use freeBlocks as‑is and keep reservedBlocks only as metadata, or derive used space from blockCount - freeBlocks while tracking reserved separately).

    Resolving security issues and compilation errors.
    @deepin-ci-robot
    Copy link

    deepin pr auto review

    我来对这段代码进行审查,从语法逻辑、代码质量、性能和安全几个方面进行分析:

    1. .gitignore 文件修改:
    • 添加了 build 和 .cache 目录的忽略规则是合理的
    • 建议统一使用目录通配符格式:build/ 和 .cache/
    1. CMakeLists.txt 修改:
    • Qt版本检测逻辑改进很好,使用 find_package(Qt6 QUIET) 更可靠
    • 添加了 Qt5 的兼容性支持,提高了代码的可移植性
    • 建议在检测失败时添加更详细的错误信息
    1. application/CMakeLists.txt:
    • 根据 Qt 版本选择对应的翻译函数,这个改进很好
    • 代码结构清晰,逻辑合理
    1. 文件系统相关改进:
    • utils.cpp 中修复了文件系统大小计算的问题,使用 f_bavail 替代 f_bfree 更准确
    • ext2.cpp 中的改进很大:
      • 添加了更详细的日志输出
      • 改进了空间计算逻辑,考虑了保留块
      • 对已挂载分区使用 stat 获取更准确的信息
      • 代码结构更清晰,错误处理更完善
    1. 安全性改进:
    • diskmanagerservice.cpp 中添加了 NO_DBUS_CALLER_AUTH_CHECK 宏,便于调试
    • 建议在生产环境中始终启用权限检查
    1. 其他改进:
    • 统一使用 "\n" 替代 Qt::endl,提高性能
    • 添加了更多的调试日志输出
    • DeviceStorage.cpp 中改进了设备型号检测逻辑

    建议改进:

    1. 在 CMakeLists.txt 中添加编译选项检查,确保所需的编译器特性可用
    2. 考虑添加更多的单元测试,特别是文件系统空间计算相关的逻辑
    3. 对于敏感操作(如磁盘分区操作),建议添加更多的安全检查和日志记录
    4. 考虑将一些魔法数字(如 UFS 版本号)定义为常量
    5. 在处理用户输入时添加更多的验证逻辑

    总体来说,这些修改提高了代码的可靠性、可维护性和跨平台兼容性。特别是在文件系统空间计算方面的改进很有价值,修复了一些潜在的问题。

    @deepin-ci-robot
    Copy link

    [APPROVALNOTIFIER] This PR is NOT APPROVED

    This pull-request has been approved by: lzwind, wangrong1069

    The full list of commands accepted by this bot can be found here.

    Details Needs approval from an approver in each of these files:

    Approvers can indicate their approval by writing /approve in a comment
    Approvers can cancel approval by writing /approve cancel in a comment

    @wangrong1069
    Copy link
    Contributor Author

    /merge

    @deepin-bot deepin-bot bot merged commit f025ed5 into linuxdeepin:master Dec 19, 2025
    18 checks passed
    @wangrong1069 wangrong1069 deleted the pr1219 branch December 19, 2025 06:39
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Labels

    None yet

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    5 participants