Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
7c77464d
TDengine
项目概览
taosdata
/
TDengine
大约 1 年 前同步成功
通知
1181
Star
22014
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
7c77464d
编写于
1月 18, 2022
作者:
S
Shengliang Guan
提交者:
GitHub
1月 18, 2022
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #9886 from taosdata/feature/tfs
Feature/tfs
上级
8237e15e
d6359f3a
变更
10
显示空白变更内容
内联
并排
Showing
10 changed file
with
313 addition
and
313 deletion
+313
-313
include/libs/tfs/tfs.h
include/libs/tfs/tfs.h
+27
-35
include/os/osSysinfo.h
include/os/osSysinfo.h
+3
-3
include/util/taoserror.h
include/util/taoserror.h
+1
-1
source/libs/tfs/inc/tfsInt.h
source/libs/tfs/inc/tfsInt.h
+34
-49
source/libs/tfs/src/tfs.c
source/libs/tfs/src/tfs.c
+79
-92
source/libs/tfs/src/tfsDisk.c
source/libs/tfs/src/tfsDisk.c
+21
-24
source/libs/tfs/src/tfsTier.c
source/libs/tfs/src/tfsTier.c
+143
-0
source/os/src/osSysinfo.c
source/os/src/osSysinfo.c
+4
-5
source/util/src/terror.c
source/util/src/terror.c
+1
-1
src/inc/tfs.h
src/inc/tfs.h
+0
-103
未找到文件。
include/libs/tfs/tfs.h
浏览文件 @
7c77464d
...
@@ -13,8 +13,8 @@
...
@@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifndef
TD_TFS_H
#ifndef
_TD_TFS_H_
#define
TD_TFS_H
#define
_TD_TFS_H_
#include "tglobal.h"
#include "tglobal.h"
...
@@ -23,8 +23,8 @@ extern "C" {
...
@@ -23,8 +23,8 @@ extern "C" {
#endif
#endif
typedef
struct
{
typedef
struct
{
int
level
;
int
32_t
level
;
int
id
;
int
32_t
id
;
}
SDiskID
;
}
SDiskID
;
#define TFS_UNDECIDED_LEVEL -1
#define TFS_UNDECIDED_LEVEL -1
...
@@ -36,31 +36,23 @@ typedef struct {
...
@@ -36,31 +36,23 @@ typedef struct {
// FS APIs ====================================
// FS APIs ====================================
typedef
struct
{
typedef
struct
{
int64_t
t
size
;
int64_t
t
otal
;
int64_t
used
;
int64_t
used
;
int64_t
avail
;
int64_t
avail
;
}
SFSMeta
;
}
SFSMeta
;
typedef
struct
{
int32_t
tfsInit
(
SDiskCfg
*
pDiskCfg
,
int32_t
ndisk
);
int64_t
size
;
int64_t
used
;
int64_t
free
;
int16_t
nAvailDisks
;
// # of Available disks
}
STierMeta
;
int
tfsInit
(
SDiskCfg
*
pDiskCfg
,
int
ndisk
);
void
tfsCleanup
();
void
tfsCleanup
();
void
tfsUpdateInfo
(
SFSMeta
*
pFSMeta
,
STierMeta
*
tierMetas
,
int8_t
numLevels
);
void
tfsUpdateSize
(
SFSMeta
*
pFSMeta
);
void
tfsGetMeta
(
SFSMeta
*
pMeta
);
void
tfsAllocDisk
(
int32_t
expLevel
,
int32_t
*
level
,
int32_t
*
id
);
void
tfsAllocDisk
(
int
expLevel
,
int
*
level
,
int
*
id
);
const
char
*
TFS_PRIMARY_PATH
();
const
char
*
TFS_PRIMARY_PATH
();
const
char
*
TFS_DISK_PATH
(
int
level
,
in
t
id
);
const
char
*
TFS_DISK_PATH
(
int
32_t
level
,
int32_
t
id
);
// TFILE APIs ====================================
// TFILE APIs ====================================
typedef
struct
{
typedef
struct
{
int
level
;
int
32_t
level
;
int
id
;
int
32_t
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
}
TFILE
;
}
TFILE
;
...
@@ -76,23 +68,23 @@ typedef struct {
...
@@ -76,23 +68,23 @@ typedef struct {
#define tfscopy(sf, df) taosCopyFile(TFILE_NAME(sf), TFILE_NAME(df))
#define tfscopy(sf, df) taosCopyFile(TFILE_NAME(sf), TFILE_NAME(df))
#define tfsrename(sf, df) taosRename(TFILE_NAME(sf), TFILE_NAME(df))
#define tfsrename(sf, df) taosRename(TFILE_NAME(sf), TFILE_NAME(df))
void
tfsInitFile
(
TFILE
*
pf
,
int
level
,
in
t
id
,
const
char
*
bname
);
void
tfsInitFile
(
TFILE
*
pf
,
int32_t
level
,
int32_
t
id
,
const
char
*
bname
);
bool
tfsIsSameFile
(
const
TFILE
*
pf1
,
const
TFILE
*
pf2
);
bool
tfsIsSameFile
(
const
TFILE
*
pf1
,
const
TFILE
*
pf2
);
int
tfsEncodeFile
(
void
**
buf
,
TFILE
*
pf
);
int
32_t
tfsEncodeFile
(
void
**
buf
,
TFILE
*
pf
);
void
*
tfsDecodeFile
(
void
*
buf
,
TFILE
*
pf
);
void
*
tfsDecodeFile
(
void
*
buf
,
TFILE
*
pf
);
void
tfsbasename
(
const
TFILE
*
pf
,
char
*
dest
);
void
tfsbasename
(
const
TFILE
*
pf
,
char
*
dest
);
void
tfsdirname
(
const
TFILE
*
pf
,
char
*
dest
);
void
tfsdirname
(
const
TFILE
*
pf
,
char
*
dest
);
// DIR APIs ====================================
// DIR APIs ====================================
int
tfsMkdirAt
(
const
char
*
rname
,
int
level
,
in
t
id
);
int
32_t
tfsMkdirAt
(
const
char
*
rname
,
int32_t
level
,
int32_
t
id
);
int
tfsMkdirRecurAt
(
const
char
*
rname
,
int
level
,
in
t
id
);
int
32_t
tfsMkdirRecurAt
(
const
char
*
rname
,
int32_t
level
,
int32_
t
id
);
int
tfsMkdir
(
const
char
*
rname
);
int
32_t
tfsMkdir
(
const
char
*
rname
);
int
tfsRmdir
(
const
char
*
rname
);
int
32_t
tfsRmdir
(
const
char
*
rname
);
int
tfsRename
(
char
*
orname
,
char
*
nrname
);
int
32_t
tfsRename
(
char
*
orname
,
char
*
nrname
);
typedef
struct
TDIR
TDIR
;
typedef
struct
TDIR
TDIR
;
TDIR
*
tfsOpendir
(
const
char
*
rname
);
TDIR
*
tfsOpendir
(
const
char
*
rname
);
const
TFILE
*
tfsReaddir
(
TDIR
*
tdir
);
const
TFILE
*
tfsReaddir
(
TDIR
*
tdir
);
void
tfsClosedir
(
TDIR
*
tdir
);
void
tfsClosedir
(
TDIR
*
tdir
);
...
@@ -100,4 +92,4 @@ void tfsClosedir(TDIR *tdir);
...
@@ -100,4 +92,4 @@ void tfsClosedir(TDIR *tdir);
}
}
#endif
#endif
#endif
#endif
/*_TD_TFS_H_*/
include/os/osSysinfo.h
浏览文件 @
7c77464d
...
@@ -35,12 +35,12 @@ extern char tsLocale[];
...
@@ -35,12 +35,12 @@ extern char tsLocale[];
extern
char
tsCharset
[];
// default encode string
extern
char
tsCharset
[];
// default encode string
typedef
struct
{
typedef
struct
{
int64_t
t
size
;
int64_t
t
otal
;
int64_t
used
;
int64_t
used
;
int64_t
avail
;
int64_t
avail
;
}
S
ys
DiskSize
;
}
SDiskSize
;
int32_t
taosGetDiskSize
(
char
*
dataDir
,
S
ys
DiskSize
*
diskSize
);
int32_t
taosGetDiskSize
(
char
*
dataDir
,
SDiskSize
*
diskSize
);
int32_t
taosGetCpuCores
();
int32_t
taosGetCpuCores
();
void
taosGetSystemInfo
();
void
taosGetSystemInfo
();
bool
taosReadProcIO
(
int64_t
*
rchars
,
int64_t
*
wchars
);
bool
taosReadProcIO
(
int64_t
*
rchars
,
int64_t
*
wchars
);
...
...
include/util/taoserror.h
浏览文件 @
7c77464d
...
@@ -411,7 +411,7 @@ int32_t* taosGetErrno();
...
@@ -411,7 +411,7 @@ int32_t* taosGetErrno();
#define TSDB_CODE_WAL_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x1004) //"WAL out of memory")
#define TSDB_CODE_WAL_OUT_OF_MEMORY TAOS_DEF_ERROR_CODE(0, 0x1004) //"WAL out of memory")
// tfs
// tfs
#define TSDB_CODE_FS_
OUT_OF_MEMORY
TAOS_DEF_ERROR_CODE(0, 0x2200) //"tfs out of memory")
#define TSDB_CODE_FS_
APP_ERROR
TAOS_DEF_ERROR_CODE(0, 0x2200) //"tfs out of memory")
#define TSDB_CODE_FS_INVLD_CFG TAOS_DEF_ERROR_CODE(0, 0x2201) //"tfs invalid mount config")
#define TSDB_CODE_FS_INVLD_CFG TAOS_DEF_ERROR_CODE(0, 0x2201) //"tfs invalid mount config")
#define TSDB_CODE_FS_TOO_MANY_MOUNT TAOS_DEF_ERROR_CODE(0, 0x2202) //"tfs too many mount")
#define TSDB_CODE_FS_TOO_MANY_MOUNT TAOS_DEF_ERROR_CODE(0, 0x2202) //"tfs too many mount")
#define TSDB_CODE_FS_DUP_PRIMARY TAOS_DEF_ERROR_CODE(0, 0x2203) //"tfs duplicate primary mount")
#define TSDB_CODE_FS_DUP_PRIMARY TAOS_DEF_ERROR_CODE(0, 0x2203) //"tfs duplicate primary mount")
...
...
source/libs/tfs/inc/tfs
i
nt.h
→
source/libs/tfs/inc/tfs
I
nt.h
浏览文件 @
7c77464d
...
@@ -13,19 +13,20 @@
...
@@ -13,19 +13,20 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#ifndef
TD_TFSINT_H
#ifndef
_TD_TFS_INT_H_
#define
TD_TFSINT_H
#define
_TD_TFS_INT_H_
#include "tlog.h"
#include "os.h"
#include "tglobal.h"
#include "tfs.h"
#include "tcoding.h"
#ifdef __cplusplus
#include "taosdef.h"
extern
"C"
{
#include "taoserror.h"
#endif
#include "tcoding.h"
#include "tfs.h"
#include "tglobal.h"
#include "thash.h"
#include "tlog.h"
extern
int
fsDebugFlag
;
extern
int
32_t
fsDebugFlag
;
// For debug purpose
// For debug purpose
#define fFatal(...) { if (fsDebugFlag & DEBUG_FATAL) { taosPrintLog("TFS FATAL ", 255, __VA_ARGS__); }}
#define fFatal(...) { if (fsDebugFlag & DEBUG_FATAL) { taosPrintLog("TFS FATAL ", 255, __VA_ARGS__); }}
...
@@ -38,60 +39,44 @@ extern int fsDebugFlag;
...
@@ -38,60 +39,44 @@ extern int fsDebugFlag;
// Global Definitions
// Global Definitions
#define TFS_MIN_DISK_FREE_SIZE 50 * 1024 * 1024
#define TFS_MIN_DISK_FREE_SIZE 50 * 1024 * 1024
// tdisk.c ======================================================
typedef
struct
{
int64_t
size
;
int64_t
used
;
int64_t
free
;
}
SDiskMeta
;
typedef
struct
SDisk
{
typedef
struct
SDisk
{
int
level
;
int
32_t
level
;
int
id
;
int
32_t
id
;
char
dir
[
TSDB_FILENAME_LEN
]
;
char
*
path
;
SDisk
Meta
dmeta
;
SDisk
Size
size
;
}
SDisk
;
}
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_USED_SIZE(pd) ((pd)->dmeta.used)
#define DISK_FREE_SIZE(pd) ((pd)->dmeta.free)
SDisk
*
tfsNewDisk
(
int
level
,
int
id
,
const
char
*
dir
);
SDisk
*
tfsFreeDisk
(
SDisk
*
pDisk
);
int
tfsUpdateDiskInfo
(
SDisk
*
pDisk
);
// ttier.c ======================================================
typedef
struct
STier
{
typedef
struct
STier
{
pthread_spinlock_t
lock
;
pthread_spinlock_t
lock
;
int
level
;
int32_t
level
;
int16_t
ndisk
;
// # of disks mounted to this tier
int16_t
nextid
;
// next disk id to allocate
int16_t
nextid
;
// next disk id to allocate
STierMeta
tmeta
;
int16_t
ndisk
;
// # of disks mounted to this tier
SDisk
*
disks
[
TSDB_MAX_DISKS_PER_TIER
];
int16_t
nAvailDisks
;
// # of Available disks
SDisk
*
disks
[
TSDB_MAX_DISKS_PER_TIER
];
SDiskSize
size
;
}
STier
;
}
STier
;
#define TIER_LEVEL(pt) ((pt)->level)
#define TIER_LEVEL(pt) ((pt)->level)
#define TIER_NDISKS(pt) ((pt)->ndisk)
#define TIER_NDISKS(pt) ((pt)->ndisk)
#define TIER_SIZE(pt) ((pt)->tmeta.size)
#define TIER_SIZE(pt) ((pt)->tmeta.size)
#define TIER_FREE_SIZE(pt) ((pt)->tmeta.free)
#define TIER_FREE_SIZE(pt) ((pt)->tmeta.free)
#define TIER_AVAIL_DISKS(pt) ((pt)->tmeta.nAvailDisks)
#define DISK_AT_TIER(pt, id) ((pt)->disks[id])
#define DISK_AT_TIER(pt, id) ((pt)->disks[id])
#define DISK_DIR(pd) ((pd)->path)
int
tfsInitTier
(
STier
*
pTier
,
int
level
);
SDisk
*
tfsNewDisk
(
int32_t
level
,
int32_t
id
,
const
char
*
dir
);
SDisk
*
tfsFreeDisk
(
SDisk
*
pDisk
);
int32_t
tfsUpdateDiskSize
(
SDisk
*
pDisk
);
int32_t
tfsInitTier
(
STier
*
pTier
,
int32_t
level
);
void
tfsDestroyTier
(
STier
*
pTier
);
void
tfsDestroyTier
(
STier
*
pTier
);
SDisk
*
tfsMountDiskToTier
(
STier
*
pTier
,
SDiskCfg
*
pCfg
);
SDisk
*
tfsMountDiskToTier
(
STier
*
pTier
,
SDiskCfg
*
pCfg
);
void
tfsUpdateTierInfo
(
STier
*
pTier
,
STierMeta
*
pTierMeta
);
void
tfsUpdateTierSize
(
STier
*
pTier
);
int
tfsAllocDiskOnTier
(
STier
*
pTier
);
int32_t
tfsAllocDiskOnTier
(
STier
*
pTier
);
void
tfsGetTierMeta
(
STier
*
pTier
,
STierMeta
*
pTierMeta
);
void
tfsPosNextId
(
STier
*
pTier
);
void
tfsPosNextId
(
STier
*
pTier
);
#ifdef __cplusplus
#ifdef __cplusplus
}
}
#endif
#endif
#endif
#endif
/*_TD_TFS_INT_H_*/
source/libs/tfs/src/tfs.c
浏览文件 @
7c77464d
...
@@ -13,22 +13,17 @@
...
@@ -13,22 +13,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "os.h"
#define _DEFAULT_SOURCE
#include "tfsInt.h"
#include "taosdef.h"
#include "taoserror.h"
#include "tfs.h"
#include "tfsint.h"
#include "thash.h"
#define TMPNAME_LEN (TSDB_FILENAME_LEN * 2 + 32)
#define TMPNAME_LEN (TSDB_FILENAME_LEN * 2 + 32)
typedef
struct
{
typedef
struct
{
pthread_spinlock_t
lock
;
pthread_spinlock_t
lock
;
SFSMeta
meta
;
SFSMeta
meta
;
int
nlevel
;
int
32_t
nlevel
;
STier
tiers
[
TSDB_MAX_TIERS
];
STier
tiers
[
TSDB_MAX_TIERS
];
SHashObj
*
map
;
// name to did map
SHashObj
*
map
;
// name to did map
}
SFS
;
}
SFS
;
typedef
struct
{
typedef
struct
{
...
@@ -52,21 +47,24 @@ static SFS tfs = {0};
...
@@ -52,21 +47,24 @@ static SFS tfs = {0};
static
SFS
*
pfs
=
&
tfs
;
static
SFS
*
pfs
=
&
tfs
;
// STATIC DECLARATION
// STATIC DECLARATION
static
int
tfsMount
(
SDiskCfg
*
pCfg
);
static
int
32_t
tfsMount
(
SDiskCfg
*
pCfg
);
static
int
tfsCheck
();
static
int
32_t
tfsCheck
();
static
int
tfsCheckAndFormatCfg
(
SDiskCfg
*
pCfg
);
static
int
32_t
tfsCheckAndFormatCfg
(
SDiskCfg
*
pCfg
);
static
int
tfsFormatDir
(
char
*
idir
,
char
*
odir
);
static
int
32_t
tfsFormatDir
(
char
*
idir
,
char
*
odir
);
static
SDisk
*
tfsGetDiskByID
(
SDiskID
did
);
static
SDisk
*
tfsGetDiskByID
(
SDiskID
did
);
static
SDisk
*
tfsGetDiskByName
(
const
char
*
dir
);
static
SDisk
*
tfsGetDiskByName
(
const
char
*
dir
);
static
int
tfsOpendirImpl
(
TDIR
*
tdir
);
static
int
32_t
tfsOpendirImpl
(
TDIR
*
tdir
);
static
void
tfsInitDiskIter
(
SDiskIter
*
pIter
);
static
void
tfsInitDiskIter
(
SDiskIter
*
pIter
);
static
SDisk
*
tfsNextDisk
(
SDiskIter
*
pIter
);
static
SDisk
*
tfsNextDisk
(
SDiskIter
*
pIter
);
// FS APIs ====================================
// FS APIs ====================================
int
tfsInit
(
SDiskCfg
*
pDiskCfg
,
int
ndisk
)
{
int32_t
tfsInit
(
SDiskCfg
*
pDiskCfg
,
int32_t
ndisk
)
{
ASSERT
(
ndisk
>
0
);
if
(
ndisk
<
0
)
{
terrno
=
TSDB_CODE_INVALID_PARA
;
return
-
1
;
}
for
(
int
level
=
0
;
level
<
TSDB_MAX_TIERS
;
level
++
)
{
for
(
int
32_t
level
=
0
;
level
<
TSDB_MAX_TIERS
;
level
++
)
{
if
(
tfsInitTier
(
TFS_TIER_AT
(
level
),
level
)
<
0
)
{
if
(
tfsInitTier
(
TFS_TIER_AT
(
level
),
level
)
<
0
)
{
while
(
true
)
{
while
(
true
)
{
level
--
;
level
--
;
...
@@ -84,12 +82,12 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
...
@@ -84,12 +82,12 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
pfs
->
map
=
taosHashInit
(
TSDB_MAX_TIERS
*
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_OUT_OF_MEMORY
;
tfsCleanup
();
tfsCleanup
();
return
-
1
;
return
-
1
;
}
}
for
(
int
idisk
=
0
;
idisk
<
ndisk
;
idisk
++
)
{
for
(
int
32_t
idisk
=
0
;
idisk
<
ndisk
;
idisk
++
)
{
if
(
tfsMount
(
pDiskCfg
+
idisk
)
<
0
)
{
if
(
tfsMount
(
pDiskCfg
+
idisk
)
<
0
)
{
tfsCleanup
();
tfsCleanup
();
return
-
1
;
return
-
1
;
...
@@ -101,8 +99,8 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
...
@@ -101,8 +99,8 @@ int tfsInit(SDiskCfg *pDiskCfg, int ndisk) {
return
-
1
;
return
-
1
;
}
}
tfsUpdate
Info
(
NULL
,
NULL
,
0
);
tfsUpdate
Size
(
NULL
);
for
(
int
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
for
(
int
32_t
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
tfsPosNextId
(
TFS_TIER_AT
(
level
));
tfsPosNextId
(
TFS_TIER_AT
(
level
));
}
}
...
@@ -114,32 +112,27 @@ void tfsCleanup() {
...
@@ -114,32 +112,27 @@ void tfsCleanup() {
pfs
->
map
=
NULL
;
pfs
->
map
=
NULL
;
pthread_spin_destroy
(
&
(
pfs
->
lock
));
pthread_spin_destroy
(
&
(
pfs
->
lock
));
for
(
int
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
for
(
int
32_t
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
tfsDestroyTier
(
TFS_TIER_AT
(
level
));
tfsDestroyTier
(
TFS_TIER_AT
(
level
));
}
}
}
}
void
tfsUpdate
Info
(
SFSMeta
*
pFSMeta
,
STierMeta
*
tierMetas
,
int8_t
numTiers
)
{
void
tfsUpdate
Size
(
SFSMeta
*
pFSMeta
)
{
SFSMeta
fsMeta
;
SFSMeta
fsMeta
=
{
0
}
;
S
TierMeta
tierMeta
;
S
DiskSize
size
=
{
0
}
;
if
(
pFSMeta
==
NULL
)
{
if
(
pFSMeta
==
NULL
)
{
pFSMeta
=
&
fsMeta
;
pFSMeta
=
&
fsMeta
;
}
}
memset
(
pFSMeta
,
0
,
sizeof
(
*
pFSMeta
));
memset
(
pFSMeta
,
0
,
sizeof
(
SFSMeta
));
for
(
int
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
STierMeta
*
pTierMeta
=
&
tierMeta
;
if
(
tierMetas
&&
level
<
numTiers
)
{
pTierMeta
=
tierMetas
+
level
;
}
for
(
int32_t
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
STier
*
pTier
=
TFS_TIER_AT
(
level
);
STier
*
pTier
=
TFS_TIER_AT
(
level
);
tfsUpdateTier
Info
(
pTier
,
pTierMeta
);
tfsUpdateTier
Size
(
pTier
);
pFSMeta
->
t
size
+=
pTierMeta
->
size
;
pFSMeta
->
t
otal
+=
pTier
->
size
.
total
;
pFSMeta
->
avail
+=
pTier
Meta
->
free
;
pFSMeta
->
avail
+=
pTier
->
size
.
avail
;
pFSMeta
->
used
+=
pTier
Meta
->
used
;
pFSMeta
->
used
+=
pTier
->
size
.
used
;
}
}
tfsLock
();
tfsLock
();
...
@@ -147,17 +140,9 @@ void tfsUpdateInfo(SFSMeta *pFSMeta, STierMeta *tierMetas, int8_t numTiers) {
...
@@ -147,17 +140,9 @@ void tfsUpdateInfo(SFSMeta *pFSMeta, STierMeta *tierMetas, int8_t numTiers) {
tfsUnLock
();
tfsUnLock
();
}
}
void
tfsGetMeta
(
SFSMeta
*
pMeta
)
{
ASSERT
(
pMeta
);
tfsLock
();
*
pMeta
=
pfs
->
meta
;
tfsUnLock
();
}
/* Allocate an existing available tier level
/* Allocate an existing available tier level
*/
*/
void
tfsAllocDisk
(
int
expLevel
,
int
*
level
,
in
t
*
id
)
{
void
tfsAllocDisk
(
int
32_t
expLevel
,
int32_t
*
level
,
int32_
t
*
id
)
{
ASSERT
(
expLevel
>=
0
);
ASSERT
(
expLevel
>=
0
);
*
level
=
expLevel
;
*
level
=
expLevel
;
...
@@ -182,10 +167,10 @@ void tfsAllocDisk(int expLevel, int *level, int *id) {
...
@@ -182,10 +167,10 @@ void tfsAllocDisk(int expLevel, int *level, int *id) {
}
}
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
,
in
t
id
)
{
return
DISK_DIR
(
TFS_DISK_AT
(
level
,
id
));
}
const
char
*
TFS_DISK_PATH
(
int
32_t
level
,
int32_
t
id
)
{
return
DISK_DIR
(
TFS_DISK_AT
(
level
,
id
));
}
// TFILE APIs ====================================
// TFILE APIs ====================================
void
tfsInitFile
(
TFILE
*
pf
,
int
level
,
in
t
id
,
const
char
*
bname
)
{
void
tfsInitFile
(
TFILE
*
pf
,
int
32_t
level
,
int32_
t
id
,
const
char
*
bname
)
{
ASSERT
(
TFS_IS_VALID_DISK
(
level
,
id
));
ASSERT
(
TFS_IS_VALID_DISK
(
level
,
id
));
SDisk
*
pDisk
=
TFS_DISK_AT
(
level
,
id
);
SDisk
*
pDisk
=
TFS_DISK_AT
(
level
,
id
);
...
@@ -208,8 +193,8 @@ bool tfsIsSameFile(const TFILE *pf1, const TFILE *pf2) {
...
@@ -208,8 +193,8 @@ bool tfsIsSameFile(const TFILE *pf1, const TFILE *pf2) {
return
true
;
return
true
;
}
}
int
tfsEncodeFile
(
void
**
buf
,
TFILE
*
pf
)
{
int
32_t
tfsEncodeFile
(
void
**
buf
,
TFILE
*
pf
)
{
int
tlen
=
0
;
int
32_t
tlen
=
0
;
tlen
+=
taosEncodeVariantI32
(
buf
,
pf
->
level
);
tlen
+=
taosEncodeVariantI32
(
buf
,
pf
->
level
);
tlen
+=
taosEncodeVariantI32
(
buf
,
pf
->
id
);
tlen
+=
taosEncodeVariantI32
(
buf
,
pf
->
id
);
...
@@ -220,7 +205,7 @@ int tfsEncodeFile(void **buf, TFILE *pf) {
...
@@ -220,7 +205,7 @@ int tfsEncodeFile(void **buf, TFILE *pf) {
void
*
tfsDecodeFile
(
void
*
buf
,
TFILE
*
pf
)
{
void
*
tfsDecodeFile
(
void
*
buf
,
TFILE
*
pf
)
{
int32_t
level
,
id
;
int32_t
level
,
id
;
char
*
rname
;
char
*
rname
;
buf
=
taosDecodeVariantI32
(
buf
,
&
(
level
));
buf
=
taosDecodeVariantI32
(
buf
,
&
(
level
));
buf
=
taosDecodeVariantI32
(
buf
,
&
(
id
));
buf
=
taosDecodeVariantI32
(
buf
,
&
(
id
));
...
@@ -247,7 +232,7 @@ void tfsdirname(const TFILE *pf, char *dest) {
...
@@ -247,7 +232,7 @@ void tfsdirname(const TFILE *pf, char *dest) {
}
}
// DIR APIs ====================================
// DIR APIs ====================================
int
tfsMkdirAt
(
const
char
*
rname
,
int
level
,
in
t
id
)
{
int
32_t
tfsMkdirAt
(
const
char
*
rname
,
int32_t
level
,
int32_
t
id
)
{
SDisk
*
pDisk
=
TFS_DISK_AT
(
level
,
id
);
SDisk
*
pDisk
=
TFS_DISK_AT
(
level
,
id
);
char
aname
[
TMPNAME_LEN
];
char
aname
[
TMPNAME_LEN
];
...
@@ -260,7 +245,7 @@ int tfsMkdirAt(const char *rname, int level, int id) {
...
@@ -260,7 +245,7 @@ int tfsMkdirAt(const char *rname, int level, int id) {
return
0
;
return
0
;
}
}
int
tfsMkdirRecurAt
(
const
char
*
rname
,
int
level
,
in
t
id
)
{
int
32_t
tfsMkdirRecurAt
(
const
char
*
rname
,
int32_t
level
,
int32_
t
id
)
{
if
(
tfsMkdirAt
(
rname
,
level
,
id
)
<
0
)
{
if
(
tfsMkdirAt
(
rname
,
level
,
id
)
<
0
)
{
if
(
errno
==
ENOENT
)
{
if
(
errno
==
ENOENT
)
{
// Try to create upper
// Try to create upper
...
@@ -293,10 +278,10 @@ int tfsMkdirRecurAt(const char *rname, int level, int id) {
...
@@ -293,10 +278,10 @@ int tfsMkdirRecurAt(const char *rname, int level, int id) {
return
0
;
return
0
;
}
}
int
tfsMkdir
(
const
char
*
rname
)
{
int
32_t
tfsMkdir
(
const
char
*
rname
)
{
for
(
int
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
for
(
int
32_t
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
STier
*
pTier
=
TFS_TIER_AT
(
level
);
STier
*
pTier
=
TFS_TIER_AT
(
level
);
for
(
int
id
=
0
;
id
<
TIER_NDISKS
(
pTier
);
id
++
)
{
for
(
int
32_t
id
=
0
;
id
<
TIER_NDISKS
(
pTier
);
id
++
)
{
if
(
tfsMkdirAt
(
rname
,
level
,
id
)
<
0
)
{
if
(
tfsMkdirAt
(
rname
,
level
,
id
)
<
0
)
{
return
-
1
;
return
-
1
;
}
}
...
@@ -306,15 +291,15 @@ int tfsMkdir(const char *rname) {
...
@@ -306,15 +291,15 @@ int tfsMkdir(const char *rname) {
return
0
;
return
0
;
}
}
int
tfsRmdir
(
const
char
*
rname
)
{
int
32_t
tfsRmdir
(
const
char
*
rname
)
{
char
aname
[
TMPNAME_LEN
]
=
"
\0
"
;
char
aname
[
TMPNAME_LEN
]
=
"
\0
"
;
for
(
int
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
for
(
int
32_t
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
STier
*
pTier
=
TFS_TIER_AT
(
level
);
STier
*
pTier
=
TFS_TIER_AT
(
level
);
for
(
int
id
=
0
;
id
<
TIER_NDISKS
(
pTier
);
id
++
)
{
for
(
int
32_t
id
=
0
;
id
<
TIER_NDISKS
(
pTier
);
id
++
)
{
SDisk
*
pDisk
=
DISK_AT_TIER
(
pTier
,
id
)
;
SDisk
*
pDisk
=
pTier
->
disks
[
id
]
;
snprintf
(
aname
,
TMPNAME_LEN
,
"%s
/%s"
,
DISK_DIR
(
pDisk
)
,
rname
);
snprintf
(
aname
,
TMPNAME_LEN
,
"%s
%s%s"
,
DISK_DIR
(
pDisk
),
TS_PATH_DELIMITER
,
rname
);
taosRemoveDir
(
aname
);
taosRemoveDir
(
aname
);
}
}
...
@@ -323,13 +308,14 @@ int tfsRmdir(const char *rname) {
...
@@ -323,13 +308,14 @@ int tfsRmdir(const char *rname) {
return
0
;
return
0
;
}
}
int
tfsRename
(
char
*
orname
,
char
*
nrname
)
{
#if 0
int32_t tfsRename(char *orname, char *nrname) {
char oaname[TMPNAME_LEN] = "\0";
char oaname[TMPNAME_LEN] = "\0";
char naname[TMPNAME_LEN] = "\0";
char naname[TMPNAME_LEN] = "\0";
for
(
int
level
=
0
;
level
<
pfs
->
nlevel
;
level
++
)
{
for (int
32_t
level = 0; level < pfs->nlevel; level++) {
STier *pTier = TFS_TIER_AT(level);
STier *pTier = TFS_TIER_AT(level);
for
(
int
id
=
0
;
id
<
TIER_NDISKS
(
pTier
);
id
++
)
{
for (int
32_t
id = 0; id < TIER_NDISKS(pTier); id++) {
SDisk *pDisk = DISK_AT_TIER(pTier, id);
SDisk *pDisk = DISK_AT_TIER(pTier, id);
snprintf(oaname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), orname);
snprintf(oaname, TMPNAME_LEN, "%s/%s", DISK_DIR(pDisk), orname);
...
@@ -341,20 +327,21 @@ int tfsRename(char *orname, char *nrname) {
...
@@ -341,20 +327,21 @@ int tfsRename(char *orname, char *nrname) {
return 0;
return 0;
}
}
#endif
struct
TDIR
{
struct
TDIR
{
SDiskIter
iter
;
SDiskIter
iter
;
int
level
;
int
32_t
level
;
int
id
;
int
32_t
id
;
char
dirname
[
TSDB_FILENAME_LEN
];
char
dirname
[
TSDB_FILENAME_LEN
];
TFILE
tfile
;
TFILE
tfile
;
DIR
*
dir
;
DIR
*
dir
;
};
};
TDIR
*
tfsOpendir
(
const
char
*
rname
)
{
TDIR
*
tfsOpendir
(
const
char
*
rname
)
{
TDIR
*
tdir
=
(
TDIR
*
)
calloc
(
1
,
sizeof
(
*
tdir
));
TDIR
*
tdir
=
(
TDIR
*
)
calloc
(
1
,
sizeof
(
*
tdir
));
if
(
tdir
==
NULL
)
{
if
(
tdir
==
NULL
)
{
terrno
=
TSDB_CODE_
FS_
OUT_OF_MEMORY
;
terrno
=
TSDB_CODE_OUT_OF_MEMORY
;
return
NULL
;
return
NULL
;
}
}
...
@@ -407,9 +394,9 @@ void tfsClosedir(TDIR *tdir) {
...
@@ -407,9 +394,9 @@ void tfsClosedir(TDIR *tdir) {
}
}
// private
// private
static
int
tfsMount
(
SDiskCfg
*
pCfg
)
{
static
int
32_t
tfsMount
(
SDiskCfg
*
pCfg
)
{
SDiskID
did
;
SDiskID
did
;
SDisk
*
pDisk
=
NULL
;
SDisk
*
pDisk
=
NULL
;
if
(
tfsCheckAndFormatCfg
(
pCfg
)
<
0
)
return
-
1
;
if
(
tfsCheckAndFormatCfg
(
pCfg
)
<
0
)
return
-
1
;
...
@@ -419,7 +406,7 @@ static int tfsMount(SDiskCfg *pCfg) {
...
@@ -419,7 +406,7 @@ static int tfsMount(SDiskCfg *pCfg) {
fError
(
"failed to mount disk %s to level %d since %s"
,
pCfg
->
dir
,
pCfg
->
level
,
tstrerror
(
terrno
));
fError
(
"failed to mount disk %s to level %d since %s"
,
pCfg
->
dir
,
pCfg
->
level
,
tstrerror
(
terrno
));
return
-
1
;
return
-
1
;
}
}
did
.
id
=
DISK_ID
(
pDisk
)
;
did
.
id
=
pDisk
->
id
;
taosHashPut
(
pfs
->
map
,
(
void
*
)(
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
;
if
(
pfs
->
nlevel
<
pCfg
->
level
+
1
)
pfs
->
nlevel
=
pCfg
->
level
+
1
;
...
@@ -427,7 +414,7 @@ static int tfsMount(SDiskCfg *pCfg) {
...
@@ -427,7 +414,7 @@ static int tfsMount(SDiskCfg *pCfg) {
return
0
;
return
0
;
}
}
static
int
tfsCheckAndFormatCfg
(
SDiskCfg
*
pCfg
)
{
static
int
32_t
tfsCheckAndFormatCfg
(
SDiskCfg
*
pCfg
)
{
char
dirName
[
TSDB_FILENAME_LEN
]
=
"
\0
"
;
char
dirName
[
TSDB_FILENAME_LEN
]
=
"
\0
"
;
struct
stat
pstat
;
struct
stat
pstat
;
...
@@ -486,10 +473,10 @@ static int tfsCheckAndFormatCfg(SDiskCfg *pCfg) {
...
@@ -486,10 +473,10 @@ static int tfsCheckAndFormatCfg(SDiskCfg *pCfg) {
return
0
;
return
0
;
}
}
static
int
tfsFormatDir
(
char
*
idir
,
char
*
odir
)
{
static
int
32_t
tfsFormatDir
(
char
*
idir
,
char
*
odir
)
{
wordexp_t
wep
=
{
0
};
wordexp_t
wep
=
{
0
};
int
code
=
wordexp
(
idir
,
&
wep
,
0
);
int
32_t
code
=
wordexp
(
idir
,
&
wep
,
0
);
if
(
code
!=
0
)
{
if
(
code
!=
0
)
{
terrno
=
TAOS_SYSTEM_ERROR
(
code
);
terrno
=
TAOS_SYSTEM_ERROR
(
code
);
return
-
1
;
return
-
1
;
...
@@ -507,14 +494,14 @@ static int tfsFormatDir(char *idir, char *odir) {
...
@@ -507,14 +494,14 @@ static int tfsFormatDir(char *idir, char *odir) {
return
0
;
return
0
;
}
}
static
int
tfsCheck
()
{
static
int
32_t
tfsCheck
()
{
if
(
TFS_PRIMARY_DISK
()
==
NULL
)
{
if
(
TFS_PRIMARY_DISK
()
==
NULL
)
{
fError
(
"no primary disk is set"
);
fError
(
"no primary disk is set"
);
terrno
=
TSDB_CODE_FS_NO_PRIMARY_DISK
;
terrno
=
TSDB_CODE_FS_NO_PRIMARY_DISK
;
return
-
1
;
return
-
1
;
}
}
for
(
int
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
for
(
int
32_t
level
=
0
;
level
<
TFS_NLEVEL
();
level
++
)
{
if
(
TIER_NDISKS
(
TFS_TIER_AT
(
level
))
==
0
)
{
if
(
TIER_NDISKS
(
TFS_TIER_AT
(
level
))
==
0
)
{
fError
(
"no disk at level %d"
,
level
);
fError
(
"no disk at level %d"
,
level
);
terrno
=
TSDB_CODE_FS_NO_MOUNT_AT_TIER
;
terrno
=
TSDB_CODE_FS_NO_MOUNT_AT_TIER
;
...
@@ -528,8 +515,8 @@ static int tfsCheck() {
...
@@ -528,8 +515,8 @@ static int tfsCheck() {
static
SDisk
*
tfsGetDiskByID
(
SDiskID
did
)
{
return
TFS_DISK_AT
(
did
.
level
,
did
.
id
);
}
static
SDisk
*
tfsGetDiskByID
(
SDiskID
did
)
{
return
TFS_DISK_AT
(
did
.
level
,
did
.
id
);
}
static
SDisk
*
tfsGetDiskByName
(
const
char
*
dir
)
{
static
SDisk
*
tfsGetDiskByName
(
const
char
*
dir
)
{
SDiskID
did
;
SDiskID
did
;
SDisk
*
pDisk
=
NULL
;
SDisk
*
pDisk
=
NULL
;
void
*
pr
=
NULL
;
void
*
pr
=
NULL
;
pr
=
taosHashGet
(
pfs
->
map
,
(
void
*
)
dir
,
strnlen
(
dir
,
TSDB_FILENAME_LEN
));
pr
=
taosHashGet
(
pfs
->
map
,
(
void
*
)
dir
,
strnlen
(
dir
,
TSDB_FILENAME_LEN
));
if
(
pr
==
NULL
)
return
NULL
;
if
(
pr
==
NULL
)
return
NULL
;
...
@@ -541,7 +528,7 @@ static SDisk *tfsGetDiskByName(const char *dir) {
...
@@ -541,7 +528,7 @@ static SDisk *tfsGetDiskByName(const char *dir) {
return
pDisk
;
return
pDisk
;
}
}
static
int
tfsOpendirImpl
(
TDIR
*
tdir
)
{
static
int
32_t
tfsOpendirImpl
(
TDIR
*
tdir
)
{
SDisk
*
pDisk
=
NULL
;
SDisk
*
pDisk
=
NULL
;
char
adir
[
TMPNAME_LEN
*
2
]
=
"
\0
"
;
char
adir
[
TMPNAME_LEN
*
2
]
=
"
\0
"
;
...
@@ -554,10 +541,10 @@ static int tfsOpendirImpl(TDIR *tdir) {
...
@@ -554,10 +541,10 @@ static int tfsOpendirImpl(TDIR *tdir) {
pDisk
=
tfsNextDisk
(
&
(
tdir
->
iter
));
pDisk
=
tfsNextDisk
(
&
(
tdir
->
iter
));
if
(
pDisk
==
NULL
)
return
0
;
if
(
pDisk
==
NULL
)
return
0
;
tdir
->
level
=
DISK_LEVEL
(
pDisk
)
;
tdir
->
level
=
pDisk
->
level
;
tdir
->
id
=
DISK_ID
(
pDisk
)
;
tdir
->
id
=
pDisk
->
id
;
snprintf
(
adir
,
TMPNAME_LEN
*
2
,
"%s
/%s"
,
DISK_DIR
(
pDisk
),
tdir
->
dirname
);
snprintf
(
adir
,
TMPNAME_LEN
*
2
,
"%s
%s%s"
,
pDisk
->
path
,
TS_PATH_DELIMITER
,
tdir
->
dirname
);
tdir
->
dir
=
opendir
(
adir
);
tdir
->
dir
=
opendir
(
adir
);
if
(
tdir
->
dir
!=
NULL
)
break
;
if
(
tdir
->
dir
!=
NULL
)
break
;
}
}
...
@@ -572,8 +559,8 @@ static SDisk *tfsNextDisk(SDiskIter *pIter) {
...
@@ -572,8 +559,8 @@ static SDisk *tfsNextDisk(SDiskIter *pIter) {
if
(
pDisk
==
NULL
)
return
NULL
;
if
(
pDisk
==
NULL
)
return
NULL
;
int
level
=
DISK_LEVEL
(
pDisk
)
;
int
32_t
level
=
pDisk
->
level
;
int
id
=
DISK_ID
(
pDisk
)
;
int
32_t
id
=
pDisk
->
id
;
id
++
;
id
++
;
if
(
id
<
TIER_NDISKS
(
TFS_TIER_AT
(
level
)))
{
if
(
id
<
TIER_NDISKS
(
TFS_TIER_AT
(
level
)))
{
...
@@ -596,21 +583,21 @@ static SDisk *tfsNextDisk(SDiskIter *pIter) {
...
@@ -596,21 +583,21 @@ static SDisk *tfsNextDisk(SDiskIter *pIter) {
// OTHER FUNCTIONS ===================================
// OTHER FUNCTIONS ===================================
void
taosGetDisk
()
{
void
taosGetDisk
()
{
const
double
unit
=
1024
*
1024
*
1024
;
const
double
unit
=
1024
*
1024
*
1024
;
S
ysDiskSize
diskSize
;
S
DiskSize
diskSize
;
SFSMeta
fsMeta
;
SFSMeta
fsMeta
;
tfsUpdate
Info
(
&
fsMeta
,
NULL
,
0
);
tfsUpdate
Size
(
&
fsMeta
);
tsTotalDataDirGB
=
(
float
)(
fsMeta
.
t
size
/
unit
);
tsTotalDataDirGB
=
(
float
)(
fsMeta
.
t
otal
/
unit
);
tsUsedDataDirGB
=
(
float
)(
fsMeta
.
used
/
unit
);
tsUsedDataDirGB
=
(
float
)(
fsMeta
.
used
/
unit
);
tsAvailDataDirGB
=
(
float
)(
fsMeta
.
avail
/
unit
);
tsAvailDataDirGB
=
(
float
)(
fsMeta
.
avail
/
unit
);
if
(
taosGetDiskSize
(
tsLogDir
,
&
diskSize
)
==
0
)
{
if
(
taosGetDiskSize
(
tsLogDir
,
&
diskSize
)
==
0
)
{
tsTotalLogDirGB
=
(
float
)(
diskSize
.
t
size
/
unit
);
tsTotalLogDirGB
=
(
float
)(
diskSize
.
t
otal
/
unit
);
tsAvailLogDirGB
=
(
float
)(
diskSize
.
avail
/
unit
);
tsAvailLogDirGB
=
(
float
)(
diskSize
.
avail
/
unit
);
}
}
if
(
taosGetDiskSize
(
tsTempDir
,
&
diskSize
)
==
0
)
{
if
(
taosGetDiskSize
(
tsTempDir
,
&
diskSize
)
==
0
)
{
tsTotalTmpDirGB
=
(
float
)(
diskSize
.
t
size
/
unit
);
tsTotalTmpDirGB
=
(
float
)(
diskSize
.
t
otal
/
unit
);
tsAvailTmpDirectorySpace
=
(
float
)(
diskSize
.
avail
/
unit
);
tsAvailTmpDirectorySpace
=
(
float
)(
diskSize
.
avail
/
unit
);
}
}
}
}
source/libs/tfs/src/t
d
isk.c
→
source/libs/tfs/src/t
fsD
isk.c
浏览文件 @
7c77464d
...
@@ -12,48 +12,45 @@
...
@@ -12,48 +12,45 @@
* You should have received a copy of the GNU Affero General Public License
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "os.h"
#
include "taoserror.h"
#
define _DEFAULT_SOURCE
#include "tfs
i
nt.h"
#include "tfs
I
nt.h"
// PROTECTED ====================================
SDisk
*
tfsNewDisk
(
int32_t
level
,
int32_t
id
,
const
char
*
path
)
{
SDisk
*
tfsNewDisk
(
int
level
,
int
id
,
const
char
*
dir
)
{
SDisk
*
pDisk
=
calloc
(
1
,
sizeof
(
SDisk
));
SDisk
*
pDisk
=
(
SDisk
*
)
calloc
(
1
,
sizeof
(
*
pDisk
));
if
(
pDisk
==
NULL
)
{
if
(
pDisk
==
NULL
)
{
terrno
=
TSDB_CODE_FS_OUT_OF_MEMORY
;
terrno
=
TSDB_CODE_OUT_OF_MEMORY
;
return
NULL
;
}
pDisk
->
path
=
strdup
(
path
);
if
(
pDisk
->
path
==
NULL
)
{
free
(
pDisk
);
terrno
=
TSDB_CODE_OUT_OF_MEMORY
;
return
NULL
;
return
NULL
;
}
}
pDisk
->
level
=
level
;
pDisk
->
level
=
level
;
pDisk
->
id
=
id
;
pDisk
->
id
=
id
;
tstrncpy
(
pDisk
->
dir
,
dir
,
TSDB_FILENAME_LEN
);
taosGetDiskSize
(
pDisk
->
path
,
&
pDisk
->
size
);
return
pDisk
;
return
pDisk
;
}
}
SDisk
*
tfsFreeDisk
(
SDisk
*
pDisk
)
{
SDisk
*
tfsFreeDisk
(
SDisk
*
pDisk
)
{
if
(
pDisk
)
{
if
(
pDisk
!=
NULL
)
{
free
(
pDisk
->
path
);
free
(
pDisk
);
free
(
pDisk
);
}
}
return
NULL
;
return
NULL
;
}
}
int
tfsUpdateDiskInfo
(
SDisk
*
pDisk
)
{
int32_t
tfsUpdateDiskSize
(
SDisk
*
pDisk
)
{
ASSERT
(
pDisk
!=
NULL
);
if
(
taosGetDiskSize
(
pDisk
->
path
,
&
pDisk
->
size
)
!=
0
)
{
SysDiskSize
diskSize
=
{
0
};
int
code
=
taosGetDiskSize
(
pDisk
->
dir
,
&
diskSize
);
if
(
code
!=
0
)
{
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
);
terrno
=
TAOS_SYSTEM_ERROR
(
errno
);
fError
(
"failed to get disk:%s size, level:%d id:%d since %s"
,
pDisk
->
path
,
pDisk
->
level
,
pDisk
->
id
,
terrstr
());
return
-
1
;
}
}
pDisk
->
dmeta
.
size
=
diskSize
.
tsize
;
return
0
;
pDisk
->
dmeta
.
used
=
diskSize
.
used
;
pDisk
->
dmeta
.
free
=
diskSize
.
avail
;
return
code
;
}
}
source/libs/tfs/src/t
t
ier.c
→
source/libs/tfs/src/t
fsT
ier.c
浏览文件 @
7c77464d
...
@@ -12,53 +12,43 @@
...
@@ -12,53 +12,43 @@
* You should have received a copy of the GNU Affero General Public License
* 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/>.
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "os.h"
#include "taosdef.h"
#define _DEFAULT_SOURCE
#include "taoserror.h"
#include "tfsInt.h"
#include "tfsint.h"
#define tfsLockTier(pTier) pthread_spin_lock(&(
(pTier)->lock)
)
#define tfsLockTier(pTier) pthread_spin_lock(&(
pTier)->lock
)
#define tfsUnLockTier(pTier) pthread_spin_unlock(&(
(pTier)->lock)
)
#define tfsUnLockTier(pTier) pthread_spin_unlock(&(
pTier)->lock
)
// PROTECTED ==========================================
int32_t
tfsInitTier
(
STier
*
pTier
,
int32_t
level
)
{
int
tfsInitTier
(
STier
*
pTier
,
int
level
)
{
memset
(
pTier
,
0
,
sizeof
(
STier
));
memset
((
void
*
)
pTier
,
0
,
sizeof
(
*
pTier
));
int
code
=
pthread_spin_init
(
&
(
pTier
->
lock
),
0
);
if
(
pthread_spin_init
(
&
pTier
->
lock
,
0
)
!=
0
)
{
if
(
code
)
{
terrno
=
TAOS_SYSTEM_ERROR
(
errno
);
terrno
=
TAOS_SYSTEM_ERROR
(
code
);
return
-
1
;
return
-
1
;
}
}
pTier
->
level
=
level
;
pTier
->
level
=
level
;
return
0
;
return
0
;
}
}
void
tfsDestroyTier
(
STier
*
pTier
)
{
void
tfsDestroyTier
(
STier
*
pTier
)
{
for
(
int
id
=
0
;
id
<
TSDB_MAX_DISKS_PER_TIER
;
id
++
)
{
for
(
int
32_t
id
=
0
;
id
<
TSDB_MAX_DISKS_PER_TIER
;
id
++
)
{
DISK_AT_TIER
(
pTier
,
id
)
=
tfsFreeDisk
(
DISK_AT_TIER
(
pTier
,
id
)
);
pTier
->
disks
[
id
]
=
tfsFreeDisk
(
pTier
->
disks
[
id
]
);
}
}
pTier
->
ndisk
=
0
;
pTier
->
ndisk
=
0
;
pthread_spin_destroy
(
&
(
pTier
->
lock
));
pthread_spin_destroy
(
&
(
pTier
->
lock
));
}
}
SDisk
*
tfsMountDiskToTier
(
STier
*
pTier
,
SDiskCfg
*
pCfg
)
{
SDisk
*
tfsMountDiskToTier
(
STier
*
pTier
,
SDiskCfg
*
pCfg
)
{
ASSERT
(
pTier
->
level
==
pCfg
->
level
);
if
(
pTier
->
ndisk
>=
TSDB_MAX_DISKS_PER_TIER
)
{
int
id
=
0
;
SDisk
*
pDisk
;
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
;
}
}
int32_t
id
=
0
;
if
(
pTier
->
level
==
0
)
{
if
(
pTier
->
level
==
0
)
{
if
(
DISK_AT_TIER
(
pTier
,
0
)
!=
NULL
)
{
if
(
pTier
->
disks
[
0
]
!=
NULL
)
{
id
=
pTier
->
ndisk
;
id
=
pTier
->
ndisk
;
}
else
{
}
else
{
if
(
pCfg
->
primary
)
{
if
(
pCfg
->
primary
)
{
...
@@ -66,102 +56,85 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
...
@@ -66,102 +56,85 @@ SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
}
else
{
}
else
{
id
=
pTier
->
ndisk
+
1
;
id
=
pTier
->
ndisk
+
1
;
}
}
if
(
id
>=
TSDB_MAX_DISKS_PER_TIER
)
{
terrno
=
TSDB_CODE_FS_TOO_MANY_MOUNT
;
return
NULL
;
}
}
}
}
else
{
}
else
{
id
=
pTier
->
ndisk
;
id
=
pTier
->
ndisk
;
}
}
pDisk
=
tfsNewDisk
(
pCfg
->
level
,
id
,
pCfg
->
dir
);
if
(
id
>=
TSDB_MAX_DISKS_PER_TIER
)
{
terrno
=
TSDB_CODE_FS_TOO_MANY_MOUNT
;
return
NULL
;
}
SDisk
*
pDisk
=
tfsNewDisk
(
pCfg
->
level
,
id
,
pCfg
->
dir
);
if
(
pDisk
==
NULL
)
return
NULL
;
if
(
pDisk
==
NULL
)
return
NULL
;
DISK_AT_TIER
(
pTier
,
id
)
=
pDisk
;
pTier
->
disks
[
id
]
=
pDisk
;
pTier
->
ndisk
++
;
pTier
->
ndisk
++
;
fInfo
(
"disk %s is mounted to tier level %d id %d"
,
pCfg
->
dir
,
pCfg
->
level
,
id
);
fInfo
(
"disk %s is mounted to tier level %d id %d"
,
pCfg
->
dir
,
pCfg
->
level
,
id
);
return
pTier
->
disks
[
id
];
return
DISK_AT_TIER
(
pTier
,
id
);
}
}
void
tfsUpdateTierInfo
(
STier
*
pTier
,
STierMeta
*
pTierMeta
)
{
void
tfsUpdateTierSize
(
STier
*
pTier
)
{
STierMeta
tmeta
;
SDiskSize
size
=
{
0
};
int16_t
nAvailDisks
=
0
;
if
(
pTierMeta
==
NULL
)
{
pTierMeta
=
&
tmeta
;
}
memset
(
pTierMeta
,
0
,
sizeof
(
*
pTierMeta
));
tfsLockTier
(
pTier
);
tfsLockTier
(
pTier
);
for
(
int
id
=
0
;
id
<
pTier
->
ndisk
;
id
++
)
{
for
(
int
32_t
id
=
0
;
id
<
pTier
->
ndisk
;
id
++
)
{
if
(
tfsUpdateDiskInfo
(
DISK_AT_TIER
(
pTier
,
id
))
<
0
)
{
SDisk
*
pDisk
=
pTier
->
disks
[
id
];
continue
;
if
(
pDisk
==
NULL
)
continue
;
}
pTierMeta
->
size
+=
DISK_SIZE
(
DISK_AT_TIER
(
pTier
,
id
))
;
size
.
total
+=
pDisk
->
size
.
total
;
pTierMeta
->
used
+=
DISK_USED_SIZE
(
DISK_AT_TIER
(
pTier
,
id
))
;
size
.
used
+=
pDisk
->
size
.
used
;
pTierMeta
->
free
+=
DISK_FREE_SIZE
(
DISK_AT_TIER
(
pTier
,
id
))
;
size
.
avail
+=
pDisk
->
size
.
avail
;
pTierMeta
->
nAvailDisks
++
;
nAvailDisks
++
;
}
}
pTier
->
tmeta
=
*
pTierMeta
;
pTier
->
size
=
size
;
pTier
->
nAvailDisks
=
nAvailDisks
;
tfsUnLockTier
(
pTier
);
tfsUnLockTier
(
pTier
);
}
}
// Round-Robin to allocate disk on a tier
// Round-Robin to allocate disk on a tier
int
tfsAllocDiskOnTier
(
STier
*
pTier
)
{
int32_t
tfsAllocDiskOnTier
(
STier
*
pTier
)
{
ASSERT
(
pTier
->
ndisk
>
0
);
terrno
=
TSDB_CODE_FS_NO_VALID_DISK
;
int
id
=
TFS_UNDECIDED_ID
;
SDisk
*
pDisk
;
tfsLockTier
(
pTier
);
tfsLockTier
(
pTier
);
if
(
TIER_AVAIL_DISKS
(
pTier
)
<=
0
)
{
if
(
pTier
->
ndisk
<=
0
||
pTier
->
nAvailDisks
<=
0
)
{
tfsUnLockTier
(
pTier
);
tfsUnLockTier
(
pTier
);
return
id
;
return
-
1
;
}
}
i
d
=
pTier
->
nextid
;
i
nt32_t
retId
=
-
1
;
while
(
true
)
{
for
(
int32_t
id
=
0
;
id
<
TSDB_MAX_DISKS_PER_TIER
;
++
id
)
{
pDisk
=
DISK_AT_TIER
(
pTier
,
id
)
;
int32_t
diskId
=
(
pTier
->
nextid
+
id
)
%
pTier
->
ndisk
;
ASSERT
(
pDisk
!=
NULL
)
;
SDisk
*
pDisk
=
pTier
->
disks
[
diskId
]
;
if
(
DISK_FREE_SIZE
(
pDisk
)
<
TFS_MIN_DISK_FREE_SIZE
)
{
if
(
pDisk
==
NULL
)
continue
;
id
=
(
id
+
1
)
%
pTier
->
ndisk
;
if
(
id
==
pTier
->
nextid
)
{
tfsUnLockTier
(
pTier
);
return
TFS_UNDECIDED_ID
;
}
else
{
continue
;
}
}
else
{
pTier
->
nextid
=
(
id
+
1
)
%
pTier
->
ndisk
;
break
;
}
}
tfsUnLockTier
(
pTier
);
if
(
pDisk
->
size
.
avail
<
TFS_MIN_DISK_FREE_SIZE
)
continue
;
return
id
;
}
void
tfsGetTierMeta
(
STier
*
pTier
,
STierMeta
*
pTierMeta
)
{
retId
=
diskId
;
ASSERT
(
pTierMeta
!=
NULL
);
terrno
=
0
;
pTier
->
nextid
=
(
diskId
+
1
)
%
pTier
->
ndisk
;
break
;
}
tfsLockTier
(
pTier
);
*
pTierMeta
=
pTier
->
tmeta
;
tfsUnLockTier
(
pTier
);
tfsUnLockTier
(
pTier
);
return
retId
;
}
}
void
tfsPosNextId
(
STier
*
pTier
)
{
void
tfsPosNextId
(
STier
*
pTier
)
{
ASSERT
(
pTier
->
ndisk
>
0
);
int32_t
nextid
=
0
;
int
nextid
=
0
;
for
(
int
id
=
1
;
id
<
pTier
->
ndisk
;
id
++
)
{
for
(
int
32_t
id
=
1
;
id
<
pTier
->
ndisk
;
id
++
)
{
SDisk
*
pLDisk
=
DISK_AT_TIER
(
pTier
,
nextid
)
;
SDisk
*
pLDisk
=
pTier
->
disks
[
nextid
]
;
SDisk
*
pDisk
=
DISK_AT_TIER
(
pTier
,
id
)
;
SDisk
*
pDisk
=
pTier
->
disks
[
id
]
;
if
(
DISK_FREE_SIZE
(
pDisk
)
>
TFS_MIN_DISK_FREE_SIZE
&&
DISK_FREE_SIZE
(
pDisk
)
>
DISK_FREE_SIZE
(
pLDisk
)
)
{
if
(
pDisk
->
size
.
avail
>
TFS_MIN_DISK_FREE_SIZE
&&
pDisk
->
size
.
avail
>
pLDisk
->
size
.
avail
)
{
nextid
=
id
;
nextid
=
id
;
}
}
}
}
...
...
source/os/src/osSysinfo.c
浏览文件 @
7c77464d
...
@@ -121,7 +121,7 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
...
@@ -121,7 +121,7 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
return
true
;
return
true
;
}
}
int32_t
taosGetDiskSize
(
char
*
dataDir
,
S
ys
DiskSize
*
diskSize
)
{
int32_t
taosGetDiskSize
(
char
*
dataDir
,
SDiskSize
*
diskSize
)
{
unsigned
_int64
i64FreeBytesToCaller
;
unsigned
_int64
i64FreeBytesToCaller
;
unsigned
_int64
i64TotalBytes
;
unsigned
_int64
i64TotalBytes
;
unsigned
_int64
i64FreeBytes
;
unsigned
_int64
i64FreeBytes
;
...
@@ -438,7 +438,7 @@ int taosSystem(const char *cmd) {
...
@@ -438,7 +438,7 @@ int taosSystem(const char *cmd) {
void
taosSetCoreDump
()
{}
void
taosSetCoreDump
()
{}
int32_t
taosGetDiskSize
(
char
*
dataDir
,
S
ys
DiskSize
*
diskSize
)
{
int32_t
taosGetDiskSize
(
char
*
dataDir
,
SDiskSize
*
diskSize
)
{
struct
statvfs
info
;
struct
statvfs
info
;
if
(
statvfs
(
dataDir
,
&
info
))
{
if
(
statvfs
(
dataDir
,
&
info
))
{
//printf("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
//printf("failed to get disk size, dataDir:%s errno:%s", tsDataDir, strerror(errno));
...
@@ -771,13 +771,12 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
...
@@ -771,13 +771,12 @@ bool taosGetCpuUsage(float *sysCpuUsage, float *procCpuUsage) {
return
true
;
return
true
;
}
}
int32_t
taosGetDiskSize
(
char
*
dataDir
,
S
ys
DiskSize
*
diskSize
)
{
int32_t
taosGetDiskSize
(
char
*
dataDir
,
SDiskSize
*
diskSize
)
{
struct
statvfs
info
;
struct
statvfs
info
;
if
(
statvfs
(
dataDir
,
&
info
))
{
if
(
statvfs
(
dataDir
,
&
info
))
{
//printf("failed to get disk size, dataDir:%s errno:%s", dataDir, strerror(errno));
return
-
1
;
return
-
1
;
}
else
{
}
else
{
diskSize
->
t
size
=
info
.
f_blocks
*
info
.
f_frsize
;
diskSize
->
t
otal
=
info
.
f_blocks
*
info
.
f_frsize
;
diskSize
->
avail
=
info
.
f_bavail
*
info
.
f_frsize
;
diskSize
->
avail
=
info
.
f_bavail
*
info
.
f_frsize
;
diskSize
->
used
=
(
info
.
f_blocks
-
info
.
f_bfree
)
*
info
.
f_frsize
;
diskSize
->
used
=
(
info
.
f_blocks
-
info
.
f_bfree
)
*
info
.
f_frsize
;
return
0
;
return
0
;
...
...
source/util/src/terror.c
浏览文件 @
7c77464d
...
@@ -396,7 +396,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_WAL_FILE_CORRUPTED, "WAL file is corrupted
...
@@ -396,7 +396,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_WAL_FILE_CORRUPTED, "WAL file is corrupted
TAOS_DEFINE_ERROR
(
TSDB_CODE_WAL_SIZE_LIMIT
,
"WAL size exceeds limit"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_WAL_SIZE_LIMIT
,
"WAL size exceeds limit"
)
// tfs
// tfs
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_
OUT_OF_MEMORY
,
"tfs out of memory"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_
APP_ERROR
,
"tfs out of memory"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_INVLD_CFG
,
"tfs invalid mount config"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_INVLD_CFG
,
"tfs invalid mount config"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_TOO_MANY_MOUNT
,
"tfs too many mount"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_TOO_MANY_MOUNT
,
"tfs too many mount"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_DUP_PRIMARY
,
"tfs duplicate primary mount"
)
TAOS_DEFINE_ERROR
(
TSDB_CODE_FS_DUP_PRIMARY
,
"tfs duplicate primary mount"
)
...
...
src/inc/tfs.h
已删除
100644 → 0
浏览文件 @
8237e15e
/*
* 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/>.
*/
#ifndef TD_TFS_H
#define TD_TFS_H
#include "tglobal.h"
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
{
int
level
;
int
id
;
}
SDiskID
;
#define TFS_UNDECIDED_LEVEL -1
#define TFS_UNDECIDED_ID -1
#define TFS_PRIMARY_LEVEL 0
#define TFS_PRIMARY_ID 0
#define TFS_MIN_LEVEL 0
#define TFS_MAX_LEVEL (TSDB_MAX_TIERS - 1)
// FS APIs ====================================
typedef
struct
{
int64_t
tsize
;
int64_t
used
;
int64_t
avail
;
}
SFSMeta
;
typedef
struct
{
int64_t
size
;
int64_t
used
;
int64_t
free
;
int16_t
nAvailDisks
;
// # of Available disks
}
STierMeta
;
int
tfsInit
(
SDiskCfg
*
pDiskCfg
,
int
ndisk
);
void
tfsCleanup
();
void
tfsUpdateInfo
(
SFSMeta
*
pFSMeta
,
STierMeta
*
tierMetas
,
int8_t
numLevels
);
void
tfsGetMeta
(
SFSMeta
*
pMeta
);
void
tfsAllocDisk
(
int
expLevel
,
int
*
level
,
int
*
id
);
const
char
*
TFS_PRIMARY_PATH
();
const
char
*
TFS_DISK_PATH
(
int
level
,
int
id
);
// TFILE APIs ====================================
typedef
struct
{
int
level
;
int
id
;
char
rname
[
TSDB_FILENAME_LEN
];
// REL name
char
aname
[
TSDB_FILENAME_LEN
];
// ABS name
}
TFILE
;
#define TFILE_LEVEL(pf) ((pf)->level)
#define TFILE_ID(pf) ((pf)->id)
#define TFILE_NAME(pf) ((pf)->aname)
#define TFILE_REL_NAME(pf) ((pf)->rname)
#define tfsopen(pf, flags) open(TFILE_NAME(pf), flags)
#define tfsclose(fd) close(fd)
#define tfsremove(pf) remove(TFILE_NAME(pf))
#define tfscopy(sf, df) taosCopy(TFILE_NAME(sf), TFILE_NAME(df))
#define tfsrename(sf, df) taosRename(TFILE_NAME(sf), TFILE_NAME(df))
void
tfsInitFile
(
TFILE
*
pf
,
int
level
,
int
id
,
const
char
*
bname
);
bool
tfsIsSameFile
(
const
TFILE
*
pf1
,
const
TFILE
*
pf2
);
int
tfsEncodeFile
(
void
**
buf
,
TFILE
*
pf
);
void
*
tfsDecodeFile
(
void
*
buf
,
TFILE
*
pf
);
void
tfsbasename
(
const
TFILE
*
pf
,
char
*
dest
);
void
tfsdirname
(
const
TFILE
*
pf
,
char
*
dest
);
// DIR APIs ====================================
int
tfsMkdirAt
(
const
char
*
rname
,
int
level
,
int
id
);
int
tfsMkdirRecurAt
(
const
char
*
rname
,
int
level
,
int
id
);
int
tfsMkdir
(
const
char
*
rname
);
int
tfsRmdir
(
const
char
*
rname
);
int
tfsRename
(
char
*
orname
,
char
*
nrname
);
typedef
struct
TDIR
TDIR
;
TDIR
*
tfsOpendir
(
const
char
*
rname
);
const
TFILE
*
tfsReaddir
(
TDIR
*
tdir
);
void
tfsClosedir
(
TDIR
*
tdir
);
#ifdef __cplusplus
}
#endif
#endif
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录