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.

60 lines
3.0 KiB

  1. # rename and link
  2. **NOTE:** If you're receiving errors from software when files are
  3. moved / renamed / linked then you should consider changing the create
  4. policy to one which is **not** path preserving, enabling
  5. `ignorepponrename`, or contacting the author of the offending software
  6. and requesting that `EXDEV` (cross device / improper link) be properly
  7. handled.
  8. `rename` and `link` are arguably the most complicated functions to
  9. create in a union filesystem. `rename` only works within a single
  10. filesystem or device. If a `rename` can not be done due to the source
  11. and destination paths existing on different mount points it will
  12. return an error (EXDEV, cross device / improper link). So if a
  13. `rename`'s source and target are on different filesystems within the
  14. pool it creates an issue.
  15. Originally mergerfs would return EXDEV whenever a rename was requested
  16. which was cross directory in any way. This made the code simple and
  17. was technically compliant with POSIX requirements. However, many
  18. applications fail to handle EXDEV at all and treat it as a normal
  19. error or otherwise handle it poorly. Such apps include: gvfsd-fuse
  20. v1.20.3 and prior, Finder / CIFS/SMB client in Apple OSX 10.9+,
  21. NZBGet, Samba's recycling bin feature.
  22. As a result a compromise was made in order to get most software to
  23. work while still obeying mergerfs' policies. The behavior is explained
  24. below.
  25. * If using a **create** policy which tries to preserve directory paths (epff,eplfs,eplus,epmfs)
  26. * Using the **rename** policy get the list of files to rename
  27. * For each file attempt rename:
  28. * If failure with ENOENT (no such file or directory) run **create** policy
  29. * If create policy returns the same branch as currently evaluating then clone the path
  30. * Re-attempt rename
  31. * If **any** of the renames succeed the higher level rename is considered a success
  32. * If **no** renames succeed the first error encountered will be returned
  33. * On success:
  34. * Remove the target from all branches with no source file
  35. * Remove the source from all branches which failed to rename
  36. * If using a **create** policy which does **not** try to preserve directory paths
  37. * Using the **rename** policy get the list of files to rename
  38. * Using the **getattr** policy get the target path
  39. * For each file attempt rename:
  40. * If the source branch != target branch:
  41. * Clone target path from target branch to source branch
  42. * rename
  43. * If **any** of the renames succeed the higher level rename is considered a success
  44. * If **no** renames succeed the first error encountered will be returned
  45. * On success:
  46. * Remove the target from all branches with no source file
  47. * Remove the source from all branches which failed to rename
  48. The removals are subject to normal entitlement checks. If the unlink
  49. fails it will fail silently.
  50. The above behavior will help minimize the likelihood of EXDEV being
  51. returned but it will still be possible.
  52. **link** uses the same strategy but without the removals.