api: Introduce metadata update APIs to update only metadata (#11962)

Current implementation heavily relies on readAllFileInfo
but with the advent of xl.meta inlined with data, we cannot
easily avoid reading data when we are only interested is
updating metadata, this leads to invariably write
amplification during metadata updates, repeatedly reading
data when we are only interested in updating metadata.

This PR ensures that we implement a metadata only update
API at storage layer, that handles updates to metadata alone
for any given version - given the version is valid and
present.

This helps reduce the chattiness for following calls..

- PutObjectTags
- DeleteObjectTags
- PutObjectLegalHold
- PutObjectRetention
- ReplicateObject (updates metadata on replication status)
This commit is contained in:
Harshavardhana
2021-04-04 13:32:31 -07:00
committed by GitHub
parent 8a9d15ace2
commit d46386246f
20 changed files with 378 additions and 153 deletions

View File

@@ -30,7 +30,7 @@ type LRWMutex struct {
source string
isWriteLock bool
ref int
m sync.Mutex // Mutex to prevent multiple simultaneous locks
mu sync.Mutex // Mutex to prevent multiple simultaneous locks
}
// NewLRWMutex - initializes a new lsync RW mutex.
@@ -73,7 +73,9 @@ func (lm *LRWMutex) GetRLock(ctx context.Context, id string, source string, time
}
func (lm *LRWMutex) lock(id, source string, isWriteLock bool) (locked bool) {
lm.m.Lock()
lm.mu.Lock()
defer lm.mu.Unlock()
lm.id = id
lm.source = source
if isWriteLock {
@@ -88,7 +90,6 @@ func (lm *LRWMutex) lock(id, source string, isWriteLock bool) (locked bool) {
locked = true
}
}
lm.m.Unlock()
return locked
}
@@ -147,7 +148,8 @@ func (lm *LRWMutex) RUnlock() {
}
func (lm *LRWMutex) unlock(isWriteLock bool) (unlocked bool) {
lm.m.Lock()
lm.mu.Lock()
defer lm.mu.Unlock()
// Try to release lock.
if isWriteLock {
@@ -165,16 +167,17 @@ func (lm *LRWMutex) unlock(isWriteLock bool) (unlocked bool) {
}
}
lm.m.Unlock()
return unlocked
}
// ForceUnlock will forcefully clear a write or read lock.
func (lm *LRWMutex) ForceUnlock() {
lm.m.Lock()
lm.mu.Lock()
defer lm.mu.Unlock()
lm.ref = 0
lm.isWriteLock = false
lm.m.Unlock()
}
// DRLocker returns a sync.Locker interface that implements