diff --git a/cmd/cmount/fs.go b/cmd/cmount/fs.go index bcbf76b4f..567d44d3e 100644 --- a/cmd/cmount/fs.go +++ b/cmd/cmount/fs.go @@ -298,7 +298,11 @@ func (fsys *FS) Create(filePath string, flags int, mode uint32) (errc int, fh ui if errc != 0 { return errc, fhUnset } - _, handle, err := parentDir.Create(leaf) + file, err := parentDir.Create(leaf) + if err != nil { + return translateError(err), fhUnset + } + handle, err := file.Open(flags) if err != nil { return translateError(err), fhUnset } diff --git a/cmd/mount/dir.go b/cmd/mount/dir.go index 1155b1353..4a4079240 100644 --- a/cmd/mount/dir.go +++ b/cmd/mount/dir.go @@ -122,7 +122,11 @@ var _ fusefs.NodeCreater = (*Dir)(nil) // Create makes a new file func (d *Dir) Create(ctx context.Context, req *fuse.CreateRequest, resp *fuse.CreateResponse) (node fusefs.Node, handle fusefs.Handle, err error) { defer fs.Trace(d, "name=%q", req.Name)("node=%v, handle=%v, err=%v", &node, &handle, &err) - file, fh, err := d.Dir.Create(req.Name) + file, err := d.Dir.Create(req.Name) + if err != nil { + return nil, nil, translateError(err) + } + fh, err := file.Open(int(req.Flags)) if err != nil { return nil, nil, translateError(err) } diff --git a/vfs/dir.go b/vfs/dir.go index 8fffb0b42..a75de3998 100644 --- a/vfs/dir.go +++ b/vfs/dir.go @@ -316,23 +316,14 @@ func (d *Dir) Open(flags int) (fd Handle, err error) { return newDirHandle(d), nil } -// Create makes a new file -func (d *Dir) Create(name string) (*File, *WriteFileHandle, error) { - if d.vfs.Opt.ReadOnly { - return nil, nil, EROFS - } - path := path.Join(d.path, name) +// Create makes a new file node +func (d *Dir) Create(name string) (*File, error) { // fs.Debugf(path, "Dir.Create") - src := newCreateInfo(d.f, path) - // This gets added to the directory when the file is written - file := newFile(d, nil, name) - fh, err := newWriteFileHandle(d, file, src) - if err != nil { - fs.Errorf(d, "Dir.Create error: %v", err) - return nil, nil, err + if d.vfs.Opt.ReadOnly { + return nil, EROFS } - // fs.Debugf(path, "Dir.Create OK") - return file, fh, nil + // This gets added to the directory when the file is written + return newFile(d, nil, name), nil } // Mkdir creates a new directory diff --git a/vfs/dir_test.go b/vfs/dir_test.go index 5f3cf0016..f1724572e 100644 --- a/vfs/dir_test.go +++ b/vfs/dir_test.go @@ -278,10 +278,13 @@ func TestDirCreate(t *testing.T) { defer r.Finalise() vfs, dir, _ := dirCreate(t, r) - file, fd, err := dir.Create("potato") + file, err := dir.Create("potato") require.NoError(t, err) assert.Equal(t, int64(0), file.Size()) + fd, err := file.Open(os.O_WRONLY) + require.NoError(t, err) + // FIXME Note that this fails with the current implementation // until the file has been opened. @@ -300,7 +303,7 @@ func TestDirCreate(t *testing.T) { assert.Equal(t, int64(5), file2.Size()) vfs.Opt.ReadOnly = true - _, _, err = dir.Create("sausage") + _, err = dir.Create("sausage") assert.Equal(t, EROFS, err) } diff --git a/vfs/file.go b/vfs/file.go index f32dcd0cf..70fb8da67 100644 --- a/vfs/file.go +++ b/vfs/file.go @@ -33,12 +33,17 @@ func newFile(d *Dir, o fs.Object, leaf string) *File { } } +// path returns the full path of the file +func (f *File) path() string { + return path.Join(f.d.path, f.leaf) +} + // String converts it to printable func (f *File) String() string { if f == nil { return "" } - return path.Join(f.d.path, f.leaf) + return f.path() } // IsFile returns true for File - satisfies Node interface @@ -228,14 +233,9 @@ func (f *File) OpenWrite() (fh *WriteFileHandle, err error) { if f.d.vfs.Opt.ReadOnly { return nil, EROFS } - // if o is nil it isn't valid yet - o, err := f.waitForValidObject() - if err != nil { - return nil, err - } // fs.Debugf(o, "File.OpenWrite") - src := newCreateInfo(f.d.f, o.Remote()) + src := newCreateInfo(f.d.f, f.path()) fh, err = newWriteFileHandle(f.d, f, src) err = errors.Wrap(err, "open for write") diff --git a/vfs/vfs.go b/vfs/vfs.go index 598b86499..40ac5a132 100644 --- a/vfs/vfs.go +++ b/vfs/vfs.go @@ -266,15 +266,18 @@ func (vfs *VFS) StatParent(name string) (dir *Dir, leaf string, err error) { func (vfs *VFS) OpenFile(name string, flags int, perm os.FileMode) (fd Handle, err error) { node, err := vfs.Stat(name) if err != nil { - if err == ENOENT && flags&os.O_CREATE != 0 { - dir, leaf, err := vfs.StatParent(name) - if err != nil { - return nil, err - } - _, fd, err = dir.Create(leaf) - return fd, err + if err != ENOENT || flags&os.O_CREATE == 0 { + return nil, err + } + // If not found and O_CREATE then create the file + dir, leaf, err := vfs.StatParent(name) + if err != nil { + return nil, err + } + node, err = dir.Create(leaf) + if err != nil { + return nil, err } - return nil, err } return node.Open(flags) }