tsdbFS.c 14.0 KB
Newer Older
H
Hongze Cheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * 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/>.
H
Hongze Cheng 已提交
14 15
 */

H
Hongze Cheng 已提交
16
#include "inc/tsdbFS.h"
H
Hongze Cheng 已提交
17

H
Hongze Cheng 已提交
18 19
#define TSDB_FS_EDIT_MIN TSDB_FEDIT_COMMIT
#define TSDB_FS_EDIT_MAX (TSDB_FEDIT_MERGE + 1)
H
Hongze Cheng 已提交
20 21 22 23 24 25 26 27

enum {
  TSDB_FS_STATE_NONE = 0,
  TSDB_FS_STATE_OPEN,
  TSDB_FS_STATE_EDIT,
  TSDB_FS_STATE_CLOSE,
};

H
Hongze Cheng 已提交
28 29
typedef enum {
  TSDB_FCURRENT = 1,
H
Hongze Cheng 已提交
30 31
  TSDB_FCURRENT_C,  // for commit
  TSDB_FCURRENT_M,  // for merge
H
Hongze Cheng 已提交
32 33 34 35
} EFCurrentT;

static const char *gCurrentFname[] = {
    [TSDB_FCURRENT] = "current.json",
H
Hongze Cheng 已提交
36 37
    [TSDB_FCURRENT_C] = "current.c.json",
    [TSDB_FCURRENT_M] = "current.m.json",
H
Hongze Cheng 已提交
38 39
};

H
Hongze Cheng 已提交
40 41 42 43 44 45 46 47 48 49
static int32_t create_fs(STsdb *pTsdb, STFileSystem **fs) {
  fs[0] = taosMemoryCalloc(1, sizeof(*fs[0]));
  if (fs[0] == NULL) return TSDB_CODE_OUT_OF_MEMORY;

  fs[0]->cstate = taosArrayInit(16, sizeof(STFileSet));
  fs[0]->nstate = taosArrayInit(16, sizeof(STFileSet));
  if (fs[0]->cstate == NULL || fs[0]->nstate == NULL) {
    taosArrayDestroy(fs[0]->nstate);
    taosArrayDestroy(fs[0]->cstate);
    taosMemoryFree(fs[0]);
H
Hongze Cheng 已提交
50 51 52
    return TSDB_CODE_OUT_OF_MEMORY;
  }

H
Hongze Cheng 已提交
53 54 55 56
  fs[0]->pTsdb = pTsdb;
  fs[0]->state = TSDB_FS_STATE_NONE;
  tsem_init(&fs[0]->canEdit, 0, 1);
  fs[0]->neid = 0;
H
Hongze Cheng 已提交
57

H
Hongze Cheng 已提交
58 59 60
  return 0;
}

H
Hongze Cheng 已提交
61 62 63 64 65 66 67
static int32_t destroy_fs(STFileSystem **fs) {
  if (fs[0] == NULL) return 0;
  taosArrayDestroy(fs[0]->nstate);
  taosArrayDestroy(fs[0]->cstate);
  tsem_destroy(&fs[0]->canEdit);
  taosMemoryFree(fs[0]);
  fs[0] = NULL;
H
Hongze Cheng 已提交
68 69 70
  return 0;
}

H
Hongze Cheng 已提交
71
static int32_t current_fname(STsdb *pTsdb, char *fname, EFCurrentT ftype) {
H
Hongze Cheng 已提交
72 73 74 75 76 77 78 79
  if (pTsdb->pVnode->pTfs) {
    snprintf(fname,                                   //
             TSDB_FILENAME_LEN,                       //
             "%s%s%s%s%s",                            //
             tfsGetPrimaryPath(pTsdb->pVnode->pTfs),  //
             TD_DIRSEP,                               //
             pTsdb->path,                             //
             TD_DIRSEP,                               //
H
Hongze Cheng 已提交
80
             gCurrentFname[ftype]);
H
Hongze Cheng 已提交
81 82 83 84 85 86
  } else {
    snprintf(fname,              //
             TSDB_FILENAME_LEN,  //
             "%s%s%s",           //
             pTsdb->path,        //
             TD_DIRSEP,          //
H
Hongze Cheng 已提交
87
             gCurrentFname[ftype]);
H
Hongze Cheng 已提交
88 89 90 91
  }
  return 0;
}

H
Hongze Cheng 已提交
92
static int32_t fs_from_json_str(const char *pData, STFileSystem *pFS) {
H
Hongze Cheng 已提交
93 94 95
  int32_t code = 0;
  int32_t lino;

H
Hongze Cheng 已提交
96
  ASSERTS(0, "TODO: Not implemented yet");
H
Hongze Cheng 已提交
97

H
Hongze Cheng 已提交
98 99 100
_exit:
  return code;
}
H
Hongze Cheng 已提交
101

H
Hongze Cheng 已提交
102
static int32_t save_json(const cJSON *json, const char *fname) {
H
Hongze Cheng 已提交
103
  int32_t code = 0;
H
Hongze Cheng 已提交
104 105 106 107 108 109 110 111

  char *data = cJSON_Print(json);
  if (data == NULL) return TSDB_CODE_OUT_OF_MEMORY;

  TdFilePtr fp = taosOpenFile(fname, TD_FILE_WRITE | TD_FILE_CREATE | TD_FILE_TRUNC);
  if (fp == NULL) {
    code = TAOS_SYSTEM_ERROR(code);
    goto _exit;
H
Hongze Cheng 已提交
112 113
  }

H
Hongze Cheng 已提交
114 115 116
  if (taosWriteFile(fp, data, strlen(data) + 1) < 0) {
    code = TAOS_SYSTEM_ERROR(code);
    goto _exit;
H
Hongze Cheng 已提交
117 118
  }

H
Hongze Cheng 已提交
119 120 121 122
  if (taosFsyncFile(fp) < 0) {
    code = TAOS_SYSTEM_ERROR(code);
    goto _exit;
  }
H
Hongze Cheng 已提交
123

H
Hongze Cheng 已提交
124
  taosCloseFile(&fp);
H
Hongze Cheng 已提交
125 126

_exit:
H
Hongze Cheng 已提交
127
  taosMemoryFree(data);
H
Hongze Cheng 已提交
128 129 130
  return code;
}

H
Hongze Cheng 已提交
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
static int32_t load_json(const char *fname, cJSON **json) {
  int32_t code = 0;
  void   *data = NULL;

  TdFilePtr fp = taosOpenFile(fname, TD_FILE_READ);
  if (fp == NULL) return TAOS_SYSTEM_ERROR(code);

  int64_t size;
  if (taosFStatFile(fp, &size, NULL) < 0) {
    code = TAOS_SYSTEM_ERROR(code);
    goto _exit;
  }

  data = taosMemoryMalloc(size);
  if (data == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
    goto _exit;
  }

  if (taosReadFile(fp, data, size) < 0) {
    code = TAOS_SYSTEM_ERROR(code);
    goto _exit;
  }

  json[0] = cJSON_Parse(data);
  if (json[0] == NULL) {
    code = TSDB_CODE_FILE_CORRUPTED;
    goto _exit;
  }

_exit:
  taosCloseFile(&fp);
  if (data) taosMemoryFree(data);
  if (code) json[0] = NULL;
  return code;
}

