You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							141 lines
						
					
					
						
							2.7 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							141 lines
						
					
					
						
							2.7 KiB
						
					
					
				| package filesys | |
| 
 | |
| import ( | |
| 	"github.com/chrislusf/seaweedfs/weed/glog" | |
| 	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" | |
| 	"github.com/chrislusf/seaweedfs/weed/util" | |
| 	"github.com/seaweedfs/fuse" | |
| ) | |
| 
 | |
| func getxattr(entry *filer_pb.Entry, req *fuse.GetxattrRequest, resp *fuse.GetxattrResponse) error { | |
| 
 | |
| 	if entry == nil { | |
| 		return fuse.ErrNoXattr | |
| 	} | |
| 	if entry.Extended == nil { | |
| 		return fuse.ErrNoXattr | |
| 	} | |
| 	data, found := entry.Extended[req.Name] | |
| 	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 | |
| 		} | |
| 		if size == 0 { | |
| 			resp.Xattr = data[req.Position:] | |
| 		} else { | |
| 			resp.Xattr = data[req.Position : req.Position+size] | |
| 		} | |
| 	} | |
| 
 | |
| 	return nil | |
| 
 | |
| } | |
| 
 | |
| func setxattr(entry *filer_pb.Entry, req *fuse.SetxattrRequest) error { | |
| 
 | |
| 	if entry == nil { | |
| 		return fuse.EIO | |
| 	} | |
| 
 | |
| 	if entry.Extended == nil { | |
| 		entry.Extended = make(map[string][]byte) | |
| 	} | |
| 	data, _ := entry.Extended[req.Name] | |
| 
 | |
| 	newData := make([]byte, int(req.Position)+len(req.Xattr)) | |
| 
 | |
| 	copy(newData, data) | |
| 
 | |
| 	copy(newData[int(req.Position):], req.Xattr) | |
| 
 | |
| 	entry.Extended[req.Name] = newData | |
| 
 | |
| 	return nil | |
| 
 | |
| } | |
| 
 | |
| func removexattr(entry *filer_pb.Entry, req *fuse.RemovexattrRequest) error { | |
| 
 | |
| 	if entry == nil { | |
| 		return fuse.ErrNoXattr | |
| 	} | |
| 
 | |
| 	if entry.Extended == nil { | |
| 		return fuse.ErrNoXattr | |
| 	} | |
| 
 | |
| 	_, found := entry.Extended[req.Name] | |
| 
 | |
| 	if !found { | |
| 		return fuse.ErrNoXattr | |
| 	} | |
| 
 | |
| 	delete(entry.Extended, req.Name) | |
| 
 | |
| 	return nil | |
| 
 | |
| } | |
| 
 | |
| func listxattr(entry *filer_pb.Entry, req *fuse.ListxattrRequest, resp *fuse.ListxattrResponse) error { | |
| 
 | |
| 	if entry == nil { | |
| 		return fuse.EIO | |
| 	} | |
| 
 | |
| 	for k := range entry.Extended { | |
| 		resp.Append(k) | |
| 	} | |
| 
 | |
| 	size := req.Size | |
| 	if req.Position+size >= uint32(len(resp.Xattr)) { | |
| 		size = uint32(len(resp.Xattr)) - req.Position | |
| 	} | |
| 
 | |
| 	if size == 0 { | |
| 		resp.Xattr = resp.Xattr[req.Position:] | |
| 	} else { | |
| 		resp.Xattr = resp.Xattr[req.Position : req.Position+size] | |
| 	} | |
| 
 | |
| 	return nil | |
| 
 | |
| } | |
| 
 | |
| func (wfs *WFS) maybeLoadEntry(dir, name string) (entry *filer_pb.Entry, err error) { | |
| 
 | |
| 	fullpath := util.NewFullPath(dir, name) | |
| 	entry = wfs.cacheGet(fullpath) | |
| 	if entry != nil { | |
| 		return | |
| 	} | |
| 	// glog.V(3).Infof("read entry cache miss %s", fullpath) | |
|  | |
| 	err = wfs.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { | |
| 
 | |
| 		request := &filer_pb.LookupDirectoryEntryRequest{ | |
| 			Name:      name, | |
| 			Directory: dir, | |
| 		} | |
| 
 | |
| 		resp, err := filer_pb.LookupEntry(client, request) | |
| 		if err != nil { | |
| 			if err == filer_pb.ErrNotFound { | |
| 				glog.V(3).Infof("file attr read not found file %v: %v", request, err) | |
| 				return fuse.ENOENT | |
| 			} | |
| 			glog.V(3).Infof("attr read %v: %v", request, err) | |
| 			return fuse.EIO | |
| 		} | |
| 
 | |
| 		entry = resp.Entry | |
| 		wfs.cacheSet(fullpath, entry, wfs.option.EntryCacheTtl) | |
| 
 | |
| 		return nil | |
| 	}) | |
| 
 | |
| 	return | |
| }
 |