From 1b4a34cc7b6f1520582638ebe8afd24783f82125 Mon Sep 17 00:00:00 2001 From: Srdjan Rilak Date: Fri, 24 Nov 2017 12:44:41 +0100 Subject: [PATCH] Add CreateLink implementation --- conversions.go | 31 +++++++++++++++++++++++++ fuseops/ops.go | 20 ++++++++++++++++ fuseutil/file_system.go | 4 ++++ fuseutil/not_implemented_file_system.go | 7 ++++++ 4 files changed, 62 insertions(+) diff --git a/conversions.go b/conversions.go index 6b0f16e..66be34f 100644 --- a/conversions.go +++ b/conversions.go @@ -420,6 +420,32 @@ func convertInMessage( Flags: fusekernel.InitFlags(in.Flags), } + case fusekernel.OpLink: + type input fusekernel.LinkIn + in := (*input)(inMsg.Consume(unsafe.Sizeof(input{}))) + if in == nil { + err = errors.New("Corrupt OpLink") + return + } + + name := inMsg.ConsumeBytes(inMsg.Len()) + i := bytes.IndexByte(name, '\x00') + if i < 0 { + err = errors.New("Corrupt OpLink") + return + } + name = name[:i] + if len(name) == 0 { + err = errors.New("Corrupt OpLink (Name not read)") + return + } + + o = &fuseops.CreateLinkOp{ + Parent: fuseops.InodeID(inMsg.Header().Nodeid), + Name: string(name), + Target: fuseops.InodeID(in.Oldnodeid), + } + case fusekernel.OpRemovexattr: buf := inMsg.ConsumeBytes(inMsg.Len()) n := len(buf) @@ -647,6 +673,11 @@ func (c *Connection) kernelResponseForOp( out := (*fusekernel.EntryOut)(m.Grow(size)) convertChildInodeEntry(&o.Entry, out) + case *fuseops.CreateLinkOp: + size := int(fusekernel.EntryOutSize(c.protocol)) + out := (*fusekernel.EntryOut)(m.Grow(size)) + convertChildInodeEntry(&o.Entry, out) + case *fuseops.RenameOp: // Empty response diff --git a/fuseops/ops.go b/fuseops/ops.go index a939799..56fe89c 100644 --- a/fuseops/ops.go +++ b/fuseops/ops.go @@ -317,6 +317,26 @@ type CreateSymlinkOp struct { Entry ChildInodeEntry } +// Create a hard link to an inode. If the name already exists, the file system +// should return EEXIST (cf. the notes on CreateFileOp and MkDirOp). +type CreateLinkOp struct { + // The ID of parent directory inode within which to create the child hard + // link. + Parent InodeID + + // The name of the new inode. + Name string + + // The ID of the target inode. + Target InodeID + + // Set by the file system: information about the inode that was created. + // + // The lookup count for the inode is implicitly incremented. See notes on + // ForgetInodeOp for more information. + Entry ChildInodeEntry +} + //////////////////////////////////////////////////////////////////////// // Unlinking //////////////////////////////////////////////////////////////////////// diff --git a/fuseutil/file_system.go b/fuseutil/file_system.go index fce16db..3a2a2cc 100644 --- a/fuseutil/file_system.go +++ b/fuseutil/file_system.go @@ -43,6 +43,7 @@ type FileSystem interface { MkDir(context.Context, *fuseops.MkDirOp) error MkNode(context.Context, *fuseops.MkNodeOp) error CreateFile(context.Context, *fuseops.CreateFileOp) error + CreateLink(context.Context, *fuseops.CreateLinkOp) error CreateSymlink(context.Context, *fuseops.CreateSymlinkOp) error Rename(context.Context, *fuseops.RenameOp) error RmDir(context.Context, *fuseops.RmDirOp) error @@ -159,6 +160,9 @@ func (s *fileSystemServer) handleOp( case *fuseops.CreateFileOp: err = s.fs.CreateFile(ctx, typed) + case *fuseops.CreateLinkOp: + err = s.fs.CreateLink(ctx, typed) + case *fuseops.CreateSymlinkOp: err = s.fs.CreateSymlink(ctx, typed) diff --git a/fuseutil/not_implemented_file_system.go b/fuseutil/not_implemented_file_system.go index b21e1e3..15cc1a0 100644 --- a/fuseutil/not_implemented_file_system.go +++ b/fuseutil/not_implemented_file_system.go @@ -92,6 +92,13 @@ func (fs *NotImplementedFileSystem) CreateSymlink( return } +func (fs *NotImplementedFileSystem) CreateLink( + ctx context.Context, + op *fuseops.CreateLinkOp) (err error) { + err = fuse.ENOSYS + return +} + func (fs *NotImplementedFileSystem) Rename( ctx context.Context, op *fuseops.RenameOp) (err error) {