Commit fb9b7327 authored by Han-Wen Nienhuys's avatar Han-Wen Nienhuys

fuse: support RENAME2 in RawFileSystem

In practice, this only triggers for RENAME_EXCHANGE, as the kernel
issues the RENAME opcode in case of a normal rename or a
RENAME_NOREPLACE.

We have always advertised rename2 support (protocol v23), but it returned
ENOSYS always. Instead, rename RenameIn => Rename1In, and add Flags to
RenameIn.

For raw filesystems that want to support rename2 should examine
RenameIn.Flags and check for syscall.RENAME_XXX.

For fuse/nodefs, we return ENOSYS in case of Rename2, since we lack
API surface to propagate the flags.
parent afa3a28f
......@@ -305,6 +305,9 @@ func (c *rawBridge) Symlink(header *fuse.InHeader, pointedTo string, linkName st
}
func (c *rawBridge) Rename(input *fuse.RenameIn, oldName string, newName string) (code fuse.Status) {
if input.Flags != 0 {
return fuse.ENOSYS
}
oldParent := c.toInode(input.NodeId)
child := oldParent.GetChild(oldName)
......
......@@ -56,7 +56,7 @@ const (
_OP_BATCH_FORGET = int32(42)
_OP_FALLOCATE = int32(43) // protocol version 19.
_OP_READDIRPLUS = int32(44) // protocol version 21.
_OP_FUSE_RENAME2 = int32(45) // protocol version 23.
_OP_RENAME2 = int32(45) // protocol version 23.
// The following entries don't have to be compatible across Go-FUSE versions.
_OP_NOTIFY_INVAL_ENTRY = int32(100)
......@@ -410,6 +410,15 @@ func doSymlink(server *Server, req *request) {
}
func doRename(server *Server, req *request) {
in1 := (*Rename1In)(req.inData)
in := RenameIn{
InHeader: in1.InHeader,
Newdir: in1.Newdir,
}
req.status = server.fileSystem.Rename(&in, req.filenames[0], req.filenames[1])
}
func doRename2(server *Server, req *request) {
req.status = server.fileSystem.Rename((*RenameIn)(req.inData), req.filenames[0], req.filenames[1])
}
......@@ -499,7 +508,7 @@ func init() {
_OP_SETATTR: unsafe.Sizeof(SetAttrIn{}),
_OP_MKNOD: unsafe.Sizeof(MknodIn{}),
_OP_MKDIR: unsafe.Sizeof(MkdirIn{}),
_OP_RENAME: unsafe.Sizeof(RenameIn{}),
_OP_RENAME: unsafe.Sizeof(Rename1In{}),
_OP_LINK: unsafe.Sizeof(LinkIn{}),
_OP_OPEN: unsafe.Sizeof(OpenIn{}),
_OP_READ: unsafe.Sizeof(ReadIn{}),
......@@ -527,6 +536,7 @@ func init() {
_OP_NOTIFY_REPLY: unsafe.Sizeof(NotifyRetrieveIn{}),
_OP_FALLOCATE: unsafe.Sizeof(FallocateIn{}),
_OP_READDIRPLUS: unsafe.Sizeof(ReadIn{}),
_OP_RENAME2: unsafe.Sizeof(RenameIn{}),
} {
operationHandlers[op].InputSize = sz
}
......@@ -608,6 +618,7 @@ func init() {
_OP_NOTIFY_DELETE: "NOTIFY_DELETE",
_OP_FALLOCATE: "FALLOCATE",
_OP_READDIRPLUS: "READDIRPLUS",
_OP_RENAME2: "RENAME2",
} {
operationHandlers[op].Name = v
}
......@@ -652,6 +663,7 @@ func init() {
_OP_NOTIFY_REPLY: doNotifyReply,
_OP_FALLOCATE: doFallocate,
_OP_READDIRPLUS: doReadDirPlus,
_OP_RENAME2: doRename2,
} {
operationHandlers[op].Func = v
}
......@@ -704,10 +716,11 @@ func init() {
_OP_FALLOCATE: func(ptr unsafe.Pointer) interface{} { return (*FallocateIn)(ptr) },
_OP_NOTIFY_REPLY: func(ptr unsafe.Pointer) interface{} { return (*NotifyRetrieveIn)(ptr) },
_OP_READDIRPLUS: func(ptr unsafe.Pointer) interface{} { return (*ReadIn)(ptr) },
_OP_RENAME: func(ptr unsafe.Pointer) interface{} { return (*RenameIn)(ptr) },
_OP_RENAME: func(ptr unsafe.Pointer) interface{} { return (*Rename1In)(ptr) },
_OP_GETLK: func(ptr unsafe.Pointer) interface{} { return (*LkIn)(ptr) },
_OP_SETLK: func(ptr unsafe.Pointer) interface{} { return (*LkIn)(ptr) },
_OP_SETLKW: func(ptr unsafe.Pointer) interface{} { return (*LkIn)(ptr) },
_OP_RENAME2: func(ptr unsafe.Pointer) interface{} { return (*RenameIn)(ptr) },
} {
operationHandlers[op].DecodeIn = f
}
......@@ -723,6 +736,7 @@ func init() {
_OP_MKNOD: 1,
_OP_REMOVEXATTR: 1,
_OP_RENAME: 2,
_OP_RENAME2: 2,
_OP_RMDIR: 1,
_OP_SYMLINK: 2,
_OP_UNLINK: 1,
......
......@@ -115,8 +115,12 @@ func (me *MkdirIn) string() string {
return fmt.Sprintf("{0%o (0%o)}", me.Mode, me.Umask)
}
func (me *Rename1In) string() string {
return fmt.Sprintf("{i%d}", me.Newdir)
}
func (me *RenameIn) string() string {
return fmt.Sprintf("{%d}", me.Newdir)
return fmt.Sprintf("{i%d %x}", me.Newdir, me.Flags)
}
func (me *SetAttrIn) string() string {
......
......@@ -97,12 +97,12 @@ type MkdirIn struct {
Umask uint32
}
type RenameIn struct {
type Rename1In struct {
InHeader
Newdir uint64
}
type Rename2In struct {
type RenameIn struct {
InHeader
Newdir uint64
Flags uint32
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment