2019-10-29 15:35:16 +08:00
|
|
|
package backend
|
|
|
|
|
|
|
|
import (
|
2022-08-10 23:21:57 +08:00
|
|
|
"github.com/seaweedfs/seaweedfs/weed/glog"
|
|
|
|
. "github.com/seaweedfs/seaweedfs/weed/storage/types"
|
2022-08-16 06:35:31 +08:00
|
|
|
"os"
|
2022-10-10 22:28:02 +08:00
|
|
|
"runtime"
|
2022-08-16 06:35:31 +08:00
|
|
|
"time"
|
2019-10-29 15:35:16 +08:00
|
|
|
)
|
|
|
|
|
|
|
|
var (
|
2019-11-29 10:33:18 +08:00
|
|
|
_ BackendStorageFile = &DiskFile{}
|
2019-10-29 15:35:16 +08:00
|
|
|
)
|
|
|
|
|
2022-10-10 22:28:02 +08:00
|
|
|
const isMac = runtime.GOOS == "darwin"
|
|
|
|
|
2019-10-29 15:35:16 +08:00
|
|
|
type DiskFile struct {
|
|
|
|
File *os.File
|
|
|
|
fullFilePath string
|
2021-02-21 04:42:09 +08:00
|
|
|
fileSize int64
|
|
|
|
modTime time.Time
|
2019-10-29 15:35:16 +08:00
|
|
|
}
|
|
|
|
|
2019-10-30 13:37:36 +08:00
|
|
|
func NewDiskFile(f *os.File) *DiskFile {
|
2021-02-21 04:42:09 +08:00
|
|
|
stat, err := f.Stat()
|
|
|
|
if err != nil {
|
|
|
|
glog.Fatalf("stat file %s: %v", f.Name(), err)
|
|
|
|
}
|
2021-02-21 12:06:06 +08:00
|
|
|
offset := stat.Size()
|
|
|
|
if offset%NeedlePaddingSize != 0 {
|
|
|
|
offset = offset + (NeedlePaddingSize - offset%NeedlePaddingSize)
|
|
|
|
}
|
2021-02-21 04:42:09 +08:00
|
|
|
|
2019-10-29 15:35:16 +08:00
|
|
|
return &DiskFile{
|
2019-10-30 13:37:36 +08:00
|
|
|
fullFilePath: f.Name(),
|
2019-10-29 15:35:16 +08:00
|
|
|
File: f,
|
2021-02-21 12:06:06 +08:00
|
|
|
fileSize: offset,
|
2021-02-21 04:42:09 +08:00
|
|
|
modTime: stat.ModTime(),
|
2019-10-29 15:35:16 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (df *DiskFile) ReadAt(p []byte, off int64) (n int, err error) {
|
|
|
|
return df.File.ReadAt(p, off)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (df *DiskFile) WriteAt(p []byte, off int64) (n int, err error) {
|
2021-02-21 04:42:09 +08:00
|
|
|
n, err = df.File.WriteAt(p, off)
|
|
|
|
if err == nil {
|
|
|
|
waterMark := off + int64(n)
|
|
|
|
if waterMark > df.fileSize {
|
|
|
|
df.fileSize = waterMark
|
|
|
|
df.modTime = time.Now()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return
|
2019-10-29 15:35:16 +08:00
|
|
|
}
|
|
|
|
|
2021-03-05 18:29:38 +08:00
|
|
|
func (df *DiskFile) Write(p []byte) (n int, err error) {
|
2021-02-21 12:06:06 +08:00
|
|
|
return df.WriteAt(p, df.fileSize)
|
|
|
|
}
|
|
|
|
|
2019-10-29 15:35:16 +08:00
|
|
|
func (df *DiskFile) Truncate(off int64) error {
|
2021-02-21 04:42:09 +08:00
|
|
|
err := df.File.Truncate(off)
|
|
|
|
if err == nil {
|
|
|
|
df.fileSize = off
|
|
|
|
df.modTime = time.Now()
|
|
|
|
}
|
|
|
|
return err
|
2019-10-29 15:35:16 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (df *DiskFile) Close() error {
|
2022-10-13 15:51:20 +08:00
|
|
|
if err := df.Sync(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-10-29 15:35:16 +08:00
|
|
|
return df.File.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (df *DiskFile) GetStat() (datSize int64, modTime time.Time, err error) {
|
2022-03-10 21:58:56 +08:00
|
|
|
if df.File == nil {
|
|
|
|
err = os.ErrInvalid
|
|
|
|
}
|
|
|
|
return df.fileSize, df.modTime, err
|
2019-10-29 15:35:16 +08:00
|
|
|
}
|
|
|
|
|
2019-12-09 11:44:16 +08:00
|
|
|
func (df *DiskFile) Name() string {
|
2019-10-29 15:35:16 +08:00
|
|
|
return df.fullFilePath
|
|
|
|
}
|
2022-08-16 06:35:31 +08:00
|
|
|
|
|
|
|
func (df *DiskFile) Sync() error {
|
2022-10-10 22:28:02 +08:00
|
|
|
if df.File == nil {
|
|
|
|
return os.ErrInvalid
|
|
|
|
}
|
|
|
|
if isMac {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
return df.File.Sync()
|
2022-08-16 06:35:31 +08:00
|
|
|
}
|