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

Implement RemoveXAttr.

parent 648e8455
...@@ -522,6 +522,15 @@ func (me *SubmountFileSystem) GetXAttr(header *fuse.InHeader, attr string) (data ...@@ -522,6 +522,15 @@ func (me *SubmountFileSystem) GetXAttr(header *fuse.InHeader, attr string) (data
return subfs.Fs.GetXAttr(header, attr) return subfs.Fs.GetXAttr(header, attr)
} }
func (me *SubmountFileSystem) RemoveXAttr(header *fuse.InHeader, attr string) (code fuse.Status) {
var subfs *subFsInfo
header.NodeId, subfs = me.getSubFs(header.NodeId)
if subfs == nil {
return fuse.ENOENT
}
return subfs.Fs.RemoveXAttr(header, attr)
}
func (me *SubmountFileSystem) Access(header *fuse.InHeader, input *fuse.AccessIn) (code fuse.Status) { func (me *SubmountFileSystem) Access(header *fuse.InHeader, input *fuse.AccessIn) (code fuse.Status) {
var subfs *subFsInfo var subfs *subFsInfo
header.NodeId, subfs = me.getSubFs(header.NodeId) header.NodeId, subfs = me.getSubFs(header.NodeId)
......
...@@ -77,6 +77,10 @@ func (me *DefaultRawFuseFileSystem) ListXAttr(header *InHeader) (data []byte, co ...@@ -77,6 +77,10 @@ func (me *DefaultRawFuseFileSystem) ListXAttr(header *InHeader) (data []byte, co
return nil, ENOSYS return nil, ENOSYS
} }
func (me *DefaultRawFuseFileSystem) RemoveXAttr(header *InHeader, attr string) (Status) {
return ENOSYS
}
func (me *DefaultRawFuseFileSystem) Access(header *InHeader, input *AccessIn) (code Status) { func (me *DefaultRawFuseFileSystem) Access(header *InHeader, input *AccessIn) (code Status) {
return ENOSYS return ENOSYS
} }
...@@ -166,6 +170,10 @@ func (me *DefaultPathFilesystem) ListXAttr(name string) ([]string, Status) { ...@@ -166,6 +170,10 @@ func (me *DefaultPathFilesystem) ListXAttr(name string) ([]string, Status) {
return nil, ENOSYS return nil, ENOSYS
} }
func (me *DefaultPathFilesystem) RemoveXAttr(name string, attr string) (Status) {
return ENOSYS
}
func (me *DefaultPathFilesystem) Readlink(name string) (string, Status) { func (me *DefaultPathFilesystem) Readlink(name string) (string, Status) {
return "", ENOSYS return "", ENOSYS
} }
......
...@@ -382,7 +382,8 @@ func (me *MountState) dispatch(req *fuseRequest) { ...@@ -382,7 +382,8 @@ func (me *MountState) dispatch(req *fuseRequest) {
if h.Opcode == FUSE_UNLINK || h.Opcode == FUSE_RMDIR || if h.Opcode == FUSE_UNLINK || h.Opcode == FUSE_RMDIR ||
h.Opcode == FUSE_LOOKUP || h.Opcode == FUSE_MKDIR || h.Opcode == FUSE_LOOKUP || h.Opcode == FUSE_MKDIR ||
h.Opcode == FUSE_MKNOD || h.Opcode == FUSE_CREATE || h.Opcode == FUSE_MKNOD || h.Opcode == FUSE_CREATE ||
h.Opcode == FUSE_LINK || h.Opcode == FUSE_GETXATTR { h.Opcode == FUSE_LINK || h.Opcode == FUSE_GETXATTR ||
h.Opcode == FUSE_REMOVEXATTR {
filename = strings.TrimRight(string(data), "\x00") filename = strings.TrimRight(string(data), "\x00")
} }
if me.Debug { if me.Debug {
...@@ -478,8 +479,8 @@ func (me *MountState) dispatch(req *fuseRequest) { ...@@ -478,8 +479,8 @@ func (me *MountState) dispatch(req *fuseRequest) {
req.data, req.flatData, status = doGetXAttr(me, h, (*GetXAttrIn)(inData), filename, h.Opcode) req.data, req.flatData, status = doGetXAttr(me, h, (*GetXAttrIn)(inData), filename, h.Opcode)
case FUSE_LISTXATTR: case FUSE_LISTXATTR:
req.data, req.flatData, status = doGetXAttr(me, h, (*GetXAttrIn)(inData), filename, h.Opcode) req.data, req.flatData, status = doGetXAttr(me, h, (*GetXAttrIn)(inData), filename, h.Opcode)
// case FUSE_REMOVEXATTR case FUSE_REMOVEXATTR:
status = fs.RemoveXAttr(h, filename)
case FUSE_ACCESS: case FUSE_ACCESS:
status = fs.Access(h, (*AccessIn)(inData)) status = fs.Access(h, (*AccessIn)(inData))
case FUSE_CREATE: case FUSE_CREATE:
......
...@@ -158,6 +158,10 @@ func (me *LoopbackFileSystem) ListXAttr(name string) ([]string, Status) { ...@@ -158,6 +158,10 @@ func (me *LoopbackFileSystem) ListXAttr(name string) ([]string, Status) {
return data, Status(errNo) return data, Status(errNo)
} }
func (me *LoopbackFileSystem) RemoveXAttr(name string, attr string) (Status) {
return Status(Removexattr(me.GetPath(name), attr))
}
func (me *LoopbackFileSystem) FillOptions(options *PathFileSystemConnectorOptions) { func (me *LoopbackFileSystem) FillOptions(options *PathFileSystemConnectorOptions) {
options.NegativeTimeout = 3.0 options.NegativeTimeout = 3.0
options.AttrTimeout = 3.0 options.AttrTimeout = 3.0
......
...@@ -728,6 +728,15 @@ func (me *PathFileSystemConnector) GetXAttr(header *InHeader, attribute string) ...@@ -728,6 +728,15 @@ func (me *PathFileSystemConnector) GetXAttr(header *InHeader, attribute string)
return data, code return data, code
} }
func (me *PathFileSystemConnector) RemoveXAttr(header *InHeader, attr string) (Status) {
path, mount := me.GetPath(header.NodeId)
if mount == nil {
return ENOENT
}
return mount.fs.RemoveXAttr(path, attr)
}
func (me *PathFileSystemConnector) SetXAttr(header *InHeader, input *SetXAttrIn, attr string, data []byte) (Status) { func (me *PathFileSystemConnector) SetXAttr(header *InHeader, input *SetXAttrIn, attr string, data []byte) (Status) {
path, mount := me.GetPath(header.NodeId) path, mount := me.GetPath(header.NodeId)
if mount == nil { if mount == nil {
......
...@@ -106,6 +106,11 @@ func (me *TimingPathFilesystem) ListXAttr(name string) ([]string, Status) { ...@@ -106,6 +106,11 @@ func (me *TimingPathFilesystem) ListXAttr(name string) ([]string, Status) {
return me.original.ListXAttr(name) return me.original.ListXAttr(name)
} }
func (me *TimingPathFilesystem) RemoveXAttr(name string, attr string) (Status) {
defer me.startTimer("RemoveXAttr", name)()
return me.original.RemoveXAttr(name, attr)
}
func (me *TimingPathFilesystem) Readlink(name string) (string, Status) { func (me *TimingPathFilesystem) Readlink(name string) (string, Status) {
defer me.startTimer("Readlink", name)() defer me.startTimer("Readlink", name)()
return me.original.Readlink(name) return me.original.Readlink(name)
......
...@@ -136,6 +136,11 @@ func (me *TimingRawFilesystem) ListXAttr(header *InHeader) (data []byte, code St ...@@ -136,6 +136,11 @@ func (me *TimingRawFilesystem) ListXAttr(header *InHeader) (data []byte, code St
return me.original.ListXAttr(header) return me.original.ListXAttr(header)
} }
func (me *TimingRawFilesystem) RemoveXAttr(header *InHeader, attr string) (Status) {
defer me.startTimer("RemoveXAttr")()
return me.original.RemoveXAttr(header, attr)
}
func (me *TimingRawFilesystem) Access(header *InHeader, input *AccessIn) (code Status) { func (me *TimingRawFilesystem) Access(header *InHeader, input *AccessIn) (code Status) {
defer me.startTimer("Access")() defer me.startTimer("Access")()
return me.original.Access(header, input) return me.original.Access(header, input)
......
...@@ -519,7 +519,7 @@ type RawFileSystem interface { ...@@ -519,7 +519,7 @@ type RawFileSystem interface {
GetXAttr(header *InHeader, attr string) (data []byte, code Status) GetXAttr(header *InHeader, attr string) (data []byte, code Status)
ListXAttr(header *InHeader) (attributes []byte, code Status) ListXAttr(header *InHeader) (attributes []byte, code Status)
SetXAttr(header *InHeader, input *SetXAttrIn, attr string, data []byte) (Status) SetXAttr(header *InHeader, input *SetXAttrIn, attr string, data []byte) (Status)
RemoveXAttr(header *InHeader, attr string) (code Status)
Access(header *InHeader, input *AccessIn) (code Status) Access(header *InHeader, input *AccessIn) (code Status)
Create(header *InHeader, input *CreateIn, name string) (flags uint32, fuseFile RawFuseFile, out *EntryOut, code Status) Create(header *InHeader, input *CreateIn, name string) (flags uint32, fuseFile RawFuseFile, out *EntryOut, code Status)
Bmap(header *InHeader, input *BmapIn) (out *BmapOut, code Status) Bmap(header *InHeader, input *BmapIn) (out *BmapOut, code Status)
...@@ -565,13 +565,11 @@ type PathFilesystem interface { ...@@ -565,13 +565,11 @@ type PathFilesystem interface {
Open(name string, flags uint32) (file RawFuseFile, code Status) Open(name string, flags uint32) (file RawFuseFile, code Status)
GetXAttr(name string, attribute string) (data []byte, code Status) GetXAttr(name string, attribute string) (data []byte, code Status)
// Where to hook up statfs?
//
// Unimplemented:
// RemoveXAttr,
SetXAttr(name string, attr string, data []byte, flags int) Status SetXAttr(name string, attr string, data []byte, flags int) Status
ListXAttr(name string) (attributes []string, code Status) ListXAttr(name string) (attributes []string, code Status)
RemoveXAttr(name string, attr string) (Status)
// Where to hook up statfs?
OpenDir(name string) (stream chan DirEntry, code Status) OpenDir(name string) (stream chan DirEntry, code Status)
......
...@@ -88,6 +88,10 @@ func (me *WrappingPathFilesystem) ListXAttr(name string) ([]string, Status) { ...@@ -88,6 +88,10 @@ func (me *WrappingPathFilesystem) ListXAttr(name string) ([]string, Status) {
return me.original.ListXAttr(name) return me.original.ListXAttr(name)
} }
func (me *WrappingPathFilesystem) RemoveXAttr(name string, attr string) (Status) {
return me.original.RemoveXAttr(name, attr)
}
//////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////
// Wrapping raw FS. // Wrapping raw FS.
...@@ -168,6 +172,10 @@ func (me *WrappingRawFilesystem) ListXAttr(header *InHeader) (data []byte, code ...@@ -168,6 +172,10 @@ func (me *WrappingRawFilesystem) ListXAttr(header *InHeader) (data []byte, code
return me.original.ListXAttr(header) return me.original.ListXAttr(header)
} }
func (me *WrappingRawFilesystem) RemoveXAttr(header *InHeader, attr string) (Status) {
return me.original.RemoveXAttr(header, attr)
}
func (me *WrappingRawFilesystem) Access(header *InHeader, input *AccessIn) (code Status) { func (me *WrappingRawFilesystem) Access(header *InHeader, input *AccessIn) (code Status) {
return me.original.Access(header, input) return me.original.Access(header, input)
} }
......
...@@ -86,3 +86,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (errno int) { ...@@ -86,3 +86,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (errno int) {
return int(errNo) return int(errNo)
} }
func Removexattr(path string, attr string) (errno int) {
pathbs := syscall.StringBytePtr(path)
attrbs := syscall.StringBytePtr(attr)
_, _, errNo := syscall.Syscall(
syscall.SYS_REMOVEXATTR,
uintptr(unsafe.Pointer(pathbs)),
uintptr(unsafe.Pointer(attrbs)), 0)
return int(errNo)
}
...@@ -3,10 +3,12 @@ package fuse ...@@ -3,10 +3,12 @@ package fuse
import ( import (
"bytes" "bytes"
"testing" "testing"
"log"
"path/filepath" "path/filepath"
"os" "os"
"syscall" "syscall"
) )
var _ = log.Print
type XAttrTestFs struct { type XAttrTestFs struct {
filename string filename string
...@@ -66,6 +68,19 @@ func (me *XAttrTestFs) ListXAttr(name string) (data []string, code Status) { ...@@ -66,6 +68,19 @@ func (me *XAttrTestFs) ListXAttr(name string) (data []string, code Status) {
return data, OK return data, OK
} }
func (me *XAttrTestFs) RemoveXAttr(name string, attr string) (Status) {
if name != me.filename {
return ENOENT
}
_, ok := me.attrs[attr]
log.Println(name, attr, ok)
if !ok {
return syscall.ENODATA
}
me.attrs[attr] = nil, false
return OK
}
func TestXAttrRead(t *testing.T) { func TestXAttrRead(t *testing.T) {
nm := "filename" nm := "filename"
...@@ -123,7 +138,13 @@ func TestXAttrRead(t *testing.T) { ...@@ -123,7 +138,13 @@ func TestXAttrRead(t *testing.T) {
Setxattr(mounted, "third", []byte("value"), 0) Setxattr(mounted, "third", []byte("value"), 0)
val, errno = GetXAttr(mounted, "third") val, errno = GetXAttr(mounted, "third")
if errno != 0 || string(val) != "value" { if errno != 0 || string(val) != "value" {
t.Error("Read back set xattr:", err, val) t.Error("Read back set xattr:", errno, val)
}
Removexattr(mounted, "third")
val, errno = GetXAttr(mounted, "third")
if errno != syscall.ENODATA {
t.Error("Data not removed?", errno, val)
} }
} }
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