refactor
This commit is contained in:
parent
eecfc4976f
commit
c9e7117bb7
|
@ -186,7 +186,7 @@ static int32_t dnodeInitStorage() {
|
||||||
dError("failed to init TFS since %s", tstrerror(terrno));
|
dError("failed to init TFS since %s", tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
snprintf(tsDataDir, tfsPrimaryPath(), TSDB_FILENAME_LEN);
|
snprintf(tsDataDir, TFS_PRIMARY_PATH(), TSDB_FILENAME_LEN);
|
||||||
sprintf(tsMnodeDir, "%s/mnode", tsDataDir);
|
sprintf(tsMnodeDir, "%s/mnode", tsDataDir);
|
||||||
sprintf(tsVnodeDir, "%s/vnode", tsDataDir);
|
sprintf(tsVnodeDir, "%s/vnode", tsDataDir);
|
||||||
sprintf(tsDnodeDir, "%s/dnode", tsDataDir);
|
sprintf(tsDnodeDir, "%s/dnode", tsDataDir);
|
||||||
|
@ -203,12 +203,12 @@ static int32_t dnodeInitStorage() {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tfsCreateDir("vnode") < 0) {
|
if (tfsMkdir("vnode") < 0) {
|
||||||
dError("failed to create vnode dir since %s", tstrerror(terrno));
|
dError("failed to create vnode dir since %s", tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tfsCreateDir("vnode_bak") < 0) {
|
if (tfsMkdir("vnode_bak") < 0) {
|
||||||
dError("failed to create vnode_bak dir since %s", tstrerror(terrno));
|
dError("failed to create vnode_bak dir since %s", tstrerror(terrno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,36 +40,30 @@ void tfsUpdateInfo();
|
||||||
const char *TFS_PRIMARY_PATH();
|
const char *TFS_PRIMARY_PATH();
|
||||||
const char *TFS_DISK_PATH(int level, int id);
|
const char *TFS_DISK_PATH(int level, int id);
|
||||||
|
|
||||||
// MANIP APIS ====================================
|
// TFILE APIs ====================================
|
||||||
int tfsMkdir(const char *rname);
|
typedef struct {
|
||||||
int tfsRmdir(const char *rname);
|
|
||||||
int tfsRename(char *orname, char *nrname);
|
|
||||||
|
|
||||||
// tfcntl.c ====================================
|
|
||||||
typedef struct TFSFILE {
|
|
||||||
int level;
|
int level;
|
||||||
int id;
|
int id;
|
||||||
char rname[TSDB_FILENAME_LEN]; // REL name
|
char rname[TSDB_FILENAME_LEN]; // REL name
|
||||||
char aname[TSDB_FILENAME_LEN]; // ABS name
|
char aname[TSDB_FILENAME_LEN]; // ABS name
|
||||||
} TFSFILE;
|
} TFILE;
|
||||||
|
|
||||||
const char *tfsAbsName(TFSFILE *pfile);
|
#define TFILE_LEVEL(pf) ((pf)->level)
|
||||||
const char *tfsRelName(TFSFILE *pfile);
|
#define TFILE_ID(pf) ((pf)->id)
|
||||||
void tfsDirName(TFSFILE *pfile, char dest[]);
|
#define TFILE_NAME(pf) ((pf)->aname)
|
||||||
void tfsBaseName(TFSFILE *pfile, char dest[]);
|
|
||||||
int tfsopen(TFSFILE *pfile, int flags);
|
|
||||||
int tfsclose(int fd);
|
|
||||||
int tfsremove(TFSFILE *pfile);
|
|
||||||
SDiskID tfsFileID(TFSFILE *pfile);
|
|
||||||
|
|
||||||
typedef struct TFSDIR TFSDIR;
|
int tfsInitFile(TFILE *pf, int level, int id, const char *bname);
|
||||||
|
|
||||||
int tfsCreateDir(char *dirname);
|
// DIR APIs ====================================
|
||||||
int tfsRemoveDir(char *dirname);
|
int tfsMkdir(const char *rname);
|
||||||
int tfsRename(char *oldpath, char *newpath);
|
int tfsRmdir(const char *rname);
|
||||||
TFSDIR * tfsOpenDir(char *dir);
|
int tfsRename(char *orname, char *nrname);
|
||||||
void tfsCloseDir(TFSDIR *tdir);
|
|
||||||
const TFSFILE *tfsReadDir(TFSDIR *tdir);
|
typedef struct TDIR TDIR;
|
||||||
|
|
||||||
|
TDIR * tfsOpendir(const char *rname);
|
||||||
|
const TFILE *tfsReaddir(TDIR *tdir);
|
||||||
|
void tfsClosedir(TDIR *tdir);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,6 @@ SDisk *tfsFreeDisk(SDisk *pDisk);
|
||||||
void tfsUpdateDiskInfo(SDisk *pDisk);
|
void tfsUpdateDiskInfo(SDisk *pDisk);
|
||||||
|
|
||||||
// ttier.c ======================================================
|
// ttier.c ======================================================
|
||||||
#define TSDB_MAX_DISK_PER_TIER 16
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t size;
|
int64_t size;
|
||||||
int64_t free;
|
int64_t free;
|
||||||
|
@ -70,7 +68,7 @@ typedef struct STier {
|
||||||
int level;
|
int level;
|
||||||
int32_t ndisk;
|
int32_t ndisk;
|
||||||
STierMeta tmeta;
|
STierMeta tmeta;
|
||||||
SDisk * disks[TSDB_MAX_DISK_PER_TIER];
|
SDisk * disks[TSDB_MAX_DISKS_PER_TIER];
|
||||||
} STier;
|
} STier;
|
||||||
|
|
||||||
#define TIER_LEVEL(pt) ((pt)->level)
|
#define TIER_LEVEL(pt) ((pt)->level)
|
||||||
|
|
|
@ -1,247 +0,0 @@
|
||||||
/*
|
|
||||||
* 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 "os.h"
|
||||||
|
|
||||||
|
#include "taosdef.h"
|
||||||
#include "hash.h"
|
#include "hash.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
#include "tfs.h"
|
#include "tfs.h"
|
||||||
#include "tfsint.h"
|
#include "tfsint.h"
|
||||||
|
|
||||||
#define TSDB_MAX_TIER 3
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wformat-truncation"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int64_t tsize;
|
int64_t tsize;
|
||||||
|
@ -32,10 +34,14 @@ typedef struct {
|
||||||
bool locked;
|
bool locked;
|
||||||
SFSMeta meta;
|
SFSMeta meta;
|
||||||
int nlevel;
|
int nlevel;
|
||||||
STier tiers[TSDB_MAX_TIER];
|
STier tiers[TSDB_MAX_TIERS];
|
||||||
SHashObj * map; // name to did map
|
SHashObj * map; // name to did map
|
||||||
} SFS;
|
} SFS;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
SDisk *pDisk;
|
||||||
|
} SDiskIter;
|
||||||
|
|
||||||
#define TFS_LOCKED() (pfs->locked)
|
#define TFS_LOCKED() (pfs->locked)
|
||||||
#define TFS_META() (pfs->meta)
|
#define TFS_META() (pfs->meta)
|
||||||
#define TFS_NLEVEL() (pfs->nlevel)
|
#define TFS_NLEVEL() (pfs->nlevel)
|
||||||
|
@ -44,6 +50,9 @@ typedef struct {
|
||||||
#define TFS_TIER_AT(level) (TFS_TIERS() + (level))
|
#define TFS_TIER_AT(level) (TFS_TIERS() + (level))
|
||||||
#define TFS_DISK_AT(level, id) DISK_AT_TIER(TFS_TIER_AT(level), id)
|
#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_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 tfs = {0};
|
||||||
static SFS *pfs = &tfs;
|
static SFS *pfs = &tfs;
|
||||||
|
@ -57,12 +66,15 @@ static SDisk *tfsGetDiskByID(SDiskID did);
|
||||||
static SDisk *tfsGetDiskByName(const char *dir);
|
static SDisk *tfsGetDiskByName(const char *dir);
|
||||||
static int tfsLock();
|
static int tfsLock();
|
||||||
static int tfsUnLock();
|
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) {
|
int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
|
||||||
ASSERT(ndisk > 0);
|
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);
|
tfsInitTier(TFS_TIER_AT(level), level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +84,7 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
|
||||||
return -1;
|
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);
|
taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_NO_LOCK);
|
||||||
if (pfs->map == NULL) {
|
if (pfs->map == NULL) {
|
||||||
terrno = TSDB_CODE_FS_OUT_OF_MEMORY;
|
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_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)); }
|
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) {
|
int tfsMkdir(const char *rname) {
|
||||||
char aname[TSDB_FILENAME_LEN] = "\0";
|
char aname[TSDB_FILENAME_LEN] = "\0";
|
||||||
|
|
||||||
|
@ -180,6 +206,68 @@ int tfsRename(char *orname, char *nrname) {
|
||||||
return 0;
|
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() {
|
static int tfsLock() {
|
||||||
int code = pthread_mutex_lock(&(pfs->lock));
|
int code = pthread_mutex_lock(&(pfs->lock));
|
||||||
if (code != 0) {
|
if (code != 0) {
|
||||||
|
@ -229,7 +317,7 @@ static int tfsCheckAndFormatCfg(SDiskCfg *pCfg) {
|
||||||
char dirName[TSDB_FILENAME_LEN] = "\0";
|
char dirName[TSDB_FILENAME_LEN] = "\0";
|
||||||
struct stat pstat;
|
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);
|
fError("failed to mount %s to FS since invalid level %d", pCfg->dir, pCfg->level);
|
||||||
terrno = TSDB_CODE_FS_INVLD_CFG;
|
terrno = TSDB_CODE_FS_INVLD_CFG;
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -337,3 +425,57 @@ static SDisk *tfsGetDiskByName(const char *dir) {
|
||||||
|
|
||||||
return pDisk;
|
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
|
|
@ -14,14 +14,15 @@
|
||||||
*/
|
*/
|
||||||
#include "os.h"
|
#include "os.h"
|
||||||
|
|
||||||
#include "tfsint.h"
|
#include "taosdef.h"
|
||||||
#include "taoserror.h"
|
#include "taoserror.h"
|
||||||
|
#include "tfsint.h"
|
||||||
|
|
||||||
// PROTECTED ==========================================
|
// PROTECTED ==========================================
|
||||||
void tfsInitTier(STier *pTier, int level) { pTier->level = level; }
|
void tfsInitTier(STier *pTier, int level) { pTier->level = level; }
|
||||||
|
|
||||||
void tfsDestroyTier(STier *pTier) {
|
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));
|
DISK_AT_TIER(pTier, id) = tfsFreeDisk(DISK_AT_TIER(pTier, id));
|
||||||
}
|
}
|
||||||
pTier->ndisk = 0;
|
pTier->ndisk = 0;
|
||||||
|
@ -31,7 +32,7 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
|
||||||
ASSERT(pTier->level == pCfg->level);
|
ASSERT(pTier->level == pCfg->level);
|
||||||
int id = 0;
|
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;
|
terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +42,7 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
|
||||||
id = pTier->ndisk;
|
id = pTier->ndisk;
|
||||||
} else {
|
} else {
|
||||||
id = pTier->ndisk + 1;
|
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;
|
terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,7 +189,7 @@ typedef struct {
|
||||||
} STsdbFileInfo;
|
} STsdbFileInfo;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
TFSFILE file;
|
TFILE file;
|
||||||
STsdbFileInfo info;
|
STsdbFileInfo info;
|
||||||
int fd;
|
int fd;
|
||||||
} SFile;
|
} SFile;
|
||||||
|
|
|
@ -67,14 +67,14 @@ int tsdbOpenFileH(STsdbRepo *pRepo) { // TODO
|
||||||
char dataDir[TSDB_FILENAME_LEN] = "\0";
|
char dataDir[TSDB_FILENAME_LEN] = "\0";
|
||||||
|
|
||||||
// 1. scan and get all files corresponds
|
// 1. scan and get all files corresponds
|
||||||
TFSDIR *tdir = NULL;
|
TDIR *tdir = NULL;
|
||||||
char fname[TSDB_FILENAME_LEN] = "\0";
|
char fname[TSDB_FILENAME_LEN] = "\0";
|
||||||
regex_t regex = {0};
|
regex_t regex = {0};
|
||||||
int code = 0;
|
int code = 0;
|
||||||
int vid = 0;
|
int vid = 0;
|
||||||
int fid = 0;
|
int fid = 0;
|
||||||
|
|
||||||
const TFSFILE *pfile = NULL;
|
const TFILE *pfile = NULL;
|
||||||
|
|
||||||
code = regcomp(®ex, "^v[0-9]+f[0-9]+\\.(head|data|last|h|d|l)$", REG_EXTENDED);
|
code = regcomp(®ex, "^v[0-9]+f[0-9]+\\.(head|data|last|h|d|l)$", REG_EXTENDED);
|
||||||
if (code != 0) {
|
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));
|
snprintf(dataDir, TSDB_FILENAME_LEN, "vnode/vnode%d/tsdb/data", REPO_ID(pRepo));
|
||||||
tdir = tfsOpenDir(dataDir);
|
tdir = tfsOpendir(dataDir);
|
||||||
if (tdir == NULL) {
|
if (tdir == NULL) {
|
||||||
// TODO: deal the error
|
// TODO: deal the error
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((pfile = tfsReadDir(tdir)) != NULL) {
|
while ((pfile = tfsReaddir(tdir)) != NULL) {
|
||||||
tfsBaseName(pfile, fname);
|
tfsBaseName(pfile, fname);
|
||||||
|
|
||||||
if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) continue;
|
if (strcmp(fname, ".") == 0 || strcmp(fname, "..") == 0) continue;
|
||||||
|
|
|
@ -102,7 +102,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
|
||||||
return TSDB_CODE_SUCCESS;
|
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));
|
vError("vgId:%d, failed to create vnode dir, reason:%s", pVnodeCfg->cfg.vgId, tstrerror(terrno));
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
@ -112,7 +112,7 @@ int32_t vnodeCreate(SCreateVnodeMsg *pVnodeCfg) {
|
||||||
|
|
||||||
char vnodeDir[TSDB_FILENAME_LEN] = "\0";
|
char vnodeDir[TSDB_FILENAME_LEN] = "\0";
|
||||||
snprintf(vnodeDir, TSDB_FILENAME_LEN, "vnode%d", pVnodeCfg->cfg.vgId);
|
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));
|
vError("vgId:%d, failed to create vnode %d dir, reason:%s", pVnodeCfg->cfg.vgId, strerror(errno));
|
||||||
return terrno;
|
return terrno;
|
||||||
}
|
}
|
||||||
|
@ -442,11 +442,11 @@ void vnodeRelease(void *vparam) {
|
||||||
if (0 == tsEnableVnodeBak) {
|
if (0 == tsEnableVnodeBak) {
|
||||||
vInfo("vgId:%d, vnode backup not enabled", pVnode->vgId);
|
vInfo("vgId:%d, vnode backup not enabled", pVnode->vgId);
|
||||||
} else {
|
} else {
|
||||||
tfsRemoveDir(newDir);
|
tfsRmdir(newDir);
|
||||||
tfsRename(rootDir, newDir);
|
tfsRename(rootDir, newDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
tfsRemoveDir(rootDir);
|
tfsRmdir(rootDir);
|
||||||
dnodeSendStatusMsgToMnode();
|
dnodeSendStatusMsgToMnode();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue