diff --git a/fuseops/convert.go b/fuseops/convert.go index 87baa23..fb30d8e 100644 --- a/fuseops/convert.go +++ b/fuseops/convert.go @@ -57,15 +57,17 @@ func Convert( } to := &LookUpInodeOp{ - Parent: InodeID(m.Hdr.Nodeid), - Name: string(buf[:n-1]), + protocol: protocol, + Parent: InodeID(m.Hdr.Nodeid), + Name: string(buf[:n-1]), } io = to co = &to.commonOp case fusekernel.OpGetattr: to := &GetInodeAttributesOp{ - Inode: InodeID(m.Hdr.Nodeid), + protocol: protocol, + Inode: InodeID(m.Hdr.Nodeid), } io = to co = &to.commonOp @@ -78,7 +80,8 @@ func Convert( } to := &SetInodeAttributesOp{ - Inode: InodeID(m.Hdr.Nodeid), + protocol: protocol, + Inode: InodeID(m.Hdr.Nodeid), } valid := fusekernel.SetattrValid(in.Valid) @@ -134,10 +137,19 @@ func Convert( name = name[:i] to := &MkDirOp{ - Parent: InodeID(m.Hdr.Nodeid), - Name: string(name), - Mode: fuseshim.FileMode(in.Mode), + protocol: protocol, + Parent: InodeID(m.Hdr.Nodeid), + Name: string(name), + + // On Linux, vfs_mkdir calls through to the inode with at most + // permissions and sticky bits set (cf. https://goo.gl/WxgQXk), and fuse + // passes that on directly (cf. https://goo.gl/f31aMo). In other words, + // the fact that this is a directory is implicit in the fact that the + // opcode is mkdir. But we want the correct mode to go through, so ensure + // that os.ModeDir is set. + Mode: fuseshim.FileMode(in.Mode) | os.ModeDir, } + io = to co = &to.commonOp @@ -157,9 +169,10 @@ func Convert( name = name[:i] to := &CreateFileOp{ - Parent: InodeID(m.Hdr.Nodeid), - Name: string(name), - Mode: fuseshim.FileMode(in.Mode), + protocol: protocol, + Parent: InodeID(m.Hdr.Nodeid), + Name: string(name), + Mode: fuseshim.FileMode(in.Mode), } io = to co = &to.commonOp @@ -179,9 +192,10 @@ func Convert( newName, target := names[0:i], names[i+1:len(names)-1] to := &CreateSymlinkOp{ - Parent: InodeID(m.Hdr.Nodeid), - Name: string(newName), - Target: string(target), + protocol: protocol, + Parent: InodeID(m.Hdr.Nodeid), + Name: string(newName), + Target: string(target), } io = to co = &to.commonOp diff --git a/fuseops/ops.go b/fuseops/ops.go index c3f7c68..cd528f1 100644 --- a/fuseops/ops.go +++ b/fuseops/ops.go @@ -60,6 +60,7 @@ type Op interface { // when resolving user paths to dentry structs, which are then cached. type LookUpInodeOp struct { commonOp + protocol fusekernel.Protocol // The ID of the directory inode to which the child belongs. Parent InodeID @@ -88,7 +89,7 @@ func (o *LookUpInodeOp) ShortDesc() (desc string) { } func (o *LookUpInodeOp) kernelResponse() (msg []byte) { - size := fusekernel.EntryOutSize(fusekernel.Protocol{0, 0}) + size := fusekernel.EntryOutSize(o.protocol) buf := fuseshim.NewBuffer(size) out := (*fusekernel.EntryOut)(buf.Alloc(size)) convertChildInodeEntry(&o.Entry, out) @@ -103,6 +104,7 @@ func (o *LookUpInodeOp) kernelResponse() (msg []byte) { // field of ChildInodeEntry, etc. type GetInodeAttributesOp struct { commonOp + protocol fusekernel.Protocol // The inode of interest. Inode InodeID @@ -123,7 +125,7 @@ func (o *GetInodeAttributesOp) DebugString() string { } func (o *GetInodeAttributesOp) kernelResponse() (msg []byte) { - size := fusekernel.AttrOutSize(fusekernel.Protocol{0, 0}) + size := fusekernel.AttrOutSize(o.protocol) buf := fuseshim.NewBuffer(size) out := (*fusekernel.AttrOut)(buf.Alloc(size)) out.AttrValid, out.AttrValidNsec = convertExpirationTime(o.AttributesExpiration) @@ -139,6 +141,7 @@ func (o *GetInodeAttributesOp) kernelResponse() (msg []byte) { // cases like ftrunctate(2). type SetInodeAttributesOp struct { commonOp + protocol fusekernel.Protocol // The inode of interest. Inode InodeID @@ -157,7 +160,7 @@ type SetInodeAttributesOp struct { } func (o *SetInodeAttributesOp) kernelResponse() (msg []byte) { - size := fusekernel.AttrOutSize(fusekernel.Protocol{0, 0}) + size := fusekernel.AttrOutSize(o.protocol) buf := fuseshim.NewBuffer(size) out := (*fusekernel.AttrOut)(buf.Alloc(size)) out.AttrValid, out.AttrValidNsec = convertExpirationTime(o.AttributesExpiration) @@ -238,6 +241,7 @@ func (o *ForgetInodeOp) kernelResponse() (msg []byte) { // Therefore the file system should return EEXIST if the name already exists. type MkDirOp struct { commonOp + protocol fusekernel.Protocol // The ID of parent directory inode within which to create the child. Parent InodeID @@ -259,7 +263,7 @@ func (o *MkDirOp) ShortDesc() (desc string) { } func (o *MkDirOp) kernelResponse() (msg []byte) { - size := fusekernel.EntryOutSize(fusekernel.Protocol{0, 0}) + size := fusekernel.EntryOutSize(o.protocol) buf := fuseshim.NewBuffer(size) out := (*fusekernel.EntryOut)(buf.Alloc(size)) convertChildInodeEntry(&o.Entry, out) @@ -280,6 +284,7 @@ func (o *MkDirOp) kernelResponse() (msg []byte) { // Therefore the file system should return EEXIST if the name already exists. type CreateFileOp struct { commonOp + protocol fusekernel.Protocol // The ID of parent directory inode within which to create the child file. Parent InodeID @@ -311,7 +316,7 @@ func (o *CreateFileOp) ShortDesc() (desc string) { } func (o *CreateFileOp) kernelResponse() (msg []byte) { - eSize := fusekernel.EntryOutSize(fusekernel.Protocol{0, 0}) + eSize := fusekernel.EntryOutSize(o.protocol) buf := fuseshim.NewBuffer(eSize + unsafe.Sizeof(fusekernel.OpenOut{})) e := (*fusekernel.EntryOut)(buf.Alloc(eSize)) @@ -328,6 +333,7 @@ func (o *CreateFileOp) kernelResponse() (msg []byte) { // return EEXIST (cf. the notes on CreateFileOp and MkDirOp). type CreateSymlinkOp struct { commonOp + protocol fusekernel.Protocol // The ID of parent directory inode within which to create the child symlink. Parent InodeID @@ -357,7 +363,7 @@ func (o *CreateSymlinkOp) ShortDesc() (desc string) { } func (o *CreateSymlinkOp) kernelResponse() (msg []byte) { - size := fusekernel.EntryOutSize(fusekernel.Protocol{0, 0}) + size := fusekernel.EntryOutSize(o.protocol) buf := fuseshim.NewBuffer(size) out := (*fusekernel.EntryOut)(buf.Alloc(size)) convertChildInodeEntry(&o.Entry, out) diff --git a/internal/fusekernel/fuse_kernel_linux.go b/internal/fusekernel/fuse_kernel_linux.go index a464e50..0472e1d 100644 --- a/internal/fusekernel/fuse_kernel_linux.go +++ b/internal/fusekernel/fuse_kernel_linux.go @@ -1,8 +1,8 @@ -package fuseshim +package fusekernel import "time" -type attr struct { +type Attr struct { Ino uint64 Size uint64 Blocks uint64 @@ -21,31 +21,31 @@ type attr struct { padding uint32 } -func (a *attr) Crtime() time.Time { +func (a *Attr) Crtime() time.Time { return time.Time{} } -func (a *attr) SetCrtime(s uint64, ns uint32) { +func (a *Attr) SetCrtime(s uint64, ns uint32) { // Ignored on Linux. } -func (a *attr) SetFlags(f uint32) { +func (a *Attr) SetFlags(f uint32) { // Ignored on Linux. } -type setattrIn struct { +type SetattrIn struct { setattrInCommon } -func (in *setattrIn) BkupTime() time.Time { +func (in *SetattrIn) BkupTime() time.Time { return time.Time{} } -func (in *setattrIn) Chgtime() time.Time { +func (in *SetattrIn) Chgtime() time.Time { return time.Time{} } -func (in *setattrIn) Flags() uint32 { +func (in *SetattrIn) Flags() uint32 { return 0 } @@ -61,10 +61,10 @@ func openFlags(flags uint32) OpenFlags { return OpenFlags(flags) } -type getxattrIn struct { +type GetxattrIn struct { getxattrInCommon } -type setxattrIn struct { +type SetxattrIn struct { setxattrInCommon } diff --git a/internal/fuseshim/unmount_linux.go b/internal/fuseshim/unmount_linux.go index e4c18d6..6a165cc 100644 --- a/internal/fuseshim/unmount_linux.go +++ b/internal/fuseshim/unmount_linux.go @@ -1,4 +1,4 @@ -package bazilfuse +package fuseshim import ( "bytes"