cubefs

Форк
0
/
inode.go 
1862 строки · 53.7 Кб
1
// Copyright 2018 The CubeFS Authors.
2
//
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
6
//
7
//     http://www.apache.org/licenses/LICENSE-2.0
8
//
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.
14

15
package metanode
16

17
import (
18
	"bytes"
19
	"encoding/binary"
20
	"encoding/json"
21
	"fmt"
22
	"io"
23
	syslog "log"
24
	"math"
25
	"runtime/debug"
26
	"sync"
27
	"time"
28

29
	"github.com/cubefs/cubefs/proto"
30
	"github.com/cubefs/cubefs/util/log"
31
	"github.com/cubefs/cubefs/util/timeutil"
32
)
33

34
const (
35
	DeleteMarkFlag = 1 << 0
36
	InodeDelTop    = 1 << 1
37
)
38

39
var (
40
	// InodeV1Flag uint64 = 0x01
41
	V2EnableColdInodeFlag uint64 = 0x02
42
	V3EnableSnapInodeFlag uint64 = 0x04
43
)
44

45
// Inode wraps necessary properties of `Inode` information in the file system.
46
// Marshal exporterKey:
47
//  +-------+-------+
48
//  | item  | Inode |
49
//  +-------+-------+
50
//  | bytes |   8   |
51
//  +-------+-------+
52
// Marshal value:
53
//  +-------+------+------+-----+----+----+----+--------+------------------+
54
//  | item  | Type | Size | Gen | CT | AT | MT | ExtLen | MarshaledExtents |
55
//  +-------+------+------+-----+----+----+----+--------+------------------+
56
//  | bytes |  4   |  8   |  8  | 8  | 8  | 8  |   4    |      ExtLen      |
57
//  +-------+------+------+-----+----+----+----+--------+------------------+
58
// Marshal entity:
59
//  +-------+-----------+--------------+-----------+--------------+
60
//  | item  | KeyLength | MarshaledKey | ValLength | MarshaledVal |
61
//  +-------+-----------+--------------+-----------+--------------+
62
//  | bytes |     4     |   KeyLength  |     4     |   ValLength  |
63
//  +-------+-----------+--------------+-----------+--------------+
64

65
type InodeMultiSnap struct {
66
	verSeq        uint64 // latest version be create or modified
67
	multiVersions InodeBatch
68
	ekRefMap      *sync.Map
69
}
70

71
type Inode struct {
72
	sync.RWMutex
73
	Inode      uint64 // Inode ID
74
	Type       uint32
75
	Uid        uint32
76
	Gid        uint32
77
	Size       uint64
78
	Generation uint64
79
	CreateTime int64
80
	AccessTime int64
81
	ModifyTime int64
82
	LinkTarget []byte // SymLink target name
83
	NLink      uint32 // NodeLink counts
84
	Flag       int32
85
	Reserved   uint64 // reserved space
86
	// Extents    *ExtentsTree
87
	Extents    *SortedExtents
88
	ObjExtents *SortedObjExtents
89
	// Snapshot
90
	multiSnap *InodeMultiSnap
91
}
92

93
func (i *Inode) GetMultiVerString() string {
94
	if i.multiSnap == nil {
95
		return "nil"
96
	}
97

98
	return fmt.Sprintf("%v", i.multiSnap.multiVersions)
99
}
100

101
func (i *Inode) RangeMultiVer(visitor func(idx int, info *Inode) bool) {
102
	if i.multiSnap == nil {
103
		return
104
	}
105
	for k, v := range i.multiSnap.multiVersions {
106
		if !visitor(k, v) {
107
			break
108
		}
109
	}
110
}
111

112
func isInitSnapVer(seq uint64) bool {
113
	return seq == math.MaxUint64
114
}
115

116
func NewMultiSnap(seq uint64) *InodeMultiSnap {
117
	return &InodeMultiSnap{
118
		verSeq: seq,
119
	}
120
}
121

122
func (i *Inode) verUpdate(seq uint64) {
123
	if seq == 0 && i.multiSnap == nil {
124
		return
125
	}
126
	if i.multiSnap == nil {
127
		i.multiSnap = NewMultiSnap(seq)
128
	} else {
129
		i.multiSnap.verSeq = seq
130
	}
131
}
132

133
func (i *Inode) setVerNoCheck(seq uint64) {
134
	i.verUpdate(seq)
135
}
136

137
func (i *Inode) setVer(seq uint64) {
138
	if i.getVer() > seq {
139
		syslog.Println(fmt.Sprintf("inode[%v] old seq [%v] cann't use seq [%v]", i.getVer(), seq, string(debug.Stack())))
140
		log.LogFatalf("inode[%v] old seq [%v] cann't use seq [%v] stack %v", i.Inode, i.getVer(), seq, string(debug.Stack()))
141
	}
142
	i.verUpdate(seq)
143
}
144

145
func (i *Inode) insertEkRefMap(mpId uint64, ek *proto.ExtentKey) {
146
	if i.multiSnap == nil {
147
		i.multiSnap = NewMultiSnap(i.getVer())
148
	}
149
	if i.multiSnap.ekRefMap == nil {
150
		i.multiSnap.ekRefMap = new(sync.Map)
151
	}
152
	storeEkSplit(mpId, i.Inode, i.multiSnap.ekRefMap, ek)
153
}
154

155
func (i *Inode) isEkInRefMap(mpId uint64, ek *proto.ExtentKey) (ok bool) {
156
	if i.multiSnap == nil {
157
		return
158
	}
159
	if i.multiSnap.ekRefMap == nil {
160
		log.LogErrorf("[storeEkSplit] mpId [%v] inodeID %v ekRef nil", mpId, i.Inode)
161
		return
162
	}
163
	log.LogDebugf("[storeEkSplit] mpId [%v] inode[%v] mp[%v] extent id[%v] ek [%v]", mpId, i.Inode, ek.PartitionId, ek.ExtentId, ek)
164
	id := ek.PartitionId<<32 | ek.ExtentId
165
	_, ok = i.multiSnap.ekRefMap.Load(id)
166
	return
167
}
168

169
func (i *Inode) getVer() uint64 {
170
	if i.multiSnap == nil {
171
		return 0
172
	}
173
	return i.multiSnap.verSeq
174
}
175

176
func (i *Inode) getLayerLen() int {
177
	if i.multiSnap == nil {
178
		return 0
179
	}
180
	return len(i.multiSnap.multiVersions)
181
}
182

183
func (i *Inode) getLayerVer(layer int) uint64 {
184
	if i.multiSnap == nil {
185
		log.LogErrorf("getLayerVer. inode[%v] multi snap nil", i.Inode)
186
		return 0
187
	}
188

189
	if layer > i.getLayerLen()-1 {
190
		log.LogErrorf("getLayerVer. inode[%v] layer %v not exist, len %v", i.Inode, layer, i.getLayerLen())
191
		return 0
192
	}
193
	if i.multiSnap.multiVersions[layer] == nil {
194
		log.LogErrorf("getLayerVer. inode[%v] layer %v nil", i.Inode, layer)
195
		return 0
196
	}
197
	return i.multiSnap.multiVersions[layer].getVer()
198
}
199

200
func (i *Inode) isEmptyVerList() bool {
201
	return i.getLayerLen() == 0
202
}
203

204
func (i *Inode) isTailIndexInList(id int) bool {
205
	return id == i.getLayerLen()-1
206
}
207

208
func (i *Inode) getTailVerInList() (verSeq uint64, found bool) {
209
	mLen := i.getLayerLen()
210
	if mLen > 0 {
211
		return i.getLayerVer(mLen - 1), true
212
	}
213
	return 0, false
214
}
215

216
// freelist clean inode get all exist extents info, deal special case for split key
217
func (inode *Inode) GetAllExtsOfflineInode(mpID uint64) (extInfo map[uint64][]*proto.ExtentKey) {
218
	log.LogDebugf("deleteMarkedInodes. GetAllExtsOfflineInode.mp[%v] inode[%v] inode.Extents: %v, ino verList: %v",
219
		mpID, inode.Inode, inode.Extents, inode.GetMultiVerString())
220

221
	extInfo = make(map[uint64][]*proto.ExtentKey)
222

223
	if inode.getLayerLen() > 0 {
224
		log.LogWarnf("deleteMarkedInodes. GetAllExtsOfflineInode.mp[%v] inode[%v] verlist len %v should not drop",
225
			mpID, inode.Inode, inode.getLayerLen())
226
	}
227

228
	for i := 0; i < inode.getLayerLen()+1; i++ {
229
		dIno := inode
230
		if i > 0 {
231
			dIno = inode.multiSnap.multiVersions[i-1]
232
		}
233
		log.LogDebugf("deleteMarkedInodes. GetAllExtsOfflineInode.mp[%v] inode[%v] dino[%v]", mpID, inode.Inode, dIno)
234
		dIno.Extents.Range(func(_ int, ek proto.ExtentKey) bool {
235
			if ek.IsSplit() {
236
				var (
237
					dOK  bool
238
					last bool
239
				)
240
				log.LogDebugf("deleteMarkedInodes DecSplitEk mpID %v inode[%v]", mpID, inode.Inode)
241
				if dOK, last = dIno.DecSplitEk(mpID, &ek); !dOK {
242
					return false
243
				}
244
				if !last {
245
					log.LogDebugf("deleteMarkedInodes. GetAllExtsOfflineInode.mp[%v] inode[%v] ek [%v] be removed", mpID, inode.Inode, ek)
246
					return true
247
				}
248

249
				log.LogDebugf("deleteMarkedInodes. GetAllExtsOfflineInode.mp[%v] inode[%v] ek [%v] be removed", mpID, inode.Inode, ek)
250
			}
251
			extInfo[ek.PartitionId] = append(extInfo[ek.PartitionId], &ek)
252
			// NOTE: unnecessary to set ext
253
			log.LogWritef("GetAllExtsOfflineInode. mp[%v] ino(%v) deleteExtent(%v)", mpID, inode.Inode, ek.String())
254
			return true
255
		})
256
		// NOTE: clear all extents in this layer
257
		dIno.Extents = NewSortedExtents()
258
	}
259
	return
260
}
261

262
type InodeBatch []*Inode
263

264
type TxInode struct {
265
	Inode  *Inode
266
	TxInfo *proto.TransactionInfo
267
}
268

