提交 c9e7117b 编写于 作者: H Hongze Cheng

refactor

上级 eecfc497
......@@ -186,7 +186,7 @@ static int32_t dnodeInitStorage() {
dError("failed to init TFS since %s", tstrerror(terrno));
return -1;
}
snprintf(tsDataDir, tfsPrimaryPath(), TSDB_FILENAME_LEN);
snprintf(tsDataDir, TFS_PRIMARY_PATH(), TSDB_FILENAME_LEN);
sprintf(tsMnodeDir, "%s/mnode", tsDataDir);
sprintf(tsVnodeDir, "%s/vnode", tsDataDir);
sprintf(tsDnodeDir, "%s/dnode", tsDataDir);
......@@ -203,12 +203,12 @@ static int32_t dnodeInitStorage() {
return -1;
}
if (tfsCreateDir("vnode") < 0) {
if (tfsMkdir("vnode") < 0) {
dError("failed to create vnode dir since %s", tstrerror(terrno));
return -1;
}
if (tfsCreateDir("vnode_bak") < 0) {
if (tfsMkdir("vnode_bak") < 0) {
dError("failed to create vnode_bak dir since %s", tstrerror(terrno));
return -1;
}
......
......@@ -40,36 +40,30 @@ void tfsUpdateInfo();
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 {
// TFILE APIs ====================================
typedef struct {
int level;
int id;
char rname[TSDB_FILENAME_LEN]; // REL name
char aname[TSDB_FILENAME_LEN]; // ABS name
} TFSFILE;
} TFILE;
const char *tfsAbsName(TFSFILE *pfile);
const char *tfsRelName(TFSFILE *pfile);
void tfsDirName(TFSFILE *pfile, char dest[]);
void tfsBaseName(TFSFILE *pfile, char dest[]);
int tfsopen(TFSFILE *pfile, int flags);
int tfsclose(int fd);
int tfsremove(TFSFILE *pfile);
SDiskID tfsFileID(TFSFILE *pfile);
#define TFILE_LEVEL(pf) ((pf)->level)
#define TFILE_ID(pf) ((pf)->id)
#define TFILE_NAME(pf) ((pf)->aname)
int tfsInitFile(TFILE *pf, int level, int id, const char *bname);
// DIR APIs ====================================
int tfsMkdir(const char *rname);
int tfsRmdir(const char *rname);
int tfsRename(char *orname, char *nrname);
typedef struct TFSDIR TFSDIR;
typedef struct TDIR TDIR;
int tfsCreateDir(char *dirname);
int tfsRemoveDir(char *dirname);
int tfsRename(char *oldpath, char *newpath);
TFSDIR * tfsOpenDir(char *dir);
void tfsCloseDir(TFSDIR *tdir);
const TFSFILE *tfsReadDir(TFSDIR *tdir);
TDIR * tfsOpendir(const char *rname);
const TFILE *tfsReaddir(TDIR *tdir);
void tfsClosedir(TDIR *tdir);
#ifdef __cplusplus
}
......
......@@ -60,8 +60,6 @@ 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;
......@@ -70,7 +68,7 @@ typedef struct STier {
int level;
int32_t ndisk;
STierMeta tmeta;
SDisk * disks[TSDB_MAX_DISK_PER_TIER];
SDisk * disks[TSDB_MAX_DISKS_PER_TIER];
} STier;
#define TIER_LEVEL(pt) ((pt)->level)
......
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os.h"
#include "taoserror.h"
#include "tfs.h"
#include "tfsint.h"
struct TFSDIR {
int level;
int id;
char name[TSDB_FILENAME_LEN];
TFSFILE tfsfile;
DIR * dir;
};
static int tfsOpenDirImpl(TFSDIR *tdir);
static void tfsInitFile(TFSFILE *pfile, int level, int id, char *rname);
static TFSFILE *tfsNewFile(int level, int id, char *rname);
// PUBLIC ==========================================
TFSDIR *tfsOpenDir(char *dir) {
TFSDIR *tdir = (TFSDIR *)calloc(1, sizeof(*tdir));
if (tdir == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
return NULL;
}
if (tfsOpenDirImpl(tdir) < 0) {
tfsCloseDir(tdir);
return NULL;
}
return tdir;
}
void tfsCloseDir(TFSDIR *tdir) {
if (tdir) {
if (tdir->dir != NULL) {
closedir(tdir->dir);
tdir->dir = NULL;
}
free(tdir);
}
}
const TFSFILE *tfsReadDir(TFSDIR *tdir) {
if (tdir->dir == NULL) return NULL;
char rname[TSDB_FILENAME_LEN] = "\0";
while (true) {
struct dirent *dp = readdir(tdir->dir);
if (dp != NULL) {
snprintf(rname, TSDB_FILENAME_LEN, "%s/%s", tdir->name, dp->d_name);
tfsInitFile(&(tdir->tfsfile), tdir->level, tdir->id, rname);
return &(tdir->tfsfile);
}
closedir(tdir->dir);
// Move to next
if (tdir->id < tfsNDisksAt(tdir->level) - 1) {
tdir->id++;
} else {
tdir->level++;
tdir->id = 0;
}
if (tfsOpenDirImpl(tdir) < 0) {
return NULL;
}
if (tdir->dir == NULL) return NULL;
}
}
const char *tfsAbsName(TFSFILE *pfile) { return pfile->aname; }
const char *tfsRelName(TFSFILE *pfile) { return pfile->rname; }
void tfsDirName(TFSFILE *pfile, char dest[]) {
char fname[TSDB_FILENAME_LEN] = "\0";
strncpy(fname, tfsAbsName(pfile), TSDB_FILENAME_LEN);
strncpy(dest, dirname(fname), TSDB_FILENAME_LEN);
}
void tfsBaseName(TFSFILE *pfile, char dest[]) {
char fname[TSDB_FILENAME_LEN] = "\0";
strncpy(fname, tfsAbsName(pfile), TSDB_FILENAME_LEN);
strncpy(dest, basename(fname), TSDB_FILENAME_LEN);
}
int tfsopen(TFSFILE *pfile, int flags) {
ASSERT(pfile->level != TFS_UNDECIDED_LEVEL);
if (flags & O_CREAT) {
if (access(pfile->aname, F_OK) == 0) {
terrno = TSDB_CODE_FS_FILE_ALREADY_EXISTS;
return -1;
}
// adjust level
if (pfile->level > tfsLevels()) {
pfile->level = tfsLevels();
}
// adjust id
if (pfile->id == TFS_UNDECIDED_ID) {
// TODO
}
}
ASSERT(pfile->id != TFS_UNDECIDED_ID);
int fd = open(pfile->aname, flags);
if (fd < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
if (flags & O_CREAT) {
tfsLock();
tfsIncFileAt(pfile->level, pfile->id);
tfsUnLock();
}
return fd;
}
int tfsclose(int fd) {
if (close(fd) < 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
return 0;
}
int tfsremove(TFSFILE *pfile) {
int code = remove(pfile->aname);
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
tfsLock();
tfsDecFileAt(pfile->level, pfile->id);
tfsUnLock();
return 0;
}
int tfsRemoveFiles(int nfile, ...) {
va_list valist;
TFSFILE *pfile = NULL;
int code = 0;
va_start(valist, nfile);
tfsLock();
for (int i = 0; i < nfile; i++) {
pfile = va_arg(valist, TFSFILE *);
code = remove(pfile->aname);
if (code != 0) {
terrno = TAOS_SYSTEM_ERROR(errno);
tfsUnLock();
va_end(valist);
return -1;
}
tfsDecFileAt(pfile->level, pfile->id);
}
tfsUnLock();
va_end(valist);
return 0;
}
SDiskID tfsFileID(TFSFILE *pfile) {
SDiskID did;
did.level = pfile->level;
did.id = pfile->id;
return did;
}
// PRIVATE =============================================
static int tfsOpenDirImpl(TFSDIR *tdir) {
char dirName[TSDB_FILENAME_LEN] = "\0";
while (tdir->level < tfsMaxLevel()) {
while (tdir->id < tfsNDisksAt(tdir->level)) {
snprintf(dirName, TSDB_FILENAME_LEN, "%s/%s", tfsGetDiskDir(tdir->level, tdir->id), tdir->name);
tdir->dir = opendir(dirName);
if (tdir->dir == NULL) {
if (errno == ENOENT) {
tdir->id++;
} else {
fError("failed to open dir %s since %s", dirName, strerror(errno));
terrno = TAOS_SYSTEM_ERROR(errno);
return -1;
}
} else {
return 0;
}
}
tdir->id = 0;
tdir->level++;
}
ASSERT(tdir->dir == NULL);
return 0;
}
static void tfsInitFile(TFSFILE *pfile, int level, int id, char *rname) {
pfile->level = level;
pfile->id = id;
strncpy(pfile->rname, rname, TSDB_FILENAME_LEN);
snprintf(pfile->aname, TSDB_FILENAME_LEN, "%s/%s", tfsGetDiskName(level, id), rname);
}
static TFSFILE *tfsNewFile(int level, int id, char *rname) {
TFSFILE *pfile = (TFSFILE *)calloc(1, sizeof(*pfile));
if (pfile == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
return NULL;
}
tfsInitFile(pfile, level, id, rname);
return pfile;
}
......@@ -15,12 +15,14 @@
#include "os.h"
#include "taosdef.h"
#include "hash.h"
#include "taoserror.h"
#include "tfs.h"
#include "tfsint.h"
#define TSDB_MAX_TIER 3
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-truncation"
typedef struct {
int64_t tsize;
......@@ -32,10 +34,14 @@ typedef struct {
bool locked;
SFSMeta meta;
int nlevel;
STier tiers[TSDB_MAX_TIER];
STier tiers[TSDB_MAX_TIERS];
SHashObj * map; // name to did map
} SFS;
typedef struct {
SDisk *pDisk;
} SDiskIter;
#define TFS_LOCKED() (pfs->locked)
#define TFS_META() (pfs->meta)
#define TFS_NLEVEL() (pfs->nlevel)
......@@ -44,6 +50,9 @@ typedef struct {
#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)
#define TFS_IS_VALID_LEVEL(level) (((level) >= 0) && ((level) < TFS_NLEVEL()))
#define TFS_IS_VALID_ID(level, id) (((id) >= 0) && ((id) < TIER_NDISKS(TFS_TIER_AT(level))))
#define TFS_IS_VALID_DISK(level, id) (TFS_IS_VALID_LEVEL(level) && TFS_IS_VALID_ID(level, id))
static SFS tfs = {0};
static SFS *pfs = &tfs;
......@@ -57,12 +66,15 @@ static SDisk *tfsGetDiskByID(SDiskID did);
static SDisk *tfsGetDiskByName(const char *dir);
static int tfsLock();
static int tfsUnLock();
static int tfsOpendirImpl(TDIR *tdir);
static void tfsInitDiskIter(SDiskIter *pIter);
static SDisk *tfsNextDisk(SDiskIter *pIter);
// FS APIs
// FS APIs ====================================
int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
ASSERT(ndisk > 0);
for (int level = 0; level < TSDB_MAX_TIER; level++) {
for (int level = 0; level < TSDB_MAX_TIERS; level++) {
tfsInitTier(TFS_TIER_AT(level), level);
}
......@@ -72,7 +84,7 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
return -1;
}
pfs->map = taosHashInit(TSDB_MAX_TIER * TSDB_MAX_DISKS_PER_TIER * 2,
pfs->map = taosHashInit(TSDB_MAX_TIERS * TSDB_MAX_DISKS_PER_TIER * 2,
taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
if (pfs->map == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
......@@ -123,7 +135,21 @@ void tfsUpdateInfo() {
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)); }
// MANIP APIS ====================================
// TFILE APIs ====================================
int tfsInitFile(TFILE *pf, int level, int id, const char *bname) {
if (!TFS_IS_VALID_DISK(level, id)) return -1;
SDisk *pDisk = TFS_DISK_AT(level, id);
pf->level = level;
pf->id = id;
strncpy(pf->rname, bname, TSDB_FILENAME_LEN);
snprintf(pf->aname, TSDB_FILENAME_LEN, "%s/%s", DISK_DIR(pDisk), pf->rname);
return 0;
}
// DIR APIs ====================================
int tfsMkdir(const char *rname) {
char aname[TSDB_FILENAME_LEN] = "\0";
......@@ -180,6 +206,68 @@ int tfsRename(char *orname, char *nrname) {
return 0;
}
struct TDIR {
SDiskIter iter;
int level;
int id;
char dirname[TSDB_FILENAME_LEN];
TFILE tfile;
DIR * dir;
};
TDIR *tfsOpendir(const char *rname) {
TDIR *tdir = (TDIR *)calloc(1, sizeof(*tdir));
if (tdir == NULL) {
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
return NULL;
}
tfsInitDiskIter(&(tdir->iter));
strncpy(tdir->dirname, rname, TSDB_FILENAME_LEN);
if (tfsOpendirImpl(tdir) < 0) {
free(tdir);
return NULL;
}
return tdir;
}
const TFILE *tfsReaddir(TDIR *tdir) {
if (tdir == NULL || tdir->dir == NULL) return NULL;
char bname[TSDB_FILENAME_LEN] = "\0";
while (true) {
struct dirent *dp = NULL;
dp = readdir(tdir->dir);
if (dp != NULL) {
snprintf(bname, TSDB_FILENAME_LEN, "%s/%s", tdir->dirname, dp->d_name);
tfsInitFile(&(tdir->tfile), tdir->level, tdir->id, bname);
return &(tdir->tfile);
}
if (tfsOpendirImpl(tdir) < 0) {
return NULL;
}
if (tdir->dir == NULL) {
terrno = TSDB_CODE_SUCCESS;
return NULL;
}
}
}
void tfsClosedir(TDIR *tdir) {
if (tdir) {
if (tdir->dir != NULL) {
closedir(tdir->dir);
tdir->dir = NULL;
}
free(tdir);
}
}
// Static functions
static int tfsLock() {
int code = pthread_mutex_lock(&(pfs->lock));
if (code != 0) {
......@@ -229,7 +317,7 @@ static int tfsCheckAndFormatCfg(SDiskCfg *pCfg) {
char dirName[TSDB_FILENAME_LEN] = "\0";
struct stat pstat;
if (pCfg->level < 0 || pCfg->level >= TSDB_MAX_TIER) {
if (pCfg->level < 0 || pCfg->level >= TSDB_MAX_TIERS) {
fError("failed to mount %s to FS since invalid level %d", pCfg->dir, pCfg->level);
terrno = TSDB_CODE_FS_INVLD_CFG;
return -1;
......@@ -337,3 +425,57 @@ static SDisk *tfsGetDiskByName(const char *dir) {
return pDisk;
}
static int tfsOpendirImpl(TDIR *tdir) {
SDisk *pDisk = NULL;
char adir[TSDB_FILENAME_LEN] = "\0";
if (tdir->dir != NULL) {
closedir(tdir->dir);
tdir->dir = NULL;
}
while (true) {
pDisk = tfsNextDisk(&(tdir->iter));
if (pDisk == NULL) return 0;
tdir->level = DISK_LEVEL(pDisk);
tdir->id = DISK_ID(pDisk);
snprintf(adir, TSDB_FILENAME_LEN, "%s/%s", DISK_DIR(pDisk), tdir->dirname);
tdir->dir = opendir(adir);
if (tdir->dir != NULL) break;
}
return 0;
}
static void tfsInitDiskIter(SDiskIter *pIter) { pIter->pDisk = TFS_DISK_AT(0, 0); }
static SDisk *tfsNextDisk(SDiskIter *pIter) {
SDisk *pDisk = pIter->pDisk;
if (pDisk == NULL) return NULL;
int level = DISK_LEVEL(pDisk);
int id = DISK_ID(pDisk);
id++;
if (id < TIER_NDISKS(TFS_TIER_AT(level))) {
pIter->pDisk = TFS_DISK_AT(level, id);
ASSERT(pIter->pDisk != NULL);
} else {
level++;
id = 0;
if (level < TFS_NLEVEL()) {
pIter->pDisk = TFS_DISK_AT(level, id);
ASSERT(pIter->pDisk != NULL);
} else {
pIter->pDisk = NULL;
}
}
return pDisk;
}
#pragma GCC diagnostic pop
\ No newline at end of file
......@@ -14,14 +14,15 @@
*/
#include "os.h"
#include "tfsint.h"
#include "taosdef.h"
#include "taoserror.h"
#include "tfsint.h"
// PROTECTED ==========================================
void tfsInitTier(STier *pTier, int level) { pTier->level = level; }
void tfsDestroyTier(STier *pTier) {
for (int id = 0; id < TSDB_MAX_DISK_PER_TIER; id++) {
for (int id = 0; id < TSDB_MAX_DISKS_PER_TIER; id++) {
DISK_AT_TIER(pTier, id) = tfsFreeDisk(DISK_AT_TIER(pTier, id));
}
pTier->ndisk = 0;
......@@ -31,7 +32,7 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
ASSERT(pTier->level == pCfg->level);
int id = 0;
if (TIER_NDISKS(pTier) >= TSDB_MAX_DISK_PER_TIER) {
if (TIER_NDISKS(pTier) >= TSDB_MAX_DISKS_PER_TIER) {
terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
return NULL;
}
......@@ -41,7 +42,7 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
id = pTier->ndisk;
} else {
id = pTier->ndisk + 1;
if (id >= TSDB_MAX_DISK_PER_TIER) {
if (id >= TSDB_MAX_DISKS_PER_TIER) {
terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
return NULL;
}
......
......@@ -189,7 +189,7 @@ typedef struct {
} STsdbFileInfo;
typedef struct {
TFSFILE file;
TFILE file;
STsdbFileInfo info;
int fd;
} SFile;
......
......@@ -67,14 +67,14 @@ int tsdbOpenFileH(STsdbRepo *pRepo) { // TODO
char dataDir[TSDB_FILENAME_LEN] = "\0";
// 1. scan and get all files corresponds
TFSDIR *tdir = NULL;
TDIR *tdir = NULL;
char fname[TSDB_FILENAME_LEN] = "\0";
regex_t regex = {0};
int code = 0;
int vid = 0;
int fid = 0;
const TFSFILE *pfile = NULL;
const TFILE *pfile = NULL;
code = regcomp(&regex, "^v[0-9]+f[0-9]+\\.(head|data|last|h|d|l)$", REG_EXTENDED);
if (code != 0) {
......@@ -82,12 +82,12 @@ int tsdbOpenFileH(STsdbRepo *pRepo) { // TODO
}
snprintf(dataDir, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data", REPO_ID(pRepo));
tdir = tfsOpenDir(dataDir);
tdir = tfsOpendir(dataDir);
if (tdir == NULL) {
// TODO: deal the error
}
while ((pfile = tfsReadDir(tdir)) != NULL) {
while ((pfile = tfsReaddir(tdir)) != NULL) {
tfsBaseName(pfile, fname);
if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) continue;
......
......@@ -102,7 +102,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
return TSDB_CODE_SUCCESS;
}
if (tfsCreateDir("vnode") < 0) {
if (tfsMkdir("vnode") < 0) {
vError("vgId:%d, failed to create vnode dir, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
return terrno;
}
......@@ -112,7 +112,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
char vnodeDir[TSDB_FILENAME_LEN] = "\0";
snprintf(vnodeDir, TSDB_FILENAME_LEN, "vnode%d", pVnodeCfg->cfg.vgId);
if (tfsCreateDir(vnodeDir) < 0) {
if (tfsMkdir(vnodeDir) < 0) {
vError("vgId:%d, failed to create vnode %d dir, reason:%s", pVnodeCfg->cfg.vgId, strerror(errno));
return terrno;
}
......@@ -442,11 +442,11 @@ void vnodeRelease(void *vparam) {
if (0 == tsEnableVnodeBak) {
vInfo("vgId:%d, vnode backup not enabled", pVnode->vgId);
} else {
tfsRemoveDir(newDir);
tfsRmdir(newDir);
tfsRename(rootDir, newDir);
}
tfsRemoveDir(rootDir);
tfsRmdir(rootDir);
dnodeSendStatusMsgToMnode();
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册