Files
cloudpods/cmd/fetcherfs/dir.go
2021-07-16 12:20:52 +08:00

112 lines
2.7 KiB
Go

// Copyright 2019 Yunion
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package main
import (
"context"
"os"
"syscall"
"bazil.org/fuse"
"bazil.org/fuse/fs"
"github.com/pkg/errors"
)
const (
CONTENT_FILE_NAME = "content"
META_FILE_NAME = "meta"
)
// Dir implements both Node and Handle for the root directory.
type Dir struct{}
func (Dir) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 1
a.Mode = os.ModeDir | 0755
return nil
}
func (Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
if name == CONTENT_FILE_NAME {
return Content{}, nil
} else if name == META_FILE_NAME {
return Meta{}, nil
}
return nil, syscall.ENOENT
}
func (Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
return dirDirs, nil
}
var (
dirDirs = []fuse.Dirent{
{Inode: 2, Name: CONTENT_FILE_NAME, Type: fuse.DT_File},
{Inode: 3, Name: META_FILE_NAME, Type: fuse.DT_File},
}
)
// Content implements both Node and Handle for the content file.
type Content struct{}
func NewContent() *Content {
return &Content{}
}
func (Content) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 2
a.Mode = 0444
a.Size = uint64(fetcherFs.GetSize())
a.BlockSize = uint32(opt.Blocksize) * 1024 * 1024
return nil
}
func (Content) Read(ctx context.Context, req *fuse.ReadRequest, resp *fuse.ReadResponse) error {
// fmt.Printf("req.Size %d, req.Offset %d, resp.Data %d", req.Size, req.Offset, len(resp.Data))
if req.Offset >= 0 && req.Offset < fetcherFs.GetSize() {
if req.Offset+int64(req.Size) > fetcherFs.GetSize() {
req.Size = int(fetcherFs.GetSize() - req.Offset)
}
if data, err := fetcherFs.doRead(req.Size, req.Offset); err != nil {
return err
} else {
resp.Data = data
return nil
}
} else if req.Offset == fetcherFs.GetSize() {
return nil
} else {
return errors.Errorf("bad offset %d", req.Offset)
}
}
// Meta implements both Node and Handle for the meta file.
type Meta struct{}
func NewMeta() *Meta {
return &Meta{}
}
func (Meta) Attr(ctx context.Context, a *fuse.Attr) error {
a.Inode = 3
a.Mode = 0444
a.Size = uint64(len(fetcherFs.GetMeta()))
return nil
}
func (Meta) ReadAll(ctx context.Context) ([]byte, error) {
return []byte(fetcherFs.GetMeta()), nil
}