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

S
Shengliang Guan 已提交
16 17
#define _DEFAULT_SOURCE
#include "tfsInt.h"
H
Hongze Cheng 已提交
18

S
Shengliang Guan 已提交
19 20
#define tfsLockTier(pTier) pthread_spin_lock(&(pTier)->lock)
#define tfsUnLockTier(pTier) pthread_spin_unlock(&(pTier)->lock)
H
Hongze Cheng 已提交
21

S
Shengliang Guan 已提交
22 23 24 25 26 27 28
int32_t tfsInitTier(STier *pTier, int32_t level) {
  if (pTier == NULL) {
    terrno = TSDB_CODE_INVALID_PARA;
    return -1;
  }

  memset(pTier, 0, sizeof(STier));
H
Hongze Cheng 已提交
29

S
Shengliang Guan 已提交
30 31
  int32_t code = pthread_spin_init(&pTier->lock, 0);
  if (code != 0) {
H
Hongze Cheng 已提交
32 33 34 35 36 37 38
    terrno = TAOS_SYSTEM_ERROR(code);
    return -1;
  }

  pTier->level = level;
  return 0;
}
H
Hongze Cheng 已提交
39

H
refact  
Hongze Cheng 已提交
40
void tfsDestroyTier(STier *pTier) {
S
Shengliang Guan 已提交
41 42 43
  if (pTier == NULL) return;

  for (int32_t id = 0; id < TSDB_MAX_DISKS_PER_TIER; id++) {
H
Hongze Cheng 已提交
44
    DISK_AT_TIER(pTier, id) = tfsFreeDisk(DISK_AT_TIER(pTier, id));
H
Hongze Cheng 已提交
45
  }
H
Hongze Cheng 已提交
46

H
refact  
Hongze Cheng 已提交
47
  pTier->ndisk = 0;
H
Hongze Cheng 已提交
48
  pthread_spin_destroy(&(pTier->lock));
H
Hongze Cheng 已提交
49 50
}

H
refact  
Hongze Cheng 已提交
51
SDisk *tfsMountDiskToTier(STier *pTier, SDiskCfg *pCfg) {
S
Shengliang Guan 已提交
52 53 54 55
  if (pTier == NULL || pCfg == NULL || pTier->level != pCfg->level) {
    terrno = TSDB_CODE_INVALID_PARA;
    return -1;
  }
H
Hongze Cheng 已提交
56

H
Hongze Cheng 已提交
57
  if (TIER_NDISKS(pTier) >= TSDB_MAX_DISKS_PER_TIER) {
H
refact  
Hongze Cheng 已提交
58
    terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
H
Hongze Cheng 已提交
59
    return NULL;
H
Hongze Cheng 已提交
60 61
  }

S
Shengliang Guan 已提交
62
  int32_t id = 0;
H
refact  
Hongze Cheng 已提交
63 64
  if (pTier->level == 0) {
    if (DISK_AT_TIER(pTier, 0) != NULL) {
H
Hongze Cheng 已提交
65
      id = pTier->ndisk;
H
refact  
Hongze Cheng 已提交
66
    } else {
H
fix bug  
Hongze Cheng 已提交
67 68 69 70 71
      if (pCfg->primary) {
        id = 0;
      } else {
        id = pTier->ndisk + 1;
      }
H
Hongze Cheng 已提交
72
      if (id >= TSDB_MAX_DISKS_PER_TIER) {
H
refact  
Hongze Cheng 已提交
73
        terrno = TSDB_CODE_FS_TOO_MANY_MOUNT;
H
Hongze Cheng 已提交
74
        return NULL;
H
refact  
Hongze Cheng 已提交
75
      }
H
Hongze Cheng 已提交
76
    }
H
refact  
Hongze Cheng 已提交
77 78
  } else {
    id = pTier->ndisk;
H
Hongze Cheng 已提交
79 80
  }

S
Shengliang Guan 已提交
81
  SDisk *pDisk = tfsNewDisk(pCfg->level, id, pCfg->dir);
H
Hongze Cheng 已提交
82
  if (pDisk == NULL) return NULL;
S
Shengliang Guan 已提交
83

H
Hongze Cheng 已提交
84
  DISK_AT_TIER(pTier, id) = pDisk;
H
refact  
Hongze Cheng 已提交
85
  pTier->ndisk++;
H
Hongze Cheng 已提交
86

H
more  
Hongze Cheng 已提交
87
  fInfo("disk %s is mounted to tier level %d id %d", pCfg->dir, pCfg->level, id);
H
Hongze Cheng 已提交
88
  return DISK_AT_TIER(pTier, id);
H
Hongze Cheng 已提交
89 90
}

