From b366fa96875d63d5176103cc99d22211d9dc4cab Mon Sep 17 00:00:00 2001 From: Jiuzhu Dong Date: Thu, 12 Aug 2021 21:50:41 +0800 Subject: [PATCH] exfat_mkfs: define exfat_mkfs to make exfat file system we can reuse this code at other component Change-Id: Ic7d6f055d28571ca9cdba885e9c0b61d6f623fb0 Signed-off-by: Jiuzhu Dong --- mkfs/main.c | 150 +------------------------------------------------ mkfs/mkexfat.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++- mkfs/mkexfat.h | 6 +- 3 files changed, 149 insertions(+), 153 deletions(-) diff --git a/mkfs/main.c b/mkfs/main.c index 07620244..3dbef241 100644 --- a/mkfs/main.c +++ b/mkfs/main.c @@ -21,161 +21,15 @@ */ #include "mkexfat.h" -#include "vbr.h" -#include "fat.h" -#include "cbm.h" -#include "uct.h" -#include "rootdir.h" #include #include -#include #include #include #include #include +#include #include -const struct fs_object* objects[] = -{ - &vbr, - &vbr, - &fat, - /* clusters heap */ - &cbm, - &uct, - &rootdir, - NULL, -}; - -static struct -{ - int sector_bits; - int spc_bits; - off_t volume_size; - le16_t volume_label[EXFAT_ENAME_MAX + 1]; - uint32_t volume_serial; - uint64_t first_sector; -} -param; - -int get_sector_bits(void) -{ - return param.sector_bits; -} - -int get_spc_bits(void) -{ - return param.spc_bits; -} - -off_t get_volume_size(void) -{ - return param.volume_size; -} - -const le16_t* get_volume_label(void) -{ - return param.volume_label; -} - -uint32_t get_volume_serial(void) -{ - return param.volume_serial; -} - -uint64_t get_first_sector(void) -{ - return param.first_sector; -} - -int get_sector_size(void) -{ - return 1 << get_sector_bits(); -} - -int get_cluster_size(void) -{ - return get_sector_size() << get_spc_bits(); -} - -static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size) -{ - int i; - - if (user_defined != -1) - { - off_t cluster_size = 1 << sector_bits << user_defined; - if (volume_size / cluster_size > EXFAT_LAST_DATA_CLUSTER) - { - struct exfat_human_bytes chb, vhb; - - exfat_humanize_bytes(cluster_size, &chb); - exfat_humanize_bytes(volume_size, &vhb); - exfat_error("cluster size %"PRIu64" %s is too small for " - "%"PRIu64" %s volume, try -s %d", - chb.value, chb.unit, - vhb.value, vhb.unit, - 1 << setup_spc_bits(sector_bits, -1, volume_size)); - return -1; - } - return user_defined; - } - - if (volume_size < 256LL * 1024 * 1024) - return MAX(0, 12 - sector_bits); /* 4 KB */ - if (volume_size < 32LL * 1024 * 1024 * 1024) - return MAX(0, 15 - sector_bits); /* 32 KB */ - - for (i = 17; ; i++) /* 128 KB or more */ - if (DIV_ROUND_UP(volume_size, 1 << i) <= EXFAT_LAST_DATA_CLUSTER) - return MAX(0, i - sector_bits); -} - -static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s) -{ - memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t)); - if (s == NULL) - return 0; - return exfat_utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s)); -} - -static uint32_t setup_volume_serial(uint32_t user_defined) -{ - struct timeval now; - - if (user_defined != 0) - return user_defined; - - if (gettimeofday(&now, NULL) != 0) - { - exfat_error("failed to form volume id"); - return 0; - } - return (now.tv_sec << 20) | now.tv_usec; -} - -static int setup(struct exfat_dev* dev, int sector_bits, int spc_bits, - const char* volume_label, uint32_t volume_serial, - uint64_t first_sector) -{ - param.sector_bits = sector_bits; - param.first_sector = first_sector; - param.volume_size = exfat_get_size(dev); - - param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size); - if (param.spc_bits == -1) - return 1; - - if (setup_volume_label(param.volume_label, volume_label) != 0) - return 1; - - param.volume_serial = setup_volume_serial(volume_serial); - if (param.volume_serial == 0) - return 1; - - return mkfs(dev, param.volume_size); -} - static int logarithm2(int n) { size_t i; @@ -242,7 +96,7 @@ int main(int argc, char* argv[]) dev = exfat_open(spec, EXFAT_MODE_RW); if (dev == NULL) return 1; - if (setup(dev, 9, spc_bits, volume_label, volume_serial, + if (exfat_mkfs(dev, 9, spc_bits, volume_label, volume_serial, first_sector) != 0) { exfat_close(dev); diff --git a/mkfs/mkexfat.c b/mkfs/mkexfat.c index eadbe968..fa1f1cec 100644 --- a/mkfs/mkexfat.c +++ b/mkfs/mkexfat.c @@ -21,12 +21,137 @@ */ #include "mkexfat.h" +#include "vbr.h" +#include "fat.h" +#include "cbm.h" +#include "uct.h" +#include "rootdir.h" #include +#include #include #include #include #include +static const struct fs_object* objects[] = +{ + &vbr, + &vbr, + &fat, + /* clusters heap */ + &cbm, + &uct, + &rootdir, + NULL, +}; + +static struct +{ + int sector_bits; + int spc_bits; + off_t volume_size; + le16_t volume_label[EXFAT_ENAME_MAX + 1]; + uint32_t volume_serial; + uint64_t first_sector; +} +param; + +int get_sector_bits(void) +{ + return param.sector_bits; +} + +int get_spc_bits(void) +{ + return param.spc_bits; +} + +off_t get_volume_size(void) +{ + return param.volume_size; +} + +const le16_t* get_volume_label(void) +{ + return param.volume_label; +} + +uint32_t get_volume_serial(void) +{ + return param.volume_serial; +} + +uint64_t get_first_sector(void) +{ + return param.first_sector; +} + +int get_sector_size(void) +{ + return 1 << get_sector_bits(); +} + +int get_cluster_size(void) +{ + return get_sector_size() << get_spc_bits(); +} + +static int setup_spc_bits(int sector_bits, int user_defined, off_t volume_size) +{ + int i; + + if (user_defined != -1) + { + off_t cluster_size = 1 << sector_bits << user_defined; + if (volume_size / cluster_size > EXFAT_LAST_DATA_CLUSTER) + { + struct exfat_human_bytes chb, vhb; + + exfat_humanize_bytes(cluster_size, &chb); + exfat_humanize_bytes(volume_size, &vhb); + exfat_error("cluster size %"PRIu64" %s is too small for " + "%"PRIu64" %s volume, try -s %d", + chb.value, chb.unit, + vhb.value, vhb.unit, + 1 << setup_spc_bits(sector_bits, -1, volume_size)); + return -1; + } + return user_defined; + } + + if (volume_size < 256LL * 1024 * 1024) + return MAX(0, 12 - sector_bits); /* 4 KB */ + if (volume_size < 32LL * 1024 * 1024 * 1024) + return MAX(0, 15 - sector_bits); /* 32 KB */ + + for (i = 17; ; i++) /* 128 KB or more */ + if (DIV_ROUND_UP(volume_size, 1 << i) <= EXFAT_LAST_DATA_CLUSTER) + return MAX(0, i - sector_bits); +} + +static int setup_volume_label(le16_t label[EXFAT_ENAME_MAX + 1], const char* s) +{ + memset(label, 0, (EXFAT_ENAME_MAX + 1) * sizeof(le16_t)); + if (s == NULL) + return 0; + return exfat_utf8_to_utf16(label, s, EXFAT_ENAME_MAX + 1, strlen(s)); +} + +static uint32_t setup_volume_serial(uint32_t user_defined) +{ + struct timeval now; + + if (user_defined != 0) + return user_defined; + + if (gettimeofday(&now, NULL) != 0) + { + exfat_error("failed to form volume id"); + return 0; + } + return (now.tv_sec << 20) | now.tv_usec; +} + static int check_size(off_t volume_size) { const struct fs_object** pp; @@ -124,9 +249,26 @@ static int create(struct exfat_dev* dev) return 0; } -int mkfs(struct exfat_dev* dev, off_t volume_size) +int exfat_mkfs(struct exfat_dev* dev, int sector_bits, int spc_bits, + const char* volume_label, uint32_t volume_serial, + uint64_t first_sector) { - if (check_size(volume_size) != 0) + param.sector_bits = sector_bits; + param.first_sector = first_sector; + param.volume_size = exfat_get_size(dev); + + param.spc_bits = setup_spc_bits(sector_bits, spc_bits, param.volume_size); + if (param.spc_bits == -1) + return 1; + + if (setup_volume_label(param.volume_label, volume_label) != 0) + return 1; + + param.volume_serial = setup_volume_serial(volume_serial); + if (param.volume_serial == 0) + return 1; + + if (check_size(param.volume_size) != 0) return 1; fputs("Creating... ", stdout); diff --git a/mkfs/mkexfat.h b/mkfs/mkexfat.h index 963b3e5f..41a8984e 100644 --- a/mkfs/mkexfat.h +++ b/mkfs/mkexfat.h @@ -32,8 +32,6 @@ struct fs_object int (*write)(struct exfat_dev* dev); }; -extern const struct fs_object* objects[]; - int get_sector_bits(void); int get_spc_bits(void); off_t get_volume_size(void); @@ -43,7 +41,9 @@ uint64_t get_first_sector(void); int get_sector_size(void); int get_cluster_size(void); -int mkfs(struct exfat_dev* dev, off_t volume_size); +int exfat_mkfs(struct exfat_dev* dev, int sector_bits, int spc_bits, + const char* volume_label, uint32_t volume_serial, + uint64_t first_sector); off_t get_position(const struct fs_object* object); #endif /* ifndef MKFS_MKEXFAT_H_INCLUDED */