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
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) {
var subfs *subFsInfo
header.NodeId, subfs = me.getSubFs(header.NodeId)
......
......@@ -77,6 +77,10 @@ func (me *DefaultRawFuseFileSystem) ListXAttr(header *InHeader) (data []byte, co
return nil, ENOSYS
}
func (me *DefaultRawFuseFileSystem) RemoveXAttr(header *InHeader, attr string) (Status) {
return ENOSYS
}
func (me *DefaultRawFuseFileSystem) Access(header *InHeader, input *AccessIn) (code Status) {
return ENOSYS
}
......@@ -166,6 +170,10 @@ func (me *DefaultPathFilesystem) ListXAttr(name string) ([]string, Status) {
return nil, ENOSYS
}
func (me *DefaultPathFilesystem) RemoveXAttr(name string, attr string) (Status) {
return ENOSYS
}
func (me *DefaultPathFilesystem) Readlink(name string) (string, Status) {
return "", ENOSYS
}
......
......@@ -382,7 +382,8 @@ func (me *MountState) dispatch(req *fuseRequest) {
if h.Opcode == FUSE_UNLINK || h.Opcode == FUSE_RMDIR ||
h.Opcode == FUSE_LOOKUP || h.Opcode == FUSE_MKDIR ||
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")
}
if me.Debug {
......@@ -478,8 +479,8 @@ func (me *MountState) dispatch(req *fuseRequest) {
req.data, req.flatData, status = doGetXAttr(me, h, (*GetXAttrIn)(inData), filename, h.Opcode)
case FUSE_LISTXATTR:
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:
status = fs.Access(h, (*AccessIn)(inData))
case FUSE_CREATE:
......
......@@ -158,6 +158,10 @@ func (me *LoopbackFileSystem) ListXAttr(name string) ([]string, Status) {
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) {
options.NegativeTimeout = 3.0
options.AttrTimeout = 3.0
......
......@@ -728,6 +728,15 @@ func (me *PathFileSystemConnector) GetXAttr(header *InHeader, attribute string)
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) {
path, mount := me.GetPath(header.NodeId)
if mount == nil {
......
......@@ -106,6 +106,11 @@ func (me *TimingPathFilesystem) ListXAttr(name string) ([]string, Status) {
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) {
defer me.startTimer("Readlink", name)()
return me.original.Readlink(name)
......
......@@ -136,6 +136,11 @@ func (me *TimingRawFilesystem) ListXAttr(header *InHeader) (data []byte, code St
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) {
defer me.startTimer("Access")()
return me.original.Access(header, input)
......
......@@ -519,7 +519,7 @@ type RawFileSystem interface {
GetXAttr(header *InHeader, attr string) (data []byte, code Status)
ListXAttr(header *InHeader) (attributes []byte, code 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)
Create(header *InHeader, input *CreateIn, name string) (flags uint32, fuseFile RawFuseFile, out *EntryOut, code Status)
Bmap(header *InHeader, input *BmapIn) (out *BmapOut, code Status)
......@@ -565,14 +565,12 @@ type PathFilesystem interface {
Open(name string, flags uint32) (file RawFuseFile, 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
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)
// TODO - what is a good interface?
......
......@@ -88,6 +88,10 @@ func (me *WrappingPathFilesystem) ListXAttr(name string) ([]string, Status) {
return me.original.ListXAttr(name)
}
func (me *WrappingPathFilesystem) RemoveXAttr(name string, attr string) (Status) {
return me.original.RemoveXAttr(name, attr)
}
////////////////////////////////////////////////////////////////
// Wrapping raw FS.
......@@ -168,6 +172,10 @@ func (me *WrappingRawFilesystem) ListXAttr(header *InHeader) (data []byte, code
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) {
return me.original.Access(header, input)
}
......
......@@ -86,3 +86,13 @@ func Setxattr(path string, attr string, data []byte, flags int) (errno int) {
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
import (
"bytes"
"testing"
"log"
"path/filepath"
"os"
"syscall"
)
var _ = log.Print
type XAttrTestFs struct {
filename string
......@@ -66,6 +68,19 @@ func (me *XAttrTestFs) ListXAttr(name string) (data []string, code Status) {
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) {
nm := "filename"
......@@ -123,7 +138,13 @@ func TestXAttrRead(t *testing.T) {
Setxattr(mounted, "third", []byte("value"), 0)
val, errno = GetXAttr(mounted, "third")
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