H
Hongze Cheng 已提交
168
static int32_t save_fs(int64_t eid, SArray *aTFileSet, const char *fname) {
H
Hongze Cheng 已提交
169
  int32_t code = 0;
H
Hongze Cheng 已提交
170
  int32_t lino = 0;
H
Hongze Cheng 已提交
171

H
Hongze Cheng 已提交
172 173
  cJSON *json = cJSON_CreateObject();
  if (json == NULL) return TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
174

H
Hongze Cheng 已提交
175 176 177
  // fmtv
  if (cJSON_AddNumberToObject(json, "fmtv", 1) == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
178
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
179 180
  }

H
Hongze Cheng 已提交
181 182 183
  // eid
  if (cJSON_AddNumberToObject(json, "eid", eid) == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
184
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
185 186
  }

H
Hongze Cheng 已提交
187 188 189 190
  // fset
  cJSON *ajson = cJSON_AddArrayToObject(json, "fset");
  if (ajson == NULL) {
    code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
191
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
192 193 194
  }
  for (int32_t i = 0; i < taosArrayGetSize(aTFileSet); i++) {
    STFileSet *pFileSet = (STFileSet *)taosArrayGet(aTFileSet, i);
H
Hongze Cheng 已提交
195
    cJSON     *item;
H
Hongze Cheng 已提交
196

H
Hongze Cheng 已提交
197
    if ((item = cJSON_CreateObject()) == NULL) {
H
Hongze Cheng 已提交
198
      code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
199
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
200 201
    }

H
Hongze Cheng 已提交
202
    code = tsdbFileSetToJson(pFileSet, item);
H
Hongze Cheng 已提交
203
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
204

H
Hongze Cheng 已提交
205
    cJSON_AddItemToArray(ajson, item);
H
Hongze Cheng 已提交
206 207
  }

H
Hongze Cheng 已提交
208
  code = save_json(json, fname);
H
Hongze Cheng 已提交
209
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
210 211 212

_exit:
  if (code) {
H
Hongze Cheng 已提交
213
    tsdbError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
214
  }
H
Hongze Cheng 已提交
215
  cJSON_Delete(json);
H
Hongze Cheng 已提交
216
  return code;
H
Hongze Cheng 已提交
217 218
}

H
Hongze Cheng 已提交
219 220 221 222 223 224 225 226 227
static int32_t load_fs(const char *fname, SArray *aTFileSet, int64_t *eid) {
  int32_t code = 0;
  int32_t lino = 0;

  taosArrayClear(aTFileSet);

  // load json
  cJSON *json = NULL;
  code = load_json(fname, &json);
H
Hongze Cheng 已提交
228
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
229 230 231 232 233 234 235 236 237

  // parse json
  const cJSON *item;

  /* fmtv */
  item = cJSON_GetObjectItem(json, "fmtv");
  if (cJSON_IsNumber(item)) {
    ASSERT(item->valuedouble == 1);
  } else {
H
Hongze Cheng 已提交
238
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
H
Hongze Cheng 已提交
239 240 241 242 243 244 245
  }

  /* eid */
  item = cJSON_GetObjectItem(json, "eid");
  if (cJSON_IsNumber(item)) {
    eid[0] = item->valuedouble;
  } else {
H
Hongze Cheng 已提交
246
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
H
Hongze Cheng 已提交
247 248 249 250 251 252 253
  }

  /* fset */
  item = cJSON_GetObjectItem(json, "fset");
  if (cJSON_IsArray(item)) {
    const cJSON *titem;
    cJSON_ArrayForEach(titem, item) {
H
Hongze Cheng 已提交
254 255 256
      STFileSet *pFileSet;
      if ((pFileSet = taosArrayReserve(aTFileSet, 1)) == NULL) {
        TSDB_CHECK_CODE(code = TSDB_CODE_OUT_OF_MEMORY, lino, _exit);
H
Hongze Cheng 已提交
257 258 259
      }

      code = tsdbFileSetFromJson(titem, pFileSet);
H
Hongze Cheng 已提交
260
      TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
261 262
    }
  } else {
H
Hongze Cheng 已提交
263
    TSDB_CHECK_CODE(code = TSDB_CODE_FILE_CORRUPTED, lino, _exit);
H
Hongze Cheng 已提交
264 265 266 267 268 269 270 271
  }

_exit:
  if (code) {
    tsdbError("%s failed at line %d since %s, fname:%s", __func__, lino, tstrerror(code), fname);
  }
  if (json) cJSON_Delete(json);
  return code;
H
Hongze Cheng 已提交
272 273
}

