Android系统userdata自适应方案

  • Android 11
diff --git a/system/core/fs_mgr/fs_mgr.cpp b/system/core/fs_mgr/fs_mgr.cpp
index d70d5a7..6b5d438 100755
--- a/system/core/fs_mgr/fs_mgr.cpp
+++ b/system/core/fs_mgr/fs_mgr.cpp
@@ -679,6 +679,63 @@
     }
     return sb == cpu_to_le32(F2FS_SUPER_MAGIC);
 }
+/*add for auto userdata resize*/
+static int get_dev_sz(const char *fs_blkdev, uint64_t *dev_sz)
+{
+  int fd;
+
+  if ((fd = open(fs_blkdev, O_RDONLY)) < 0) {
+    LERROR << "Cannot open block device";
+    return -1;
+  }
+
+  if ((ioctl(fd, BLKGETSIZE64, dev_sz)) == -1) {
+    LERROR << "Cannot get block device size";
+    close(fd);
+    return -1;
+  }
+
+  close(fd);
+  return 0;
+}
+
+static bool read_f2fs_size(const std::string& blk_device, uint64_t* size) {
+  android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC)));
+  __le64 block_count1, block_count2;
+  __le32 log_blocksize1, log_blocksize2;
+
+  if (fd < 0) {
+    PERROR << "Failed to open '" << blk_device << "'";
+    return false;
+  }
+
+  if (TEMP_FAILURE_RETRY(pread(fd, &log_blocksize1, sizeof(log_blocksize1),
+                               F2FS_SUPER_OFFSET + sizeof(__le32)*4)) != sizeof(log_blocksize1)) {
+    PERROR << "Can't read '" << blk_device << "' superblock1";
+  }
+  if (TEMP_FAILURE_RETRY(pread(fd, &block_count1, sizeof(block_count1),
+                               F2FS_SUPER_OFFSET + sizeof(__le32)*9)) != sizeof(block_count1)) {
+    PERROR << "Can't read '" << blk_device << "' superblock1";
+  }
+  if (TEMP_FAILURE_RETRY(pread(fd, &log_blocksize2, sizeof(log_blocksize2),
+                               F2FS_BLKSIZE + F2FS_SUPER_OFFSET + sizeof(__le32)*4))
+      != sizeof(log_blocksize2)) {
+    PERROR << "Can't read '" << blk_device << "' superblock2";
+  }
+  if (TEMP_FAILURE_RETRY(pread(fd, &block_count2, sizeof(block_count2),
+                               F2FS_BLKSIZE + F2FS_SUPER_OFFSET + sizeof(__le32)*9))
+      != sizeof(block_count2)) {
+    PERROR << "Can't read '" << blk_device << "' superblock2";
+  }
+  LINFO << __func__ << "get " << blk_device << " log_blocksize1:" << log_blocksize1
+        << " block_count1:" << block_count1 << " log_blocksize2:" << log_blocksize2
+        << " block_count2:" << block_count2;
+  if (log_blocksize1 != log_blocksize2 || block_count1 != block_count2)
+    return false;
+  *size = (1 << log_blocksize1) * block_count1;
+  return true;
+}
+/*add for auto userdata resize*/
 
 //
 // Prepare the filesystem on the given block device to be mounted.
@@ -714,7 +771,50 @@
             return fs_stat;
         }
     }
+/*add for auto userdata resize*/
+    LINFO<< __func__<<" : mount "<<entry.mount_point;
+    if(!strcmp(entry.mount_point.c_str(),"/data")){
+        uint64_t dev_sz = 0;
 
+        int rc = get_dev_sz(blk_device.c_str(), &dev_sz);
+
+        uint64_t partition_size = 0;
+        if (is_f2fs(entry.fs_type)) {
+          read_f2fs_size(blk_device, &partition_size);
+        } else {
+          partition_size = entry.length;
+        }
+
+        if (!rc && partition_size) {
+            LINFO << __func__<< blk_device<<","<<" real size: "<<dev_sz ;
+            LINFO << __func__<< blk_device<<","<<" partition_size: "<<partition_size ;
+
+            if(dev_sz > partition_size+1073741824 || dev_sz < partition_size){
+                if (access("/system/bin/make_f2fs", X_OK)) {
+                    LINFO << "Not running resize on " << blk_device << " (executable not in system image)";
+                } else {
+                    #define CRYPT_FOOTER_OFFSET 0x4000
+                    dev_sz -= CRYPT_FOOTER_OFFSET;
+                    std::string size_str = std::to_string(dev_sz / 4096);
+                    // clang-format off
+                    const char* const args[] = {
+                        "/system/bin/make_f2fs",
+                        "-g", "android",
+                        blk_device.c_str(),
+                        size_str.c_str(),
+                        nullptr
+                    };
+                    // clang-format on
+                    rc = logwrap_fork_execvp(ARRAY_SIZE(args), args, nullptr, false,
+                          LOG_KLOG, false, nullptr);
+                    if(rc){
+                        LERROR << "make_f2fs returned " << rc;
+                    }
+                }
+            }
+        }
+    }
+/*add for auto userdata resize*/
     if (entry.fs_mgr_flags.check ||
         (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
         check_fs(blk_device, entry.fs_type, entry.mount_point, &fs_stat);

  • Android10
diff --git a/system/core/fs_mgr/fs_mgr.cpp b/system/core/fs_mgr/fs_mgr.cpp
index d70d5a7..6b5d438 100755
--- a/system/core/fs_mgr/fs_mgr.cpp
+++ b/system/core/fs_mgr/fs_mgr.cpp
@@ -679,6 +679,63 @@
     }
     return sb == cpu_to_le32(F2FS_SUPER_MAGIC);
 }
 
