Commit 5770d3f1 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Merge remote branch 'origin/master' into tip

parents 14d2b1e7 d0eb74c0
...@@ -65,12 +65,12 @@ type UnionFs struct { ...@@ -65,12 +65,12 @@ type UnionFs struct {
roots []string roots []string
branches []*fuse.LoopbackFileSystem branches []*fuse.LoopbackFileSystem
// The same, but as interfaces. // The same, but as interfaces.
fileSystems []fuse.FileSystem fileSystems []fuse.FileSystem
cachingFileSystems []*CachingFileSystem cachingFileSystems []*CachingFileSystem
// A file-existence cache. // A file-existence cache.
deletionCache *DirCache deletionCache *DirCache
...@@ -153,10 +153,10 @@ type branchResult struct { ...@@ -153,10 +153,10 @@ type branchResult struct {
func (me *UnionFs) getBranchAttrNoCache(name string) branchResult { func (me *UnionFs) getBranchAttrNoCache(name string) branchResult {
name = stripSlash(name) name = stripSlash(name)
parent, base := path.Split(name) parent, base := path.Split(name)
parent = stripSlash(parent) parent = stripSlash(parent)
parentBranch := 0 parentBranch := 0
if base != "" { if base != "" {
parentBranch = me.getBranch(parent).branch parentBranch = me.getBranch(parent).branch
...@@ -168,11 +168,8 @@ func (me *UnionFs) getBranchAttrNoCache(name string) branchResult { ...@@ -168,11 +168,8 @@ func (me *UnionFs) getBranchAttrNoCache(name string) branchResult {
a, s := fs.GetAttr(name) a, s := fs.GetAttr(name)
if s.Ok() { if s.Ok() {
if a.Mode&fuse.S_IFDIR != 0 { // Make all files appear writable
// Make all directories appear writable a.Mode |= 0222
a.Mode |= 0200
}
return branchResult{ return branchResult{
attr: a, attr: a,
code: s, code: s,
...@@ -265,12 +262,12 @@ func (me *UnionFs) Promote(name string, srcResult branchResult) fuse.Status { ...@@ -265,12 +262,12 @@ func (me *UnionFs) Promote(name string, srcResult branchResult) fuse.Status {
// Promote directories. // Promote directories.
me.promoteDirsTo(name) me.promoteDirsTo(name)
_, err := CopyFile(writable.GetPath(name), sourceFs.GetPath(name)) _, err := CopyFile(writable.GetPath(name), sourceFs.GetPath(name))
r := me.getBranch(name) r := me.getBranch(name)
r.branch = 0 r.branch = 0
me.branchCache.Set(name, r) me.branchCache.Set(name, r)
if err != nil { if err != nil {
log.Println("promote error: ", name, err.String()) log.Println("promote error: ", name, err.String())
return fuse.EPERM return fuse.EPERM
...@@ -320,7 +317,7 @@ func (me *UnionFs) Mkdir(path string, mode uint32) (code fuse.Status) { ...@@ -320,7 +317,7 @@ func (me *UnionFs) Mkdir(path string, mode uint32) (code fuse.Status) {
if r.code != fuse.ENOENT { if r.code != fuse.ENOENT {
return syscall.EEXIST return syscall.EEXIST
} }
code = me.promoteDirsTo(path) code = me.promoteDirsTo(path)
if code.Ok() { if code.Ok() {
code = me.fileSystems[0].Mkdir(path, mode) code = me.fileSystems[0].Mkdir(path, mode)
...@@ -354,15 +351,17 @@ func (me *UnionFs) Truncate(path string, offset uint64) (code fuse.Status) { ...@@ -354,15 +351,17 @@ func (me *UnionFs) Truncate(path string, offset uint64) (code fuse.Status) {
if code.Ok() { if code.Ok() {
code = me.fileSystems[0].Truncate(path, offset) code = me.fileSystems[0].Truncate(path, offset)
} }
if code.Ok() { if code.Ok() {
r.attr.Size = int64(offset) r.attr.Size = int64(offset)
r.attr.Mtime_ns = time.Nanoseconds() now := time.Nanoseconds()
r.attr.Mtime_ns = now
r.attr.Ctime_ns = now
me.branchCache.Set(path, r) me.branchCache.Set(path, r)
} }
return code return code
} }
func (me *UnionFs) Utimens(name string, atime uint64, mtime uint64) (code fuse.Status) { func (me *UnionFs) Utimens(name string, atime uint64, mtime uint64) (code fuse.Status) {
name = stripSlash(name) name = stripSlash(name)
r := me.getBranch(name) r := me.getBranch(name)
...@@ -377,6 +376,7 @@ func (me *UnionFs) Utimens(name string, atime uint64, mtime uint64) (code fuse.S ...@@ -377,6 +376,7 @@ func (me *UnionFs) Utimens(name string, atime uint64, mtime uint64) (code fuse.S
if code.Ok() { if code.Ok() {
r.attr.Atime_ns = int64(atime) r.attr.Atime_ns = int64(atime)
r.attr.Mtime_ns = int64(mtime) r.attr.Mtime_ns = int64(mtime)
r.attr.Ctime_ns = time.Nanoseconds()
me.branchCache.Set(name, r) me.branchCache.Set(name, r)
} }
return code return code
...@@ -388,11 +388,11 @@ func (me *UnionFs) Chown(name string, uid uint32, gid uint32) (code fuse.Status) ...@@ -388,11 +388,11 @@ func (me *UnionFs) Chown(name string, uid uint32, gid uint32) (code fuse.Status)
if r.attr == nil || r.code != fuse.OK { if r.attr == nil || r.code != fuse.OK {
return r.code return r.code
} }
if os.Geteuid() != 0 { if os.Geteuid() != 0 {
return fuse.EPERM return fuse.EPERM
} }
if r.attr.Uid != int(uid) || r.attr.Gid != int(gid) { if r.attr.Uid != int(uid) || r.attr.Gid != int(gid) {
if r.branch > 0 { if r.branch > 0 {
code := me.Promote(name, r) code := me.Promote(name, r)
...@@ -488,7 +488,7 @@ func stripSlash(fn string) string { ...@@ -488,7 +488,7 @@ func stripSlash(fn string) string {
func (me *UnionFs) promoteDirsTo(filename string) fuse.Status { func (me *UnionFs) promoteDirsTo(filename string) fuse.Status {
dirName, _ := filepath.Split(filename) dirName, _ := filepath.Split(filename)
dirName = stripSlash(dirName) dirName = stripSlash(dirName)
var todo []string var todo []string
var results []branchResult var results []branchResult
for dirName != "" { for dirName != "" {
...@@ -537,8 +537,11 @@ func (me *UnionFs) Create(name string, flags uint32, mode uint32) (fuseFile fuse ...@@ -537,8 +537,11 @@ func (me *UnionFs) Create(name string, flags uint32, mode uint32) (fuseFile fuse
if code.Ok() { if code.Ok() {
me.removeDeletion(name) me.removeDeletion(name)
now := time.Nanoseconds()
a := os.FileInfo{ a := os.FileInfo{
Mode: fuse.S_IFREG | mode, Mode: fuse.S_IFREG | mode,
Ctime_ns: now,
Mtime_ns: now,
} }
me.branchCache.Set(name, branchResult{&a, fuse.OK, 0}) me.branchCache.Set(name, branchResult{&a, fuse.OK, 0})
} }
...@@ -682,7 +685,7 @@ func (me *UnionFs) Rename(src string, dst string) (code fuse.Status) { ...@@ -682,7 +685,7 @@ func (me *UnionFs) Rename(src string, dst string) (code fuse.Status) {
if code.Ok() { if code.Ok() {
code = me.fileSystems[0].Rename(src, dst) code = me.fileSystems[0].Rename(src, dst)
} }
if code.Ok() { if code.Ok() {
me.removeDeletion(dst) me.removeDeletion(dst)
srcResult.branch = 0 srcResult.branch = 0
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment