forked from TrueCloudLab/rclone
mountlib: store only Node in *Dir removing DirEntry struct
This commit is contained in:
parent
8b6daaa877
commit
2fac74b517
4 changed files with 33 additions and 56 deletions
|
@ -301,7 +301,7 @@ func (fsys *FS) Readdir(dirPath string,
|
||||||
fill(".", nil, 0)
|
fill(".", nil, 0)
|
||||||
fill("..", nil, 0)
|
fill("..", nil, 0)
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
name := path.Base(item.Obj.Remote())
|
name := path.Base(item.DirEntry().Remote())
|
||||||
fill(name, nil, 0)
|
fill(name, nil, 0)
|
||||||
}
|
}
|
||||||
itemsRead = len(items)
|
itemsRead = len(items)
|
||||||
|
|
|
@ -111,7 +111,7 @@ func (d *Dir) ReadDirAll(ctx context.Context) (dirents []fuse.Dirent, err error)
|
||||||
}
|
}
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
var dirent fuse.Dirent
|
var dirent fuse.Dirent
|
||||||
switch x := item.Obj.(type) {
|
switch x := item.DirEntry().(type) {
|
||||||
case fs.Object:
|
case fs.Object:
|
||||||
dirent = fuse.Dirent{
|
dirent = fuse.Dirent{
|
||||||
// Inode FIXME ???
|
// Inode FIXME ???
|
||||||
|
|
|
@ -11,14 +11,6 @@ import (
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// DirEntry describes the contents of a directory entry
|
|
||||||
//
|
|
||||||
// It can be a file or a directory
|
|
||||||
type DirEntry struct {
|
|
||||||
Obj fs.DirEntry
|
|
||||||
Node Node
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dir represents a directory entry
|
// Dir represents a directory entry
|
||||||
type Dir struct {
|
type Dir struct {
|
||||||
fsys *FS
|
fsys *FS
|
||||||
|
@ -28,9 +20,9 @@ type Dir struct {
|
||||||
path string
|
path string
|
||||||
modTime time.Time
|
modTime time.Time
|
||||||
entry fs.Directory
|
entry fs.Directory
|
||||||
mu sync.Mutex // 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 // NB can be nil when directory not read yet
|
items map[string]Node // NB can be nil when directory not read yet
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDir(fsys *FS, f fs.Fs, parent *Dir, fsDir fs.Directory) *Dir {
|
func newDir(fsys *FS, f fs.Fs, parent *Dir, fsDir fs.Directory) *Dir {
|
||||||
|
@ -124,8 +116,8 @@ func (d *Dir) walk(absPath string, fun func(*Dir)) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
if d.items != nil {
|
if d.items != nil {
|
||||||
for _, entry := range d.items {
|
for _, node := range d.items {
|
||||||
if dir, ok := entry.Node.(*Dir); ok {
|
if dir, ok := node.(*Dir); ok {
|
||||||
dir.walk(absPath, fun)
|
dir.walk(absPath, fun)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,17 +144,12 @@ func (d *Dir) rename(newParent *Dir, fsDir fs.Directory) {
|
||||||
// addObject adds a new object or directory to the directory
|
// addObject adds a new object or directory to the directory
|
||||||
//
|
//
|
||||||
// note that we add new objects rather than updating old ones
|
// note that we add new objects rather than updating old ones
|
||||||
func (d *Dir) addObject(o fs.DirEntry, node Node) *DirEntry {
|
func (d *Dir) addObject(node Node) {
|
||||||
item := &DirEntry{
|
|
||||||
Obj: o,
|
|
||||||
Node: node,
|
|
||||||
}
|
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
if d.items != nil {
|
if d.items != nil {
|
||||||
d.items[path.Base(o.Remote())] = item
|
d.items[node.Name()] = node
|
||||||
}
|
}
|
||||||
d.mu.Unlock()
|
d.mu.Unlock()
|
||||||
return item
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// delObject removes an object from the directory
|
// delObject removes an object from the directory
|
||||||
|
@ -201,32 +188,26 @@ func (d *Dir) _readDir() error {
|
||||||
oldItems := d.items
|
oldItems := d.items
|
||||||
|
|
||||||
// Cache the items by name
|
// Cache the items by name
|
||||||
d.items = make(map[string]*DirEntry, len(entries))
|
d.items = make(map[string]Node, len(entries))
|
||||||
for _, entry := range entries {
|
for _, entry := range entries {
|
||||||
switch item := entry.(type) {
|
switch item := entry.(type) {
|
||||||
case fs.Object:
|
case fs.Object:
|
||||||
obj := item
|
obj := item
|
||||||
name := path.Base(obj.Remote())
|
name := path.Base(obj.Remote())
|
||||||
d.items[name] = &DirEntry{
|
d.items[name] = newFile(d, obj, name)
|
||||||
Obj: obj,
|
|
||||||
Node: newFile(d, obj, name),
|
|
||||||
}
|
|
||||||
case fs.Directory:
|
case fs.Directory:
|
||||||
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 oldItems != nil {
|
if oldItems != nil {
|
||||||
if oldItem, ok := oldItems[name]; ok {
|
if oldNode, ok := oldItems[name]; ok {
|
||||||
if _, ok := oldItem.Obj.(fs.Directory); ok {
|
if oldNode.IsDir() {
|
||||||
d.items[name] = oldItem
|
d.items[name] = oldNode
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d.items[name] = &DirEntry{
|
d.items[name] = newDir(d.fsys, d.f, d, dir)
|
||||||
Obj: dir,
|
|
||||||
Node: newDir(d.fsys, d.f, d, dir),
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
err = errors.Errorf("unknown type %T", item)
|
err = errors.Errorf("unknown type %T", item)
|
||||||
fs.Errorf(d.path, "readDir error: %v", err)
|
fs.Errorf(d.path, "readDir error: %v", err)
|
||||||
|
@ -240,7 +221,7 @@ func (d *Dir) _readDir() error {
|
||||||
// lookup a single item in the directory
|
// lookup a single item in the directory
|
||||||
//
|
//
|
||||||
// returns ENOENT if not found.
|
// returns ENOENT if not found.
|
||||||
func (d *Dir) lookup(leaf string) (*DirEntry, error) {
|
func (d *Dir) lookup(leaf string) (Node, error) {
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
err := d._readDir()
|
err := d._readDir()
|
||||||
|
@ -296,7 +277,7 @@ func (d *Dir) SetModTime(modTime time.Time) error {
|
||||||
func (d *Dir) Lookup(name string) (node Node, err error) {
|
func (d *Dir) Lookup(name string) (node Node, err error) {
|
||||||
path := path.Join(d.path, name)
|
path := path.Join(d.path, name)
|
||||||
// fs.Debugf(path, "Dir.Lookup")
|
// fs.Debugf(path, "Dir.Lookup")
|
||||||
item, err := d.lookup(name)
|
node, err = d.lookup(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != ENOENT {
|
if err != ENOENT {
|
||||||
fs.Errorf(path, "Dir.Lookup error: %v", err)
|
fs.Errorf(path, "Dir.Lookup error: %v", err)
|
||||||
|
@ -304,11 +285,11 @@ func (d *Dir) Lookup(name string) (node Node, err error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// fs.Debugf(path, "Dir.Lookup OK")
|
// fs.Debugf(path, "Dir.Lookup OK")
|
||||||
return item.Node, nil
|
return node, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 []Node, err error) {
|
||||||
// fs.Debugf(d.path, "Dir.ReadDirAll")
|
// fs.Debugf(d.path, "Dir.ReadDirAll")
|
||||||
d.mu.Lock()
|
d.mu.Lock()
|
||||||
defer d.mu.Unlock()
|
defer d.mu.Unlock()
|
||||||
|
@ -357,7 +338,7 @@ func (d *Dir) Mkdir(name string) (*Dir, error) {
|
||||||
}
|
}
|
||||||
fsDir := fs.NewDir(path, time.Now())
|
fsDir := fs.NewDir(path, time.Now())
|
||||||
dir := newDir(d.fsys, d.f, d, fsDir)
|
dir := newDir(d.fsys, d.f, d, fsDir)
|
||||||
d.addObject(fsDir, dir)
|
d.addObject(dir)
|
||||||
// fs.Debugf(path, "Dir.Mkdir OK")
|
// fs.Debugf(path, "Dir.Mkdir OK")
|
||||||
return dir, nil
|
return dir, nil
|
||||||
}
|
}
|
||||||
|
@ -396,15 +377,15 @@ func (d *Dir) RemoveAll() error {
|
||||||
return EROFS
|
return EROFS
|
||||||
}
|
}
|
||||||
// Remove contents of the directory
|
// Remove contents of the directory
|
||||||
items, err := d.ReadDirAll()
|
nodes, err := d.ReadDirAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(d.path, "Dir.RemoveAll failed to read directory: %v", err)
|
fs.Errorf(d.path, "Dir.RemoveAll failed to read directory: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, item := range items {
|
for _, node := range nodes {
|
||||||
err = item.Node.RemoveAll()
|
err = node.RemoveAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(item.Obj, "Dir.RemoveAll failed to remove: %v", err)
|
fs.Errorf(node.DirEntry(), "Dir.RemoveAll failed to remove: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -425,12 +406,12 @@ func (d *Dir) RemoveName(name string) error {
|
||||||
}
|
}
|
||||||
path := path.Join(d.path, name)
|
path := path.Join(d.path, name)
|
||||||
// fs.Debugf(path, "Dir.Remove")
|
// fs.Debugf(path, "Dir.Remove")
|
||||||
item, err := d.lookup(name)
|
node, err := d.lookup(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(path, "Dir.Remove error: %v", err)
|
fs.Errorf(path, "Dir.Remove error: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return item.Node.Remove()
|
return node.Remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename the file
|
// Rename the file
|
||||||
|
@ -441,14 +422,12 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
||||||
oldPath := path.Join(d.path, oldName)
|
oldPath := path.Join(d.path, oldName)
|
||||||
newPath := path.Join(destDir.path, newName)
|
newPath := path.Join(destDir.path, newName)
|
||||||
// fs.Debugf(oldPath, "Dir.Rename to %q", newPath)
|
// fs.Debugf(oldPath, "Dir.Rename to %q", newPath)
|
||||||
oldItem, err := d.lookup(oldName)
|
oldNode, err := d.lookup(oldName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fs.Errorf(oldPath, "Dir.Rename error: %v", err)
|
fs.Errorf(oldPath, "Dir.Rename error: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var newObj fs.DirEntry
|
switch x := oldNode.DirEntry().(type) {
|
||||||
oldNode := oldItem.Node
|
|
||||||
switch x := oldItem.Obj.(type) {
|
|
||||||
case fs.Object:
|
case fs.Object:
|
||||||
oldObject := x
|
oldObject := x
|
||||||
// FIXME: could Copy then Delete if Move not available
|
// FIXME: could Copy then Delete if Move not available
|
||||||
|
@ -464,11 +443,10 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
||||||
fs.Errorf(oldPath, "Dir.Rename error: %v", err)
|
fs.Errorf(oldPath, "Dir.Rename error: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
newObj = newObject
|
|
||||||
// Update the node with the new details
|
// Update the node with the new details
|
||||||
if oldNode != nil {
|
if oldNode != nil {
|
||||||
if oldFile, ok := oldNode.(*File); ok {
|
if oldFile, ok := oldNode.(*File); ok {
|
||||||
fs.Debugf(oldItem.Obj, "Updating file with %v %p", newObject, oldFile)
|
fs.Debugf(oldNode.DirEntry(), "Updating file with %v %p", newObject, oldFile)
|
||||||
oldFile.rename(destDir, newObject)
|
oldFile.rename(destDir, newObject)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -487,23 +465,22 @@ func (d *Dir) Rename(oldName, newName string, destDir *Dir) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
newDir := fs.NewDirCopy(x).SetRemote(newPath)
|
newDir := fs.NewDirCopy(x).SetRemote(newPath)
|
||||||
newObj = newDir
|
|
||||||
// Update the node with the new details
|
// Update the node with the new details
|
||||||
if oldNode != nil {
|
if oldNode != nil {
|
||||||
if oldDir, ok := oldNode.(*Dir); ok {
|
if oldDir, ok := oldNode.(*Dir); ok {
|
||||||
fs.Debugf(oldItem.Obj, "Updating dir with %v %p", newDir, oldDir)
|
fs.Debugf(oldNode.DirEntry(), "Updating dir with %v %p", newDir, oldDir)
|
||||||
oldDir.rename(destDir, newDir)
|
oldDir.rename(destDir, newDir)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
err = errors.Errorf("unknown type %T", oldItem)
|
err = errors.Errorf("unknown type %T", oldNode)
|
||||||
fs.Errorf(d.path, "Dir.ReadDirAll error: %v", err)
|
fs.Errorf(d.path, "Dir.ReadDirAll error: %v", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Show moved - delete from old dir and add to new
|
// Show moved - delete from old dir and add to new
|
||||||
d.delObject(oldName)
|
d.delObject(oldName)
|
||||||
destDir.addObject(newObj, oldNode)
|
destDir.addObject(oldNode)
|
||||||
|
|
||||||
// fs.Debugf(newPath, "Dir.Rename renamed from %q", oldPath)
|
// fs.Debugf(newPath, "Dir.Rename renamed from %q", oldPath)
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -179,7 +179,7 @@ func (f *File) setObject(o fs.Object) {
|
||||||
defer f.mu.Unlock()
|
defer f.mu.Unlock()
|
||||||
f.o = o
|
f.o = o
|
||||||
_ = f.applyPendingModTime()
|
_ = f.applyPendingModTime()
|
||||||
f.d.addObject(o, f)
|
f.d.addObject(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for f.o to become non nil for a short time returning it or an
|
// Wait for f.o to become non nil for a short time returning it or an
|
||||||
|
|
Loading…
Reference in a new issue