Move the metaMu lock from the fs to the object

Signed-off-by: Anagh Kumar Baranwal <6824881+darthShadow@users.noreply.github.com>
This commit is contained in:
Anagh Kumar Baranwal 2023-08-04 14:51:35 +05:30
parent 0b35ff3893
commit bb45b6bb51
No known key found for this signature in database
1 changed files with 32 additions and 32 deletions

View File

@ -247,16 +247,16 @@ type Fs struct {
xattrSupported atomic.Int32 // whether xattrs are supported xattrSupported atomic.Int32 // whether xattrs are supported
// do os.Lstat or os.Stat // do os.Lstat or os.Stat
lstat func(name string) (os.FileInfo, error) lstat func(name string) (os.FileInfo, error)
objectMetaMu sync.RWMutex // global lock for Object metadata
} }
// Object represents a local filesystem object // Object represents a local filesystem object
type Object struct { type Object struct {
fs *Fs // The Fs this object is part of fs *Fs // The Fs this object is part of
remote string // The remote path (encoded path) remote string // The remote path (encoded path)
path string // The local path (OS path) path string // The local path (OS path)
// When using these items the fs.objectMetaMu must be held metaMu sync.RWMutex // lock for metadata
// When using these items the metaMu must be held
size int64 // file metadata - always present size int64 // file metadata - always present
mode os.FileMode mode os.FileMode
modTime time.Time modTime time.Time
@ -777,9 +777,9 @@ func (f *Fs) Move(ctx context.Context, src fs.Object, remote string) (fs.Object,
// Temporary Object under construction // Temporary Object under construction
dstObj := f.newObject(remote) dstObj := f.newObject(remote)
dstObj.fs.objectMetaMu.RLock() dstObj.metaMu.RLock()
dstObjMode := dstObj.mode dstObjMode := dstObj.mode
dstObj.fs.objectMetaMu.RUnlock() dstObj.metaMu.RUnlock()
// Check it is a file if it exists // Check it is a file if it exists
err := dstObj.lstat() err := dstObj.lstat()
@ -941,10 +941,10 @@ func (o *Object) Remote() string {
// Hash returns the requested hash of a file as a lowercase hex string // Hash returns the requested hash of a file as a lowercase hex string
func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) { func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) {
// Check that the underlying file hasn't changed // Check that the underlying file hasn't changed
o.fs.objectMetaMu.RLock() o.metaMu.RLock()
oldtime := o.modTime oldtime := o.modTime
oldsize := o.size oldsize := o.size
o.fs.objectMetaMu.RUnlock() o.metaMu.RUnlock()
err := o.lstat() err := o.lstat()
var changed bool var changed bool
if err != nil { if err != nil {
@ -956,14 +956,14 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) {
return "", fmt.Errorf("hash: failed to stat: %w", err) return "", fmt.Errorf("hash: failed to stat: %w", err)
} }
} else { } else {
o.fs.objectMetaMu.RLock() o.metaMu.RLock()
changed = !o.modTime.Equal(oldtime) || oldsize != o.size changed = !o.modTime.Equal(oldtime) || oldsize != o.size
o.fs.objectMetaMu.RUnlock() o.metaMu.RUnlock()
} }
o.fs.objectMetaMu.RLock() o.metaMu.RLock()
hashValue, hashFound := o.hashes[r] hashValue, hashFound := o.hashes[r]
o.fs.objectMetaMu.RUnlock() o.metaMu.RUnlock()
if changed || !hashFound { if changed || !hashFound {
var in io.ReadCloser var in io.ReadCloser
@ -994,28 +994,28 @@ func (o *Object) Hash(ctx context.Context, r hash.Type) (string, error) {
return "", fmt.Errorf("hash: failed to close: %w", closeErr) return "", fmt.Errorf("hash: failed to close: %w", closeErr)
} }
hashValue = hashes[r] hashValue = hashes[r]
o.fs.objectMetaMu.Lock() o.metaMu.Lock()
if o.hashes == nil { if o.hashes == nil {
o.hashes = hashes o.hashes = hashes
} else { } else {
o.hashes[r] = hashValue o.hashes[r] = hashValue
} }
o.fs.objectMetaMu.Unlock() o.metaMu.Unlock()
} }
return hashValue, nil return hashValue, nil
} }
// Size returns the size of an object in bytes // Size returns the size of an object in bytes
func (o *Object) Size() int64 { func (o *Object) Size() int64 {
o.fs.objectMetaMu.RLock() o.metaMu.RLock()
defer o.fs.objectMetaMu.RUnlock() defer o.metaMu.RUnlock()
return o.size return o.size
} }
// ModTime returns the modification time of the object // ModTime returns the modification time of the object
func (o *Object) ModTime(ctx context.Context) time.Time { func (o *Object) ModTime(ctx context.Context) time.Time {
o.fs.objectMetaMu.RLock() o.metaMu.RLock()
defer o.fs.objectMetaMu.RUnlock() defer o.metaMu.RUnlock()
return o.modTime return o.modTime
} }
@ -1044,9 +1044,9 @@ func (o *Object) SetModTime(ctx context.Context, modTime time.Time) error {
// Storable returns a boolean showing if this object is storable // Storable returns a boolean showing if this object is storable
func (o *Object) Storable() bool { func (o *Object) Storable() bool {
o.fs.objectMetaMu.RLock() o.metaMu.RLock()
mode := o.mode mode := o.mode
o.fs.objectMetaMu.RUnlock() o.metaMu.RUnlock()
if mode&os.ModeSymlink != 0 && !o.fs.opt.TranslateSymlinks { if mode&os.ModeSymlink != 0 && !o.fs.opt.TranslateSymlinks {
if !o.fs.opt.SkipSymlinks { if !o.fs.opt.SkipSymlinks {
fs.Logf(o, "Can't follow symlink without -L/--copy-links") fs.Logf(o, "Can't follow symlink without -L/--copy-links")
@ -1079,10 +1079,10 @@ func (file *localOpenFile) Read(p []byte) (n int, err error) {
if err != nil { if err != nil {
return 0, fmt.Errorf("can't read status of source file while transferring: %w", err) return 0, fmt.Errorf("can't read status of source file while transferring: %w", err)
} }
file.o.fs.objectMetaMu.RLock() file.o.metaMu.RLock()
oldtime := file.o.modTime oldtime := file.o.modTime
oldsize := file.o.size oldsize := file.o.size
file.o.fs.objectMetaMu.RUnlock() file.o.metaMu.RUnlock()
if oldsize != fi.Size() { if oldsize != fi.Size() {
return 0, fserrors.NoLowLevelRetryError(fmt.Errorf("can't copy - source file is being updated (size changed from %d to %d)", oldsize, fi.Size())) return 0, fserrors.NoLowLevelRetryError(fmt.Errorf("can't copy - source file is being updated (size changed from %d to %d)", oldsize, fi.Size()))
} }
@ -1104,9 +1104,9 @@ func (file *localOpenFile) Close() (err error) {
err = file.in.Close() err = file.in.Close()
if err == nil { if err == nil {
if file.hash.Size() == file.o.Size() { if file.hash.Size() == file.o.Size() {
file.o.fs.objectMetaMu.Lock() file.o.metaMu.Lock()
file.o.hashes = file.hash.Sums() file.o.hashes = file.hash.Sums()
file.o.fs.objectMetaMu.Unlock() file.o.metaMu.Unlock()
} }
} }
return err return err
@ -1298,9 +1298,9 @@ func (o *Object) Update(ctx context.Context, in io.Reader, src fs.ObjectInfo, op
// All successful so update the hashes // All successful so update the hashes
if hasher != nil { if hasher != nil {
o.fs.objectMetaMu.Lock() o.metaMu.Lock()
o.hashes = hasher.Sums() o.hashes = hasher.Sums()
o.fs.objectMetaMu.Unlock() o.metaMu.Unlock()
} }
// Set the mtime // Set the mtime
@ -1374,11 +1374,11 @@ func (o *Object) setMetadata(info os.FileInfo) {
if o.fs.opt.NoCheckUpdated && !o.modTime.IsZero() { if o.fs.opt.NoCheckUpdated && !o.modTime.IsZero() {
return return
} }
o.fs.objectMetaMu.Lock() o.metaMu.Lock()
o.size = info.Size() o.size = info.Size()
o.modTime = info.ModTime() o.modTime = info.ModTime()
o.mode = info.Mode() o.mode = info.Mode()
o.fs.objectMetaMu.Unlock() o.metaMu.Unlock()
// Read the size of the link. // Read the size of the link.
// //
// The value in info.Size() is not always correct // The value in info.Size() is not always correct
@ -1397,9 +1397,9 @@ func (o *Object) setMetadata(info os.FileInfo) {
// clearHashCache wipes any cached hashes for the object // clearHashCache wipes any cached hashes for the object
func (o *Object) clearHashCache() { func (o *Object) clearHashCache() {
o.fs.objectMetaMu.Lock() o.metaMu.Lock()
o.hashes = nil o.hashes = nil
o.fs.objectMetaMu.Unlock() o.metaMu.Unlock()
} }
// Stat an Object into info // Stat an Object into info