269
func NewTxInode(ino uint64, t uint32, txInfo *proto.TransactionInfo) *TxInode {
270
	ti := &TxInode{
271
		Inode:  NewInode(ino, t),
272
		TxInfo: txInfo,
273
	}
274
	return ti
275
}
276

277
func (ti *TxInode) Marshal() (result []byte, err error) {
278
	buff := bytes.NewBuffer(make([]byte, 0))
279

280
	bs, err := ti.Inode.Marshal()
281
	if err != nil {
282
		return nil, err
283
	}
284
	if err = binary.Write(buff, binary.BigEndian, uint32(len(bs))); err != nil {
285
		return nil, err
286
	}
287
	if _, err := buff.Write(bs); err != nil {
288
		return nil, err
289
	}
290

291
	bs, err = ti.TxInfo.Marshal()
292
	if err != nil {
293
		return nil, err
294
	}
295
	if err = binary.Write(buff, binary.BigEndian, uint32(len(bs))); err != nil {
296
		return nil, err
297
	}
298
	if _, err := buff.Write(bs); err != nil {
299
		return nil, err
300
	}
301
	result = buff.Bytes()
302
	return
303
}
304

305
func (ti *TxInode) Unmarshal(raw []byte) (err error) {
306
	buff := bytes.NewBuffer(raw)
307

308
	var dataLen uint32
309
	if err = binary.Read(buff, binary.BigEndian, &dataLen); err != nil {
310
		return
311
	}
312
	data := make([]byte, int(dataLen))
313
	if _, err = buff.Read(data); err != nil {
314
		return
315
	}
316
	ino := NewInode(0, 0)
317
	if err = ino.Unmarshal(data); err != nil {
318
		return
319
	}
320
	ti.Inode = ino
321

322
	if err = binary.Read(buff, binary.BigEndian, &dataLen); err != nil {
323
		return
324
	}
325
	data = make([]byte, int(dataLen))
326
	if _, err = buff.Read(data); err != nil {
327
		return
328
	}
329
	txInfo := proto.NewTransactionInfo(0, proto.TxTypeUndefined)
330
	if err = txInfo.Unmarshal(data); err != nil {
331
		return
332
	}
333
	ti.TxInfo = txInfo
334
	return
335
}
336

337
func (i *InodeBatch) Clone() InodeBatch {
338
	var rB []*Inode
339
	for _, inode := range []*Inode(*i) {
340
		rB = append(rB, inode.Copy().(*Inode))
341
	}
342
	return rB
343
}
344

345
func (ino *Inode) getAllInodesInfo() (rsp []proto.InodeInfo) {
346
	ino.RLock()
347
	defer ino.RUnlock()
348

349
	ino.RangeMultiVer(func(idx int, info *Inode) bool {
350
		rspInodeInfo := &proto.InodeInfo{}
351
		replyInfoNoCheck(rspInodeInfo, info)
352
		rsp = append(rsp, *rspInodeInfo)
353
		return true
354
	})
355
	return
356
}
357

358
func (ino *Inode) getAllLayerEks() (rsp []proto.LayerInfo) {
359
	ino.RLock()
360
	defer ino.RUnlock()
361
	rspInodeInfo := &proto.InodeInfo{}
362
	replyInfoNoCheck(rspInodeInfo, ino)
363

364
	layerInfo := proto.LayerInfo{
365
		LayerIdx: 0,
366
		Info:     rspInodeInfo,
367
		Eks:      ino.Extents.eks,
368
	}
369
	rsp = append(rsp, layerInfo)
370

371
	ino.RangeMultiVer(func(idx int, info *Inode) bool {
372
		rspInodeInfo := &proto.InodeInfo{}
373
		replyInfo(rspInodeInfo, info, nil)
374
		layerInfo := proto.LayerInfo{
375
			LayerIdx: uint32(idx + 1),
376
			Info:     rspInodeInfo,
377
			Eks:      info.Extents.eks,
378
		}
379
		rsp = append(rsp, layerInfo)
380
		return true
381
	})
382

383
	return
384
}
385

386
// String returns the string format of the inode.
387
func (i *Inode) String() string {
388
	i.RLock()
389
	defer i.RUnlock()
390
	buff := bytes.NewBuffer(nil)
391
	buff.Grow(128)
392
	buff.WriteString("Inode{")
393
	buff.WriteString(fmt.Sprintf("Inode[%d]", i.Inode))
394
	buff.WriteString(fmt.Sprintf("Type[%d]", i.Type))
395
	buff.WriteString(fmt.Sprintf("Uid[%d]", i.Uid))
396
	buff.WriteString(fmt.Sprintf("Gid[%d]", i.Gid))
397
	buff.WriteString(fmt.Sprintf("Size[%d]", i.Size))
398
	buff.WriteString(fmt.Sprintf("Gen[%d]", i.Generation))
399
	buff.WriteString(fmt.Sprintf("CT[%d]", i.CreateTime))
400
	buff.WriteString(fmt.Sprintf("AT[%d]", i.AccessTime))
401
	buff.WriteString(fmt.Sprintf("MT[%d]", i.ModifyTime))
402
	buff.WriteString(fmt.Sprintf("LinkT[%s]", i.LinkTarget))
403
	buff.WriteString(fmt.Sprintf("NLink[%d]", i.NLink))
404
	buff.WriteString(fmt.Sprintf("Flag[%d]", i.Flag))
405
	buff.WriteString(fmt.Sprintf("Reserved[%d]", i.Reserved))
406
	buff.WriteString(fmt.Sprintf("Extents[%s]", i.Extents))
407
	buff.WriteString(fmt.Sprintf("ObjExtents[%s]", i.ObjExtents))
408
	buff.WriteString(fmt.Sprintf("verSeq[%v]", i.getVer()))
409
	buff.WriteString(fmt.Sprintf("multiSnap.multiVersions.len[%v]", i.getLayerLen()))
410
	buff.WriteString("}")
411
	return buff.String()
412
}
413

414
// NewInode returns a new Inode instance with specified Inode ID, name and type.
415
// The AccessTime and ModifyTime will be set to the current time.
416
func NewInode(ino uint64, t uint32) *Inode {
417
	ts := timeutil.GetCurrentTimeUnix()
418
	i := &Inode{
419
		Inode:      ino,
420
		Type:       t,
421
		Generation: 1,
422
		CreateTime: ts,
423
		AccessTime: ts,
424
		ModifyTime: ts,
425
		NLink:      1,
426
		Extents:    NewSortedExtents(),
427
		ObjExtents: NewSortedObjExtents(),
428
		multiSnap:  nil,
429
	}
430
	if proto.IsDir(t) {
431
		i.NLink = 2
432
	}
433
	return i
434
}
435

436
// Less tests whether the current Inode item is less than the given one.
437
// This method is necessary fot B-Tree item implementation.
438
func (i *Inode) Less(than BtreeItem) bool {
439
	ino, ok := than.(*Inode)
440
	return ok && i.Inode < ino.Inode
441
}
442

443
// Copy returns a copy of the inode.
444
func (i *Inode) Copy() BtreeItem {
445
	newIno := NewInode(i.Inode, i.Type)
446
	i.RLock()
447
	newIno.Uid = i.Uid
448
	newIno.Gid = i.Gid
449
	newIno.Size = i.Size
450
	newIno.Generation = i.Generation
451
	newIno.CreateTime = i.CreateTime
452
	newIno.ModifyTime = i.ModifyTime
453
	newIno.AccessTime = i.AccessTime
454
	if size := len(i.LinkTarget); size > 0 {
455
		newIno.LinkTarget = make([]byte, size)
456
		copy(newIno.LinkTarget, i.LinkTarget)
457
	}
458
	newIno.NLink = i.NLink
459
	newIno.Flag = i.Flag
460
	newIno.Reserved = i.Reserved
461
	newIno.Extents = i.Extents.Clone()
462
	newIno.ObjExtents = i.ObjExtents.Clone()
463
	if i.multiSnap != nil {
464
		newIno.multiSnap = &InodeMultiSnap{
465
			verSeq:        i.getVer(),
466
			multiVersions: i.multiSnap.multiVersions.Clone(),
467
			ekRefMap:      i.multiSnap.ekRefMap,
468
		}
469
	}
470
	i.RUnlock()
471
	return newIno
472
}
473

474
func (i *Inode) CopyInodeOnly(cInode *Inode) *Inode {
475
	tmpInode := cInode.CopyDirectly().(*Inode)
476
	tmpInode.Extents = i.Extents
477
	tmpInode.ObjExtents = i.ObjExtents
478
	tmpInode.multiSnap = i.multiSnap
479
	return tmpInode
480
}
481

482
func (i *Inode) CopyDirectly() BtreeItem {
483
	newIno := NewInode(i.Inode, i.Type)
484

485
	newIno.Uid = i.Uid
486
	newIno.Gid = i.Gid
487
	newIno.Size = i.Size
488
	newIno.Generation = i.Generation
489
	newIno.CreateTime = i.CreateTime
490
	newIno.ModifyTime = i.ModifyTime
491
	newIno.AccessTime = i.AccessTime
492
	if size := len(i.LinkTarget); size > 0 {
493
		newIno.LinkTarget = make([]byte, size)
494
		copy(newIno.LinkTarget, i.LinkTarget)
495
	}
496
	newIno.NLink = i.NLink
497
	newIno.Flag = i.Flag
498
	newIno.Reserved = i.Reserved
499
	newIno.Extents = i.Extents.Clone()
500
	newIno.ObjExtents = i.ObjExtents.Clone()
501

502
	return newIno
503
}
504

505
// MarshalToJSON is the wrapper of json.Marshal.
506
func (i *Inode) MarshalToJSON() ([]byte, error) {
507
	i.RLock()
508
	defer i.RUnlock()
509
	return json.Marshal(i)
510
}
511

512
// Marshal marshals the inode into a byte array.
513
func (i *Inode) Marshal() (result []byte, err error) {
514
	keyBytes := i.MarshalKey()
515
	valBytes := i.MarshalValue()
516
	keyLen := uint32(len(keyBytes))
517
	valLen := uint32(len(valBytes))
518
	buff := bytes.NewBuffer(make([]byte, 0, 128))
519
	if err = binary.Write(buff, binary.BigEndian, keyLen); err != nil {
520
		return
521
	}
522
	if _, err = buff.Write(keyBytes); err != nil {
523
		return
524
	}
525
	if err = binary.Write(buff, binary.BigEndian, valLen); err != nil {
526
		return
527
	}
528
	if _, err = buff.Write(valBytes); err != nil {
529
		return
530
	}
531
	result = buff.Bytes()
532
	return
533
}
534

