Commit 19ab9e27 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

Only use r/w files for doing SetAttr.

parent 4ec1bc56
...@@ -674,3 +674,18 @@ func TestOriginalIsSymlink(t *testing.T) { ...@@ -674,3 +674,18 @@ func TestOriginalIsSymlink(t *testing.T) {
CheckSuccess(err) CheckSuccess(err)
} }
func TestDoubleOpen(t *testing.T) {
ts := NewTestCase(t)
defer ts.Cleanup()
err := ioutil.WriteFile(ts.orig +"/file", []byte("blabla"), 0644)
CheckSuccess(err)
roFile, err := os.Open(ts.mnt + "/file")
CheckSuccess(err)
defer roFile.Close()
rwFile, err := os.OpenFile(ts.mnt + "/file", os.O_WRONLY | os.O_TRUNC, 0666)
CheckSuccess(err)
defer rwFile.Close()
}
...@@ -68,10 +68,10 @@ func (me *FileSystemConnector) getOpenedFile(h uint64) *openedFile { ...@@ -68,10 +68,10 @@ func (me *FileSystemConnector) getOpenedFile(h uint64) *openedFile {
return b return b
} }
func (me *fileSystemMount) unregisterFileHandle(node *inode, handle uint64) *openedFile { func (me *fileSystemMount) unregisterFileHandle(handle uint64) *openedFile {
obj := me.openFiles.Forget(handle) obj := me.openFiles.Forget(handle)
opened := (*openedFile)(unsafe.Pointer(obj)) opened := (*openedFile)(unsafe.Pointer(obj))
node := opened.inode
node.OpenFilesMutex.Lock() node.OpenFilesMutex.Lock()
defer node.OpenFilesMutex.Unlock() defer node.OpenFilesMutex.Unlock()
...@@ -646,12 +646,11 @@ func (me *FileSystemConnector) unsafeUnmountNode(node *inode) { ...@@ -646,12 +646,11 @@ func (me *FileSystemConnector) unsafeUnmountNode(node *inode) {
unmounted.fs.Unmount() unmounted.fs.Unmount()
} }
func (me *FileSystemConnector) getOpenFileData(nodeid uint64, fh uint64) (f File, m *fileSystemMount, p string, node *inode) { // Returns an openedFile for the gived inode.
func (me *FileSystemConnector) getOpenFileData(nodeid uint64, fh uint64) (opened *openedFile, m *fileSystemMount, p string, node *inode) {
node = me.getInodeData(nodeid) node = me.getInodeData(nodeid)
if fh != 0 { if fh != 0 {
opened := me.getOpenedFile(fh) opened = me.getOpenedFile(fh)
m = opened.fileSystemMount
f = opened.file
} }
path, mount := node.GetPath() path, mount := node.GetPath()
...@@ -664,12 +663,14 @@ func (me *FileSystemConnector) getOpenFileData(nodeid uint64, fh uint64) (f File ...@@ -664,12 +663,14 @@ func (me *FileSystemConnector) getOpenFileData(nodeid uint64, fh uint64) (f File
m = mount m = mount
p = path p = path
} }
if f == nil { if opened == nil {
node.OpenFilesMutex.Lock() node.OpenFilesMutex.Lock()
defer node.OpenFilesMutex.Unlock() defer node.OpenFilesMutex.Unlock()
if len(node.OpenFiles) > 0 { for _, f := range node.OpenFiles {
f = node.OpenFiles[0].file if f.OpenFlags & O_ANYWRITE != 0 || opened == nil {
opened = f
}
} }
} }
return return
......
...@@ -113,13 +113,13 @@ func (me *FileSystemConnector) GetAttr(header *InHeader, input *GetAttrIn) (out ...@@ -113,13 +113,13 @@ func (me *FileSystemConnector) GetAttr(header *InHeader, input *GetAttrIn) (out
fh = input.Fh fh = input.Fh
} }
f, mount, fullPath, node := me.getOpenFileData(header.NodeId, fh) opened, mount, fullPath, node := me.getOpenFileData(header.NodeId, fh)
if mount == nil && f == nil { if mount == nil && opened == nil {
return nil, ENOENT return nil, ENOENT
} }
if f != nil { if opened != nil {
fi, err := f.GetAttr() fi, err := opened.file.GetAttr()
if err != OK && err != ENOSYS { if err != OK && err != ENOSYS {
return nil, err return nil, err
} }
...@@ -198,7 +198,6 @@ func (me *FileSystemConnector) Open(header *InHeader, input *OpenIn) (flags uint ...@@ -198,7 +198,6 @@ func (me *FileSystemConnector) Open(header *InHeader, input *OpenIn) (flags uint
} }
h, opened := mount.registerFileHandle(node, nil, f, input.Flags) h, opened := mount.registerFileHandle(node, nil, f, input.Flags)
return opened.FuseFlags, h, OK return opened.FuseFlags, h, OK
} }
...@@ -212,16 +211,19 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out ...@@ -212,16 +211,19 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
getAttrIn.Flags |= FUSE_GETATTR_FH getAttrIn.Flags |= FUSE_GETATTR_FH
} }
f, mount, fullPath, _ := me.getOpenFileData(header.NodeId, fh) opened, mount, fullPath, _ := me.getOpenFileData(header.NodeId, fh)
if mount == nil { if mount == nil {
return nil, ENOENT return nil, ENOENT
} }
if opened != nil && opened.OpenFlags & O_ANYWRITE == 0 {
opened = nil
}
fileResult := ENOSYS fileResult := ENOSYS
if err.Ok() && input.Valid&FATTR_MODE != 0 { if err.Ok() && input.Valid&FATTR_MODE != 0 {
permissions := uint32(07777) & input.Mode permissions := uint32(07777) & input.Mode
if f != nil { if opened != nil {
fileResult = f.Chmod(permissions) fileResult = opened.file.Chmod(permissions)
} }
if fileResult == ENOSYS { if fileResult == ENOSYS {
err = mount.fs.Chmod(fullPath, permissions, &header.Context) err = mount.fs.Chmod(fullPath, permissions, &header.Context)
...@@ -231,8 +233,8 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out ...@@ -231,8 +233,8 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
} }
} }
if err.Ok() && (input.Valid&(FATTR_UID|FATTR_GID) != 0) { if err.Ok() && (input.Valid&(FATTR_UID|FATTR_GID) != 0) {
if f != nil { if opened != nil {
fileResult = f.Chown(uint32(input.Uid), uint32(input.Gid)) fileResult = opened.file.Chown(uint32(input.Uid), uint32(input.Gid))
} }
if fileResult == ENOSYS { if fileResult == ENOSYS {
...@@ -244,8 +246,8 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out ...@@ -244,8 +246,8 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
} }
} }
if err.Ok() && input.Valid&FATTR_SIZE != 0 { if err.Ok() && input.Valid&FATTR_SIZE != 0 {
if f != nil { if opened != nil {
fileResult = f.Truncate(input.Size) fileResult = opened.file.Truncate(input.Size)
} }
if fileResult == ENOSYS { if fileResult == ENOSYS {
err = mount.fs.Truncate(fullPath, input.Size, &header.Context) err = mount.fs.Truncate(fullPath, input.Size, &header.Context)
...@@ -265,8 +267,8 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out ...@@ -265,8 +267,8 @@ func (me *FileSystemConnector) SetAttr(header *InHeader, input *SetAttrIn) (out
mtime = uint64(time.Nanoseconds()) mtime = uint64(time.Nanoseconds())
} }
if f != nil { if opened != nil {
fileResult = f.Utimens(atime, mtime) fileResult = opened.file.Utimens(atime, mtime)
} }
if fileResult == ENOSYS { if fileResult == ENOSYS {
err = mount.fs.Utimens(fullPath, atime, mtime, &header.Context) err = mount.fs.Utimens(fullPath, atime, mtime, &header.Context)
...@@ -428,9 +430,8 @@ func (me *FileSystemConnector) Create(header *InHeader, input *CreateIn, name st ...@@ -428,9 +430,8 @@ func (me *FileSystemConnector) Create(header *InHeader, input *CreateIn, name st
} }
func (me *FileSystemConnector) Release(header *InHeader, input *ReleaseIn) { func (me *FileSystemConnector) Release(header *InHeader, input *ReleaseIn) {
node := me.getInodeData(header.NodeId) opened := me.getOpenedFile(input.Fh)
opened := node.mount.unregisterFileHandle(node, input.Fh) opened.inode.mount.unregisterFileHandle(input.Fh)
opened.file.Release()
} }
func (me *FileSystemConnector) Flush(input *FlushIn) Status { func (me *FileSystemConnector) Flush(input *FlushIn) Status {
...@@ -453,7 +454,7 @@ func (me *FileSystemConnector) Flush(input *FlushIn) Status { ...@@ -453,7 +454,7 @@ func (me *FileSystemConnector) Flush(input *FlushIn) Status {
func (me *FileSystemConnector) ReleaseDir(header *InHeader, input *ReleaseIn) { func (me *FileSystemConnector) ReleaseDir(header *InHeader, input *ReleaseIn) {
node := me.getInodeData(header.NodeId) node := me.getInodeData(header.NodeId)
opened := node.mount.unregisterFileHandle(node, input.Fh) opened := node.mount.unregisterFileHandle(input.Fh)
opened.dir.Release() opened.dir.Release()
me.considerDropInode(node) me.considerDropInode(node)
} }
......
...@@ -876,8 +876,7 @@ func TestDeletedGetAttr(t *testing.T) { ...@@ -876,8 +876,7 @@ func TestDeletedGetAttr(t *testing.T) {
} }
} }
// Eclipse writes files in this manner: func TestDoubleOpen(t *testing.T) {
func DisabledTestDoubleOpen(t *testing.T) {
wd, clean := setupUfs(t) wd, clean := setupUfs(t)
defer clean() defer clean()
err := ioutil.WriteFile(wd+"/ro/file", []byte("blabla"), 0644) err := ioutil.WriteFile(wd+"/ro/file", []byte("blabla"), 0644)
...@@ -889,4 +888,13 @@ func DisabledTestDoubleOpen(t *testing.T) { ...@@ -889,4 +888,13 @@ func DisabledTestDoubleOpen(t *testing.T) {
rwFile, err := os.OpenFile(wd + "/mount/file", os.O_WRONLY | os.O_TRUNC, 0666) rwFile, err := os.OpenFile(wd + "/mount/file", os.O_WRONLY | os.O_TRUNC, 0666)
CheckSuccess(err) CheckSuccess(err)
defer rwFile.Close() defer rwFile.Close()
output, err := ioutil.ReadAll(roFile)
CheckSuccess(err)
if len(output) != 0 {
t.Errorf("After r/w truncation, r/o file should be empty too:", output)
}
// There are still failure cases here: writes to the r/w will
// not be read back by the ro/o files.
} }
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