H
Hongze Cheng 已提交
91
void tfsUpdateTierInfo(STier *pTier, STierMeta *pTierMeta) {
S
Shengliang Guan 已提交
92
  STierMeta tmeta = {0};
H
Hongze Cheng 已提交
93 94 95 96

  if (pTierMeta == NULL) {
    pTierMeta = &tmeta;
  }
S
Shengliang Guan 已提交
97
  memset(pTierMeta, 0, sizeof(STierMeta));
H
Hongze Cheng 已提交
98 99

  tfsLockTier(pTier);
H
Hongze Cheng 已提交
100

S
Shengliang Guan 已提交
101 102
  for (int32_t id = 0; id < pTier->ndisk; id++) {
    if (tfsUpdateDiskInfo(DISK_AT_TIER(pTier, id)) != 0) {
H
Hongze Cheng 已提交
103 104
      continue;
    }
S
Shengliang Guan 已提交
105

H
Hongze Cheng 已提交
106
    pTierMeta->size += DISK_SIZE(DISK_AT_TIER(pTier, id));
107
    pTierMeta->used += DISK_USED_SIZE(DISK_AT_TIER(pTier, id));
H
Hongze Cheng 已提交
108 109 110 111 112 113 114 115 116 117
    pTierMeta->free += DISK_FREE_SIZE(DISK_AT_TIER(pTier, id));
    pTierMeta->nAvailDisks++;
  }

  pTier->tmeta = *pTierMeta;

  tfsUnLockTier(pTier);
}

// Round-Robin to allocate disk on a tier
S
Shengliang Guan 已提交
118 119 120 121 122
int32_t tfsAllocDiskOnTier(STier *pTier) {
  if (pTier == NULL || pTier->ndisk <= 0) {
    terrno = TSDB_CODE_INVALID_PARA;
    return -1;
  }
H
Hongze Cheng 已提交
123 124 125 126 127

  tfsLockTier(pTier);

  if (TIER_AVAIL_DISKS(pTier) <= 0) {
    tfsUnLockTier(pTier);
S
Shengliang Guan 已提交
128
    return TFS_UNDECIDED_ID;
H
Hongze Cheng 已提交
129 130
  }

S
Shengliang Guan 已提交
131
  int32_t id = pTier->nextid;
H
Hongze Cheng 已提交
132
  while (true) {
S
Shengliang Guan 已提交
133 134 135 136 137
    SDisk *pDisk = DISK_AT_TIER(pTier, id);
    if (pDisk == NULL) {
      tfsUnLockTier(pTier);
      return TFS_UNDECIDED_ID;
    }
H
Hongze Cheng 已提交
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

    if (DISK_FREE_SIZE(pDisk) < TFS_MIN_DISK_FREE_SIZE) {
      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);
  return id;
}

void tfsGetTierMeta(STier *pTier, STierMeta *pTierMeta) {
S
Shengliang Guan 已提交
158
  if (pTierMeta == NULL || pTierMeta == NULL) return;
H
Hongze Cheng 已提交
159 160 161 162 163 164 165

  tfsLockTier(pTier);
  *pTierMeta = pTier->tmeta;
  tfsUnLockTier(pTier);
}

void tfsPosNextId(STier *pTier) {
S
Shengliang Guan 已提交
166 167 168
  if (pTier == NULL || pTier->ndisk <= 0) return;

  int32_t nextid = 0;
H
Hongze Cheng 已提交
169

S
Shengliang Guan 已提交
170
  for (int32_t id = 1; id < pTier->ndisk; id++) {
H
Hongze Cheng 已提交
171 172 173 174 175
    SDisk *pLDisk = DISK_AT_TIER(pTier, nextid);
    SDisk *pDisk = DISK_AT_TIER(pTier, id);
    if (DISK_FREE_SIZE(pDisk) > TFS_MIN_DISK_FREE_SIZE && DISK_FREE_SIZE(pDisk) > DISK_FREE_SIZE(pLDisk)) {
      nextid = id;
    }
H
Hongze Cheng 已提交
176
  }
H
Hongze Cheng 已提交
177

H
Hongze Cheng 已提交
178
  pTier->nextid = nextid;
179
}