535
// Unmarshal unmarshals the inode.
536
func (i *Inode) Unmarshal(raw []byte) (err error) {
537
	var (
538
		keyLen uint32
539
		valLen uint32
540
	)
541
	buff := bytes.NewBuffer(raw)
542
	if err = binary.Read(buff, binary.BigEndian, &keyLen); err != nil {
543
		return
544
	}
545
	keyBytes := make([]byte, keyLen)
546
	if _, err = buff.Read(keyBytes); err != nil {
547
		return
548
	}
549
	if err = i.UnmarshalKey(keyBytes); err != nil {
550
		return
551
	}
552
	if err = binary.Read(buff, binary.BigEndian, &valLen); err != nil {
553
		return
554
	}
555
	valBytes := make([]byte, valLen)
556
	if _, err = buff.Read(valBytes); err != nil {
557
		return
558
	}
559
	err = i.UnmarshalValue(valBytes)
560
	return
561
}
562

563
// Marshal marshals the inodeBatch into a byte array.
564
func (i InodeBatch) Marshal() ([]byte, error) {
565
	buff := bytes.NewBuffer(make([]byte, 0))
566
	if err := binary.Write(buff, binary.BigEndian, uint32(len(i))); err != nil {
567
		return nil, err
568
	}
569
	for _, inode := range i {
570
		bs, err := inode.Marshal()
571
		if err != nil {
572
			return nil, err
573
		}
574
		if err = binary.Write(buff, binary.BigEndian, uint32(len(bs))); err != nil {
575
			return nil, err
576
		}
577
		if _, err := buff.Write(bs); err != nil {
578
			return nil, err
579
		}
580
	}
581
	return buff.Bytes(), nil
582
}
583

584
// Unmarshal unmarshals the inodeBatch.
585
func InodeBatchUnmarshal(raw []byte) (InodeBatch, error) {
586
	buff := bytes.NewBuffer(raw)
587
	var batchLen uint32
588
	if err := binary.Read(buff, binary.BigEndian, &batchLen); err != nil {
589
		return nil, err
590
	}
591

592
	result := make(InodeBatch, 0, int(batchLen))
593

594
	var dataLen uint32
595
	for j := 0; j < int(batchLen); j++ {
596
		if err := binary.Read(buff, binary.BigEndian, &dataLen); err != nil {
597
			return nil, err
598
		}
599
		data := make([]byte, int(dataLen))
600
		if _, err := buff.Read(data); err != nil {
601
			return nil, err
602
		}
603
		ino := NewInode(0, 0)
604
		if err := ino.Unmarshal(data); err != nil {
605
			return nil, err
606
		}
607
		result = append(result, ino)
608
	}
609

610
	return result, nil
611
}
612

613
// MarshalKey marshals the exporterKey to bytes.
614
func (i *Inode) MarshalKey() (k []byte) {
615
	k = make([]byte, 8)
616
	binary.BigEndian.PutUint64(k, i.Inode)
617
	return
618
}
619

620
// UnmarshalKey unmarshals the exporterKey from bytes.
621
func (i *Inode) UnmarshalKey(k []byte) (err error) {
622
	i.Inode = binary.BigEndian.Uint64(k)
623
	return
624
}
625

626
// MarshalValue marshals the value to bytes.
627
func (i *Inode) MarshalInodeValue(buff *bytes.Buffer) {
628
	var err error
629
	if err = binary.Write(buff, binary.BigEndian, &i.Type); err != nil {
630
		panic(err)
631
	}
632
	if err = binary.Write(buff, binary.BigEndian, &i.Uid); err != nil {
633
		panic(err)
634
	}
635
	if err = binary.Write(buff, binary.BigEndian, &i.Gid); err != nil {
636
		panic(err)
637
	}
638
	if err = binary.Write(buff, binary.BigEndian, &i.Size); err != nil {
639
		panic(err)
640
	}
641
	if err = binary.Write(buff, binary.BigEndian, &i.Generation); err != nil {
642
		panic(err)
643
	}
644
	if err = binary.Write(buff, binary.BigEndian, &i.CreateTime); err != nil {
645
		panic(err)
646
	}
647
	if err = binary.Write(buff, binary.BigEndian, &i.AccessTime); err != nil {
648
		panic(err)
649
	}
650
	if err = binary.Write(buff, binary.BigEndian, &i.ModifyTime); err != nil {
651
		panic(err)
652
	}
653
	// write SymLink
654
	symSize := uint32(len(i.LinkTarget))
655
	if err = binary.Write(buff, binary.BigEndian, &symSize); err != nil {
656
		panic(err)
657
	}
658
	if _, err = buff.Write(i.LinkTarget); err != nil {
659
		panic(err)
660
	}
661

662
	if err = binary.Write(buff, binary.BigEndian, &i.NLink); err != nil {
663
		panic(err)
664
	}
665
	if err = binary.Write(buff, binary.BigEndian, &i.Flag); err != nil {
666
		panic(err)
667
	}
668
	if i.ObjExtents != nil && len(i.ObjExtents.eks) > 0 {
669
		i.Reserved |= V2EnableColdInodeFlag
670
	}
671
	i.Reserved |= V3EnableSnapInodeFlag
672

673
	// log.LogInfof("action[MarshalInodeValue] inode[%v] Reserved %v", i.Inode, i.Reserved)
674
	if err = binary.Write(buff, binary.BigEndian, &i.Reserved); err != nil {
675
		panic(err)
676
	}
677

678
	// marshal ExtentsKey
679
	extData, err := i.Extents.MarshalBinary(true)
680
	if err != nil {
681
		panic(err)
682
	}
683
	if err = binary.Write(buff, binary.BigEndian, uint32(len(extData))); err != nil {
684
		panic(err)
685
	}
686
	if _, err = buff.Write(extData); err != nil {
687
		panic(err)
688
	}
689

690
	if i.Reserved&V2EnableColdInodeFlag > 0 {
691
		// marshal ObjExtentsKey
692
		objExtData, err := i.ObjExtents.MarshalBinary()
693
		if err != nil {
694
			panic(err)
695
		}
696
		if err = binary.Write(buff, binary.BigEndian, uint32(len(objExtData))); err != nil {
697
			panic(err)
698
		}
699
		if _, err = buff.Write(objExtData); err != nil {
700
			panic(err)
701
		}
702
	}
703

704
	if err = binary.Write(buff, binary.BigEndian, i.getVer()); err != nil {
705
		panic(err)
706
	}
707

708
	return
709
}
710

711
// MarshalValue marshals the value to bytes.
712
func (i *Inode) MarshalValue() (val []byte) {
713
	var err error
714
	buff := bytes.NewBuffer(make([]byte, 0, 128))
715
	buff.Grow(64)
716

717
	i.RLock()
718
	i.MarshalInodeValue(buff)
719
	if i.getLayerLen() > 0 && i.getVer() == 0 {
720
		log.LogFatalf("action[MarshalValue] inode[%v] current verseq [%v], hist len (%v) stack(%v)", i.Inode, i.getVer(), i.getLayerLen(), string(debug.Stack()))
721
	}
722
	if err = binary.Write(buff, binary.BigEndian, int32(i.getLayerLen())); err != nil {
723
		i.RUnlock()
724
		panic(err)
725
	}
726

727
	if i.multiSnap != nil {
728
		for _, ino := range i.multiSnap.multiVersions {
729
			ino.MarshalInodeValue(buff)
730
		}
731
	}
732

733
	val = buff.Bytes()
734
	i.RUnlock()
735
	return
736
}
737

738
// UnmarshalValue unmarshals the value from bytes.
739
func (i *Inode) UnmarshalInodeValue(buff *bytes.Buffer) (err error) {
740
	if err = binary.Read(buff, binary.BigEndian, &i.Type); err != nil {
741
		return
742
	}
743
	if err = binary.Read(buff, binary.BigEndian, &i.Uid); err != nil {
744
		return
745
	}
746
	if err = binary.Read(buff, binary.BigEndian, &i.Gid); err != nil {
747
		return
748
	}
749
	if err = binary.Read(buff, binary.BigEndian, &i.Size); err != nil {
750
		return
751
	}
752
	if err = binary.Read(buff, binary.BigEndian, &i.Generation); err != nil {
753
		return
754
	}
755
	if err = binary.Read(buff, binary.BigEndian, &i.CreateTime); err != nil {
756
		return
757
	}
758
	if err = binary.Read(buff, binary.BigEndian, &i.AccessTime); err != nil {
759
		return
760
	}
761
	if err = binary.Read(buff, binary.BigEndian, &i.ModifyTime); err != nil {
762
		return
763
	}
764
	// read symLink
765
	symSize := uint32(0)
766
	if err = binary.Read(buff, binary.BigEndian, &symSize); err != nil {
767
		return
768
	}
769
	if symSize > 0 {
770
		i.LinkTarget = make([]byte, symSize)
771
		if _, err = io.ReadFull(buff, i.LinkTarget); err != nil {
772
			return
773
		}
774
	}
775

776
	if err = binary.Read(buff, binary.BigEndian, &i.NLink); err != nil {
777
		return
778
	}
779
	if err = binary.Read(buff, binary.BigEndian, &i.Flag); err != nil {
780
		return
781
	}
782
	if err = binary.Read(buff, binary.BigEndian, &i.Reserved); err != nil {
783
		return
784
	}
785

786
	// unmarshal ExtentsKey
787
	if i.Extents == nil {
788
		i.Extents = NewSortedExtents()
789
	}
790
	if i.ObjExtents == nil {
791
		i.ObjExtents = NewSortedObjExtents()
792
	}
793

794
	v3 := i.Reserved&V3EnableSnapInodeFlag > 0
795
	v2 := i.Reserved&V2EnableColdInodeFlag > 0
796

797
	if v2 || v3 {
798
		extSize := uint32(0)
799
		if err = binary.Read(buff, binary.BigEndian, &extSize); err != nil {
800
			return
801
		}
802
		if extSize > 0 {
803
			extBytes := make([]byte, extSize)
804
			if _, err = io.ReadFull(buff, extBytes); err != nil {
805
				return
806
			}
807
			var ekRef *sync.Map
808
			if err, ekRef = i.Extents.UnmarshalBinary(extBytes, v3); err != nil {
809
				return
810
			}
811
			// log.LogDebugf("inode[%v] ekRef %v", i.Inode, ekRef)
812
			if ekRef != nil {
813
				if i.multiSnap == nil {
814
					i.multiSnap = NewMultiSnap(0)
815
				}
816
				// log.LogDebugf("inode[%v] ekRef %v", i.Inode, ekRef)
817
				i.multiSnap.ekRefMap = ekRef
818
			}
819
		}
820
	} else {
821
		if err, _ = i.Extents.UnmarshalBinary(buff.Bytes(), false); err != nil {
822
			return
823
		}
824
		return
825
	}
826

827
	if v2 {
828
		// unmarshal ObjExtentsKey
829
		ObjExtSize := uint32(0)
830
		if err = binary.Read(buff, binary.BigEndian, &ObjExtSize); err != nil {
831
			return
832
		}
833
		if ObjExtSize > 0 {
834
			objExtBytes := make([]byte, ObjExtSize)
835
			if _, err = io.ReadFull(buff, objExtBytes); err != nil {
836
				return
837
			}
838
			if err = i.ObjExtents.UnmarshalBinary(objExtBytes); err != nil {
839
				return
840
			}
841
		}
842
	}
843

844
	if v3 {
845
		var seq uint64
846
		if err = binary.Read(buff, binary.BigEndian, &seq); err != nil {
847
			return
848
		}
849
		if seq != 0 {
850
			i.setVer(seq)
851
		}
852
	}
853

854
	return
855
}
856

