diff options
author | Jérôme Vouillon <vouillon@pps.jussieu.fr> | 2009-07-19 20:07:54 +0000 |
---|---|---|
committer | Jérôme Vouillon <vouillon@pps.jussieu.fr> | 2009-07-19 20:07:54 +0000 |
commit | 06be21b9c7d207030f8b91106e6ec346ba3583c7 (patch) | |
tree | 63134ff5ec74b8a71a3a9cc602d3f34e7031e91e /src/files.ml | |
parent | aa6a952fb56239c1feab44cea6ebfccef097e141 (diff) | |
download | unison-06be21b9c7d207030f8b91106e6ec346ba3583c7.zip unison-06be21b9c7d207030f8b91106e6ec346ba3583c7.tar.gz unison-06be21b9c7d207030f8b91106e6ec346ba3583c7.tar.bz2 |
* Bumped version number: incompatible protocol changes
* Create parent directories (with correct permissions) during
transport for paths which point to non-existent locations in the
destination replica.
* Keep track of which file contents are being transferred, and delay
the transfer of a file when another file with the same contents is
currently being transferred. This way, the second transfer can be
skipped and replaced by a local copy.
* Changes to the implementation of the rsync algorithm:
- use longer blocks for large files (the size of a block is the
square root of the size of the file for large files);
- transmit less checksum information per block (we still have less
than one chance in a hundred million of transferring a file
incorrectly, and Unison will catch any transfer error when
fingerprinting the whole file)
- avoid transfer overhead (which was 4 bytes per block)
For a 1G file, the first optimization saves a factor 50 on the
amount of data transferred from the target to the source (blocks
are 32768 bytes rather than just 700 bytes). The two other
optimizations save another factor of 2 (from 24 bytes per block
down to 10).
* New "links" preference. When set to false, Unison will report an
error on symlinks during update detection. (This is the default
when one host is running Windows but not Cygwin.) This is better
than failing during propagation.
* Added a preference "halfduplex" to force half-duplex communication
with the server. This may be useful on unreliable links (as a more
efficient alternative to "maxthreads = 1").
* Renamed preference "pretendwin" to "ignoreinodenumbers" (an alias is
kept for backwards compatibility).
* GTK UI: display estimated remaining time and transfer rate on the
progress bar
* GTK UI: some polishing; in particular:
- stop statistics window updates when idle (save power on laptops)
- some ok and cancel buttons were in the wrong order
* Added some support for making it easier to extend Unison without
breaking backwards compatibility.
- Possibility to mark a preference as local. Such a preference is
propagated if possible but will not result in an error if it is
not found server-side. This make it possible to add new
functionalities client-side without breaking compatibility.
- Added a function [Remove.commandAvailable] which tests whether a
command is available on a given root.
* Removed hack in findUpdates that would update the archive in a
visible way for the sake of path translation: it is no longer
needed.
Diffstat (limited to 'src/files.ml')
-rw-r--r-- | src/files.ml | 45 |
1 files changed, 44 insertions, 1 deletions
diff --git a/src/files.ml b/src/files.ml index ee27b4e..a034400 100644 --- a/src/files.ml +++ b/src/files.ml @@ -319,6 +319,36 @@ let setupTargetPathsLocal (fspath, path) = let setupTargetPaths = Remote.registerRootCmd "setupTargetPaths" setupTargetPathsLocal +let rec createDirectories fspath localPath props = + match props with + [] -> + () + | desc :: rem -> + match Path.deconstructRev localPath with + None -> + assert false + | Some (_, parentPath) -> + createDirectories fspath parentPath rem; + try + let absolutePath = Fspath.concat fspath parentPath in + Fs.mkdir absolutePath (Props.perms desc) + (* The directory may have already been created + if there are several paths with the same prefix *) + with Unix.Unix_error (Unix.EEXIST, _, _) -> () + +let setupTargetPathsAndCreateParentDirectoryLocal (fspath, (path, props)) = + let localPath = Update.translatePathLocal fspath path in + Util.convertUnixErrorsToTransient + "creating parent directories" + (fun () -> createDirectories fspath localPath props); + let (workingDir,realPath) = Fspath.findWorkingDir fspath localPath in + let tempPath = Os.tempPath ~fresh:false workingDir realPath in + Lwt.return (workingDir, realPath, tempPath, localPath) + +let setupTargetPathsAndCreateParentDirectory = + Remote.registerRootCmd "setupTargetPathsAndCreateParentDirectory" + setupTargetPathsAndCreateParentDirectoryLocal + (* ------------------------------------------------------------ *) let updateSourceArchiveLocal (fspathFrom, (localPathFrom, uiFrom, errPaths)) = @@ -376,6 +406,15 @@ let deleteSpuriousChildrenLocal (_, (fspathTo, pathTo, archChildren)) = let deleteSpuriousChildren = Remote.registerRootCmd "deleteSpuriousChildren" deleteSpuriousChildrenLocal +let rec normalizePropsRec propsFrom propsTo = + match propsFrom, propsTo with + d :: r, d' :: r' -> normalizePropsRec r r' + | _, [] -> propsFrom + | [], _ :: _ -> assert false + +let normalizeProps propsFrom propsTo = + normalizePropsRec (Safelist.rev propsFrom) (Safelist.rev propsTo) + (* ------------------------------------------------------------ *) let copyReg = Lwt_util.make_region 50 @@ -385,10 +424,13 @@ let copy rootFrom pathFrom (* copy from here... *) uiFrom (* (and then check that this updateItem still describes the current state of the src replica) *) + propsFrom (* the properties of the parent directories, in + case we need to propagate them *) rootTo pathTo (* ...to here *) uiTo (* (but, before committing the copy, check that this updateItem still describes the current state of the target replica) *) + propsTo (* the properties of the parent directories *) id = (* for progress display *) debug (fun() -> Util.msg @@ -396,7 +438,8 @@ let copy (root2string rootFrom) (Path.toString pathFrom) (root2string rootTo) (Path.toString pathTo)); (* Calculate target paths *) - setupTargetPaths rootTo pathTo + setupTargetPathsAndCreateParentDirectory rootTo + (pathTo, normalizeProps propsFrom propsTo) >>= fun (workingDir, realPathTo, tempPathTo, localPathTo) -> (* When in Unicode case-insensitive mode, we want to create files with NFC normal-form filenames. *) |