H
Hongze Cheng 已提交
274 275 276 277 278 279
static int32_t apply_commit(STFileSystem *fs) {
  // TODO
  return 0;
}

static int32_t commit_edit(STFileSystem *fs) {
H
Hongze Cheng 已提交
280 281
  char current[TSDB_FILENAME_LEN];
  char current_t[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
282

H
Hongze Cheng 已提交
283 284 285 286 287
  current_fname(fs->pTsdb, current, TSDB_FCURRENT);
  if (fs->etype == TSDB_FEDIT_COMMIT) {
    current_fname(fs->pTsdb, current, TSDB_FCURRENT_C);
  } else if (fs->etype == TSDB_FEDIT_MERGE) {
    current_fname(fs->pTsdb, current, TSDB_FCURRENT_M);
H
Hongze Cheng 已提交
288 289
  } else {
    ASSERT(0);
H
Hongze Cheng 已提交
290 291
  }

H
Hongze Cheng 已提交
292 293 294
  int32_t code;
  int32_t lino;
  if ((code = taosRenameFile(current_t, current))) {
H
Hongze Cheng 已提交
295
    TSDB_CHECK_CODE(code = TAOS_SYSTEM_ERROR(code), lino, _exit);
H
Hongze Cheng 已提交
296
  }
H
Hongze Cheng 已提交
297

H
Hongze Cheng 已提交
298
  code = apply_commit(fs);
H
Hongze Cheng 已提交
299
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
300

H
Hongze Cheng 已提交
301 302
_exit:
  if (code) {
H
Hongze Cheng 已提交
303 304 305
    tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(fs->pTsdb->pVnode), __func__, lino, tstrerror(code));
  } else {
    tsdbInfo("vgId:%d %s success, eid:%" PRId64 " etype:%d", TD_VID(fs->pTsdb->pVnode), __func__, fs->eid, fs->etype);
H
Hongze Cheng 已提交
306 307
  }
  return code;
H
Hongze Cheng 已提交
308 309
}

H
Hongze Cheng 已提交
310 311 312 313 314 315 316
// static int32_t
static int32_t apply_abort(STFileSystem *fs) {
  // TODO
  return 0;
}

