mirror of
https://github.com/rclone/rclone.git
synced 2024-11-25 01:44:41 +01:00
mount: fix panic on renames - fixes #1533
Make sure d.items is not nil and improve locking
This commit is contained in:
parent
39d09c04a2
commit
c223464cd0
@ -27,9 +27,9 @@ type Dir struct {
|
|||||||
f fs.Fs
|
f fs.Fs
|
||||||
path string
|
path string
|
||||||
modTime time.Time
|
modTime time.Time
|
||||||
mu sync.RWMutex // protects the following
|
mu sync.Mutex // protects the following
|
||||||
read time.Time // time directory entry last read
|
read time.Time // time directory entry last read
|
||||||
items map[string]*DirEntry
|
items map[string]*DirEntry // NB can be nil when directory not read yet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDir(fsys *FS, f fs.Fs, fsDir fs.Directory) *Dir {
|
func newDir(fsys *FS, f fs.Fs, fsDir fs.Directory) *Dir {
|
||||||
@ -129,7 +129,9 @@ func (d *Dir) addObject(o fs.DirEntry, node Node) *DirEntry {
|
|||||||
Node: node,
|
Node: node,
|
||||||
}
|
}
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
d.items[path.Base(o.Remote())] = item
|
if d.items != nil {
|
||||||
|
d.items[path.Base(o.Remote())] = item
|
||||||
|
}
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
@ -137,16 +139,16 @@ func (d *Dir) addObject(o fs.DirEntry, node Node) *DirEntry {
|
|||||||
// delObject removes an object from the directory
|
// delObject removes an object from the directory
|
||||||
func (d *Dir) delObject(leaf string) {
|
func (d *Dir) delObject(leaf string) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
delete(d.items, leaf)
|
if d.items != nil {
|
||||||
|
delete(d.items, leaf)
|
||||||
|
}
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the directory
|
// read the directory and sets d.items - must be called with the lock held
|
||||||
func (d *Dir) readDir() error {
|
func (d *Dir) _readDir() error {
|
||||||
d.mu.Lock()
|
|
||||||
defer d.mu.Unlock()
|
|
||||||
when := time.Now()
|
when := time.Now()
|
||||||
if d.read.IsZero() {
|
if d.read.IsZero() || d.items == nil {
|
||||||
// fs.Debugf(d.path, "Reading directory")
|
// fs.Debugf(d.path, "Reading directory")
|
||||||
} else {
|
} else {
|
||||||
age := when.Sub(d.read)
|
age := when.Sub(d.read)
|
||||||
@ -184,10 +186,12 @@ func (d *Dir) readDir() error {
|
|||||||
dir := item
|
dir := item
|
||||||
name := path.Base(dir.Remote())
|
name := path.Base(dir.Remote())
|
||||||
// Use old dir value if it exists
|
// Use old dir value if it exists
|
||||||
if oldItem, ok := oldItems[name]; ok {
|
if oldItems != nil {
|
||||||
if _, ok := oldItem.Obj.(fs.Directory); ok {
|
if oldItem, ok := oldItems[name]; ok {
|
||||||
d.items[name] = oldItem
|
if _, ok := oldItem.Obj.(fs.Directory); ok {
|
||||||
continue
|
d.items[name] = oldItem
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.items[name] = &DirEntry{
|
d.items[name] = &DirEntry{
|
||||||
@ -208,13 +212,13 @@ func (d *Dir) readDir() error {
|
|||||||
//
|
//
|
||||||
// returns ENOENT if not found.
|
// returns ENOENT if not found.
|
||||||
func (d *Dir) lookup(leaf string) (*DirEntry, error) {
|
func (d *Dir) lookup(leaf string) (*DirEntry, error) {
|
||||||
err := d.readDir()
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
err := d._readDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
d.mu.RLock()
|
|
||||||
item, ok := d.items[leaf]
|
item, ok := d.items[leaf]
|
||||||
d.mu.RUnlock()
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, ENOENT
|
return nil, ENOENT
|
||||||
}
|
}
|
||||||
@ -223,12 +227,12 @@ func (d *Dir) lookup(leaf string) (*DirEntry, error) {
|
|||||||
|
|
||||||
// Check to see if a directory is empty
|
// Check to see if a directory is empty
|
||||||
func (d *Dir) isEmpty() (bool, error) {
|
func (d *Dir) isEmpty() (bool, error) {
|
||||||
err := d.readDir()
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
err := d._readDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
d.mu.RLock()
|
|
||||||
defer d.mu.RUnlock()
|
|
||||||
return len(d.items) == 0, nil
|
return len(d.items) == 0, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,13 +301,13 @@ func (d *Dir) Lookup(name string) (node Node, err error) {
|
|||||||
// ReadDirAll reads the contents of the directory
|
// ReadDirAll reads the contents of the directory
|
||||||
func (d *Dir) ReadDirAll() (items []*DirEntry, err error) {
|
func (d *Dir) ReadDirAll() (items []*DirEntry, err error) {
|
||||||
// fs.Debugf(d.path, "Dir.ReadDirAll")
|
// fs.Debugf(d.path, "Dir.ReadDirAll")
|
||||||
err = d.readDir()
|
d.mu.Lock()
|
||||||
|
defer d.mu.Unlock()
|
||||||
|
err = d._readDir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Debugf(d.path, "Dir.ReadDirAll error: %v", err)
|
fs.Debugf(d.path, "Dir.ReadDirAll error: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
d.mu.RLock()
|
|
||||||
defer d.mu.RUnlock()
|
|
||||||
for _, item := range d.items {
|
for _, item := range d.items {
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user