857
func (i *Inode) GetSpaceSize() (extSize uint64) {
858
	if i.IsTempFile() {
859
		return
860
	}
861
	extSize += i.Extents.LayerSize()
862
	return
863
}
864

865
// UnmarshalValue unmarshals the value from bytes.
866
func (i *Inode) UnmarshalValue(val []byte) (err error) {
867
	buff := bytes.NewBuffer(val)
868
	i.UnmarshalInodeValue(buff)
869
	if i.Reserved&V3EnableSnapInodeFlag > 0 {
870
		var verCnt int32
871
		if err = binary.Read(buff, binary.BigEndian, &verCnt); err != nil {
872
			log.LogInfof("action[UnmarshalValue] err get ver cnt inode[%v] new seq [%v]", i.Inode, i.getVer())
873
			return
874
		}
875
		if verCnt > 0 && i.getVer() == 0 {
876
			err = fmt.Errorf("inode[%v] verCnt %v root ver [%v]", i.Inode, verCnt, i.getVer())
877
			log.LogFatalf("UnmarshalValue. %v", err)
878
			return
879
		}
880
		for idx := int32(0); idx < verCnt; idx++ {
881
			ino := &Inode{Inode: i.Inode}
882
			ino.UnmarshalInodeValue(buff)
883
			if ino.multiSnap != nil && ino.multiSnap.ekRefMap != nil {
884
				if i.multiSnap.ekRefMap == nil {
885
					i.multiSnap.ekRefMap = new(sync.Map)
886
				}
887
				// log.LogDebugf("UnmarshalValue. inode[%v] merge top layer multiSnap.ekRefMap with layer %v", i.Inode, idx)
888
				proto.MergeSplitKey(i.Inode, i.multiSnap.ekRefMap, ino.multiSnap.ekRefMap)
889
			}
890
			if i.multiSnap == nil {
891
				i.multiSnap = &InodeMultiSnap{}
892
			}
893
			// log.LogDebugf("action[UnmarshalValue] inode[%v] old seq [%v] hist len %v", ino.Inode, ino.getVer(), i.getLayerLen())
894
			i.multiSnap.multiVersions = append(i.multiSnap.multiVersions, ino)
895
		}
896
	}
897
	return
898
}
899

900
// AppendExtents append the extent to the btree.
901
func (i *Inode) AppendExtents(eks []proto.ExtentKey, ct int64, volType int) (delExtents []proto.ExtentKey) {
902
	if proto.IsCold(volType) {
903
		return
904
	}
905
	i.Lock()
906
	defer i.Unlock()
907
	for _, ek := range eks {
908
		delItems := i.Extents.Append(ek)
909
		size := i.Extents.Size()
910
		if i.Size < size {
911
			i.Size = size
912
		}
913
		delExtents = append(delExtents, delItems...)
914
	}
915
	i.Generation++
916
	i.ModifyTime = ct
917

918
	return
919
}
920

921
// AppendObjExtents append the extent to the btree.
922
func (i *Inode) AppendObjExtents(eks []proto.ObjExtentKey, ct int64) (err error) {
923
	i.Lock()
924
	defer i.Unlock()
925

926
	for _, ek := range eks {
927
		err = i.ObjExtents.Append(ek)
928
		if err != nil {
929
			return
930
		}
931
		size := i.ObjExtents.Size()
932
		if i.Size < size {
933
			i.Size = size
934
		}
935
	}
936
	i.Generation++
937
	i.ModifyTime = ct
938
	return
939
}
940

941
func (i *Inode) PrintAllVersionInfo() {
942
	if i.multiSnap == nil {
943
		return
944
	}
945
	log.LogInfof("action[PrintAllVersionInfo] inode[%v] verSeq [%v] hist len [%v]", i.Inode, i.getVer(), i.getLayerLen())
946
	for id, info := range i.multiSnap.multiVersions {
947
		log.LogInfof("action[PrintAllVersionInfo] layer [%v]  verSeq [%v] inode[%v]", id, info.getVer(), info)
948
	}
949
}
950

951
// clear snapshot extkey with releated verSeq
952
func (i *Inode) MultiLayerClearExtByVer(layer int, dVerSeq uint64) (delExtents []proto.ExtentKey) {
953
	var ino *Inode
954
	if layer == 0 {
955
		ino = i
956
	} else {
957
		ino = i.multiSnap.multiVersions[layer-1]
958
	}
959

960
	ino.Extents.Lock()
961
	defer ino.Extents.Unlock()
962

963
	for idx, ek := range ino.Extents.eks {
964
		if ek.GetSeq() > dVerSeq {
965
			delExtents = append(delExtents, ek)
966
			ino.Extents.eks = append(ino.Extents.eks[idx:], ino.Extents.eks[:idx+1]...)
967
		}
968
	}
969
	return
970
}
971

972
func (i *Inode) mergeExtentArr(mpId uint64, extentKeysLeft []proto.ExtentKey, extentKeysRight []proto.ExtentKey) []proto.ExtentKey {
973
	lCnt := len(extentKeysLeft)
974
	rCnt := len(extentKeysRight)
975
	sortMergedExts := make([]proto.ExtentKey, 0, lCnt+rCnt)
976
	lPos, rPos := 0, 0
977

978
	doWork := func(keyArr *[]proto.ExtentKey, pos int) {
979
		mLen := len(sortMergedExts)
980
		if mLen > 0 && sortMergedExts[mLen-1].IsSequenceWithSameSeq(&(*keyArr)[pos]) {
981
			sortMergedExts[mLen-1].Size += (*keyArr)[pos].Size
982
			log.LogDebugf("[mergeExtentArr] mpId[%v]. ek left %v right %v", mpId, sortMergedExts[mLen-1], (*keyArr)[pos])
983
			if !sortMergedExts[mLen-1].IsSplit() || !(*keyArr)[pos].IsSplit() {
984
				log.LogErrorf("[mergeExtentArr] mpId[%v] ino[%v] ek merge left %v right %v not all split", mpId, i.Inode, sortMergedExts[mLen-1], (*keyArr)[pos])
985
			}
986
			i.DecSplitEk(mpId, &(*keyArr)[pos])
987
		} else {
988
			sortMergedExts = append(sortMergedExts, (*keyArr)[pos])
989
		}
990
	}
991

992
	for {
993
		if lPos == lCnt {
994
			sortMergedExts = append(sortMergedExts, extentKeysRight[rPos:]...)
995
			break
996
		}
997
		if rPos == rCnt {
998
			sortMergedExts = append(sortMergedExts, extentKeysLeft[lPos:]...)
999
			break
1000
		}
1001

1002
		if extentKeysLeft[lPos].FileOffset < extentKeysRight[rPos].FileOffset {
1003
			doWork(&extentKeysLeft, lPos)
1004
			lPos++
1005
		} else {
1006
			doWork(&extentKeysRight, rPos)
1007
			rPos++
1008
		}
1009
	}
1010

1011
	return sortMergedExts
1012
}
1013

1014
// Restore ext info to older version or deleted if no right version
1015
// The list(multiSnap.multiVersions) contains all point of modification on inode, each ext must belong to one layer.
1016
// Once the layer be deleted is top layer ver be changed to upper layer, or else the ext belongs is exclusive and can be dropped
1017
func (i *Inode) RestoreExts2NextLayer(mpId uint64, delExtentsOrigin []proto.ExtentKey, curVer uint64, idx int) (delExtents []proto.ExtentKey, err error) {
1018
	log.LogInfof("action[RestoreMultiSnapExts] mpId [%v] curVer [%v] delExtents size [%v] hist len [%v]", mpId, curVer, len(delExtentsOrigin), i.getLayerLen())
1019
	// no version left.all old versions be deleted
1020
	if i.isEmptyVerList() {
1021
		log.LogWarnf("action[RestoreMultiSnapExts] mpId [%v] inode[%v] restore have no old version left", mpId, i.Inode)
1022
		return delExtentsOrigin, nil
1023
	}
1024
	lastSeq := i.multiSnap.multiVersions[idx].getVer()
1025
	specSnapExtent := make([]proto.ExtentKey, 0)
1026

1027
	for _, delExt := range delExtentsOrigin {
1028
		// curr deleting delExt with a seq larger than the next version's seq, it doesn't belong to any
1029
		// versions,so try to delete it
1030
		log.LogDebugf("action[RestoreMultiSnapExts] mpId [%v] inode[%v] ext split [%v] with seq[%v] gSeq[%v] try to del.the last seq [%v], ek details[%v]",
1031
			mpId, i.Inode, delExt.IsSplit(), delExt.GetSeq(), curVer, lastSeq, delExt)
1032
		if delExt.GetSeq() > lastSeq {
1033
			delExtents = append(delExtents, delExt)
1034
		} else {
1035
			log.LogInfof("action[RestoreMultiSnapExts] mpId [%v] inode[%v] move to level 1 delExt [%v] specSnapExtent size [%v]", mpId, i.Inode, delExt, len(specSnapExtent))
1036
			specSnapExtent = append(specSnapExtent, delExt)
1037
		}
1038
	}
1039
	if len(specSnapExtent) == 0 {
1040
		log.LogInfof("action[RestoreMultiSnapExts] mpId [%v] inode[%v] no need to move to level 1", mpId, i.Inode)
1041
		return
1042
	}
1043
	if len(specSnapExtent) > 0 && i.isEmptyVerList() {
1044
		err = fmt.Errorf("mpId [%v] inode[%v] error not found prev snapshot index", mpId, i.Inode)
1045
		log.LogErrorf("action[RestoreMultiSnapExts] mpId [%v] inode[%v] %v", mpId, i.Inode, err)
1046
		return
1047
	}
1048

1049
	i.multiSnap.multiVersions[idx].Extents.Lock()
1050
	i.multiSnap.multiVersions[idx].Extents.eks = i.mergeExtentArr(mpId, i.multiSnap.multiVersions[idx].Extents.eks, specSnapExtent)
1051
	i.multiSnap.multiVersions[idx].Extents.Unlock()
1052

1053
	return
1054
}
1055

