|
- package vfs
-
- import (
- "os"
- "time"
-
- "gitlink.org.cn/cloudream/jcs-pub/client/internal/mount/fuse"
- "gitlink.org.cn/cloudream/jcs-pub/client/internal/mount/vfs/cache"
- clitypes "gitlink.org.cn/cloudream/jcs-pub/client/types"
- "gorm.io/gorm"
- )
-
- type FuseFileNode struct {
- vfs *Vfs
- pathComps []string
- size int64
- modTime time.Time
- mode os.FileMode
- }
-
- func newFileFromCache(info cache.CacheEntryInfo, vfs *Vfs) *FuseFileNode {
- return &FuseFileNode{
- vfs: vfs,
- pathComps: info.PathComps,
- size: info.Size,
- modTime: info.ModTime,
- mode: info.Mode,
- }
- }
-
- func newFileFromObject(vfs *Vfs, pathComps []string, obj clitypes.Object) *FuseFileNode {
- return &FuseFileNode{
- vfs: vfs,
- pathComps: pathComps,
- size: obj.Size,
- modTime: obj.UpdateTime,
- mode: os.FileMode(0755), // TODO Object元数据中是没有保存权限的
- }
- }
-
- func (n *FuseFileNode) Name() string {
- return n.pathComps[len(n.pathComps)-1]
- }
-
- func (n *FuseFileNode) Size() int64 {
- info := n.vfs.cache.Stat(n.pathComps)
- if info == nil {
- return n.size
- }
-
- return info.Size
- }
-
- func (n *FuseFileNode) Mode() os.FileMode {
- return n.mode
- }
-
- func (n *FuseFileNode) ModTime() time.Time {
- info := n.vfs.cache.Stat(n.pathComps)
- if info == nil {
- return n.modTime
- }
-
- return info.ModTime
- }
-
- func (n *FuseFileNode) IsDir() bool {
- return false
- }
-
- func (n *FuseFileNode) Truncate(size uint64) error {
- cacheFile := n.loadCacheFile()
- if cacheFile == nil {
- return fuse.ErrNotExists
- }
- defer cacheFile.Release()
-
- return cacheFile.Truncate(int64(size))
- }
-
- func (n *FuseFileNode) SetModTime(time time.Time) error {
- cacheFile := n.loadCacheFile()
- if cacheFile == nil {
- return fuse.ErrNotExists
- }
- defer cacheFile.Release()
-
- return cacheFile.SetModTime(time)
- }
-
- func (n *FuseFileNode) Open(flags uint32) (fuse.FileHandle, uint32, error) {
- cacheFile := n.loadCacheFile()
- if cacheFile == nil {
- // 如果文件不存在,也不进行创建,因为创建不应该调用这个接口
- return nil, 0, fuse.ErrNotExists
- }
- defer cacheFile.Release()
-
- hd := cacheFile.Open(flags)
- return newFileHandle(n, hd), flags, nil
- }
-
- func (n *FuseFileNode) loadCacheFile() *cache.CacheFile {
- if len(n.pathComps) <= 2 {
- return n.vfs.cache.LoadFile(n.pathComps, nil)
- }
-
- cdsObj, err := n.vfs.db.Object().GetByFullPath(n.vfs.db.DefCtx(), n.pathComps[0], n.pathComps[1], clitypes.JoinObjectPath(n.pathComps[2:]...))
- if err == nil {
- file := n.vfs.cache.LoadFile(n.pathComps, &cdsObj)
- if file == nil {
- return nil
- }
-
- return file
- }
-
- if err == gorm.ErrRecordNotFound {
- return n.vfs.cache.LoadFile(n.pathComps, nil)
- }
-
- return nil
- }
-
- type FuseFileHandle struct {
- entry *FuseFileNode
- chd *cache.CacheFileHandle
- }
-
- func newFileHandle(entry *FuseFileNode, chd *cache.CacheFileHandle) *FuseFileHandle {
- return &FuseFileHandle{
- entry: entry,
- chd: chd,
- }
- }
-
- func (hd *FuseFileHandle) Entry() fuse.FsFile {
- return hd.entry
- }
-
- func (hd *FuseFileHandle) ReadAt(buf []byte, off int64) (int, error) {
- return hd.chd.ReadAt(buf, off)
- }
-
- func (hd *FuseFileHandle) WriteAt(buf []byte, off int64) (int, error) {
- return hd.chd.WriteAt(buf, off)
- }
-
- func (hd *FuseFileHandle) Sync() error {
- return hd.chd.Sync()
- }
-
- func (hd *FuseFileHandle) Close() error {
- return hd.chd.Close()
- }
-
- func (hd *FuseFileHandle) Release() error {
- // TODO 其他清理工作
- return nil
- }
|