mirror of
https://github.com/cubefs/cubefs.git
synced 2026-08-02 10:06:14 +00:00
Fix: 1.quota list optimization
2.The path of quota update is consistent, but the inode is inconsistent, so it needs to fail
3.To delete the rootquota directory, you need to delete the quota first
4.Solve the problem that the quota has been deleted, but after restarting the master, the quota reappears
Signed-off-by: baijiaruo <huyao2@oppo.com>
This commit is contained in:
parent
342233ac00
commit
7bccbc4ea2
@ -617,3 +617,24 @@ func formatZoneView(zv *proto.ZoneView) string {
|
||||
}
|
||||
return sb.String()
|
||||
}
|
||||
|
||||
var quotaTableRowPattern = "%-6v %-30v %-15v %-8v %-10v %-10v %-10v %-12v %-12v %-10v %-10v %-10v %-10v"
|
||||
|
||||
func formatQuotaTableHeader() string {
|
||||
return fmt.Sprintf(quotaTableRowPattern, "ID", "PATH", "VOL", "STATUS", "CTIME",
|
||||
"PID", "RINODE", "LIMITEDFILES", "LIMITEDBYTES", "USEDFILES", "USEDBYTES", "MAXFILES", "MAXBYTES")
|
||||
}
|
||||
|
||||
func formatQuotaInfo(info *proto.QuotaInfo) string {
|
||||
var status string
|
||||
if info.Status == proto.QuotaInit {
|
||||
status = "Init"
|
||||
} else if info.Status == proto.QuotaComplete {
|
||||
status = "Complete"
|
||||
} else {
|
||||
status = "Deleting"
|
||||
}
|
||||
return fmt.Sprintf(quotaTableRowPattern, info.QuotaId, info.FullPath, info.VolName, status, info.CTime, info.PartitionId,
|
||||
info.RootInode, info.LimitedInfo.LimitedFiles, info.LimitedInfo.LimitedBytes, info.UsedInfo.UsedFiles, info.UsedInfo.UsedBytes,
|
||||
info.MaxFiles, info.MaxBytes)
|
||||
}
|
||||
|
||||
@ -105,7 +105,8 @@ func newQuotaSetCmd(client *master.MasterClient) *cobra.Command {
|
||||
stdout("volName %v path %v quota set failed(%v)\n", volName, fullPath, err)
|
||||
return
|
||||
}
|
||||
stdout("volName %v path %v maxFiles %v, maxBytes %v err %v.\n", volName, fullPath, maxFiles, maxBytes, err)
|
||||
stdout("setQuota: volName %v path %v inode %v maxFiles %v maxBytes %v success.\n",
|
||||
volName, fullPath, inodeId, maxFiles, maxBytes)
|
||||
},
|
||||
}
|
||||
cmd.Flags().Uint64Var(&maxFiles, CliFlagMaxFiles, cmdQuotaDefaultMaxFiles, "Specify quota max files")
|
||||
@ -126,8 +127,10 @@ func newQuotaListCmd(client *master.MasterClient) *cobra.Command {
|
||||
stdout("volName %v quota list failed(%v)\n", volName, err)
|
||||
return
|
||||
}
|
||||
stdout("[quotas]\n")
|
||||
stdout("%v\n", formatQuotaTableHeader())
|
||||
for _, quotaInfo := range quotas {
|
||||
stdout("quotas:%v\n", *quotaInfo)
|
||||
stdout("%v\n", formatQuotaInfo(quotaInfo))
|
||||
}
|
||||
},
|
||||
}
|
||||
@ -168,7 +171,8 @@ func newQuotaUpdateCmd(client *master.MasterClient) *cobra.Command {
|
||||
stdout("volName %v path %v quota update failed(%v)\n", volName, fullPath, err)
|
||||
return
|
||||
}
|
||||
stdout("volName %v path %v maxFiles %v, maxBytes %v err %v.\n", volName, fullPath, maxFiles, maxBytes, err)
|
||||
stdout("updateQuota: volName %v path %v inode %v maxFiles %v maxBytes %v success.\n",
|
||||
volName, fullPath, inodeId, maxFiles, maxBytes)
|
||||
},
|
||||
}
|
||||
cmd.Flags().Uint64Var(&maxFiles, CliFlagMaxFiles, cmdQuotaDefaultMaxFiles, "Specify quota max files")
|
||||
|
||||
@ -43,7 +43,9 @@ func (s *Super) InodeGet(ino uint64) (*proto.InodeInfo, error) {
|
||||
}
|
||||
}
|
||||
s.ic.Put(info)
|
||||
s.fslock.Lock()
|
||||
node, isFind := s.nodeCache[ino]
|
||||
s.fslock.Unlock()
|
||||
if isFind {
|
||||
if proto.IsDir(info.Mode) {
|
||||
node.(*Dir).info = info
|
||||
|
||||
@ -525,15 +525,15 @@ func (c *Cluster) checkMetaNodeHeartbeat() {
|
||||
}
|
||||
spaceInfo := vol.uidSpaceManager.getSpaceOp()
|
||||
hbReq.UidLimitInfo = append(hbReq.UidLimitInfo, spaceInfo...)
|
||||
|
||||
quotaHbInfos := vol.quotaManager.getQuotaHbInfos()
|
||||
hbReq.QuotaHbInfos = append(hbReq.QuotaHbInfos, quotaHbInfos...)
|
||||
log.LogDebugf("checkMetaNodeHeartbeat start")
|
||||
for _, info := range hbReq.QuotaHbInfos {
|
||||
log.LogDebugf("checkMetaNodeHeartbeat info [%v]", info)
|
||||
if len(quotaHbInfos) != 0 {
|
||||
hbReq.QuotaHbInfos = append(hbReq.QuotaHbInfos, quotaHbInfos...)
|
||||
}
|
||||
}
|
||||
|
||||
log.LogDebugf("checkMetaNodeHeartbeat start")
|
||||
for _, info := range hbReq.QuotaHbInfos {
|
||||
log.LogDebugf("checkMetaNodeHeartbeat info [%v]", info)
|
||||
}
|
||||
tasks = append(tasks, task)
|
||||
return true
|
||||
})
|
||||
|
||||
@ -1177,7 +1177,7 @@ func (c *Cluster) dealDeleteMetaserverQuotaResponse(nodeAddr string, resp *proto
|
||||
metadata.Op = opSyncDeleteQuota
|
||||
metadata.K = quotaPrefix + strconv.FormatUint(vol.ID, 10) + keySeparator + strconv.FormatUint(uint64(resp.QuotaId), 10)
|
||||
metadata.V = value
|
||||
|
||||
log.LogInfof("hytemp dealSetMetaserverQuotaResponse op [%v] k [%v]", metadata.Op, metadata.K)
|
||||
if err = c.submit(metadata); err != nil {
|
||||
log.LogErrorf("delete quota [%v] submit fail [%v].", quotaInfo, err)
|
||||
return
|
||||
|
||||
@ -51,6 +51,7 @@ func (alloc *IDAllocator) restore() {
|
||||
alloc.restoreMaxMetaPartitionID()
|
||||
alloc.restoreMaxCommonID()
|
||||
alloc.restoreClientID()
|
||||
alloc.restoreMaxQuotaID()
|
||||
}
|
||||
|
||||
func (alloc *IDAllocator) restoreClientID() {
|
||||
|
||||
@ -109,6 +109,12 @@ func (mqMgr *MasterQuotaManager) updateQuota(req *proto.UpdateMasterQuotaReuqest
|
||||
return
|
||||
}
|
||||
|
||||
if quotaInfo.RootInode != req.Inode {
|
||||
log.LogErrorf("vol [%v] update quota inode [%v] is not match.", mqMgr.vol.Name, req.Inode)
|
||||
err = errors.New("quota inode is not match.")
|
||||
return
|
||||
}
|
||||
|
||||
quotaInfo.MaxFiles = req.MaxFiles
|
||||
quotaInfo.MaxBytes = req.MaxBytes
|
||||
|
||||
@ -285,12 +291,14 @@ func (mqMgr *MasterQuotaManager) quotaUpdate(report *proto.MetaPartitionReport)
|
||||
defer mqMgr.Unlock()
|
||||
|
||||
mpId := report.PartitionID
|
||||
mqMgr.MpQuotaInfoMap[mpId] = report.QuotaReportInfos
|
||||
|
||||
log.LogDebugf("[quotaUpdate] mpId [%v] QuotaReportInfos [%v] leader [%v]", mpId, report.QuotaReportInfos, report.IsLeader)
|
||||
if !report.IsLeader {
|
||||
return
|
||||
}
|
||||
|
||||
mqMgr.MpQuotaInfoMap[mpId] = report.QuotaReportInfos
|
||||
|
||||
for _, quotaInfo = range mqMgr.IdQuotaInfoMap {
|
||||
quotaInfo.UsedInfo.UsedFiles = 0
|
||||
quotaInfo.UsedInfo.UsedBytes = 0
|
||||
|
||||
@ -102,7 +102,7 @@ func unmarshalTaskResponse(task *proto.AdminTask) (err error) {
|
||||
response = &proto.MetaPartitionDecommissionResponse{}
|
||||
case proto.OpMasterSetInodeQuota:
|
||||
response = &proto.BatchSetMetaserverQuotaResponse{}
|
||||
case proto.OpMetaBatchDeleteInodeQuota:
|
||||
case proto.OpMasterDeleteInodeQuota:
|
||||
response = &proto.BatchDeleteMetaserverQuotaResponse{}
|
||||
default:
|
||||
log.LogError(fmt.Sprintf("unknown operate code(%v)", task.OpCode))
|
||||
|
||||
@ -1273,7 +1273,7 @@ func (vol *Vol) initQuotaManager(c *Cluster) (err error) {
|
||||
log.LogErrorf("initQuotaManager Unmarshal fail err [%v]", err)
|
||||
return err
|
||||
}
|
||||
|
||||
log.LogDebugf("loadQuota info [%v]", quotaInfo)
|
||||
if vol.Name != quotaInfo.VolName {
|
||||
panic("vol name do not match")
|
||||
}
|
||||
|
||||
@ -1924,6 +1924,7 @@ func (m *metadataManager) OpMasterSetInodeQuota(conn net.Conn, p *Packet, remote
|
||||
adminTask := &proto.AdminTask{
|
||||
Request: req,
|
||||
}
|
||||
|
||||
log.LogInfof("[OpMasterSetInodeQuota] req [%v] start.", req)
|
||||
decode := json.NewDecoder(bytes.NewBuffer(p.Data))
|
||||
decode.UseNumber()
|
||||
@ -1946,6 +1947,9 @@ func (m *metadataManager) OpMasterSetInodeQuota(conn net.Conn, p *Packet, remote
|
||||
if !m.serveProxy(conn, mp, p) {
|
||||
return
|
||||
}
|
||||
|
||||
m.responseAckOKToMaster(conn, p)
|
||||
|
||||
resp := &proto.BatchSetMetaserverQuotaResponse{
|
||||
PartitionId: req.PartitionId,
|
||||
QuotaId: req.QuotaId,
|
||||
@ -1964,6 +1968,7 @@ func (m *metadataManager) OpMasterDeleteInodeQuota(conn net.Conn, p *Packet, rem
|
||||
adminTask := &proto.AdminTask{
|
||||
Request: req,
|
||||
}
|
||||
|
||||
log.LogInfof("[OpMasterDeleteInodeQuota] req [%v] start.", req)
|
||||
decode := json.NewDecoder(bytes.NewBuffer(p.Data))
|
||||
decode.UseNumber()
|
||||
@ -1984,6 +1989,9 @@ func (m *metadataManager) OpMasterDeleteInodeQuota(conn net.Conn, p *Packet, rem
|
||||
if !m.serveProxy(conn, mp, p) {
|
||||
return
|
||||
}
|
||||
|
||||
m.responseAckOKToMaster(conn, p)
|
||||
|
||||
resp := &proto.BatchDeleteMetaserverQuotaResponse{
|
||||
PartitionId: req.PartitionId,
|
||||
QuotaId: req.QuotaId,
|
||||
@ -1992,7 +2000,6 @@ func (m *metadataManager) OpMasterDeleteInodeQuota(conn net.Conn, p *Packet, rem
|
||||
adminTask.Response = resp
|
||||
adminTask.Request = nil
|
||||
_ = m.respondToMaster(adminTask)
|
||||
|
||||
log.LogInfof("[OpMasterDeleteInodeQuota] req [%v] resp [%v] success.", req, resp)
|
||||
return err
|
||||
}
|
||||
|
||||
@ -347,9 +347,9 @@ func (mp *metaPartition) statisticExtendByLoad(extend *Extend) {
|
||||
value, isFind := mqMgr.statisticBase.Load(quotaId)
|
||||
if isFind {
|
||||
baseInfo = value.(proto.QuotaUsedInfo)
|
||||
baseInfo.UsedBytes += int64(ino.Size)
|
||||
baseInfo.UsedFiles += 1
|
||||
}
|
||||
baseInfo.UsedBytes += int64(ino.Size)
|
||||
baseInfo.UsedFiles += 1
|
||||
mqMgr.statisticBase.Store(quotaId, baseInfo)
|
||||
log.LogDebugf("[statisticExtendByLoad] quotaId [%v] baseInfo [%v]", quotaId, baseInfo)
|
||||
}
|
||||
|
||||
@ -597,6 +597,17 @@ func (mw *MetaWrapper) delete_ll(parentID uint64, name string, isDir bool) (*pro
|
||||
if info == nil || info.Nlink > 2 {
|
||||
return nil, syscall.ENOTEMPTY
|
||||
}
|
||||
quotaInfos, err := mw.GetInodeQuota_ll(inode)
|
||||
if err != nil {
|
||||
log.LogErrorf("get inode [%v] quota failed [%v]", inode, err)
|
||||
return nil, syscall.ENOENT
|
||||
}
|
||||
for _, info := range quotaInfos {
|
||||
if info.RootInode == inode {
|
||||
log.LogErrorf("can not remove quota Root inode equal inode [%v]", inode)
|
||||
return nil, syscall.EACCES
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
status, inode, err = mw.ddelete(parentMP, parentID, name)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user