1056
func (inode *Inode) unlinkTopLayer(mpId uint64, ino *Inode, mpVer uint64, verlist *proto.VolVersionInfoList) (ext2Del []proto.ExtentKey, doMore bool, status uint8) {
1057
	// if there's no snapshot itself, nor have snapshot after inode's ver then need unlink directly and make no snapshot
1058
	// just move to upper layer, the behavior looks like that the snapshot be dropped
1059
	log.LogDebugf("action[unlinkTopLayer] mpid [%v] mpver [%v] check if have snapshot depends on the deleitng ino[%v] (with no snapshot itself) found seq [%v], verlist %v",
1060
		mpId, mpVer, ino, inode.getVer(), verlist)
1061
	status = proto.OpOk
1062

1063
	delFunc := func() (done bool) {
1064
		if inode.NLink > 1 {
1065
			log.LogDebugf("action[unlinkTopLayer] inode[%v] be unlinked, file link is %v", ino.Inode, inode.NLink)
1066
			inode.DecNLink()
1067
			doMore = false
1068
			return true
1069
		}
1070
		// first layer need delete
1071
		var err error
1072
		if ext2Del, err = inode.RestoreExts2NextLayer(mpId, inode.Extents.eks, mpVer, 0); err != nil {
1073
			log.LogErrorf("action[getAndDelVerInList] ino[%v] RestoreMultiSnapExts split error %v", inode.Inode, err)
1074
			status = proto.OpNotExistErr
1075
			log.LogDebugf("action[unlinkTopLayer] mp[%v] iino[%v]", mpId, ino)
1076
			return
1077
		}
1078
		inode.Extents.eks = inode.Extents.eks[:0]
1079
		log.LogDebugf("action[getAndDelVerInList] mp[%v] ino[%v] verseq [%v] get del exts %v", mpId, inode.Inode, inode.getVer(), ext2Del)
1080
		inode.DecNLink() // dIno should be inode
1081
		doMore = true
1082
		return
1083
	}
1084

1085
	// if topLayer verSeq is as same as mp, the current inode deletion only happen on the first layer
1086
	// or ddelete from client do deletion at top layer which should allow delete ionde with older version contrast to mp version
1087
	// because ddelete have two steps,1 is del dentry,2nd is unlink inode ,version may updated after 1st and before 2nd step, to
1088
	// make sure inode be unlinked by normal deletion, sdk add filed of dentry verSeq to identify and different from other unlink actions
1089
	if mpVer == inode.getVer() {
1090
		if inode.getLayerLen() == 0 {
1091
			log.LogDebugf("action[unlinkTopLayer] no snapshot available depends on ino[%v] not found seq [%v] and return, verlist %v", ino, inode.getVer(), verlist)
1092
			inode.DecNLink()
1093
			log.LogDebugf("action[unlinkTopLayer] inode[%v] be unlinked", ino.Inode)
1094
			// operate inode directly
1095
			doMore = true
1096
			return
1097
		}
1098

1099
		log.LogDebugf("action[unlinkTopLayer] need restore.ino[%v] withseq [%v] equal mp seq, verlist %v",
1100
			ino, inode.getVer(), verlist)
1101
		// need restore
1102
		if !proto.IsDir(inode.Type) {
1103
			delFunc()
1104
			return
1105
		}
1106
		log.LogDebugf("action[unlinkTopLayer] inode[%v] be unlinked, Dir", ino.Inode)
1107
		inode.DecNLink()
1108
		doMore = true
1109
		return
1110
	}
1111

1112
	log.LogDebugf("action[unlinkTopLayer] need create version.ino[%v] withseq [%v] not equal mp seq [%v], verlist %v", ino, inode.getVer(), mpVer, verlist)
1113
	if proto.IsDir(inode.Type) { // dir is whole info but inode is partition,which is quit different
1114
		_, err := verlist.GetNextOlderVer(mpVer)
1115
		if err == nil {
1116
			log.LogDebugf("action[unlinkTopLayer] inode[%v] cann't get next older ver [%v] err %v", inode.Inode, mpVer, err)
1117
			inode.CreateVer(mpVer)
1118
		}
1119
		inode.DecNLink()
1120
		log.LogDebugf("action[unlinkTopLayer] inode[%v] be unlinked, Dir create ver 1st layer", ino.Inode)
1121
		doMore = true
1122
	} else {
1123
		ver, err := verlist.GetNextOlderVer(mpVer)
1124
		if err != nil {
1125
			if err.Error() == "not found" {
1126
				delFunc()
1127
				return
1128
			}
1129
			log.LogErrorf("action[unlinkTopLayer] inode[%v] cann't get next older ver [%v] err %v", inode.Inode, mpVer, err)
1130
			return
1131
		}
1132
		inode.CreateVer(mpVer) // protect origin version
1133
		if inode.NLink == 1 {
1134
			inode.CreateUnlinkVer(mpVer, ver) // create a effective top level  version
1135
		}
1136
		inode.DecNLink()
1137
		log.LogDebugf("action[unlinkTopLayer] inode[%v] be unlinked, File create ver 1st layer", ino.Inode)
1138
	}
1139
	return
1140
}
1141

1142
func (inode *Inode) dirUnlinkVerInlist(ino *Inode, mpVer uint64, verlist *proto.VolVersionInfoList) (ext2Del []proto.ExtentKey, doMore bool, status uint8) {
1143
	var idxWithTopLayer int
1144
	var dIno *Inode
1145
	status = proto.OpOk
1146
	if dIno, idxWithTopLayer = inode.getInoByVer(ino.getVer(), false); dIno == nil {
1147
		log.LogDebugf("action[dirUnlinkVerInlist] ino[%v] not found", ino)
1148
		return
1149
	}
1150
	var endSeq uint64
1151
	if idxWithTopLayer == 0 {
1152
		// header layer do nothing and be depends on should not be dropped
1153
		log.LogDebugf("action[dirUnlinkVerInlist] ino[%v] first layer do nothing", ino)
1154
		return
1155
	}
1156
	// if any alive snapshot in mp dimension exist in seq scope from dino to next ascend neighbor, dio snapshot be keep or else drop
1157
	if inode.multiSnap == nil {
1158
		log.LogWarnf("action[dirUnlinkVerInlist] ino[%v] multiSnap should not be nil", inode)
1159
		inode.multiSnap = &InodeMultiSnap{}
1160
	}
1161

1162
	mIdx := idxWithTopLayer - 1
1163
	if mIdx == 0 {
1164
		endSeq = inode.getVer()
1165
	} else {
1166
		endSeq = inode.multiSnap.multiVersions[mIdx-1].getVer()
1167
	}
1168

1169
	log.LogDebugf("action[dirUnlinkVerInlist] inode[%v] try drop multiVersion idx %v effective seq scope [%v,%v) ",
1170
		inode.Inode, mIdx, dIno.getVer(), endSeq)
1171

1172
	doWork := func() bool {
1173
		verlist.RWLock.RLock()
1174
		defer verlist.RWLock.RUnlock()
1175

1176
		for vidx, info := range verlist.VerList {
1177
			if info.Ver >= dIno.getVer() && info.Ver < endSeq {
1178
				log.LogDebugf("action[dirUnlinkVerInlist] inode[%v] dir layer idx %v still have effective snapshot seq [%v].so don't drop", inode.Inode, mIdx, info.Ver)
1179
				return false
1180
			}
1181
			if info.Ver >= endSeq || vidx == len(verlist.VerList)-1 {
1182
				log.LogDebugf("action[dirUnlinkVerInlist] inode[%v] try drop multiVersion idx %v and return", inode.Inode, mIdx)
1183

1184
				inode.Lock()
1185
				inode.multiSnap.multiVersions = append(inode.multiSnap.multiVersions[:mIdx], inode.multiSnap.multiVersions[mIdx+1:]...)
1186
				inode.Unlock()
1187
				return true
1188
			}
1189
			log.LogDebugf("action[dirUnlinkVerInlist] inode[%v] try drop scope [%v, %v), mp ver [%v] not suitable", inode.Inode, dIno.getVer(), endSeq, info.Ver)
1190
			return true
1191
		}
1192
		return true
1193
	}
1194
	if !doWork() {
1195
		return
1196
	}
1197
	doMore = true
1198
	dIno.DecNLink()
1199
	return
1200
}
1201

