|
|
@ -7,12 +7,13 @@ import ( |
|
|
|
"sort" |
|
|
|
"time" |
|
|
|
|
|
|
|
"github.com/seaweedfs/fuse" |
|
|
|
"github.com/seaweedfs/fuse/fs" |
|
|
|
|
|
|
|
"github.com/chrislusf/seaweedfs/weed/filer2" |
|
|
|
"github.com/chrislusf/seaweedfs/weed/glog" |
|
|
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" |
|
|
|
"github.com/chrislusf/seaweedfs/weed/util" |
|
|
|
"github.com/seaweedfs/fuse" |
|
|
|
"github.com/seaweedfs/fuse/fs" |
|
|
|
) |
|
|
|
|
|
|
|
const blockSize = 512 |
|
|
@ -35,6 +36,7 @@ type File struct { |
|
|
|
entryViewCache []filer2.VisibleInterval |
|
|
|
isOpen int |
|
|
|
reader io.ReaderAt |
|
|
|
dirtyMetadata bool |
|
|
|
} |
|
|
|
|
|
|
|
func (file *File) fullpath() util.FullPath { |
|
|
@ -43,7 +45,7 @@ func (file *File) fullpath() util.FullPath { |
|
|
|
|
|
|
|
func (file *File) Attr(ctx context.Context, attr *fuse.Attr) error { |
|
|
|
|
|
|
|
glog.V(4).Infof("file Attr %s, open:%v, existing attr: %+v", file.fullpath(), file.isOpen, attr) |
|
|
|
glog.V(5).Infof("file Attr %s, open:%v, existing attr: %+v", file.fullpath(), file.isOpen, attr) |
|
|
|
|
|
|
|
if file.isOpen <= 0 { |
|
|
|
if err := file.maybeLoadEntry(ctx); err != nil { |
|
|
@ -54,7 +56,7 @@ func (file *File) Attr(ctx context.Context, attr *fuse.Attr) error { |
|
|
|
attr.Inode = file.fullpath().AsInode() |
|
|
|
attr.Valid = time.Second |
|
|
|
attr.Mode = os.FileMode(file.entry.Attributes.FileMode) |
|
|
|
attr.Size = filer2.TotalSize(file.entry.Chunks) |
|
|
|
attr.Size = filer2.FileSize(file.entry) |
|
|
|
if file.isOpen > 0 { |
|
|
|
attr.Size = file.entry.Attributes.FileSize |
|
|
|
glog.V(4).Infof("file Attr %s, open:%v, size: %d", file.fullpath(), file.isOpen, attr.Size) |
|
|
@ -107,22 +109,31 @@ func (file *File) Setattr(ctx context.Context, req *fuse.SetattrRequest, resp *f |
|
|
|
|
|
|
|
if req.Valid.Size() { |
|
|
|
|
|
|
|
glog.V(4).Infof("%v file setattr set size=%v", file.fullpath(), req.Size) |
|
|
|
glog.V(4).Infof("%v file setattr set size=%v chunks=%d", file.fullpath(), req.Size, len(file.entry.Chunks)) |
|
|
|
if req.Size < filer2.TotalSize(file.entry.Chunks) { |
|
|
|
// fmt.Printf("truncate %v \n", fullPath)
|
|
|
|
var chunks []*filer_pb.FileChunk |
|
|
|
var truncatedChunks []*filer_pb.FileChunk |
|
|
|
for _, chunk := range file.entry.Chunks { |
|
|
|
int64Size := int64(chunk.Size) |
|
|
|
if chunk.Offset+int64Size > int64(req.Size) { |
|
|
|
// this chunk is truncated
|
|
|
|
int64Size = int64(req.Size) - chunk.Offset |
|
|
|
} |
|
|
|
if int64Size > 0 { |
|
|
|
chunks = append(chunks, chunk) |
|
|
|
if int64Size > 0 { |
|
|
|
chunks = append(chunks, chunk) |
|
|
|
glog.V(4).Infof("truncated chunk %+v from %d to %d\n", chunk, chunk.Size, int64Size) |
|
|
|
chunk.Size = uint64(int64Size) |
|
|
|
} else { |
|
|
|
glog.V(4).Infof("truncated whole chunk %+v\n", chunk) |
|
|
|
truncatedChunks = append(truncatedChunks, chunk) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
file.wfs.deleteFileChunks(truncatedChunks) |
|
|
|
file.entry.Chunks = chunks |
|
|
|
file.entryViewCache = nil |
|
|
|
file.reader = nil |
|
|
|
file.dirtyMetadata = true |
|
|
|
} |
|
|
|
file.entry.Attributes.FileSize = req.Size |
|
|
|
} |
|
|
|