Commit bad4ee66 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Kludge up setattr/getattr handling for UnionFs.

parent 524a7603
......@@ -150,7 +150,7 @@ func (me *fsInode) Lookup(name string) (fi *os.FileInfo, code Status) {
}
func (me *fsInode) GetAttr(file File, context *Context) (fi *os.FileInfo, code Status) {
if file == nil && me.Parent == nil && me.inode.mountPoint == nil {
if file == nil {
// called on a deleted files.
file = me.inode.getAnyFile()
}
......
......@@ -249,14 +249,17 @@ func (me *inode) getMountDirEntries() (out []DirEntry) {
return out
}
// Returns any open file, preferably a r/w one.
func (me *inode) getAnyFile() (file File) {
me.OpenFilesMutex.Lock()
defer me.OpenFilesMutex.Unlock()
for _, f := range me.OpenFiles {
return f.file
if file == nil || f.OpenFlags & O_ANYWRITE != 0 {
file = f.file
}
}
return nil
return file
}
// Returns an open writable file for the given inode.
......
......@@ -159,21 +159,15 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
}
node := me.getInodeData(header.NodeId)
fi, code := node.fsInode.GetAttr(f, &header.Context)
if code.Ok() && input.Valid&FATTR_MODE != 0 {
permissions := uint32(07777) & input.Mode
code = node.fsInode.Chmod(f, permissions, &header.Context)
fi.Mode = (fi.Mode &^ 07777) | permissions
}
if code.Ok() && (input.Valid&(FATTR_UID|FATTR_GID) != 0) {
code = node.fsInode.Chown(f, uint32(input.Uid), uint32(input.Gid), &header.Context)
fi.Uid = int(input.Uid)
fi.Gid = int(input.Gid)
}
if code.Ok() && input.Valid&FATTR_SIZE != 0 {
code = node.fsInode.Truncate(f, input.Size, &header.Context)
fi.Size = int64(input.Size)
}
if code.Ok() && (input.Valid&(FATTR_ATIME|FATTR_MTIME|FATTR_ATIME_NOW|FATTR_MTIME_NOW) != 0) {
atime := uint64(input.Atime*1e9) + uint64(input.Atimensec)
......@@ -188,14 +182,15 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
// TODO - if using NOW, mtime and atime may differ.
code = node.fsInode.Utimens(f, atime, mtime, &header.Context)
fi.Atime_ns = int64(atime)
fi.Mtime_ns = int64(mtime)
}
if !code.Ok() {
return nil, code
}
// Must call GetAttr(); the filesystem may override some of
// the changes we effect here.
fi, code := node.fsInode.GetAttr(f, &header.Context)
out = &AttrOut{}
out.Attr.Ino = header.NodeId
node.mount.fileInfoToAttr(fi, out)
......
......@@ -863,7 +863,11 @@ func (me *UnionFs) Open(name string, flags uint32, context *fuse.Context) (fuseF
r.attr.Mtime_ns = time.Nanoseconds()
me.branchCache.Set(name, r)
}
return me.fileSystems[r.branch].Open(name, uint32(flags), context)
fuseFile, status = me.fileSystems[r.branch].Open(name, uint32(flags), context)
if fuseFile != nil {
fuseFile = &UnionFsFile{fuseFile}
}
return fuseFile, status
}
func (me *UnionFs) Flush(name string) fuse.Status {
......@@ -879,3 +883,17 @@ func (me *UnionFs) Name() string {
}
return fmt.Sprintf("%v", names)
}
type UnionFsFile struct {
fuse.File
}
func (me *UnionFsFile) GetAttr() (*os.FileInfo, fuse.Status) {
fi, code := me.File.GetAttr()
if fi != nil {
f := *fi
fi = &f
fi.Mode |= 0222
}
return fi, code
}
......@@ -193,12 +193,6 @@ func TestChmod(t *testing.T) {
err := os.Chmod(m_fn, 07070)
CheckSuccess(err)
err = os.Chown(m_fn, 0, 0)
code := fuse.OsErrorToErrno(err)
if code != fuse.EPERM {
t.Error("Unexpected error code", code, err)
}
fi, err := os.Lstat(m_fn)
CheckSuccess(err)
if fi.Mode&07777 != 07272 {
......@@ -210,6 +204,21 @@ func TestChmod(t *testing.T) {
}
}
func TestChown(t *testing.T) {
wd, clean := setupUfs(t)
defer clean()
ro_fn := wd + "/ro/file"
m_fn := wd + "/mount/file"
writeToFile(ro_fn, "a")
err := os.Chown(m_fn, 0, 0)
code := fuse.OsErrorToErrno(err)
if code != fuse.EPERM {
t.Error("Unexpected error code", code, err)
}
}
func TestDelete(t *testing.T) {
wd, clean := setupUfs(t)
defer clean()
......@@ -857,7 +866,6 @@ func TestDisappearing(t *testing.T) {
}
func TestDeletedGetAttr(t *testing.T) {
t.Log("TestDeletedGetAttr")
wd, clean := setupUfs(t)
defer clean()
......
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