1202
func (inode *Inode) unlinkVerInList(mpId uint64, ino *Inode, mpVer uint64, verlist *proto.VolVersionInfoList) (ext2Del []proto.ExtentKey, doMore bool, status uint8) {
1203
	log.LogDebugf("action[unlinkVerInList] mpId [%v] ino[%v] try search seq [%v] isdir %v", mpId, ino, ino.getVer(), proto.IsDir(inode.Type))
1204
	if proto.IsDir(inode.Type) { // snapshot dir deletion don't take link into consider, but considers the scope of snapshot contrast to verList
1205
		return inode.dirUnlinkVerInlist(ino, mpVer, verlist)
1206
	}
1207
	var dIno *Inode
1208
	status = proto.OpOk
1209
	// special case, snapshot is the last one and be depended by upper version,update it's version to the right one
1210
	// ascend search util to the curr unCommit version in the verList
1211
	if ino.getVer() == inode.getVer() || (isInitSnapVer(ino.getVer()) && inode.getVer() == 0) {
1212
		if len(verlist.VerList) == 0 {
1213
			status = proto.OpNotExistErr
1214
			log.LogErrorf("action[unlinkVerInList] inode[%v] verlist should be larger than 0, return not found", inode.Inode)
1215
			return
1216
		}
1217

1218
		// just move to upper layer,the request snapshot be dropped
1219
		nVerSeq, found := inode.getLastestVer(inode.getVer(), verlist)
1220
		if !found {
1221
			status = proto.OpNotExistErr
1222
			return
1223
		}
1224
		log.LogDebugf("action[unlinkVerInList] inode[%v] update current verseq [%v] to %v", inode.Inode, inode.getVer(), nVerSeq)
1225
		inode.setVer(nVerSeq)
1226
		return
1227
	} else {
1228
		// don't unlink if no version satisfied
1229
		if ext2Del, dIno = inode.getAndDelVerInList(mpId, ino.getVer(), mpVer, verlist); dIno == nil {
1230
			status = proto.OpNotExistErr
1231
			log.LogDebugf("action[unlinkVerInList] ino[%v]", ino)
1232
			return
1233
		}
1234
	}
1235

1236
	dIno.DecNLink()
1237
	log.LogDebugf("action[unlinkVerInList] inode[%v] snapshot layer be unlinked", ino.Inode)
1238
	doMore = true
1239
	return
1240
}
1241

1242
func (i *Inode) ShouldDelVer(delVer uint64, mpVer uint64) (ok bool, err error) {
1243
	if i.getVer() == 0 {
1244
		if delVer > 0 {
1245
			if isInitSnapVer(delVer) {
1246
				return true, nil
1247
			}
1248
			return false, fmt.Errorf("not found")
1249
		} else {
1250
			// mp ver larger than zero means snapshot happened but haven't take effect on this inode
1251
			if mpVer > 0 {
1252
				return false, nil
1253
			}
1254
			return true, nil
1255
		}
1256
	} else {
1257
		if delVer > i.getVer() {
1258
			return false, fmt.Errorf("not found")
1259
		} else if delVer == i.getVer() {
1260
			return true, nil
1261
		}
1262
	}
1263

1264
	if isInitSnapVer(delVer) {
1265
		tailVer, _ := i.getTailVerInList()
1266
		if tailVer == 0 {
1267
			return true, nil
1268
		}
1269
		return false, fmt.Errorf("not found")
1270
	}
1271
	if i.multiSnap == nil {
1272
		return false, fmt.Errorf("not found")
1273
	}
1274
	for _, inoVer := range i.multiSnap.multiVersions {
1275
		if inoVer.getVer() == delVer {
1276
			return true, nil
1277
		}
1278
		if inoVer.getVer() < delVer {
1279
			break
1280
		}
1281
	}
1282
	return false, fmt.Errorf("not found")
1283
}
1284

1285
// idx need calc include nclude top layer. index in multiSnap.multiVersions need add by 1
1286
//
1287
//note:search all layers.
1288
func (ino *Inode) getInoByVer(verSeq uint64, equal bool) (i *Inode, idx int) {
1289
	ino.RLock()
1290
	defer ino.RUnlock()
1291

1292
	if verSeq == 0 || verSeq == ino.getVer() || (isInitSnapVer(verSeq) && ino.getVer() == 0) {
1293
		return ino, 0
1294
	}
1295
	if isInitSnapVer(verSeq) {
1296
		listLen := ino.getLayerLen()
1297
		if listLen == 0 {
1298
			log.LogDebugf("action[getInoByVer]  ino[%v] no multiversion", ino.Inode)
1299
			return
1300
		}
1301
		i = ino.multiSnap.multiVersions[listLen-1]
1302
		if i.getVer() != 0 {
1303
			log.LogDebugf("action[getInoByVer]  ino[%v] lay seq [%v]", ino.Inode, i.getVer())
1304
			return nil, 0
1305
		}
1306
		return i, listLen
1307
	}
1308
	if verSeq > 0 && ino.getVer() > verSeq {
1309
		if ino.multiSnap != nil {
1310
			for id, iTmp := range ino.multiSnap.multiVersions {
1311
				if verSeq == iTmp.getVer() {
1312
					log.LogDebugf("action[getInoByVer]  ino[%v] get in multiversion id[%v]", ino.Inode, id)
1313
					return iTmp, id + 1
1314
				} else if verSeq > iTmp.getVer() {
1315
					if !equal {
1316
						log.LogDebugf("action[getInoByVer]  ino[%v] get in multiversion id[%v], %v, %v", ino.Inode, id, verSeq, iTmp.getVer())
1317
						return iTmp, id + 1
1318
					}
1319
					log.LogDebugf("action[getInoByVer]  ino[%v] get in multiversion id[%v]", ino.Inode, id)
1320
					return
1321
				}
1322
			}
1323
		}
1324
	} else {
1325
		if !equal {
1326
			log.LogDebugf("action[getInoByVer]  ino[%v]", ino.Inode)
1327
			return ino, 0
1328
		}
1329
	}
1330
	return
1331
}
1332

1333
// 1. check if dVer layer is the last layer of the system  1)true,drop it all 2) false goto 3
1334
// 2. if have system layer between dVer and next older inode's layer(not exist is ok), drop dVer related exts and update ver
1335
// 3. else Restore to next inode's Layer
1336

1337
func (i *Inode) getAndDelVerInList(mpId uint64, dVer uint64, mpVer uint64, verlist *proto.VolVersionInfoList) (delExtents []proto.ExtentKey, ino *Inode) {
1338
	var err error
1339
	verlist.RWLock.RLock()
1340
	defer verlist.RWLock.RUnlock()
1341

1342
	log.LogDebugf("action[getAndDelVerInList] ino[%v] verseq [%v] request del ver [%v] hist len %v isTmpFile %v",
1343
		i.Inode, i.getVer(), dVer, i.getLayerLen(), i.IsTempFile())
1344

1345
	// read inode element is fine, lock is need while write
1346
	inoVerLen := i.getLayerLen()
1347
	if inoVerLen == 0 {
1348
		log.LogDebugf("action[getAndDelVerInList] ino[%v] RestoreMultiSnapExts no left", i.Inode)
1349
		return
1350
	}
1351

1352
	// delete snapshot version
1353
	if isInitSnapVer(dVer) {
1354
		dVer = 0
1355
	}
1356
	lastVer := i.getVer()
1357
	for id, mIno := range i.multiSnap.multiVersions {
1358
		log.LogDebugf("action[getAndDelVerInList] ino[%v] multiSnap.multiVersions level %v verseq [%v]", i.Inode, id, mIno.getVer())
1359
		if mIno.getVer() < dVer {
1360
			log.LogDebugf("action[getAndDelVerInList] ino[%v] multiSnap.multiVersions level %v verseq [%v]", i.Inode, id, mIno.getVer())
1361
			return
1362
		}
1363

1364
		if mIno.getVer() == dVer {
1365
			log.LogDebugf("action[getAndDelVerInList] ino[%v] ver [%v] step 3", i.Inode, mIno.getVer())
1366
			// 2. get next version should according to verList but not only self multi list
1367

1368
			var nVerSeq uint64
1369
			if nVerSeq, err = verlist.GetNextNewerVer(dVer); err != nil {
1370
				log.LogDebugf("action[getAndDelVerInList] get next version failed, err %v", err)
1371
				return
1372
			}
1373
			if lastVer > nVerSeq {
1374
				mIno.setVer(nVerSeq)
1375
				return
1376
			}
1377
			if i.isTailIndexInList(id) {
1378
				i.multiSnap.multiVersions = i.multiSnap.multiVersions[:inoVerLen-1]
1379
				log.LogDebugf("action[getAndDelVerInList] ino[%v] idx %v be dropped", i.Inode, inoVerLen)
1380
				return mIno.Extents.eks, mIno
1381
			}
1382
			if nVerSeq, err = verlist.GetNextOlderVer(dVer); err != nil {
1383
				log.LogDebugf("action[getAndDelVerInList] get next version failed, err %v", err)
1384
				return
1385
			}
1386

1387
			log.LogDebugf("action[getAndDelVerInList] ino[%v] ver [%v] nextVerseq [%v] step 3 ver ", i.Inode, mIno.getVer(), nVerSeq)
1388
			// 2. system next layer not exist in inode ver list. update curr layer to next layer and filter out ek with verSeq
1389
			// change id layer verSeq to neighbor layer info, omit version delete process
1390

1391
			if nVerSeq > i.multiSnap.multiVersions[id+1].getVer() {
1392
				log.LogDebugf("action[getAndDelVerInList] ino[%v]  get next version in verList update ver from %v to %v.And delete exts with ver [%v]",
1393
					i.Inode, i.multiSnap.multiVersions[id].getVer(), nVerSeq, dVer)
1394

1395
				i.multiSnap.multiVersions[id].setVerNoCheck(nVerSeq)
1396
				i.multiSnap.multiVersions[id] = i.CopyInodeOnly(i.multiSnap.multiVersions[id+1])
1397

1398
				delExtents = i.MultiLayerClearExtByVer(id+1, dVer)
1399
				ino = i.multiSnap.multiVersions[id]
1400
				if len(i.multiSnap.multiVersions[id].Extents.eks) != 0 {
1401
					log.LogDebugf("action[getAndDelVerInList] ino[%v]   after clear self still have ext and left", i.Inode)
1402
					return
1403
				}
1404
			} else {
1405
				log.LogDebugf("action[getAndDelVerInList] ino[%v] ver [%v] nextver [%v] step 3 ver ", i.Inode, mIno.getVer(), nVerSeq)
1406
				// 3. next layer exist. the deleted version and  next version are neighbor in verlist, thus need restore and delete
1407
				if delExtents, err = i.RestoreExts2NextLayer(mpId, mIno.Extents.eks, dVer, id+1); err != nil {
1408
					log.LogDebugf("action[getAndDelVerInList] ino[%v] RestoreMultiSnapExts split error %v", i.Inode, err)
1409
					return
1410
				}
1411
			}
1412
			// delete layer id
1413
			i.multiSnap.multiVersions = append(i.multiSnap.multiVersions[:id], i.multiSnap.multiVersions[id+1:]...)
1414

1415
			log.LogDebugf("action[getAndDelVerInList] ino[%v] verseq [%v] get del exts %v", i.Inode, i.getVer(), delExtents)
1416
			return delExtents, mIno
1417
		}
1418
		lastVer = mIno.getVer()
1419
	}
1420
	return
1421
}
1422

1423
func (i *Inode) getLastestVer(reqVerSeq uint64, verlist *proto.VolVersionInfoList) (uint64, bool) {
1424
	verlist.RWLock.RLock()
1425
	defer verlist.RWLock.RUnlock()
1426

1427
	if len(verlist.VerList) == 0 {
1428
		return 0, false
1429
	}
1430
	for _, info := range verlist.VerList {
1431
		if info.Ver > reqVerSeq {
1432
			return info.Ver, true
1433
		}
1434
	}
1435

1436
	log.LogDebugf("action[getLastestVer] inode[%v] reqVerseq [%v] not found, the largetst one %v",
1437
		i.Inode, reqVerSeq, verlist.VerList[len(verlist.VerList)-1].Ver)
1438
	return 0, false
1439
}
1440

1441
func (i *Inode) CreateUnlinkVer(mpVer uint64, nVer uint64) {
1442
	log.LogDebugf("action[CreateUnlinkVer] inode[%v] mpver [%v] nver [%v]", i.Inode, mpVer, nVer)
1443
	// inode copy not include multi ver array
1444
	ino := i.CopyDirectly().(*Inode)
1445
	ino.setVer(nVer)
1446

1447
	i.Extents = NewSortedExtents()
1448
	i.ObjExtents = NewSortedObjExtents()
1449
	i.SetDeleteMark()
1450

1451
	log.LogDebugf("action[CreateUnlinkVer] inode[%v] create new version [%v] and store old one [%v], hist len [%v]",
1452
		i.Inode, mpVer, i.getVer(), i.getLayerLen())
1453

1454
	i.Lock()
1455
	if i.multiSnap == nil {
1456
		i.multiSnap = &InodeMultiSnap{}
1457
	}
1458
	if i.getLayerVer(0) == nVer {
1459
		i.multiSnap.multiVersions[0] = ino
1460
	} else {
1461
		i.multiSnap.multiVersions = append([]*Inode{ino}, i.multiSnap.multiVersions...)
1462
	}
1463

1464
	i.setVer(mpVer)
1465
	i.Unlock()
1466
}
1467

1468
func (i *Inode) CreateVer(ver uint64) {
1469
	// inode copy not include multi ver array
1470
	ino := i.CopyDirectly().(*Inode)
1471
	ino.Extents = NewSortedExtents()
1472
	ino.ObjExtents = NewSortedObjExtents()
1473
	ino.setVer(i.getVer())
1474
	i.setVer(ver)
1475

1476
	i.Lock()
1477
	defer i.Unlock()
1478
	log.LogDebugf("action[CreateVer] inode[%v] create new version [%v] and store old one [%v], hist len [%v]",
1479
		i.Inode, ver, i.getVer(), i.getLayerLen())
1480

1481
	if i.multiSnap == nil {
1482
		i.multiSnap = &InodeMultiSnap{}
1483
	}
1484
	i.multiSnap.multiVersions = append([]*Inode{ino}, i.multiSnap.multiVersions...)
1485
}
1486

1487
func (i *Inode) buildMultiSnap() {
1488
	if i.multiSnap == nil {
1489
		i.multiSnap = &InodeMultiSnap{}
1490
	}
1491
	if i.multiSnap.ekRefMap == nil {
1492
		i.multiSnap.ekRefMap = new(sync.Map)
1493
	}
1494
}
1495

1496
func (i *Inode) SplitExtentWithCheck(param *AppendExtParam) (delExtents []proto.ExtentKey, status uint8) {
1497
	var err error
1498
	param.ek.SetSeq(param.mpVer)
1499
	log.LogDebugf("action[SplitExtentWithCheck] mpId[%v].inode[%v],ek [%v],hist len %v", param.mpId, i.Inode, param.ek, i.getLayerLen())
1500

1501
	if param.mpVer != i.getVer() {
1502
		log.LogDebugf("action[SplitExtentWithCheck] mpId[%v].CreateVer ver [%v]", param.mpId, param.mpVer)
1503
		i.CreateVer(param.mpVer)
1504
	}
1505
	i.Lock()
1506
	defer i.Unlock()
1507

1508
	i.buildMultiSnap()
1509
	delExtents, status = i.Extents.SplitWithCheck(param.mpId, i.Inode, param.ek, i.multiSnap.ekRefMap)
1510
	if status != proto.OpOk {
1511
		log.LogErrorf("action[SplitExtentWithCheck] mpId[%v].status [%v]", param.mpId, status)
1512
		return
1513
	}
1514
	if len(delExtents) == 0 {
1515
		return
1516
	}
1517

1518
	if err = i.CreateLowerVersion(i.getVer(), param.multiVersionList); err != nil {
1519
		return
1520
	}
1521

1522
	if delExtents, err = i.RestoreExts2NextLayer(param.mpId, delExtents, param.mpVer, 0); err != nil {
1523
		log.LogErrorf("action[fsmAppendExtentWithCheck] mpId[%v].ino[%v] RestoreMultiSnapExts split error %v", param.mpId, i.Inode, err)
1524
		return
1525
	}
1526
	if proto.IsHot(param.volType) {
1527
		i.Generation++
1528
		i.ModifyTime = param.ct
1529
	}
1530

1531
	return
1532
}
1533

1534
// try to create version between curVer and seq of multiSnap.multiVersions[0] in verList
1535
func (i *Inode) CreateLowerVersion(curVer uint64, verlist *proto.VolVersionInfoList) (err error) {
1536
	verlist.RWLock.RLock()
1537
	defer verlist.RWLock.RUnlock()
1538

1539
	log.LogDebugf("CreateLowerVersion inode[%v] curver [%v]", i.Inode, curVer)
1540
	if len(verlist.VerList) <= 1 {
1541
		return
1542
	}
1543
	if i.isEmptyVerList() {
1544
		return
1545
	}
1546
	var nextVer uint64
1547
	for _, info := range verlist.VerList {
1548
		if info.Ver < curVer {
1549
			nextVer = info.Ver
1550
		}
1551
		if info.Ver >= curVer {
1552
			break
1553
		}
1554
	}
1555
	if nextVer <= i.getLayerVer(0) {
1556
		log.LogDebugf("CreateLowerVersion nextver [%v] layer 0 ver [%v]", nextVer, i.getLayerVer(0))
1557
		return
1558
	}
1559

1560
	ino := i.CopyDirectly().(*Inode)
1561
	ino.Extents = NewSortedExtents()
1562
	ino.ObjExtents = NewSortedObjExtents()
1563
	ino.setVer(nextVer)
1564

1565
	log.LogDebugf("action[CreateLowerVersion] inode[%v] create new version [%v] and store old one [%v], hist len [%v]",
1566
		i.Inode, ino, i.getVer(), i.getLayerLen())
1567
	if i.multiSnap == nil {
1568
		i.multiSnap = &InodeMultiSnap{}
1569
	}
1570
	i.multiSnap.multiVersions = append([]*Inode{ino}, i.multiSnap.multiVersions...)
1571

1572
	return
1573
}
1574

1575
type AppendExtParam struct {
1576
	mpId             uint64
1577
	mpVer            uint64
1578
	multiVersionList *proto.VolVersionInfoList
1579
	ek               proto.ExtentKey
1580
	ct               int64
1581
	discardExtents   []proto.ExtentKey
1582
	volType          int
1583
}
1584

1585
func (i *Inode) AppendExtentWithCheck(param *AppendExtParam) (delExtents []proto.ExtentKey, status uint8) {
1586
	param.ek.SetSeq(param.mpVer)
1587
	log.LogDebugf("action[AppendExtentWithCheck] mpId[%v].mpver [%v] inode[%v] and fsm ver [%v],ek [%v],hist len %v",
1588
		param.mpId, param.mpVer, i.Inode, i.getVer(), param.ek, i.getLayerLen())
1589

1590
	if param.mpVer != i.getVer() {
1591
		log.LogInfof("action[AppendExtentWithCheck] mpId[%v].inode ver [%v]", param.mpId, i.getVer())
1592
		i.CreateVer(param.mpVer)
1593
	}
1594

1595
	i.Lock()
1596
	defer i.Unlock()
1597

1598
	refFunc := func(key *proto.ExtentKey) { i.insertEkRefMap(param.mpId, key) }
1599
	delExtents, status = i.Extents.AppendWithCheck(i.Inode, param.ek, refFunc, param.discardExtents)
1600
	if status != proto.OpOk {
1601
		log.LogErrorf("action[AppendExtentWithCheck] mpId[%v].status [%v]", param.mpId, status)
1602
		return
1603
	}
1604

1605
	// multi version take effect
1606
	if i.getVer() > 0 && len(delExtents) > 0 {
1607
		var err error
1608
		if err = i.CreateLowerVersion(i.getVer(), param.multiVersionList); err != nil {
1609
			return
1610
		}
1611
		if delExtents, err = i.RestoreExts2NextLayer(param.mpId, delExtents, param.mpVer, 0); err != nil {
1612
			log.LogErrorf("action[AppendExtentWithCheck] mpId[%v].RestoreMultiSnapExts err %v", param.mpId, err)
1613
			return nil, proto.OpErr
1614
		}
1615
	}
1616

1617
	if proto.IsHot(param.volType) {
1618
		size := i.Extents.Size()
1619
		if i.Size < size {
1620
			i.Size = size
1621
		}
1622
		i.Generation++
1623
		i.ModifyTime = param.ct
1624
	}
1625
	return
1626
}
1627

1628
func (i *Inode) ExtentsTruncate(length uint64, ct int64, doOnLastKey func(*proto.ExtentKey), insertRefMap func(ek *proto.ExtentKey)) (delExtents []proto.ExtentKey) {
1629
	delExtents = i.Extents.Truncate(length, doOnLastKey, insertRefMap)
1630
	i.Size = length
1631
	i.ModifyTime = ct
1632
	i.Generation++
1633
	return
1634
}
1635

1636
// IncNLink increases the nLink value by one.
1637
func (i *Inode) IncNLink(verSeq uint64) {
1638
	if i.getVer() < verSeq {
1639
		i.CreateVer(verSeq)
1640
	}
1641
	i.Lock()
1642
	i.NLink++
1643
	i.Unlock()
1644
}
1645

1646
// DecNLink decreases the nLink value by one.
1647
func (i *Inode) DecNLink() {
1648
	i.Lock()
1649
	if proto.IsDir(i.Type) && i.NLink == 2 {
1650
		i.NLink--
1651
	}
1652
	if i.NLink > 0 {
1653
		i.NLink--
1654
	}
1655
	i.Unlock()
1656
}
1657

1658
// DecNLink decreases the nLink value by one.
1659
func (i *Inode) DecNLinkByVer(verSeq uint64) {
1660
	if i.getVer() < verSeq {
1661
		i.CreateVer(verSeq)
1662
	}
1663
	i.DecNLink()
1664
}
1665

1666
func (i *Inode) DecSplitExts(mpId uint64, delExtents interface{}) {
1667
	log.LogDebugf("[DecSplitExts] mpId [%v] inode[%v]", mpId, i.Inode)
1668
	cnt := len(delExtents.([]proto.ExtentKey))
1669
	for id := 0; id < cnt; id++ {
1670
		ek := &delExtents.([]proto.ExtentKey)[id]
1671
		if !ek.IsSplit() {
1672
			log.LogDebugf("[DecSplitExts] mpId [%v]  ek not split %v", mpId, ek)
1673
			continue
1674
		}
1675
		if i.multiSnap == nil || i.multiSnap.ekRefMap == nil {
1676
			log.LogErrorf("[DecSplitExts] mpid [%v]. inode[%v] multiSnap.ekRefMap is nil", mpId, i.Inode)
1677
			return
1678
		}
1679

1680
		ok, last := i.DecSplitEk(mpId, ek)
1681
		if !ok {
1682
			log.LogErrorf("[DecSplitExts] mpid [%v]. ek [%v] not found!", mpId, ek)
1683
			continue
1684
		}
1685
		if last {
1686
			log.LogDebugf("[DecSplitExts] mpid [%v] ek [%v] split flag be unset to remove all content", mpId, ek)
1687
			ek.SetSplit(false)
1688
		}
1689
	}
1690
}
1691

1692
func (i *Inode) DecSplitEk(mpId uint64, ext *proto.ExtentKey) (ok bool, last bool) {
1693
	log.LogDebugf("[DecSplitEk] mpId[%v] inode[%v] dp [%v] extent id[%v].key %v ext %v", mpId, i.Inode, ext.PartitionId, ext.ExtentId,
1694
		ext.PartitionId<<32|ext.ExtentId, ext)
1695

1696
	if i.multiSnap == nil || i.multiSnap.ekRefMap == nil {
1697
		log.LogErrorf("DecSplitEk. multiSnap %v", i.multiSnap)
1698
		return
1699
	}
1700
	if val, ok := i.multiSnap.ekRefMap.Load(ext.PartitionId<<32 | ext.ExtentId); !ok {
1701
		log.LogErrorf("[DecSplitEk] mpId[%v]. dp [%v] inode[%v] ext not found", mpId, ext.PartitionId, i.Inode)
1702
		return false, false
1703
	} else {
1704
		if val.(uint32) == 0 {
1705
			log.LogErrorf("[DecSplitEk] mpId[%v]. dp [%v] inode[%v] ek ref is zero!", mpId, ext.PartitionId, i.Inode)
1706
			return false, false
1707
		}
1708
		if val.(uint32) == 1 {
1709
			log.LogDebugf("[DecSplitEk] mpId[%v] inode[%v] dp [%v] extent id[%v].key %v", mpId, i.Inode, ext.PartitionId, ext.ExtentId,
1710
				ext.PartitionId<<32|ext.ExtentId)
1711
			i.multiSnap.ekRefMap.Delete(ext.PartitionId<<32 | ext.ExtentId)
1712
			return true, true
1713
		}
1714
		i.multiSnap.ekRefMap.Store(ext.PartitionId<<32|ext.ExtentId, val.(uint32)-1)
1715
		log.LogDebugf("[DecSplitEk] mpId[%v]. extend dp [%v] inode[%v] ek [%v] val %v", mpId, ext.PartitionId, i.Inode, ext, val.(uint32)-1)
1716
		return true, false
1717
	}
1718
}
1719

1720
// DecNLink decreases the nLink value by one.
1721
func (i *Inode) GetDecNLinkResult() (nLink uint32) {
1722
	i.Lock()
1723
	nLink = i.NLink
1724
	if proto.IsDir(i.Type) && nLink == 2 {
1725
		nLink--
1726
	}
1727
	if nLink > 0 {
1728
		nLink--
1729
	}
1730
	i.Unlock()
1731
	return
1732
}
1733

1734
// GetNLink returns the nLink value.
1735
func (i *Inode) GetNLink() uint32 {
1736
	i.RLock()
1737
	defer i.RUnlock()
1738
	return i.NLink
1739
}
1740

1741
func (i *Inode) IsTempFile() bool {
1742
	i.RLock()
1743
	ok := i.NLink == 0 && !proto.IsDir(i.Type)
1744
	i.RUnlock()
1745
	return ok
1746
}
1747

1748
func (i *Inode) IsEmptyDir() bool {
1749
	i.RLock()
1750
	ok := proto.IsDir(i.Type) && i.NLink <= 2
1751
	i.RUnlock()
1752
	return ok
1753
}
1754

1755
func (i *Inode) IsEmptyDirAndNoSnapshot() bool {
1756
	i.RLock()
1757
	ok := proto.IsDir(i.Type) && i.NLink <= 2 && i.getLayerLen() == 0
1758
	i.RUnlock()
1759
	return ok
1760
}
1761

1762
func (i *Inode) IsTopLayerEmptyDir() bool {
1763
	i.RLock()
1764
	ok := proto.IsDir(i.Type) && i.NLink <= 2
1765
	i.RUnlock()
1766
	return ok
1767
}
1768

1769
// SetDeleteMark set the deleteMark flag. TODO markDelete or deleteMark? markDelete has been used in datanode.
1770
func (i *Inode) SetDeleteMark() {
1771
	i.Lock()
1772
	i.Flag |= DeleteMarkFlag
1773
	i.Unlock()
1774
}
1775

1776
// ShouldDelete returns if the inode has been marked as deleted.
1777
func (i *Inode) ShouldDelete() (ok bool) {
1778
	i.RLock()
1779
	ok = i.Flag&DeleteMarkFlag == DeleteMarkFlag
1780
	i.RUnlock()
1781
	return
1782
}
1783

1784
// inode should delay remove if as 3 conditions:
1785
// 1. DeleteMarkFlag is unset
1786
// 2. NLink == 0
1787
// 3. AccessTime is 7 days ago
1788
func (i *Inode) ShouldDelayDelete() (ok bool) {
1789
	i.RLock()
1790
	ok = (i.Flag&DeleteMarkFlag != DeleteMarkFlag) &&
1791
		(i.NLink == 0) &&
1792
		time.Now().Unix()-i.AccessTime < InodeNLink0DelayDeleteSeconds
1793
	i.RUnlock()
1794
	return
1795
}
1796

1797
// SetAttr sets the attributes of the inode.
1798
func (i *Inode) SetAttr(req *SetattrRequest) {
1799
	log.LogDebugf("action[SetAttr] inode[%v] req seq [%v] inode seq [%v]", i.Inode, req.VerSeq, i.getVer())
1800

1801
	if req.VerSeq != i.getVer() {
1802
		i.CreateVer(req.VerSeq)
1803
	}
1804
	i.Lock()
1805
	log.LogDebugf("action[SetAttr] inode[%v] req seq [%v] inode seq [%v]", i.Inode, req.VerSeq, i.getVer())
1806
	if req.Valid&proto.AttrMode != 0 {
1807
		i.Type = req.Mode
1808
	}
1809
	if req.Valid&proto.AttrUid != 0 {
1810
		i.Uid = req.Uid
1811
	}
1812
	if req.Valid&proto.AttrGid != 0 {
1813
		i.Gid = req.Gid
1814
	}
1815
	if req.Valid&proto.AttrAccessTime != 0 {
1816
		i.AccessTime = req.AccessTime
1817
	}
1818
	if req.Valid&proto.AttrModifyTime != 0 {
1819
		i.ModifyTime = req.ModifyTime
1820
	}
1821

1822
	i.Unlock()
1823
}
1824

1825
func (i *Inode) DoWriteFunc(fn func()) {
1826
	i.Lock()
1827
	defer i.Unlock()
1828
	fn()
1829
}
1830

1831
// DoFunc executes the given function.
1832
func (i *Inode) DoReadFunc(fn func()) {
1833
	i.RLock()
1834
	defer i.RUnlock()
1835
	fn()
1836
}
1837

1838
// SetMtime sets mtime to the current time.
1839
func (i *Inode) SetMtime() {
1840
	mtime := timeutil.GetCurrentTimeUnix()
1841
	i.Lock()
1842
	defer i.Unlock()
1843
	i.ModifyTime = mtime
1844
}
1845

1846
// EmptyExtents clean the inode's extent list.
1847
func (i *Inode) EmptyExtents(mtime int64) (delExtents []proto.ExtentKey) {
1848
	i.Lock()
1849
	defer i.Unlock()
1850
	// eks is safe because extents be reset next and eks is will not be visit except del routine
1851
	delExtents = i.Extents.eks
1852
	i.Extents = NewSortedExtents()
1853

1854
	return delExtents
1855
}
1856

1857
// EmptyExtents clean the inode's extent list.
1858
func (i *Inode) CopyTinyExtents() (delExtents []proto.ExtentKey) {
1859
	i.RLock()
1860
	defer i.RUnlock()
1861
	return i.Extents.CopyTinyExtents()
1862
}
1863

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.