cmount: fix Getattr to work on directories
This commit is contained in:
parent
6a8e4690d3
commit
b179540e80
1 changed files with 29 additions and 22 deletions
|
@ -47,7 +47,7 @@ func NewFS(f fs.Fs) *FS {
|
||||||
type OpenFiles struct {
|
type OpenFiles struct {
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
mark uint8
|
mark uint8
|
||||||
nodes []interface{}
|
nodes []mountlib.Noder
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewOpenFiles(mark uint8) *OpenFiles {
|
func NewOpenFiles(mark uint8) *OpenFiles {
|
||||||
|
@ -57,11 +57,11 @@ func NewOpenFiles(mark uint8) *OpenFiles {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open a node returning a file handle
|
// Open a node returning a file handle
|
||||||
func (of *OpenFiles) Open(node interface{}) (fh uint64) {
|
func (of *OpenFiles) Open(node mountlib.Noder) (fh uint64) {
|
||||||
of.mu.Lock()
|
of.mu.Lock()
|
||||||
defer of.mu.Unlock()
|
defer of.mu.Unlock()
|
||||||
var i int
|
var i int
|
||||||
var oldNode interface{}
|
var oldNode mountlib.Noder
|
||||||
for i, oldNode = range of.nodes {
|
for i, oldNode = range of.nodes {
|
||||||
if oldNode == nil {
|
if oldNode == nil {
|
||||||
of.nodes[i] = node
|
of.nodes[i] = node
|
||||||
|
@ -74,26 +74,34 @@ found:
|
||||||
return uint64((i << 8) | int(of.mark))
|
return uint64((i << 8) | int(of.mark))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InRange to see if this fh could be one of ours
|
||||||
|
func (of *OpenFiles) InRange(fh uint64) bool {
|
||||||
|
return uint8(fh) == of.mark
|
||||||
|
}
|
||||||
|
|
||||||
// get the node for fh, call with the lock held
|
// get the node for fh, call with the lock held
|
||||||
func (of *OpenFiles) get(fh uint64) (i int, node interface{}, errc int) {
|
func (of *OpenFiles) get(fh uint64) (i int, node mountlib.Noder, errc int) {
|
||||||
receivedMark := uint8(fh)
|
receivedMark := uint8(fh)
|
||||||
if receivedMark != of.mark {
|
if receivedMark != of.mark {
|
||||||
|
fs.Debugf(nil, "Bad file handle: bad mark 0x%X != 0x%X: 0x%X", receivedMark, of.mark, fh)
|
||||||
return i, nil, -fuse.EBADF
|
return i, nil, -fuse.EBADF
|
||||||
}
|
}
|
||||||
i64 := fh >> 8
|
i64 := fh >> 8
|
||||||
if i64 > uint64(len(of.nodes)) {
|
if i64 > uint64(len(of.nodes)) {
|
||||||
|
fs.Debugf(nil, "Bad file handle: too big: 0x%X", fh)
|
||||||
return i, nil, -fuse.EBADF
|
return i, nil, -fuse.EBADF
|
||||||
}
|
}
|
||||||
i = int(i64)
|
i = int(i64)
|
||||||
node = of.nodes[i]
|
node = of.nodes[i]
|
||||||
if node == nil {
|
if node == nil {
|
||||||
|
fs.Debugf(nil, "Bad file handle: nil node: 0x%X", fh)
|
||||||
return i, nil, -fuse.EBADF
|
return i, nil, -fuse.EBADF
|
||||||
}
|
}
|
||||||
return i, node, 0
|
return i, node, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the node for the file handle
|
// Get the node for the file handle
|
||||||
func (of *OpenFiles) Get(fh uint64) (node interface{}, errc int) {
|
func (of *OpenFiles) Get(fh uint64) (node mountlib.Noder, errc int) {
|
||||||
of.mu.Lock()
|
of.mu.Lock()
|
||||||
_, node, errc = of.get(fh)
|
_, node, errc = of.get(fh)
|
||||||
of.mu.Unlock()
|
of.mu.Unlock()
|
||||||
|
@ -150,13 +158,17 @@ func (fsys *FS) lookupFile(path string) (file *mountlib.File, errc int) {
|
||||||
return file, 0
|
return file, 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a read or write file handle
|
// Get the underlying handle from the file handle
|
||||||
func (fsys *FS) getReadOrWriteFh(fh uint64) (handle interface{}, errc int) {
|
func (fsys *FS) getHandleFromFh(fh uint64) (handle mountlib.Noder, errc int) {
|
||||||
handle, errc = fsys.openFilesRd.Get(fh)
|
switch {
|
||||||
if errc == 0 {
|
case fsys.openFilesRd.InRange(fh):
|
||||||
return
|
return fsys.openFilesRd.Get(fh)
|
||||||
|
case fsys.openFilesWr.InRange(fh):
|
||||||
|
return fsys.openFilesWr.Get(fh)
|
||||||
|
case fsys.openDirs.InRange(fh):
|
||||||
|
return fsys.openDirs.Get(fh)
|
||||||
}
|
}
|
||||||
return fsys.openFilesWr.Get(fh)
|
return nil, -fuse.EBADF
|
||||||
}
|
}
|
||||||
|
|
||||||
// get a node from the path or from the fh if not fhUnset
|
// get a node from the path or from the fh if not fhUnset
|
||||||
|
@ -164,15 +176,10 @@ func (fsys *FS) getNode(path string, fh uint64) (node mountlib.Node, errc int) {
|
||||||
if fh == fhUnset {
|
if fh == fhUnset {
|
||||||
node, errc = fsys.lookupNode(path)
|
node, errc = fsys.lookupNode(path)
|
||||||
} else {
|
} else {
|
||||||
var n interface{}
|
var n mountlib.Noder
|
||||||
n, errc = fsys.getReadOrWriteFh(fh)
|
n, errc = fsys.getHandleFromFh(fh)
|
||||||
if errc == 0 {
|
if errc == 0 {
|
||||||
if get, ok := n.(mountlib.Noder); ok {
|
node = n.Node()
|
||||||
node = get.Node()
|
|
||||||
} else {
|
|
||||||
fs.Errorf(path, "Bad node type %T", n)
|
|
||||||
errc = -fuse.EIO
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
@ -324,7 +331,7 @@ func (fsys *FS) Open(path string, flags int) (errc int, fh uint64) {
|
||||||
}
|
}
|
||||||
rdwrMode := flags & fuse.O_ACCMODE
|
rdwrMode := flags & fuse.O_ACCMODE
|
||||||
var err error
|
var err error
|
||||||
var handle interface{}
|
var handle mountlib.Noder
|
||||||
switch {
|
switch {
|
||||||
case rdwrMode == fuse.O_RDONLY:
|
case rdwrMode == fuse.O_RDONLY:
|
||||||
handle, err = file.OpenRead()
|
handle, err = file.OpenRead()
|
||||||
|
@ -420,7 +427,7 @@ func (fsys *FS) Write(path string, buff []byte, ofst int64, fh uint64) (n int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fsys *FS) Flush(path string, fh uint64) (errc int) {
|
func (fsys *FS) Flush(path string, fh uint64) (errc int) {
|
||||||
handle, errc := fsys.getReadOrWriteFh(fh)
|
handle, errc := fsys.getHandleFromFh(fh)
|
||||||
if errc != 0 {
|
if errc != 0 {
|
||||||
return errc
|
return errc
|
||||||
}
|
}
|
||||||
|
@ -437,7 +444,7 @@ func (fsys *FS) Flush(path string, fh uint64) (errc int) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fsys *FS) Release(path string, fh uint64) (errc int) {
|
func (fsys *FS) Release(path string, fh uint64) (errc int) {
|
||||||
handle, errc := fsys.getReadOrWriteFh(fh)
|
handle, errc := fsys.getHandleFromFh(fh)
|
||||||
if errc != 0 {
|
if errc != 0 {
|
||||||
return errc
|
return errc
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue