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.

66 lines
1.6 KiB

  1. package filesys
  2. import (
  3. "context"
  4. "os"
  5. "syscall"
  6. "time"
  7. "bazil.org/fuse"
  8. "bazil.org/fuse/fs"
  9. "github.com/chrislusf/seaweedfs/weed/glog"
  10. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  11. )
  12. var _ = fs.NodeSymlinker(&Dir{})
  13. var _ = fs.NodeReadlinker(&File{})
  14. func (dir *Dir) Symlink(ctx context.Context, req *fuse.SymlinkRequest) (fs.Node, error) {
  15. glog.V(3).Infof("Symlink: %v/%v to %v", dir.Path, req.NewName, req.Target)
  16. request := &filer_pb.CreateEntryRequest{
  17. Directory: dir.Path,
  18. Entry: &filer_pb.Entry{
  19. Name: req.NewName,
  20. IsDirectory: false,
  21. Attributes: &filer_pb.FuseAttributes{
  22. Mtime: time.Now().Unix(),
  23. Crtime: time.Now().Unix(),
  24. FileMode: uint32(os.FileMode(0755) | os.ModeSymlink),
  25. Uid: req.Uid,
  26. Gid: req.Gid,
  27. SymlinkTarget: req.Target,
  28. },
  29. },
  30. }
  31. err := dir.wfs.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  32. if _, err := client.CreateEntry(ctx, request); err != nil {
  33. glog.V(0).Infof("symlink %s/%s: %v", dir.Path, req.NewName, err)
  34. return fuse.EIO
  35. }
  36. return nil
  37. })
  38. symlink := dir.newFile(req.NewName, request.Entry)
  39. return symlink, err
  40. }
  41. func (file *File) Readlink(ctx context.Context, req *fuse.ReadlinkRequest) (string, error) {
  42. if err := file.maybeLoadAttributes(ctx); err != nil {
  43. return "", err
  44. }
  45. if os.FileMode(file.entry.Attributes.FileMode)&os.ModeSymlink == 0 {
  46. return "", fuse.Errno(syscall.EINVAL)
  47. }
  48. glog.V(3).Infof("Readlink: %v/%v => %v", file.dir.Path, file.Name, file.entry.Attributes.SymlinkTarget)
  49. return file.entry.Attributes.SymlinkTarget, nil
  50. }