package vfs import ( "context" "os" "time" db2 "gitlink.org.cn/cloudream/storage2/client/internal/db" "gitlink.org.cn/cloudream/storage2/client/internal/mount/fuse" "gitlink.org.cn/cloudream/storage2/client/internal/mount/vfs/cache" clitypes "gitlink.org.cn/cloudream/storage2/client/types" "gorm.io/gorm" ) type FuseDir struct { vfs *Vfs pathComps []string modTime time.Time mode os.FileMode } func newDirFromCache(ch cache.CacheEntryInfo, vfs *Vfs) *FuseDir { return &FuseDir{ vfs: vfs, pathComps: ch.PathComps, modTime: ch.ModTime, mode: ch.Mode, } } func (r *FuseDir) PathComps() []string { return r.pathComps } func (r *FuseDir) Name() string { return r.pathComps[len(r.pathComps)-1] } func (r *FuseDir) Size() int64 { return 0 } func (r *FuseDir) Mode() os.FileMode { return os.ModeDir | r.mode } func (r *FuseDir) ModTime() time.Time { return r.modTime } func (r *FuseDir) IsDir() bool { return true } func (r *FuseDir) SetModTime(time time.Time) error { dir := r.loadCacheDir() if dir == nil { return fuse.ErrNotExists } return dir.SetModTime(time) } // 如果不存在,应该返回ErrNotExists func (r *FuseDir) Child(ctx context.Context, name string) (fuse.FsEntry, error) { return child(r.vfs, ctx, r, name) } func (r *FuseDir) Children(ctx context.Context) ([]fuse.FsEntry, error) { return listChildren(r.vfs, ctx, r) } func (r *FuseDir) ReadChildren() (fuse.DirReader, error) { ens, err := listChildren(r.vfs, context.Background(), r) if err != nil { return nil, err } return newFuseDirReader(ens), nil } func (r *FuseDir) NewDir(ctx context.Context, name string) (fuse.FsDir, error) { return newDir(r.vfs, ctx, name, r) } func (r *FuseDir) NewFile(ctx context.Context, name string, flags uint32) (fuse.FileHandle, uint32, error) { return newFile(r.vfs, ctx, name, r, flags) } func (r *FuseDir) RemoveChild(ctx context.Context, name string) error { return removeChild(r.vfs, ctx, name, r) } func (r *FuseDir) MoveChild(ctx context.Context, oldName string, newName string, newParent fuse.FsDir) error { return moveChild(r.vfs, ctx, oldName, r, newName, newParent.(FuseNode)) } func (r *FuseDir) loadCacheDir() *cache.CacheDir { var createOpt *cache.CreateDirOption err := r.vfs.db.DoTx(func(tx db2.SQLContext) error { pkg, err := r.vfs.db.Package().GetByFullName(tx, r.pathComps[0], r.pathComps[1]) if err != nil { return err } err = r.vfs.db.Object().HasObjectWithPrefix(tx, pkg.PackageID, clitypes.JoinObjectPath(r.pathComps[2:]...)) if err == nil { createOpt = &cache.CreateDirOption{ ModTime: time.Now(), } return nil } if err == gorm.ErrRecordNotFound { return nil } return err }) if err != nil { return nil } return r.vfs.cache.LoadDir(r.pathComps, createOpt) } var _ fuse.FsDir = (*FuseDir)(nil) var _ FuseNode = (*FuseDir)(nil)