diff options
author | Boyuan He <heboyuan@google.com> | 2020-08-18 21:51:06 +0000 |
---|---|---|
committer | Andrei Vagin <avagin@gmail.com> | 2020-09-16 12:19:30 -0700 |
commit | b53e10f391929e4ad9345a823a0cf33bcfedf413 (patch) | |
tree | da11060ea42ce01cd3e3611e2eb5087c7e2743b1 /pkg | |
parent | 947088e10a15b5236f2af3206f67f27245ef2770 (diff) |
Implement FUSE_MKNOD
Fixes #3492
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/abi/linux/fuse.go | 43 | ||||
-rw-r--r-- | pkg/sentry/fsimpl/fuse/fusefs.go | 13 |
2 files changed, 56 insertions, 0 deletions
diff --git a/pkg/abi/linux/fuse.go b/pkg/abi/linux/fuse.go index a1b2a2abf..97d960096 100644 --- a/pkg/abi/linux/fuse.go +++ b/pkg/abi/linux/fuse.go @@ -413,3 +413,46 @@ type FUSEReleaseIn struct { // LockOwner is the id of the lock owner if there is one. LockOwner uint64 } + +// FUSEMknodMeta contains all the static fields of FUSEMknodIn, +// which is used for FUSE_MKNOD. +// +// +marshal +type FUSEMknodMeta struct { + // Mode of the inode to create. + Mode uint32 + + // Rdev encodes device major and minor information. + Rdev uint32 + + // Umask is the current file mode creation mask. + Umask uint32 + + _ uint32 +} + +// FUSEMknodIn contains all the arguments sent by the kernel +// to the daemon, to create a new file node. +// +// Dynamically-sized objects cannot be marshalled. +type FUSEMknodIn struct { + marshal.StubMarshallable + + // MknodMeta contains mode, rdev and umash field for FUSE_MKNODS. + MknodMeta FUSEMknodMeta + + // Name is the name of the node to create. + Name string +} + +// MarshalUnsafe serializes r.MknodMeta and r.Name to the dst buffer. +func (r *FUSEMknodIn) MarshalUnsafe(buf []byte) { + r.MknodMeta.MarshalUnsafe(buf[:r.MknodMeta.SizeBytes()]) + copy(buf[r.MknodMeta.SizeBytes():], r.Name) +} + +// SizeBytes is the size of the memory representation of FUSEMknodIn. +// 1 extra byte for null-terminated string. +func (r *FUSEMknodIn) SizeBytes() int { + return r.MknodMeta.SizeBytes() + len(r.Name) + 1 +} diff --git a/pkg/sentry/fsimpl/fuse/fusefs.go b/pkg/sentry/fsimpl/fuse/fusefs.go index b5f05b80b..5cef0b94f 100644 --- a/pkg/sentry/fsimpl/fuse/fusefs.go +++ b/pkg/sentry/fsimpl/fuse/fusefs.go @@ -349,6 +349,19 @@ func (inode) Valid(ctx context.Context) bool { return true } +// NewNode implements kernfs.Inode.NewNode. +func (i *inode) NewNode(ctx context.Context, name string, opts vfs.MknodOptions) (*vfs.Dentry, error) { + in := linux.FUSEMknodIn{ + MknodMeta: linux.FUSEMknodMeta{ + Mode: uint32(opts.Mode), + Rdev: linux.MakeDeviceID(uint16(opts.DevMajor), opts.DevMinor), + Umask: uint32(kernel.TaskFromContext(ctx).FSContext().Umask()), + }, + Name: name, + } + return i.newEntry(ctx, name, opts.Mode.FileType(), linux.FUSE_MKNOD, &in) +} + // newEntry calls FUSE server for entry creation and allocates corresponding entry according to response. // Shared by FUSE_MKNOD, FUSE_MKDIR, FUSE_SYMLINK, FUSE_LINK and FUSE_LOOKUP. func (i *inode) newEntry(ctx context.Context, name string, fileType linux.FileMode, opcode linux.FUSEOpcode, payload marshal.Marshallable) (*vfs.Dentry, error) { |