1
// Copyright 2023 The CubeFS Authors.
3
// Licensed under the Apache License, Version 2.0 (the "License");
4
// you may not use this file except in compliance with the License.
5
// You may obtain a copy of the License at
7
// http://www.apache.org/licenses/LICENSE-2.0
9
// Unless required by applicable law or agreed to in writing, software
10
// distributed under the License is distributed on an "AS IS" BASIS,
11
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12
// implied. See the License for the specific language governing
13
// permissions and limitations under the License.
20
"github.com/cubefs/cubefs/proto"
21
"github.com/cubefs/cubefs/util/log"
24
func (mp *metaPartition) batchSetInodeQuota(req *proto.BatchSetMetaserverQuotaReuqest,
25
resp *proto.BatchSetMetaserverQuotaResponse) (err error) {
26
if len(req.Inodes) == 0 {
30
val, err := json.Marshal(req)
32
log.LogErrorf("batchSetInodeQuota marshal req [%v] failed [%v]", req, err)
36
r, err := mp.submit(opFSMSetInodeQuotaBatch, val)
38
log.LogErrorf("batchSetInodeQuota submit req [%v] failed [%v]", req, err)
41
resp.InodeRes = r.(*proto.BatchSetMetaserverQuotaResponse).InodeRes
42
log.LogInfof("batchSetInodeQuota quotaId [%v] mp[%v] btreeLen [%v] resp [%v] success", req.QuotaId, mp.config.PartitionId,
43
mp.extendTree.Len(), resp)
47
func (mp *metaPartition) batchDeleteInodeQuota(req *proto.BatchDeleteMetaserverQuotaReuqest,
48
resp *proto.BatchDeleteMetaserverQuotaResponse) (err error) {
49
if len(req.Inodes) == 0 {
53
val, err := json.Marshal(req)
55
log.LogErrorf("batchDeleteInodeQuota marshal req [%v] failed [%v]", req, err)
59
r, err := mp.submit(opFSMDeleteInodeQuotaBatch, val)
61
log.LogErrorf("batchDeleteInodeQuota submit req [%v] failed [%v]", req, err)
64
resp.InodeRes = r.(*proto.BatchDeleteMetaserverQuotaResponse).InodeRes
65
log.LogInfof("batchSetInodeQuota quotaId [%v] mp[%v] btreeLen [%v] resp [%v] success", req.QuotaId, mp.config.PartitionId,
66
mp.extendTree.Len(), resp)
70
func (mp *metaPartition) setQuotaHbInfo(infos []*proto.QuotaHeartBeatInfo) {
71
mp.mqMgr.setQuotaHbInfo(infos)
75
func (mp *metaPartition) getQuotaReportInfos() (infos []*proto.QuotaReportInfo) {
76
return mp.mqMgr.getQuotaReportInfos()
79
func (mp *metaPartition) statisticExtendByLoad(extend *Extend) {
81
ino := NewInode(extend.GetInode(), 0)
82
retMsg := mp.getInode(ino, true)
83
if retMsg.Status != proto.OpOk {
84
log.LogErrorf("statisticExtendByLoad get inode[%v] fail [%v].", extend.GetInode(), retMsg.Status)
91
quotaIds, isFind := mp.isExistQuota(extend.GetInode())
94
defer mqMgr.rwlock.Unlock()
95
for _, quotaId := range quotaIds {
96
var baseInfo proto.QuotaUsedInfo
97
value, isFind := mqMgr.statisticBase.Load(quotaId)
99
baseInfo = value.(proto.QuotaUsedInfo)
101
baseInfo.UsedBytes += int64(ino.Size)
102
baseInfo.UsedFiles += 1
103
mqMgr.statisticBase.Store(quotaId, baseInfo)
104
log.LogDebugf("[statisticExtendByLoad] quotaId [%v] baseInfo [%v]", quotaId, baseInfo)
108
log.LogInfof("statisticExtendByLoad ino[%v] isFind [%v].", ino.Inode, isFind)
112
func (mp *metaPartition) statisticExtendByStore(extend *Extend, inodeTree *BTree) {
114
ino := NewInode(extend.GetInode(), 0)
116
retMsg := mp.getInode(ino, true)
117
if retMsg.Status != proto.OpOk {
118
log.LogErrorf("statisticExtendByStore get inode[%v] fail [%v].", extend.GetInode(), retMsg.Status)
125
value, exist := extend.Get([]byte(proto.QuotaKey))
127
log.LogDebugf("statisticExtendByStore get quota key failed, mp[%v] inode[%v]", mp.config.PartitionId, extend.GetInode())
130
quotaInfos := &proto.MetaQuotaInfos{
131
QuotaInfoMap: make(map[uint32]*proto.MetaQuotaInfo),
133
if err := json.Unmarshal(value, "aInfos.QuotaInfoMap); err != nil {
134
log.LogErrorf("statisticExtendByStore inode[%v] Unmarshal quotaInfos fail [%v]", extend.GetInode(), err)
138
defer mqMgr.rwlock.Unlock()
139
for quotaId := range quotaInfos.QuotaInfoMap {
140
var baseInfo proto.QuotaUsedInfo
141
value, isFind := mqMgr.statisticRebuildBase.Load(quotaId)
143
baseInfo = value.(proto.QuotaUsedInfo)
145
baseInfo.UsedBytes += int64(ino.Size)
146
baseInfo.UsedFiles += 1
147
mqMgr.statisticRebuildBase.Store(quotaId, baseInfo)
148
log.LogDebugf("[statisticExtendByStore] mp[%v] quotaId [%v] inode[%v] baseInfo [%v]",
149
mp.config.PartitionId, quotaId, extend.GetInode(), baseInfo)
151
log.LogDebugf("statisticExtendByStore mp[%v] inode[%v] success.", mp.config.PartitionId, extend.GetInode())
155
func (mp *metaPartition) updateUsedInfo(size int64, files int64, ino uint64) {
156
quotaIds, isFind := mp.isExistQuota(ino)
158
log.LogInfof("updateUsedInfo ino[%v] quotaIds [%v] size [%v] files [%v]", ino, quotaIds, size, files)
159
for _, quotaId := range quotaIds {
160
mp.mqMgr.updateUsedInfo(size, files, quotaId)
166
func (mp *metaPartition) isExistQuota(ino uint64) (quotaIds []uint32, isFind bool) {
167
extend := NewExtend(ino)
168
treeItem := mp.extendTree.Get(extend)
173
extend = treeItem.(*Extend)
174
value, exist := extend.Get([]byte(proto.QuotaKey))
179
quotaInfos := &proto.MetaQuotaInfos{
180
QuotaInfoMap: make(map[uint32]*proto.MetaQuotaInfo),
182
if err := json.Unmarshal(value, "aInfos.QuotaInfoMap); err != nil {
183
log.LogErrorf("set quota inode[%v] Unmarshal quotaInfos fail [%v]", ino, err)
189
for quotaId := range quotaInfos.QuotaInfoMap {
190
quotaIds = append(quotaIds, quotaId)
193
log.LogInfof("isExistQuota inode:[%v] quotaIds [%v] isFind[%v]", ino, quotaIds, isFind)
197
func (mp *metaPartition) isOverQuota(ino uint64, size bool, files bool) (status uint8) {
198
quotaIds, isFind := mp.isExistQuota(ino)
200
for _, quotaId := range quotaIds {
201
status = mp.mqMgr.IsOverQuota(size, files, quotaId)
203
log.LogWarnf("isOverQuota ino[%v] quotaId [%v] size [%v] files[%v] status[%v]", ino, quotaId, size, files, status)
211
func (mp *metaPartition) getInodeQuota(inode uint64, p *Packet) (err error) {
212
extend := NewExtend(inode)
213
quotaInfos := &proto.MetaQuotaInfos{
214
QuotaInfoMap: make(map[uint32]*proto.MetaQuotaInfo),
220
treeItem := mp.extendTree.CopyGet(extend)
224
extend = treeItem.(*Extend)
226
value, exist = extend.Get([]byte(proto.QuotaKey))
228
if err = json.Unmarshal(value, "aInfos.QuotaInfoMap); err != nil {
229
log.LogErrorf("getInodeQuota inode[%v] Unmarshal quotaInfos fail [%v]", inode, err)
230
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
235
response := &proto.GetInodeQuotaResponse{}
236
log.LogInfof("getInodeQuota indoe %v ,map %v", inode, quotaInfos.QuotaInfoMap)
237
response.MetaQuotaInfoMap = quotaInfos.QuotaInfoMap
239
encoded, err := json.Marshal(response)
241
p.PacketErrorWithBody(proto.OpErr, []byte(err.Error()))
244
p.PacketOkWithBody(encoded)
248
func (mp *metaPartition) getInodeQuotaInfos(inode uint64) (quotaInfos map[uint32]*proto.MetaQuotaInfo, err error) {
249
log.LogInfof("getInodeQuotaInfos mp[%v] treeLen[%v]", mp.config.PartitionId, mp.extendTree.Len())
250
treeItem := mp.extendTree.Get(NewExtend(inode))
254
extend := treeItem.(*Extend)
255
info := &proto.MetaQuotaInfos{
256
QuotaInfoMap: make(map[uint32]*proto.MetaQuotaInfo),
258
value, exist := extend.Get([]byte(proto.QuotaKey))
260
if err = json.Unmarshal(value, &info.QuotaInfoMap); err != nil {
261
log.LogErrorf("getInodeQuota inode[%v] Unmarshal quotaInfos fail [%v]", inode, err)
264
quotaInfos = info.QuotaInfoMap
266
log.LogInfof("getInodeQuotaInfos inode[%v] quotaInfos [%v] exist [%v]", inode, quotaInfos, exist)
270
func (mp *metaPartition) setInodeQuota(quotaIds []uint32, inode uint64) {
271
extend := NewExtend(inode)
272
quotaInfos := &proto.MetaQuotaInfos{
273
QuotaInfoMap: make(map[uint32]*proto.MetaQuotaInfo),
275
for _, quotaId := range quotaIds {
276
quotaInfo := &proto.MetaQuotaInfo{
279
quotaInfos.QuotaInfoMap[quotaId] = quotaInfo
281
value, err := json.Marshal(quotaInfos.QuotaInfoMap)
283
log.LogErrorf("setInodeQuota marsha1 quotaInfos [%v] fail [%v]", quotaInfos, err)
286
extend.Put([]byte(proto.QuotaKey), value, mp.verSeq)
287
treeItem := mp.extendTree.CopyGet(extend)
290
mp.extendTree.ReplaceOrInsert(extend, true)
292
e = treeItem.(*Extend)
293
e.Merge(extend, true)
296
log.LogInfof("setInodeQuota inode[%v] quota [%v] success.", inode, quotaIds)