mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2024-01-19 02:48:24 +00:00
add open release, refactor
This commit is contained in:
parent
072f923a9b
commit
bb9919b07a
16
weed/mount/filehandle.go
Normal file
16
weed/mount/filehandle.go
Normal file
|
@ -0,0 +1,16 @@
|
|||
package mount
|
||||
|
||||
import "github.com/hanwen/go-fuse/v2/fuse"
|
||||
|
||||
func (wfs *WFS) AcquireHandle(inode uint64, uid, gid uint32) (fileHandle *FileHandle, code fuse.Status) {
|
||||
_, entry, status := wfs.maybeReadEntry(inode)
|
||||
if status == fuse.OK {
|
||||
fileHandle = wfs.fhmap.GetFileHandle(inode)
|
||||
fileHandle.entry = entry
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (wfs *WFS) ReleaseHandle(handleId FileHandleId) {
|
||||
wfs.fhmap.ReleaseByHandle(handleId)
|
||||
}
|
79
weed/mount/filehandle_map.go
Normal file
79
weed/mount/filehandle_map.go
Normal file
|
@ -0,0 +1,79 @@
|
|||
package mount
|
||||
|
||||
import (
|
||||
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type FileHandleId uint64
|
||||
|
||||
type FileHandleToInode struct {
|
||||
sync.RWMutex
|
||||
nextFh FileHandleId
|
||||
inode2fh map[uint64]*FileHandle
|
||||
fh2inode map[FileHandleId]uint64
|
||||
}
|
||||
type FileHandle struct {
|
||||
fh FileHandleId
|
||||
counter int64
|
||||
entry *filer_pb.Entry
|
||||
inode uint64
|
||||
}
|
||||
|
||||
func NewFileHandleToInode() *FileHandleToInode {
|
||||
return &FileHandleToInode{
|
||||
inode2fh: make(map[uint64]*FileHandle),
|
||||
fh2inode: make(map[FileHandleId]uint64),
|
||||
nextFh: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (i *FileHandleToInode) GetFileHandle(inode uint64) *FileHandle {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
fh, found := i.inode2fh[inode]
|
||||
if !found {
|
||||
fh = &FileHandle{
|
||||
fh: i.nextFh,
|
||||
counter: 1,
|
||||
inode: inode,
|
||||
}
|
||||
i.nextFh++
|
||||
i.inode2fh[inode] = fh
|
||||
i.fh2inode[fh.fh] = inode
|
||||
} else {
|
||||
fh.counter++
|
||||
}
|
||||
return fh
|
||||
}
|
||||
|
||||
func (i *FileHandleToInode) ReleaseByInode(inode uint64) {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
fh, found := i.inode2fh[inode]
|
||||
if found {
|
||||
fh.counter--
|
||||
if fh.counter <= 0 {
|
||||
delete(i.inode2fh, inode)
|
||||
delete(i.fh2inode, fh.fh)
|
||||
}
|
||||
}
|
||||
}
|
||||
func (i *FileHandleToInode) ReleaseByHandle(fh FileHandleId) {
|
||||
i.Lock()
|
||||
defer i.Unlock()
|
||||
inode, found := i.fh2inode[fh]
|
||||
if found {
|
||||
fhHandle, fhFound := i.inode2fh[inode]
|
||||
if !fhFound {
|
||||
delete(i.fh2inode, fh)
|
||||
} else {
|
||||
fhHandle.counter--
|
||||
if fhHandle.counter <= 0 {
|
||||
delete(i.inode2fh, inode)
|
||||
delete(i.fh2inode, fhHandle.fh)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -37,7 +37,6 @@ func (i *InodeToPath) Lookup(path util.FullPath) uint64 {
|
|||
i.nextInodeId++
|
||||
i.path2inode[path] = inode
|
||||
i.inode2path[inode] = &InodeEntry{path, 1}
|
||||
println("add", path, inode)
|
||||
} else {
|
||||
i.inode2path[inode].nlookup++
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ type WFS struct {
|
|||
root Directory
|
||||
signature int32
|
||||
inodeToPath *InodeToPath
|
||||
fhmap *FileHandleToInode
|
||||
}
|
||||
|
||||
func NewSeaweedFileSystem(option *Option) *WFS {
|
||||
|
@ -68,6 +69,7 @@ func NewSeaweedFileSystem(option *Option) *WFS {
|
|||
option: option,
|
||||
signature: util.RandomInt32(),
|
||||
inodeToPath: NewInodeToPath(),
|
||||
fhmap: NewFileHandleToInode(),
|
||||
}
|
||||
|
||||
wfs.root = Directory{
|
||||
|
|
|
@ -4,65 +4,6 @@ import (
|
|||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
/**
|
||||
* Read data
|
||||
*
|
||||
* Read should send exactly the number of bytes requested except
|
||||
* on EOF or error, otherwise the rest of the data will be
|
||||
* substituted with zeroes. An exception to this is when the file
|
||||
* has been opened in 'direct_io' mode, in which case the return
|
||||
* value of the read system call will reflect the return value of
|
||||
* this operation.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_buf
|
||||
* fuse_reply_iov
|
||||
* fuse_reply_data
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param size number of bytes to read
|
||||
* @param off offset to read from
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Read(cancel <-chan struct{}, in *fuse.ReadIn, buf []byte) (fuse.ReadResult, fuse.Status) {
|
||||
return nil, fuse.ENOSYS
|
||||
}
|
||||
|
||||
/**
|
||||
* Write data
|
||||
*
|
||||
* Write should return exactly the number of bytes requested
|
||||
* except on error. An exception to this is when the file has
|
||||
* been opened in 'direct_io' mode, in which case the return value
|
||||
* of the write system call will reflect the return value of this
|
||||
* operation.
|
||||
*
|
||||
* Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
|
||||
* expected to reset the setuid and setgid bits.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_write
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param buf data to write
|
||||
* @param size number of bytes to write
|
||||
* @param off offset to write to
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
|
||||
return 0, fuse.ENOSYS
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a file
|
||||
*
|
||||
|
@ -120,49 +61,11 @@ func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (wr
|
|||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Open(cancel <-chan struct{}, in *fuse.OpenIn, out *fuse.OpenOut) (status fuse.Status) {
|
||||
return fuse.ENOSYS
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush method
|
||||
*
|
||||
* This is called on each close() of the opened file.
|
||||
*
|
||||
* Since file descriptors can be duplicated (dup, dup2, fork), for
|
||||
* one open call there may be many flush calls.
|
||||
*
|
||||
* Filesystems shouldn't assume that flush will always be called
|
||||
* after some writes, or that if will be called at all.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* NOTE: the name of the method is misleading, since (unlike
|
||||
* fsync) the filesystem is not forced to flush pending writes.
|
||||
* One reason to flush data is if the filesystem wants to return
|
||||
* write errors during close. However, such use is non-portable
|
||||
* because POSIX does not require [close] to wait for delayed I/O to
|
||||
* complete.
|
||||
*
|
||||
* If the filesystem supports file locking operations (setlk,
|
||||
* getlk) it should remove all locks belonging to 'fi->owner'.
|
||||
*
|
||||
* If this request is answered with an error code of ENOSYS,
|
||||
* this is treated as success and future calls to flush() will
|
||||
* succeed automatically without being send to the filesystem
|
||||
* process.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*
|
||||
* [close]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html
|
||||
*/
|
||||
func (wfs *WFS) Flush(cancel <-chan struct{}, in *fuse.FlushIn) fuse.Status {
|
||||
return fuse.ENOSYS
|
||||
fileHandle, code := wfs.AcquireHandle(in.NodeId, in.Uid, in.Gid)
|
||||
if code == fuse.OK {
|
||||
out.Fh = uint64(fileHandle.fh)
|
||||
}
|
||||
return code
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -191,27 +94,5 @@ func (wfs *WFS) Flush(cancel <-chan struct{}, in *fuse.FlushIn) fuse.Status {
|
|||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Release(cancel <-chan struct{}, in *fuse.ReleaseIn) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize file contents
|
||||
*
|
||||
* If the datasync parameter is non-zero, then only the user data
|
||||
* should be flushed, not the meta data.
|
||||
*
|
||||
* If this request is answered with an error code of ENOSYS,
|
||||
* this is treated as success and future calls to fsync() will
|
||||
* succeed automatically without being send to the filesystem
|
||||
* process.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param datasync flag indicating if only data should be flushed
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Fsync(cancel <-chan struct{}, in *fuse.FsyncIn) (code fuse.Status) {
|
||||
return fuse.ENOSYS
|
||||
wfs.ReleaseHandle(FileHandleId(in.Fh))
|
||||
}
|
||||
|
|
34
weed/mount/weedfs_file_read.go
Normal file
34
weed/mount/weedfs_file_read.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package mount
|
||||
|
||||
import (
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
/**
|
||||
* Read data
|
||||
*
|
||||
* Read should send exactly the number of bytes requested except
|
||||
* on EOF or error, otherwise the rest of the data will be
|
||||
* substituted with zeroes. An exception to this is when the file
|
||||
* has been opened in 'direct_io' mode, in which case the return
|
||||
* value of the read system call will reflect the return value of
|
||||
* this operation.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_buf
|
||||
* fuse_reply_iov
|
||||
* fuse_reply_data
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param size number of bytes to read
|
||||
* @param off offset to read from
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Read(cancel <-chan struct{}, in *fuse.ReadIn, buf []byte) (fuse.ReadResult, fuse.Status) {
|
||||
return nil, fuse.ENOSYS
|
||||
}
|
70
weed/mount/weedfs_file_sync.go
Normal file
70
weed/mount/weedfs_file_sync.go
Normal file
|
@ -0,0 +1,70 @@
|
|||
package mount
|
||||
|
||||
import (
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
/**
|
||||
* Flush method
|
||||
*
|
||||
* This is called on each close() of the opened file.
|
||||
*
|
||||
* Since file descriptors can be duplicated (dup, dup2, fork), for
|
||||
* one open call there may be many flush calls.
|
||||
*
|
||||
* Filesystems shouldn't assume that flush will always be called
|
||||
* after some writes, or that if will be called at all.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* NOTE: the name of the method is misleading, since (unlike
|
||||
* fsync) the filesystem is not forced to flush pending writes.
|
||||
* One reason to flush data is if the filesystem wants to return
|
||||
* write errors during close. However, such use is non-portable
|
||||
* because POSIX does not require [close] to wait for delayed I/O to
|
||||
* complete.
|
||||
*
|
||||
* If the filesystem supports file locking operations (setlk,
|
||||
* getlk) it should remove all locks belonging to 'fi->owner'.
|
||||
*
|
||||
* If this request is answered with an error code of ENOSYS,
|
||||
* this is treated as success and future calls to flush() will
|
||||
* succeed automatically without being send to the filesystem
|
||||
* process.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param fi file information
|
||||
*
|
||||
* [close]: http://pubs.opengroup.org/onlinepubs/9699919799/functions/close.html
|
||||
*/
|
||||
func (wfs *WFS) Flush(cancel <-chan struct{}, in *fuse.FlushIn) fuse.Status {
|
||||
return fuse.ENOSYS
|
||||
}
|
||||
|
||||
/**
|
||||
* Synchronize file contents
|
||||
*
|
||||
* If the datasync parameter is non-zero, then only the user data
|
||||
* should be flushed, not the meta data.
|
||||
*
|
||||
* If this request is answered with an error code of ENOSYS,
|
||||
* this is treated as success and future calls to fsync() will
|
||||
* succeed automatically without being send to the filesystem
|
||||
* process.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param datasync flag indicating if only data should be flushed
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Fsync(cancel <-chan struct{}, in *fuse.FsyncIn) (code fuse.Status) {
|
||||
return fuse.ENOSYS
|
||||
}
|
35
weed/mount/weedfs_file_write.go
Normal file
35
weed/mount/weedfs_file_write.go
Normal file
|
@ -0,0 +1,35 @@
|
|||
package mount
|
||||
|
||||
import (
|
||||
"github.com/hanwen/go-fuse/v2/fuse"
|
||||
)
|
||||
|
||||
/**
|
||||
* Write data
|
||||
*
|
||||
* Write should return exactly the number of bytes requested
|
||||
* except on error. An exception to this is when the file has
|
||||
* been opened in 'direct_io' mode, in which case the return value
|
||||
* of the write system call will reflect the return value of this
|
||||
* operation.
|
||||
*
|
||||
* Unless FUSE_CAP_HANDLE_KILLPRIV is disabled, this method is
|
||||
* expected to reset the setuid and setgid bits.
|
||||
*
|
||||
* fi->fh will contain the value set by the open method, or will
|
||||
* be undefined if the open method didn't set any value.
|
||||
*
|
||||
* Valid replies:
|
||||
* fuse_reply_write
|
||||
* fuse_reply_err
|
||||
*
|
||||
* @param req request handle
|
||||
* @param ino the inode number
|
||||
* @param buf data to write
|
||||
* @param size number of bytes to write
|
||||
* @param off offset to write to
|
||||
* @param fi file information
|
||||
*/
|
||||
func (wfs *WFS) Write(cancel <-chan struct{}, in *fuse.WriteIn, data []byte) (written uint32, code fuse.Status) {
|
||||
return 0, fuse.ENOSYS
|
||||
}
|
Loading…
Reference in a new issue