dir_link.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package filesys
  2. import (
  3. "context"
  4. "os"
  5. "syscall"
  6. "time"
  7. "github.com/chrislusf/seaweedfs/weed/glog"
  8. "github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
  9. "github.com/seaweedfs/fuse"
  10. "github.com/seaweedfs/fuse/fs"
  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(0777) | os.ModeSymlink) &^ dir.wfs.option.Umask),
  25. Uid: req.Uid,
  26. Gid: req.Gid,
  27. SymlinkTarget: req.Target,
  28. },
  29. },
  30. }
  31. err := dir.wfs.WithFilerClient(ctx, func(ctx context.Context, client filer_pb.SeaweedFilerClient) error {
  32. if err := filer_pb.CreateEntry(ctx, client, 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.maybeLoadEntry(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. }