Skip to content

Commit

Permalink
Move already existing inode check into base FS code
Browse files Browse the repository at this point in the history
Linux FUSE doesn't require it, but it will only work correctly in a critical section
  • Loading branch information
vitalif committed Jun 9, 2023
1 parent 23b3e8d commit 901755d
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 40 deletions.
21 changes: 18 additions & 3 deletions internal/dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -1098,7 +1098,7 @@ func (inode *Inode) SendDelete() {
}()
}

func (parent *Inode) Create(name string) (inode *Inode, fh *FileHandle) {
func (parent *Inode) Create(name string) (inode *Inode, fh *FileHandle, err error) {

parent.logFuse("Create", name)

Expand All @@ -1107,6 +1107,11 @@ func (parent *Inode) Create(name string) (inode *Inode, fh *FileHandle) {
parent.mu.Lock()
defer parent.mu.Unlock()

inode = parent.findChildUnlocked(name)
if inode != nil {
return nil, nil, syscall.EEXIST
}

now := time.Now()
inode = NewInode(fs, parent, name)
inode.userMetadata = make(map[string][]byte)
Expand Down Expand Up @@ -1143,6 +1148,11 @@ func (parent *Inode) MkDir(
parent.mu.Lock()
defer parent.mu.Unlock()

inode = parent.findChildUnlocked(name)
if inode != nil {
return nil, syscall.EEXIST
}

inode = parent.doMkDir(name)
inode.mu.Unlock()
parent.fs.WakeupFlusher()
Expand Down Expand Up @@ -1231,7 +1241,7 @@ func (parent *Inode) doMkDir(name string) (inode *Inode) {
}

func (parent *Inode) CreateSymlink(
name string, target string) (inode *Inode) {
name string, target string) (inode *Inode, err error) {

parent.logFuse("CreateSymlink", name)

Expand All @@ -1240,6 +1250,11 @@ func (parent *Inode) CreateSymlink(
parent.mu.Lock()
defer parent.mu.Unlock()

inode = parent.findChildUnlocked(name)
if inode != nil {
return nil, syscall.EEXIST
}

now := time.Now()
inode = NewInode(fs, parent, name)
inode.userMetadata = make(map[string][]byte)
Expand All @@ -1264,7 +1279,7 @@ func (parent *Inode) CreateSymlink(

parent.touch()

return inode
return inode, nil
}

func (inode *Inode) ReadSymlink() (target string, err error) {
Expand Down
15 changes: 12 additions & 3 deletions internal/goofys_fuse.go
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,10 @@ func (fs *GoofysFuse) CreateSymlink(ctx context.Context,
return syscall.ESTALE
}

inode := parent.CreateSymlink(op.Name, op.Target)
inode, err := parent.CreateSymlink(op.Name, op.Target)
if err != nil {
return err
}
op.Entry.Child = inode.Id
op.Entry.Attributes = inode.InflateAttributes()
op.Entry.AttributesExpiration = time.Now().Add(fs.flags.StatCacheTTL)
Expand Down Expand Up @@ -553,7 +556,10 @@ func (fs *GoofysFuse) CreateFile(
return syscall.ESTALE
}

inode, fh := parent.Create(op.Name)
inode, fh, err := parent.Create(op.Name)
if err != nil {
return err
}

// Always take inode locks after fs lock if you need both...
fs.mu.Lock()
Expand Down Expand Up @@ -612,7 +618,10 @@ func (fs *GoofysFuse) MkNode(
}
} else {
var fh *FileHandle
inode, fh = parent.Create(op.Name)
inode, fh, err = parent.Create(op.Name)
if err != nil {
return err
}
fh.Release()
}
inode.Attributes.Rdev = op.Rdev
Expand Down
29 changes: 19 additions & 10 deletions internal/goofys_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1056,9 +1056,10 @@ func (s *GoofysTest) TestReadOffset(t *C) {
func (s *GoofysTest) TestCreateFiles(t *C) {
fileName := "testCreateFile"

_, fh := s.getRoot(t).Create(fileName)
_, fh, err := s.getRoot(t).Create(fileName)
t.Assert(err, IsNil)

err := fh.inode.SyncFile()
err = fh.inode.SyncFile()
t.Assert(err, IsNil)

resp, err := s.cloud.GetBlob(&GetBlobInput{Key: fileName})
Expand Down Expand Up @@ -1375,7 +1376,8 @@ func (s *GoofysTest) TestMkDir(t *C) {
_, err = s.LookUpInode(t, dirName)
t.Assert(err, IsNil)

_, fh := inode.Create(fileName)
_, fh, err := inode.Create(fileName)
t.Assert(err, IsNil)

err = fh.inode.SyncFile()
t.Assert(err, IsNil)
Expand Down Expand Up @@ -3247,7 +3249,8 @@ func (s *GoofysTest) TestDirMtimeCreate(t *C) {
m1 := attr.Mtime
time.Sleep(time.Second)

_, _ = root.Create("foo")
_, _, err := root.Create("foo")
t.Assert(err, IsNil)
attr2 := root.GetAttributes()
m2 := attr2.Mtime

Expand Down Expand Up @@ -3759,7 +3762,8 @@ func (s *GoofysTest) TestVFS(t *C) {
_, err = in.LookUp("file5", false)
t.Assert(err, Equals, syscall.ENOENT)

_, fh := in.Create("testfile")
_, fh, err := in.Create("testfile")
t.Assert(err, IsNil)
err = fh.inode.SyncFile()
t.Assert(err, IsNil)

Expand Down Expand Up @@ -3796,7 +3800,8 @@ func (s *GoofysTest) TestVFS(t *C) {

// create another file inside subdir to make sure that our
// mount check is correct for dir inside the root
_, fh = subdir.Create("testfile2")
_, fh, err = subdir.Create("testfile2")
t.Assert(err, IsNil)
err = fh.inode.SyncFile()
t.Assert(err, IsNil)

Expand Down Expand Up @@ -4083,7 +4088,8 @@ func (s *GoofysTest) testMountsNested(t *C, cloud StorageBackend,

_, err = s.LookUpInode(t, "dir5/in/testfile")
t.Assert(err, Equals, syscall.ENOENT)
_, fh := dir_in.Create("testfile")
_, fh, err := dir_in.Create("testfile")
t.Assert(err, IsNil)
err = fh.inode.SyncFile()
t.Assert(err, IsNil)

Expand All @@ -4093,7 +4099,8 @@ func (s *GoofysTest) testMountsNested(t *C, cloud StorageBackend,

//_, err = s.LookUpInode(t, "dir5/in/a/dir/testfile")
//t.Assert(err, IsNil)
_, fh = dir_dir.Create("testfile")
_, fh, err = dir_dir.Create("testfile")
t.Assert(err, IsNil)
err = fh.inode.SyncFile()
t.Assert(err, IsNil)

Expand Down Expand Up @@ -4357,7 +4364,8 @@ func (s *GoofysTest) TestWriteListFlush(t *C) {
dir, err := root.MkDir("dir")
t.Assert(err, IsNil)

in, fh := dir.Create("file1")
in, fh, err := dir.Create("file1")
t.Assert(err, IsNil)
t.Assert(in, NotNil)
t.Assert(fh, NotNil)

Expand Down Expand Up @@ -4405,7 +4413,8 @@ func (s *GoofysTest) TestWriteUnlinkFlush(t *C) {
dir, err := root.MkDir("dir")
t.Assert(err, IsNil)

in, fh := dir.Create("deleted")
in, fh, err := dir.Create("deleted")
t.Assert(err, IsNil)
t.Assert(in, NotNil)
t.Assert(fh, NotNil)

Expand Down
32 changes: 8 additions & 24 deletions internal/goofys_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,21 +163,18 @@ func (fs *GoofysWin) Mknod(path string, mode uint32, dev uint64) (ret int) {
return mapWinError(err)
}

inode, err := parent.LookUpCached(child)
if err != syscall.ENOENT {
return mapWinError(err)
}
if inode != nil {
return -fuse.EEXIST
}
var inode *Inode
if (mode & fuse.S_IFDIR) != 0 {
inode, err = parent.MkDir(child)
if err != nil {
return mapWinError(err)
}
} else {
var fh *FileHandle
inode, fh = parent.Create(child)
inode, fh, err = parent.Create(child)
if err != nil {
return mapWinError(err)
}
fh.Release()
}
inode.Attributes.Rdev = uint32(dev)
Expand All @@ -202,15 +199,7 @@ func (fs *GoofysWin) Mkdir(path string, mode uint32) (ret int) {
return mapWinError(err)
}

inode, err := parent.LookUpCached(child)
if err != syscall.ENOENT {
return mapWinError(err)
}
if inode != nil {
return -fuse.EEXIST
}

inode, err = parent.MkDir(child)
inode, err := parent.MkDir(child)
if err != nil {
return mapWinError(err)
}
Expand Down Expand Up @@ -436,15 +425,10 @@ func (fs *GoofysWin) Create(path string, flags int, mode uint32) (ret int, fhId
return mapWinError(err), 0
}

inode, err := parent.LookUpCached(child)
if err != syscall.ENOENT {
inode, fh, err := parent.Create(child)
if err != nil {
return mapWinError(err), 0
}
if inode != nil {
return -fuse.EEXIST, 0
}

inode, fh := parent.Create(child)

inode.setFileMode(fuseops.ConvertFileMode(mode))

Expand Down

0 comments on commit 901755d

Please sign in to comment.