diff --git a/src/inc/tfs.h b/src/inc/tfs.h index 2f816bfa7eeb0820f70fcb36400cdcc8aab5c3f3..a0d666c5fb209470ce2d451a85af74a7258b043a 100644 --- a/src/inc/tfs.h +++ b/src/inc/tfs.h @@ -29,14 +29,21 @@ typedef struct { #define TFS_UNDECIDED_LEVEL -1 #define TFS_UNDECIDED_ID -1 +#define TFS_PRIMARY_LEVEL 0 +#define TFS_PRIMARY_ID 0 -// tfs.c ==================================== +// FS APIs ==================================== int tfsInit(SDiskCfg *pDiskCfg, int ndisk); void tfsDestroy(); -int tfsUpdateInfo(); +void tfsUpdateInfo(); -const char *tfsGetDiskName(int level, int id); -const char *tfsPrimaryPath(); +const char *TFS_PRIMARY_PATH(); +const char *TFS_DISK_PATH(int level, int id); + +// MANIP APIS ==================================== +int tfsMkdir(const char *rname); +int tfsRmdir(const char *rname); +int tfsRename(char *orname, char *nrname); // tfcntl.c ==================================== typedef struct TFSFILE { diff --git a/src/tfs/inc/tfsint.h b/src/tfs/inc/tfsint.h index 8d59545802fc0f1084d8a246e535f87cb6d186f7..d3377d9fd24dafc1700af7e4697bc2dba1ae2ab7 100644 --- a/src/tfs/inc/tfsint.h +++ b/src/tfs/inc/tfsint.h @@ -33,40 +33,56 @@ extern int fsDebugFlag; #define fDebug(...) { if (fsDebugFlag & DEBUG_DEBUG) { taosPrintLog("TFS ", cqDebugFlag, __VA_ARGS__); }} #define fTrace(...) { if (fsDebugFlag & DEBUG_TRACE) { taosPrintLog("TFS ", cqDebugFlag, __VA_ARGS__); }} -// tdisk.c -typedef struct SDisk SDisk; - -SDisk *tfsNewDisk(int level, int id, char *dir); -void tfsFreeDisk(SDisk *pDisk); -int tfsUpdateDiskInfo(SDisk *pDisk); - -const char *tfsDiskDir(SDisk *pDisk); - -// ttier.c +// tdisk.c ====================================================== +typedef struct { + int32_t nfiles; + int64_t size; + int64_t free; +} SDiskMeta; + +typedef struct SDisk { + int level; + int id; + char dir[TSDB_FILENAME_LEN]; + SDiskMeta dmeta; +} SDisk; + +#define DISK_LEVEL(pd) ((pd)->level) +#define DISK_ID(pd) ((pd)->id) +#define DISK_DIR(pd) ((pd)->dir) +#define DISK_META(pd) ((pd)->dmeta) +#define DISK_SIZE(pd) ((pd)->dmeta.size) +#define DISK_FREE_SIZE(pd) ((pd)->dmeta.free) +#define DISK_NFILES(pd) ((pd)->dmeta.nfiles) + +SDisk *tfsNewDisk(int level, int id, const char *dir); +SDisk *tfsFreeDisk(SDisk *pDisk); +void tfsUpdateDiskInfo(SDisk *pDisk); + +// ttier.c ====================================================== #define TSDB_MAX_DISK_PER_TIER 16 +typedef struct { + int64_t size; + int64_t free; +} STierMeta; typedef struct STier { - int level; - int ndisk; - SDisk *disks[TSDB_MAX_DISK_PER_TIER]; + int level; + int32_t ndisk; + STierMeta tmeta; + SDisk * disks[TSDB_MAX_DISK_PER_TIER]; } STier; -#define DISK_AT_TIER(pTier, id) ((pTier)->disks[id]) +#define TIER_LEVEL(pt) ((pt)->level) +#define TIER_NDISKS(pt) ((pt)->ndisk) +#define TIER_SIZE(pt) ((pt)->tmeta.size) +#define TIER_FREE_SIZE(pt) ((pt)->tmeta.free) +#define DISK_AT_TIER(pt, id) ((pt)->disks[id]) void tfsInitTier(STier *pTier, int level); void tfsDestroyTier(STier *pTier); SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg); -int tfsUpdateTierInfo(STier *pTier); - -// tfs.c -void tfsIncFileAt(int level, int id); -void tfsDecFileAt(int level, int id); -int tfsLock(); -int tfsUnLock(); -bool tfsIsLocked(); -int tfsLevels(); - -// tfcntl.c +void tfsUpdateTierInfo(STier *pTier); #ifdef __cplusplus } diff --git a/src/tfs/src/tdisk.c b/src/tfs/src/tdisk.c index b73f33caabae495dbcd7d9f8b9920f261a0b48fa..8403eaa4cad049dcd7089b778301352ea70b641d 100644 --- a/src/tfs/src/tdisk.c +++ b/src/tfs/src/tdisk.c @@ -17,21 +17,8 @@ #include "taoserror.h" #include "tfsint.h" -typedef struct { - uint64_t size; - uint64_t free; - uint64_t nfiles; -} SDiskMeta; - -struct SDisk { - int level; - int id; - char dir[TSDB_FILENAME_LEN]; - SDiskMeta dmeta; -}; - // PROTECTED ==================================== -SDisk *tfsNewDisk(int level, int id, char *dir) { +SDisk *tfsNewDisk(int level, int id, const char *dir) { SDisk *pDisk = (SDisk *)calloc(1, sizeof(*pDisk)); if (pDisk == NULL) { terrno = TSDB_CODE_FS_OUT_OF_MEMORY; @@ -45,24 +32,24 @@ SDisk *tfsNewDisk(int level, int id, char *dir) { return pDisk; } -void tfsFreeDisk(SDisk *pDisk) { +SDisk *tfsFreeDisk(SDisk *pDisk) { if (pDisk) { free(pDisk); } + return NULL; } -int tfsUpdateDiskInfo(SDisk *pDisk) { +void tfsUpdateDiskInfo(SDisk *pDisk) { + ASSERT(pDisk != NULL); SysDiskSize dstat; if (taosGetDiskSize(pDisk->dir, &dstat) < 0) { - fError("failed to get dir %s information since %s", pDisk->dir, strerror(errno)); + fError("failed to update disk information at level %d id %d dir %s since %s", pDisk->level, pDisk->id, pDisk->dir, + strerror(errno)); terrno = TAOS_SYSTEM_ERROR(errno); - return -1; + pDisk->dmeta.size = 0; + pDisk->dmeta.free = 0; + } else { + pDisk->dmeta.size = dstat.tsize; + pDisk->dmeta.free = dstat.avail; } - - pDisk->dmeta.size = dstat.tsize; - pDisk->dmeta.free = dstat.avail; - - return 0; -} - -const char *tfsDiskDir(SDisk *pDisk) { return pDisk->dir; } \ No newline at end of file +} \ No newline at end of file diff --git a/src/tfs/src/tfs.c b/src/tfs/src/tfs.c index 44c2045679f325f2a6ec0fe84038ebb38d3bac51..fc091f7b23dbcb5d500ae390b28ad1f808e00979 100644 --- a/src/tfs/src/tfs.c +++ b/src/tfs/src/tfs.c @@ -17,13 +17,14 @@ #include "hash.h" #include "taoserror.h" +#include "tfs.h" #include "tfsint.h" #define TSDB_MAX_TIER 3 typedef struct { - uint64_t tsize; - uint64_t avail; + int64_t tsize; + int64_t avail; } SFSMeta; typedef struct { @@ -35,24 +36,34 @@ typedef struct { SHashObj * map; // name to did map } SFS; -static SFS tdFileSystem = {0}; -static SFS *pfs = &tdFileSystem; - -#define TIER_AT(level) (pfs->tiers + (level)) -#define DISK_AT(level, id) DISK_AT_TIER(TIER_AT(level), id) - -static int tfsMount(SDiskCfg *pCfg); -static int tfsCheckAndFormatCfg(SDiskCfg *pCfg); -static int tfsFormatDir(char *idir, char *odir); -static int tfsCheck(); -static tfsGetDiskByName(char *dirName); - -// public: +#define TFS_LOCKED() (pfs->locked) +#define TFS_META() (pfs->meta) +#define TFS_NLEVEL() (pfs->nlevel) +#define TFS_TIERS() (pfs->tiers) + +#define TFS_TIER_AT(level) (TFS_TIERS() + (level)) +#define TFS_DISK_AT(level, id) DISK_AT_TIER(TFS_TIER_AT(level), id) +#define TFS_PRIMARY_DISK() TFS_DISK_AT(TFS_PRIMARY_LEVEL, TFS_PRIMARY_ID) + +static SFS tfs = {0}; +static SFS *pfs = &tfs; + +// STATIC DECLARATION +static int tfsMount(SDiskCfg *pCfg); +static int tfsCheck(); +static int tfsCheckAndFormatCfg(SDiskCfg *pCfg); +static int tfsFormatDir(char *idir, char *odir); +static SDisk *tfsGetDiskByID(SDiskID did); +static SDisk *tfsGetDiskByName(const char *dir); +static int tfsLock(); +static int tfsUnLock(); + +// FS APIs int tfsInit(SDiskCfg *pDiskCfg, int ndisk) { ASSERT(ndisk > 0); for (int level = 0; level < TSDB_MAX_TIER; level++) { - tdInitTier(TIER_AT(level), level); + tfsInitTier(TFS_TIER_AT(level), level); } int ret = pthread_mutex_init(&(pfs->lock), NULL); @@ -81,6 +92,8 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) { return -1; } + tfsUpdateInfo(); + return 0; } @@ -89,39 +102,39 @@ void tfsDestroy() { pfs->map = NULL; pthread_mutex_destroy(&(pfs->lock)); - for (int level = 0; level < TSDB_MAX_TIER; level++) { - tfsDestroyTier(TIER_AT(level)); + for (int level = 0; level < TFS_NLEVEL(); level++) { + tfsDestroyTier(TFS_TIER_AT(level)); } } -int tfsUpdateInfo() { +void tfsUpdateInfo() { tfsLock(); - for (int level = 0; level < pfs->nlevel; level++) { - if (tfsUpdateTierInfo(TIER_AT(level)) < 0) { - // TODO: deal with the error here - } + for (int level = 0; level < TFS_NLEVEL(); level++) { + STier *pTier = TFS_TIER_AT(level); + tfsUpdateTierInfo(pTier); + pfs->meta.tsize = TIER_SIZE(pTier); + pfs->meta.avail = TIER_FREE_SIZE(pTier); } tfsUnLock(); } -const char *tfsPrimaryPath() { return tfsDiskDir(DISK_AT(0, 0)); } +const char *TFS_PRIMARY_PATH() { return DISK_DIR(TFS_PRIMARY_DISK()); } +const char *TFS_DISK_PATH(int level, int id) { return DISK_DIR(TFS_DISK_AT(level, id)); } -int tfsCreateDir(char *dirname) { - char dirName[TSDB_FILENAME_LEN] = "\0"; +// MANIP APIS ==================================== +int tfsMkdir(const char *rname) { + char aname[TSDB_FILENAME_LEN] = "\0"; - for (int level = 0; level < pfs->nlevel; level++) { - STier *pTier = TIER_AT(level); - for (int id = 0; id < pTier->ndisk; id++) { + for (int level = 0; level < TFS_NLEVEL(); level++) { + STier *pTier = TFS_TIER_AT(level); + for (int id = 0; id < TIER_NDISKS(pTier); id++) { SDisk *pDisk = DISK_AT_TIER(pTier, id); + snprintf(aname, TSDB_FILENAME_LEN, "%s/%s", DISK_DIR(pDisk), rname); - ASSERT(pDisk != NULL); - - snprintf(dirName, TSDB_FILENAME_LEN, "%s/%s", pDisk->name, dirname); - - if (mkdir(dirName, 0755) != 0 && errno != EEXIST) { - fError("failed to create directory %s since %s", dirName, strerror(errno)); + if (mkdir(aname, 0755) != 0 && errno != EEXIST) { + fError("failed to create directory %s since %s", aname, strerror(errno)); terrno = TAOS_SYSTEM_ERROR(errno); return -1; } @@ -131,60 +144,43 @@ int tfsCreateDir(char *dirname) { return 0; } -int tfsRemoveDir(char *dirname) { - char dirName[TSDB_FILENAME_LEN] = "\0"; +int tfsRmdir(const char *rname) { + char aname[TSDB_FILENAME_LEN] = "\0"; - for (int level = 0; level < pfs->nlevel; level++) { - STier *pTier = TIER_AT(level); - for (int id = 0; id < pTier->ndisk; id++) { + for (int level = 0; level < TFS_NLEVEL(); level++) { + STier *pTier = TFS_TIER_AT(level); + for (int id = 0; id < TIER_NDISKS(pTier); id++) { SDisk *pDisk = DISK_AT_TIER(pTier, id); - ASSERT(pDisk != NULL); + snprintf(aname, TSDB_FILENAME_LEN, "%s/%s", DISK_DIR(pDisk), rname); - snprintf(dirName, TSDB_FILENAME_LEN, "%s/%s", pDisk->dir, dirname); - - taosRemoveDir(dirName); + taosRemoveDir(aname); } } return 0; } -int tfsRename(char *oldpath, char *newpath) { - char oldName[TSDB_FILENAME_LEN] = "\0"; - char newName[TSDB_FILENAME_LEN] = "\0"; +int tfsRename(char *orname, char *nrname) { + char oaname[TSDB_FILENAME_LEN] = "\0"; + char naname[TSDB_FILENAME_LEN] = "\0"; for (int level = 0; level < pfs->nlevel; level++) { - STier *pTier = TIER_AT(level); - for (int id = 0; id < pTier->ndisk; id++) { + STier *pTier = TFS_TIER_AT(level); + for (int id = 0; id < TIER_NDISKS(pTier); id++) { SDisk *pDisk = DISK_AT_TIER(pTier, id); - ASSERT(pDisk != NULL); - - snprintf(oldName, TSDB_FILENAME_LEN, "%s/%s", pDisk->dir, oldpath); - snprintf(newName, TSDB_FILENAME_LEN, "%s/%s", pDisk->dir, newpath); + snprintf(oaname, TSDB_FILENAME_LEN, "%s/%s", DISK_DIR(pDisk), orname); + snprintf(naname, TSDB_FILENAME_LEN, "%s/%s", DISK_DIR(pDisk), nrname); - taosRename(oldName, newName); + taosRename(oaname, naname); } } return 0; } -// protected: -void tfsIncFileAt(int level, int id) { - ASSERT(tfsIsLocked()); - DISK_AT(level, id)->dmeta.nfiles++; - ASSERT(DISK_AT(level, id)->dmeta.nfiles > 0); -} - -void tfsDecFileAt(int level, int id) { - ASSERT(tfsIsLocked()); - DISK_AT(level, id)->dmeta.nfiles--; - ASSERT(DISK_AT(level, id)->dmeta.nfiles >= 0); -} - -int tfsLock() { +static int tfsLock() { int code = pthread_mutex_lock(&(pfs->lock)); if (code != 0) { terrno = TAOS_SYSTEM_ERROR(code); @@ -196,7 +192,7 @@ int tfsLock() { return 0; } -int tfsUnLock() { +static int tfsUnLock() { pfs->locked = false; int code = pthread_mutex_unlock(&(pfs->lock)); @@ -208,32 +204,24 @@ int tfsUnLock() { return 0; } -bool tfsIsLocked() { return pfs->locked; } - -int tfsLevels() { return pfs->nlevel; } - -const char *tfsGetDiskName(int level, int id) { - return DISK_AT(level, id)->dir; -} - // private static int tfsMount(SDiskCfg *pCfg) { SDiskID did; + SDisk * pDisk = NULL; if (tfsCheckAndFormatCfg(pCfg) < 0) return -1; did.level = pCfg->level; - did.id = tdMountToTier(TIER_AT(pCfg->level), pCfg); - if (did.id < 0) { - fError("failed to mount %s to FS since %s", pCfg->dir, tstrerror(terrno)); + pDisk = tfsMountDiskToTier(TFS_TIER_AT(did.level), pCfg); + if (pDisk == NULL) { + fError("failed to mount disk %s to level %d since %s", pCfg->dir, pCfg->level, strerror(terrno)); return -1; } + did.id = DISK_ID(pDisk); - taosHashPut(pTiers->map, pCfg->dir, strnlen(pCfg->dir, TSDB_FILENAME_LEN), (void *)(&did), sizeof(did)); + taosHashPut(pfs->map, (void *)(pCfg->dir), strnlen(pCfg->dir, TSDB_FILENAME_LEN), (void *)(&did), sizeof(did)); if (pfs->nlevel < pCfg->level + 1) pfs->nlevel = pCfg->level + 1; - // TODO: update meta info - return 0; } @@ -254,8 +242,8 @@ static int tfsCheckAndFormatCfg(SDiskCfg *pCfg) { return -1; } - if (DISK_AT(0, 0) != NULL) { - fError("failed to mount %s to FS since duplicate primary mount", pCfg->dir, pCfg->level); + if (TFS_PRIMARY_DISK() != NULL) { + fError("failed to mount %s to FS since duplicate primary mount", pCfg->dir); terrno = TSDB_CODE_FS_DUP_PRIMARY; return -1; } @@ -317,25 +305,35 @@ static int tfsFormatDir(char *idir, char *odir) { } static int tfsCheck() { - if (DISK_AT(0, 0) == NULL) { + if (TFS_PRIMARY_DISK() == NULL) { fError("no primary disk is set"); terrno = TSDB_CODE_FS_NO_PRIMARY_DISK; return -1; } - int level = 0; - do { - if (TIER_AT(level)->ndisk == 0) { + for (int level = 0; level < TFS_NLEVEL(); level++) { + if (TIER_NDISKS(TFS_TIER_AT(level)) == 0) { fError("no disk at level %d", level); terrno = TSDB_CODE_FS_NO_MOUNT_AT_TIER; return -1; } - } while (level < pfs->nlevel); + } return 0; } -static tfsGetDiskByName(char *dirName) { -} +static SDisk *tfsGetDiskByID(SDiskID did) { return TFS_DISK_AT(did.level, did.id); } +static SDisk *tfsGetDiskByName(const char *dir) { + SDiskID did; + SDisk * pDisk = NULL; + void * pr = NULL; + + pr = taosHashGet(pfs->map, (void *)dir, strnlen(dir, TSDB_FILENAME_LEN)); + if (pr == NULL) return NULL; + + did = *(SDiskID *)pr; + pDisk = tfsGetDiskByID(did); + ASSERT(pDisk != NULL); -static SDisk *tfsGetDiskByID(SDiskID did) { return DISK_AT(did.level, did.id); } \ No newline at end of file + return pDisk; +} \ No newline at end of file diff --git a/src/tfs/src/ttier.c b/src/tfs/src/ttier.c index fbad4c9f3c8eb7806438eec49c583ae080e74db5..28c45d28e7b9025c111a548f7419ba9e21f63c17 100644 --- a/src/tfs/src/ttier.c +++ b/src/tfs/src/ttier.c @@ -18,14 +18,11 @@ #include "taoserror.h" // PROTECTED ========================================== -void tfsInitTier(STier *pTier, int level) { - pTier->level = level; -} +void tfsInitTier(STier *pTier, int level) { pTier->level = level; } void tfsDestroyTier(STier *pTier) { for (int id = 0; id < TSDB_MAX_DISK_PER_TIER; id++) { - tfsFreeDisk(DISK_AT_TIER(pTier, id)); - pTier->disks[id] = NULL; + DISK_AT_TIER(pTier, id) = tfsFreeDisk(DISK_AT_TIER(pTier, id)); } pTier->ndisk = 0; } @@ -34,9 +31,9 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) { ASSERT(pTier->level == pCfg->level); int id = 0; - if (pTier->ndisk >= TSDB_MAX_DISK_PER_TIER) { + if (TIER_NDISKS(pTier) >= TSDB_MAX_DISK_PER_TIER) { terrno = TSDB_CODE_FS_TOO_MANY_MOUNT; - return -1; + return NULL; } if (pTier->level == 0) { @@ -46,7 +43,7 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) { id = pTier->ndisk + 1; if (id >= TSDB_MAX_DISK_PER_TIER) { terrno = TSDB_CODE_FS_TOO_MANY_MOUNT; - return -1; + return NULL; } } } else { @@ -54,19 +51,22 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) { } DISK_AT_TIER(pTier, id) = tfsNewDisk(pCfg->level, id, pCfg->dir); - if (DISK_AT_TIER(pTier, id) == NULL) return -1; + if (DISK_AT_TIER(pTier, id) == NULL) return NULL; pTier->ndisk++; - fDebug("disk %s is mounted to level %d id %d", pCfg->dir, pCfg->level, id); + fDebug("disk %s is mounted to tier level %d id %d", pCfg->dir, pCfg->level, id); - return id; + return DISK_AT_TIER(pTier, id); } -int tfsUpdateTierInfo(STier *pTier) { +void tfsUpdateTierInfo(STier *pTier) { + STierMeta tmeta = {0}; + for (int id = 0; id < pTier->ndisk; id++) { - if (tfsUpdateDiskInfo(DISK_AT_TIER(pTier, id)) < 0) { - return -1; - } + tfsUpdateDiskInfo(DISK_AT_TIER(pTier, id)); + tmeta.size += DISK_SIZE(DISK_AT_TIER(pTier, id)); + tmeta.free += DISK_FREE_SIZE(DISK_AT_TIER(pTier, id)); } - return 0; + + pTier->tmeta = tmeta; } \ No newline at end of file