[gparted] Make F2FS usage parsing handle NULs in dump.f2fs output (!29)



commit c74ad52046d0aa84b9b6e02ce800290340105deb
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Tue Mar 19 09:45:28 2019 +0000

    Make F2FS usage parsing handle NULs in dump.f2fs output (!29)
    
    On Fedora 28 with f2fs-tools 1.10.0, dump.f2fs is producing NUL
    characters in it's output and this completely breaks the parsing code in
    f2fs::set_used_sectors().  Glib::Regex, as used by
    Utils::regexp_label(), just doesn't match any text after the first NUL
    character from the output.
    
        # dump.f2fs -d 1 /dev/sdb1
        Info: Debug level = 1
        Info: [/dev/sdb1] Disk Model: VBOX HARDDISK   1.0 ^@^@^@^@^@^@^@^...
        Info: Segments per section = 1
        Info: Sections per zone = 1
        Info: sector size = 512
        Info: total sectors = 2097152 (1024 MB)
        ...
    
    Grep thinks the output is binary too:
    
        # dump.f2fs -d 1 /dev/sdb1 | \
        > egrep 'valid_block_count|user_block_count|log_blocksize|sector size =|total FS sectors ='
        Binary file (standard input) matches
    
        # dump.f2fs -d 1 /dev/sdb1 | \
        > egrep --text 'valid_block_count|user_block_count|log_blocksize|sector size =|total FS sectors ='
        Info: sector size = 512
        log_blocksize                           [0x       c : 12]
        Info: total FS sectors = 2097152 (1024 MB)
        user_block_count                        [0x   36400 : 222208]
        valid_block_count                       [0x       2 : 2]
    
    Re-write set_used_sectors() using string find() and sscanf() to be
    similar to how a number of the other set_used_sectors() are written for
    other file systems.
    
    Closes !29 - Enhance F2FS support

 src/f2fs.cc | 84 +++++++++++++++++++++++++++++++++++--------------------------
 1 file changed, 48 insertions(+), 36 deletions(-)
---
diff --git a/src/f2fs.cc b/src/f2fs.cc
index ec357f4f..b619cc04 100644
--- a/src/f2fs.cc
+++ b/src/f2fs.cc
@@ -56,47 +56,59 @@ FS f2fs::get_filesystem_support()
 
 void f2fs::set_used_sectors(Partition & partition)
 {
-       if (! Utils::execute_command("dump.f2fs -d 1 " + Glib::shell_quote(partition.get_path()), output, 
error, true))
-       {
-               long long int user_block_count;
-               long long int valid_block_count;
-               long long int log_blocksize;
-               long long int blocksize;
-               long long int total_fs_sectors;
-
-               Glib::ustring temp;
-               temp = Utils::regexp_label(output, "user_block_count\\s+\\[0x\\s+[0-9a-f]+ : ([0-9]+)\\]");
-               sscanf(temp.c_str(), "%lld", &user_block_count);
-
-               temp = Utils::regexp_label(output, "valid_block_count\\s+\\[0x\\s+[0-9a-f]+ : ([0-9]+)\\]");
-               sscanf(temp.c_str(), "%lld", &valid_block_count);
-
-               temp = Utils::regexp_label(output, "log_blocksize\\s+\\[0x\\s+[0-9a-f]+ : ([0-9]+)\\]");
-               sscanf(temp.c_str(), "%lld", &log_blocksize);
-
-               temp = Utils::regexp_label(output, "sector size = ([0-9]+)");
-               sscanf(temp.c_str(), "%lld", &S);
-
-               temp = Utils::regexp_label(output, "total FS sectors = ([0-9]+)");
-               sscanf(temp.c_str(), "%lld", &total_fs_sectors);
-
-               blocksize = (1 << log_blocksize);
-               N = (user_block_count - valid_block_count)*blocksize;
-               T = total_fs_sectors * S;
-
-               T = Utils::round(T / double(partition.sector_size));
-               N = Utils::round(N / double(partition.sector_size));
-
-               partition.set_sector_usage(T, N);
-               partition.fs_block_size = S;
-       }
-       else
+       exit_status = Utils::execute_command("dump.f2fs -d 1 " + Glib::shell_quote(partition.get_path()),
+                                            output, error, true);
+       if (exit_status != 0)
        {
                if (! output.empty())
                        partition.push_back_message(output);
-
                if (! error.empty())
                        partition.push_back_message(error);
+               return;
+       }
+
+       // used FS blocks
+       long long user_block_count = -1;
+       Glib::ustring::size_type index = output.find("user_block_count");
+       if (index < output.length())
+               sscanf(output.substr(index).c_str(), "user_block_count [0x %*x : %lld]", &user_block_count);
+
+       // total FS blocks
+       long long valid_block_count = -1;
+       index = output.find("valid_block_count");
+       if (index < output.length())
+               sscanf(output.substr(index).c_str(), "valid_block_count [0x %*x : %lld]", &valid_block_count);
+
+       // log2 of FS block size
+       long long log_blocksize = -1;
+       index = output.find("log_blocksize");
+       if (index < output.length())
+               sscanf(output.substr(index).c_str(), "log_blocksize [0x %*x : %lld]", &log_blocksize);
+
+       // FS "sector" size
+       long long fs_sector_size = -1;
+       index = output.find("Info: sector size =");
+       if (index < output.length())
+               sscanf(output.substr(index).c_str(), "Info: sector size = %lld", &fs_sector_size);
+
+       // FS size in "sectors"
+       long long total_fs_sectors = -1;
+       index = output.find("Info: total FS sectors =");
+       if (index < output.length())
+               sscanf(output.substr(index).c_str(), "Info: total FS sectors = %lld", &total_fs_sectors);
+
+       if (user_block_count > -1 && valid_block_count > -1 &&
+           log_blocksize > -1 && fs_sector_size > -1 && total_fs_sectors > -1)
+       {
+               long long blocksize  = 1 << log_blocksize;
+               long long fs_free_bytes = (user_block_count - valid_block_count) * blocksize;
+               long long fs_size_bytes = total_fs_sectors * fs_sector_size;
+
+               Sector fs_free_sectors = fs_free_bytes / partition.sector_size;
+               Sector fs_size_sectors = fs_size_bytes / partition.sector_size;
+
+               partition.set_sector_usage(fs_size_sectors, fs_free_sectors);
+               partition.fs_block_size = blocksize;
        }
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]