static int32_t abort_edit(STFileSystem *fs) {
H
Hongze Cheng 已提交
317
  char fname[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
318

H
Hongze Cheng 已提交
319 320 321 322
  if (fs->etype == TSDB_FEDIT_COMMIT) {
    current_fname(fs->pTsdb, fname, TSDB_FCURRENT_C);
  } else if (fs->etype == TSDB_FEDIT_MERGE) {
    current_fname(fs->pTsdb, fname, TSDB_FCURRENT_M);
H
Hongze Cheng 已提交
323 324 325
  } else {
    ASSERT(0);
  }
H
Hongze Cheng 已提交
326

H
Hongze Cheng 已提交
327 328 329
  int32_t code;
  int32_t lino;
  if ((code = taosRemoveFile(fname))) {
H
Hongze Cheng 已提交
330
    TSDB_CHECK_CODE(code = TAOS_SYSTEM_ERROR(code), lino, _exit);
H
Hongze Cheng 已提交
331
  }
H
Hongze Cheng 已提交
332

H
Hongze Cheng 已提交
333
  code = apply_abort(fs);
H
Hongze Cheng 已提交
334
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
335 336 337 338 339 340 341 342

_exit:
  if (code) {
    tsdbError("vgId:%d %s failed since %s", TD_VID(fs->pTsdb->pVnode), __func__, tstrerror(code));
  } else {
    tsdbInfo("vgId:%d %s success, eid:%" PRId64 " etype:%d", TD_VID(fs->pTsdb->pVnode), __func__, fs->eid, fs->etype);
  }
  return code;
H
Hongze Cheng 已提交
343 344
}

H
Hongze Cheng 已提交
345
static int32_t scan_and_fix_fs(STFileSystem *pFS) {
H
Hongze Cheng 已提交
346
  // TODO
H
Hongze Cheng 已提交
347 348 349
  return 0;
}

H
Hongze Cheng 已提交
350 351 352 353 354
static int32_t update_fs_if_needed(STFileSystem *pFS) {
  // TODO
  return 0;
}

H
Hongze Cheng 已提交
355
static int32_t open_fs(STFileSystem *fs, int8_t rollback) {
H
Hongze Cheng 已提交
356
  int32_t code = 0;
H
Hongze Cheng 已提交
357
  int32_t lino = 0;
H
Hongze Cheng 已提交
358
  STsdb  *pTsdb = fs->pTsdb;
H
Hongze Cheng 已提交
359

H
Hongze Cheng 已提交
360
  code = update_fs_if_needed(fs);
H
Hongze Cheng 已提交
361
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
362

H
Hongze Cheng 已提交
363 364 365
  char fCurrent[TSDB_FILENAME_LEN];
  char cCurrent[TSDB_FILENAME_LEN];
  char mCurrent[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
366

H
Hongze Cheng 已提交
367 368
  current_fname(pTsdb, fCurrent, TSDB_FCURRENT);
  current_fname(pTsdb, cCurrent, TSDB_FCURRENT_C);
H
Hongze Cheng 已提交
369
  current_fname(pTsdb, mCurrent, TSDB_FCURRENT_M);
H
Hongze Cheng 已提交
370

H
Hongze Cheng 已提交
371
  if (taosCheckExistFile(fCurrent)) {  // current.json exists
H
Hongze Cheng 已提交
372
    code = load_fs(fCurrent, fs->cstate, &fs->neid);
H
Hongze Cheng 已提交
373
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
374

H
Hongze Cheng 已提交
375
    if (taosCheckExistFile(cCurrent)) {
H
Hongze Cheng 已提交
376 377 378
      // current.c.json exists

      fs->etype = TSDB_FEDIT_COMMIT;
H
Hongze Cheng 已提交
379
      if (rollback) {
H
Hongze Cheng 已提交
380
        code = abort_edit(fs);
H
Hongze Cheng 已提交
381 382
        TSDB_CHECK_CODE(code, lino, _exit);
      } else {
H
Hongze Cheng 已提交
383
        code = load_fs(cCurrent, fs->nstate, &fs->eid);
H
Hongze Cheng 已提交
384
        TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
385 386

        code = commit_edit(fs);
H
Hongze Cheng 已提交
387 388
        TSDB_CHECK_CODE(code, lino, _exit);
      }
H
Hongze Cheng 已提交
389 390 391 392
    } else if (taosCheckExistFile(mCurrent)) {
      // current.m.json exists
      fs->etype = TSDB_FEDIT_MERGE;
      code = abort_edit(fs);
H
Hongze Cheng 已提交
393 394
      TSDB_CHECK_CODE(code, lino, _exit);
    }
H
Hongze Cheng 已提交
395

H
Hongze Cheng 已提交
396
    code = scan_and_fix_fs(fs);
H
Hongze Cheng 已提交
397
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
398
  } else {
H
Hongze Cheng 已提交
399
    code = save_fs(0, fs->cstate, fCurrent);
H
Hongze Cheng 已提交
400
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
401 402 403 404
  }

_exit:
  if (code) {
H
Hongze Cheng 已提交
405
    tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
406
  } else {
H
Hongze Cheng 已提交
407
    tsdbInfo("vgId:%d %s success", TD_VID(pTsdb->pVnode), __func__);
H
Hongze Cheng 已提交
408
  }
H
Hongze Cheng 已提交
409 410 411
  return 0;
}

H
Hongze Cheng 已提交
412
static int32_t close_file_system(STFileSystem *pFS) {
H
Hongze Cheng 已提交
413
  ASSERTS(0, "TODO: Not implemented yet");
H
Hongze Cheng 已提交
414 415
  return 0;
}
H
Hongze Cheng 已提交
416

H
Hongze Cheng 已提交
417
static int32_t apply_edit(STFileSystem *pFS) {
H
Hongze Cheng 已提交
418
  int32_t code = 0;
H
Hongze Cheng 已提交
419
  ASSERTS(0, "TODO: Not implemented yet");
H
Hongze Cheng 已提交
420
  return code;
H
Hongze Cheng 已提交
421 422
}

H
Hongze Cheng 已提交
423
static int32_t fset_cmpr_fn(const struct STFileSet *pSet1, const struct STFileSet *pSet2) {
H
Hongze Cheng 已提交
424 425 426 427 428 429 430 431
  if (pSet1->fid < pSet2->fid) {
    return -1;
  } else if (pSet1->fid > pSet2->fid) {
    return 1;
  }
  return 0;
}

H
Hongze Cheng 已提交
432
static int32_t edit_fs(STFileSystem *pFS, const SArray *aFileOp) {
H
Hongze Cheng 已提交
433
  int32_t code = 0;
H
Hongze Cheng 已提交
434
  int32_t lino = 0;
H
Hongze Cheng 已提交
435

H
Hongze Cheng 已提交
436
  STFileSet *pSet = NULL;
H
Hongze Cheng 已提交
437
  for (int32_t iop = 0; iop < taosArrayGetSize(aFileOp); iop++) {
H
Hongze Cheng 已提交
438
    struct STFileOp *op = taosArrayGet(aFileOp, iop);
H
Hongze Cheng 已提交
439

H
Hongze Cheng 已提交
440 441 442
    if (pSet == NULL || pSet->fid != op->fid) {
      STFileSet fset = {.fid = op->fid};
      pSet = taosArraySearch(pFS->nstate, &fset, (__compar_fn_t)tsdbFSetCmprFn, TD_EQ);
H
Hongze Cheng 已提交
443 444
    }

H
Hongze Cheng 已提交
445
    // create fset if need
H
Hongze Cheng 已提交
446 447
    if (pSet == NULL) {
      ASSERT(op->oState.size == 0 && op->nState.size > 0);
H
Hongze Cheng 已提交
448 449 450 451 452 453 454 455 456

      STFileSet fset = {.fid = op->fid};
      int32_t   idx = taosArraySearchIdx(pFS->nstate, &fset, (__compar_fn_t)tsdbFSetCmprFn, TD_GT);

      if (idx < 0) idx = taosArrayGetSize(pFS->nstate);

      pSet = taosArrayInsert(pFS->nstate, idx, &fset);
      if (pSet == NULL) {
        code = TSDB_CODE_OUT_OF_MEMORY;
H
Hongze Cheng 已提交
457
        TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
458 459 460
      }

      tsdbFileSetInit(pSet);
H
Hongze Cheng 已提交
461 462 463
    }

    code = tsdbFSetEdit(pSet, op);
H
Hongze Cheng 已提交
464
    TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
465 466
  }

H
Hongze Cheng 已提交
467
_exit:
H
Hongze Cheng 已提交
468 469 470
  return 0;
}

H
Hongze Cheng 已提交
471
int32_t tsdbOpenFS(STsdb *pTsdb, STFileSystem **fs, int8_t rollback) {
H
Hongze Cheng 已提交
472 473 474
  int32_t code;
  int32_t lino;

H
Hongze Cheng 已提交
475
  code = create_fs(pTsdb, fs);
H
Hongze Cheng 已提交
476 477
  TSDB_CHECK_CODE(code, lino, _exit);

H
Hongze Cheng 已提交
478
  code = open_fs(fs[0], rollback);
H
Hongze Cheng 已提交
479
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
480 481 482

_exit:
  if (code) {
H
Hongze Cheng 已提交
483
    tsdbError("vgId:%d %s failed at line %d since %s", TD_VID(pTsdb->pVnode), __func__, lino, tstrerror(code));
H
Hongze Cheng 已提交
484
    destroy_fs(fs);
H
Hongze Cheng 已提交
485
  } else {
H
Hongze Cheng 已提交
486
    tsdbInfo("vgId:%d %s success", TD_VID(pTsdb->pVnode), __func__);
H
Hongze Cheng 已提交
487 488 489 490
  }
  return 0;
}

H
Hongze Cheng 已提交
491
int32_t tsdbCloseFS(STFileSystem **ppFS) {
H
Hongze Cheng 已提交
492 493
  if (ppFS[0] == NULL) return 0;
  close_file_system(ppFS[0]);
H
Hongze Cheng 已提交
494
  destroy_fs(ppFS);
H
Hongze Cheng 已提交
495 496
  return 0;
}
H
Hongze Cheng 已提交
497

H
Hongze Cheng 已提交
498 499 500 501 502 503
int32_t tsdbFSAllocEid(STFileSystem *pFS, int64_t *eid) {
  eid[0] = ++pFS->neid;  // TODO: use atomic operation
  return 0;
}

int32_t tsdbFSEditBegin(STFileSystem *fs, int64_t eid, const SArray *aFileOp, EFEditT etype) {
H
Hongze Cheng 已提交
504
  int32_t code = 0;
H
Hongze Cheng 已提交
505
  int32_t lino;
H
Hongze Cheng 已提交
506
  char    current_t[TSDB_FILENAME_LEN];
H
Hongze Cheng 已提交
507

H
Hongze Cheng 已提交
508 509 510 511 512 513 514
  if (etype == TSDB_FEDIT_COMMIT) {
    current_fname(fs->pTsdb, current_t, TSDB_FCURRENT_C);
  } else {
    current_fname(fs->pTsdb, current_t, TSDB_FCURRENT_M);
  }

  tsem_wait(&fs->canEdit);
H
Hongze Cheng 已提交
515

H
Hongze Cheng 已提交
516
  fs->etype = etype;
H
Hongze Cheng 已提交
517
  fs->eid = eid;
H
Hongze Cheng 已提交
518

H
Hongze Cheng 已提交
519 520 521
  // edit
  code = edit_fs(fs, aFileOp);
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
522

H
Hongze Cheng 已提交
523 524
  // save fs
  code = save_fs(fs->eid, fs->nstate, current_t);
H
Hongze Cheng 已提交
525
  TSDB_CHECK_CODE(code, lino, _exit);
H
Hongze Cheng 已提交
526 527 528

_exit:
  if (code) {
H
Hongze Cheng 已提交
529 530
    tsdbError("vgId:%d %s failed at line %d since %s, eid:%" PRId64 " etype:%d", TD_VID(fs->pTsdb->pVnode), __func__,
              lino, tstrerror(code), fs->eid, etype);
H
Hongze Cheng 已提交
531
  } else {
H
Hongze Cheng 已提交
532
    tsdbInfo("vgId:%d %s done, eid:%" PRId64 " etype:%d", TD_VID(fs->pTsdb->pVnode), __func__, fs->eid, etype);
H
Hongze Cheng 已提交
533 534 535 536
  }
  return code;
}

H
Hongze Cheng 已提交
537 538 539
int32_t tsdbFSEditCommit(STFileSystem *fs) {
  int32_t code = commit_edit(fs);
  tsem_post(&fs->canEdit);
H
Hongze Cheng 已提交
540 541 542
  return code;
}

H
Hongze Cheng 已提交
543 544 545
int32_t tsdbFSEditAbort(STFileSystem *fs) {
  int32_t code = abort_edit(fs);
  tsem_post(&fs->canEdit);
H
Hongze Cheng 已提交
546
  return code;
H
Hongze Cheng 已提交
547 548 549 550 551 552
}

int32_t tsdbFSGetFSet(STFileSystem *fs, int32_t fid, const STFileSet **ppFSet) {
  STFileSet fset = {.fid = fid};
  ppFSet[0] = taosArraySearch(fs->cstate, &fset, (__compar_fn_t)tsdbFSetCmprFn, TD_EQ);
  return 0;
H
Hongze Cheng 已提交
553
}