+  //<!-- add for bug 25338,userdata resize
+  static int get_dev_sz(const char *fs_blkdev, uint64_t *dev_sz)
+  {
+    int fd;
+  
+    if ((fd = open(fs_blkdev, O_RDONLY)) < 0) {
+      LERROR << "Cannot open block device";
+      return -1;
+    }
+  
+    if ((ioctl(fd, BLKGETSIZE64, dev_sz)) == -1) {
+      LERROR << "Cannot get block device size";
+      close(fd);
+      return -1;
+    }
+  
+    close(fd);
+    return 0;
+  }
+  
+  static bool read_f2fs_size(const std::string& blk_device, uint64_t* size) {
+    android::base::unique_fd fd(TEMP_FAILURE_RETRY(open(blk_device.c_str(), O_RDONLY | O_CLOEXEC)));
+    __le64 block_count1, block_count2;
+    __le32 log_blocksize1, log_blocksize2;
+  
+    if (fd < 0) {
+      PERROR << "Failed to open '" << blk_device << "'";
+      return false;
+    }
+  
+    if (TEMP_FAILURE_RETRY(pread(fd, &log_blocksize1, sizeof(log_blocksize1),
+                                 F2FS_SUPER_OFFSET + sizeof(__le32)*4)) != sizeof(log_blocksize1)) {
+      PERROR << "Can't read '" << blk_device << "' superblock1";
+    }
+    if (TEMP_FAILURE_RETRY(pread(fd, &block_count1, sizeof(block_count1),
+                                 F2FS_SUPER_OFFSET + sizeof(__le32)*9)) != sizeof(block_count1)) {
+      PERROR << "Can't read '" << blk_device << "' superblock1";
+    }
+    if (TEMP_FAILURE_RETRY(pread(fd, &log_blocksize2, sizeof(log_blocksize2),
+                                 F2FS_BLKSIZE + F2FS_SUPER_OFFSET + sizeof(__le32)*4))
+        != sizeof(log_blocksize2)) {
+      PERROR << "Can't read '" << blk_device << "' superblock2";
+    }
+    if (TEMP_FAILURE_RETRY(pread(fd, &block_count2, sizeof(block_count2),
+                                 F2FS_BLKSIZE + F2FS_SUPER_OFFSET + sizeof(__le32)*9))
+        != sizeof(block_count2)) {
+      PERROR << "Can't read '" << blk_device << "' superblock2";
+    }
+    LINFO << __func__ << "get " << blk_device << " log_blocksize1:" << log_blocksize1
+          << " block_count1:" << block_count1 << " log_blocksize2:" << log_blocksize2
+          << " block_count2:" << block_count2;
+    if (log_blocksize1 != log_blocksize2 || block_count1 != block_count2)
+      return false;
+    *size = (1 << log_blocksize1) * block_count1;
+    return true;
+  }
+  //add for userdata resize -->
 
 //
 // Prepare the filesystem on the given block device to be mounted.
@@ -714,7 +771,50 @@
             return fs_stat;
         }
     }
+    //<!-- add for userdata resize
+    LINFO<< __func__<<" : mount "<<entry.mount_point;
+    if(!strcmp(entry.mount_point.c_str(),"/data")){
+        uint64_t dev_sz = 0;
+
+        int rc = get_dev_sz(blk_device.c_str(), &dev_sz);
+        
+        uint64_t partition_size = 0;
+        if (is_f2fs(entry.fs_type)) {
+          read_f2fs_size(blk_device, &partition_size);
+        } else {
+          partition_size = entry.length;
+        }        
+
+        if (!rc && partition_size) {
+            LINFO << __func__<< blk_device<<","<<" real size: "<<dev_sz ;
+            LINFO << __func__<< blk_device<<","<<" partition_size: "<<partition_size ;
+
+            if(dev_sz > partition_size+1073741824 || dev_sz < partition_size){
+                if (access("/system/bin/make_f2fs", X_OK)) {
+                    LINFO << "Not running resize on " << blk_device << " (executable not in system image)";
+                } else {
+                    #define CRYPT_FOOTER_OFFSET 0x4000
+                    dev_sz -= CRYPT_FOOTER_OFFSET;
+                    std::string size_str = std::to_string(dev_sz / 4096);
+                    // clang-format off
+                    const char* const args[] = {
+                        "/system/bin/make_f2fs",
+                        "-g", "android",
+                        blk_device.c_str(),
+                        size_str.c_str(),
+                        nullptr
+                    };
+                    // clang-format on
+                    rc = android_fork_execvp_ext(ARRAY_SIZE(args), const_cast<char**>(args), nullptr, false,
+                          LOG_KLOG, false, nullptr, nullptr, 0);
+                    if(rc){
+                        LERROR << "make_f2fs returned " << rc;
+                    }
+                }
+            }
+        }
+    }
+    //add for userdata resize -->
     if (entry.fs_mgr_flags.check ||
         (fs_stat & (FS_STAT_UNCLEAN_SHUTDOWN | FS_STAT_QUOTA_ENABLED))) {
         check_fs(blk_device, entry.fs_type, entry.mount_point, &fs_stat);

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值