remove MemMepFs limitation
diff --git a/README.md b/README.md
index edf0999..da4c956 100644
--- a/README.md
+++ b/README.md
@@ -357,8 +357,6 @@
permitted. If a file is present in the base layer and the overlay, only the
overlay will be removed/renamed.
-The writable overlay layer is currently limited to MemMapFs.
-
```go
base := afero.NewOsFs()
roBase := afero.NewReadOnlyFs(base)
diff --git a/copyOnWriteFs.go b/copyOnWriteFs.go
index 9f5a2ef..e0d7870 100644
--- a/copyOnWriteFs.go
+++ b/copyOnWriteFs.go
@@ -2,6 +2,7 @@
import (
"os"
+ "path/filepath"
"syscall"
"time"
"fmt"
@@ -12,10 +13,6 @@
// be made in the overlay: Changing an existing file in the base layer which
// is not present in the overlay will copy the file to the overlay ("changing"
// includes also calls to e.g. Chtimes() and Chmod()).
-// The overlay is currently limited to MemMapFs:
-// - missing MkdirAll() calls in the code below, MemMapFs creates them
-// implicitly (or better: records the full path and afero.Readdir()
-// can handle this).
//
// Reading directories is currently only supported via Open(), not OpenFile().
type CopyOnWriteFs struct {
@@ -132,8 +129,30 @@
if err = u.copyToLayer(name); err != nil {
return nil, err
}
+ return u.layer.OpenFile(name, flag, perm)
}
- return u.layer.OpenFile(name, flag, perm)
+
+ dir := filepath.Dir(name)
+ isaDir, err := IsDir(u.base, dir)
+ if err != nil {
+ return nil, err
+ }
+ if isaDir {
+ if err = u.layer.MkdirAll(dir, 0777); err != nil {
+ return nil, err
+ }
+ return u.layer.OpenFile(name, flag, perm)
+ }
+
+ isaDir, err = IsDir(u.layer, dir)
+ if err != nil {
+ return nil, err
+ }
+ if isaDir {
+ return u.layer.OpenFile(name, flag, perm)
+ }
+
+ return nil, &os.PathError{Op: "open", Path: name, Err: syscall.ENOTDIR} // ...or os.ErrNotExist?
}
if b {
return u.base.OpenFile(name, flag, perm)
@@ -217,11 +236,5 @@
}
func (u *CopyOnWriteFs) Create(name string) (File, error) {
- b, err := u.isBaseFile(name)
- if err == nil && b {
- if err = u.copyToLayer(name); err != nil {
- return nil, err
- }
- }
- return u.layer.Create(name)
+ return u.OpenFile(name, os.O_TRUNC|os.O_RDWR, 0666)
}