seaweedfs/weed/filesys/xattr.go

146 lines
3 KiB
Go
Raw Normal View History

2019-12-16 05:07:01 +00:00
package filesys
import (
"context"
"strings"
2020-06-28 17:18:32 +00:00
"github.com/seaweedfs/fuse"
2020-06-19 16:45:27 +00:00
"github.com/chrislusf/seaweedfs/weed/filesys/meta_cache"
2019-12-16 05:07:01 +00:00
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
2020-03-23 07:01:34 +00:00
"github.com/chrislusf/seaweedfs/weed/util"
2019-12-16 05:07:01 +00:00
)
const (
XATTR_PREFIX = "xattr-" // same as filer
)
func getxattr(entry *filer_pb.Entry, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error {
2019-12-16 05:07:01 +00:00
if entry == nil {
return fuse.ErrNoXattr
}
if entry.Extended == nil {
return fuse.ErrNoXattr
}
data, found := entry.Extended[XATTR_PREFIX+req.Name]
2019-12-16 05:07:01 +00:00
if !found {
return fuse.ErrNoXattr
}
if req.Position < uint32(len(data)) {
size := req.Size
if req.Position+size >= uint32(len(data)) {
size = uint32(len(data)) - req.Position
}
2019-12-18 05:45:32 +00:00
if size == 0 {
resp.Xattr = data[req.Position:]
} else {
resp.Xattr = data[req.Position : req.Position+size]
}
2019-12-16 05:07:01 +00:00
}
return nil
}
func setxattr(entry *filer_pb.Entry, req *fuse.SetxattrRequest) error {
2019-12-16 05:07:01 +00:00
if entry == nil {
return fuse.EIO
}
if entry.Extended == nil {
entry.Extended = make(map[string][]byte)
}
data, _ := entry.Extended[XATTR_PREFIX+req.Name]
2019-12-16 05:07:01 +00:00
newData := make([]byte, int(req.Position)+len(req.Xattr))
copy(newData, data)
copy(newData[int(req.Position):], req.Xattr)
entry.Extended[XATTR_PREFIX+req.Name] = newData
2019-12-16 05:07:01 +00:00
return nil
}
func removexattr(entry *filer_pb.Entry, req *fuse.RemovexattrRequest) error {
2019-12-16 05:07:01 +00:00
if entry == nil {
return fuse.ErrNoXattr
}
if entry.Extended == nil {
return fuse.ErrNoXattr
}
_, found := entry.Extended[XATTR_PREFIX+req.Name]
2019-12-16 05:07:01 +00:00
if !found {
return fuse.ErrNoXattr
}
delete(entry.Extended, XATTR_PREFIX+req.Name)
2019-12-16 05:07:01 +00:00
return nil
}
func listxattr(entry *filer_pb.Entry, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error {
2019-12-16 05:07:01 +00:00
if entry == nil {
return fuse.EIO
}
for k := range entry.Extended {
if strings.HasPrefix(k, XATTR_PREFIX) {
resp.Append(k[len(XATTR_PREFIX):])
}
2019-12-16 05:07:01 +00:00
}
size := req.Size
if req.Position+size >= uint32(len(resp.Xattr)) {
size = uint32(len(resp.Xattr)) - req.Position
}
2019-12-18 05:45:32 +00:00
if size == 0 {
resp.Xattr = resp.Xattr[req.Position:]
} else {
resp.Xattr = resp.Xattr[req.Position : req.Position+size]
}
2019-12-16 05:07:01 +00:00
return nil
}
func (wfs *WFS) maybeLoadEntry(dir, name string) (entry *filer_pb.Entry, err error) {
2019-12-16 05:07:01 +00:00
2020-03-23 07:01:34 +00:00
fullpath := util.NewFullPath(dir, name)
2020-01-25 08:31:53 +00:00
// glog.V(3).Infof("read entry cache miss %s", fullpath)
2019-12-16 05:07:01 +00:00
2021-06-02 17:30:55 +00:00
// return a valid entry for the mount root
if string(fullpath) == wfs.option.FilerMountRootPath {
return &filer_pb.Entry{
Name: name,
2021-06-02 17:30:55 +00:00
IsDirectory: true,
Attributes: &filer_pb.FuseAttributes{
Mtime: wfs.option.MountMtime.Unix(),
FileMode: uint32(wfs.option.MountMode),
Uid: wfs.option.MountUid,
Gid: wfs.option.MountGid,
Crtime: wfs.option.MountCtime.Unix(),
},
}, nil
}
// read from async meta cache
2020-06-19 16:45:27 +00:00
meta_cache.EnsureVisited(wfs.metaCache, wfs, util.FullPath(dir))
2020-06-28 17:18:32 +00:00
cachedEntry, cacheErr := wfs.metaCache.FindEntry(context.Background(), fullpath)
if cacheErr == filer_pb.ErrNotFound {
return nil, fuse.ENOENT
}
return cachedEntry.ToProtoEntry(), cacheErr
2019-12-16 05:07:01 +00:00
}