Ticket #20 (new defect)
savannah: superflous copying instead of moving
|Reported by:||ossi||Owned by:|
|Branch state:||no branch||Votes for changeset:|
Description (last modified by ossi) (diff)
|Submitted by:||Oswald Buddenhagen <ossi>||Submitted on:||Mon 11 Jul 2005 03:44:56 PM UTC|
|Category:||Core||Severity:||3 - Normal|
|Release:||current (CVS or snapshot)||Operating System:||All|
situation: foo/name/file exists. bar/name/ exists. both on the same partition. you're in "foo/", cursor over "name". press <f6>, enter "../bar", confirm. effect: file is moved by copying. this is because mc incorrectly diagnoses a cross-device move. the code in question is file.c, move_file_file() & move_dir_dir(). when fixing, please consider the case of moving a tree where only a subtree is on another device. but maybe it was already considered. :)
Comment 1 by Pavel Tsekov <ptsekov> at Mon 11 Jul 2005 05:01:24 PM UTC:
Unfortunately there is nothing to fix here :( If the destination directory exits, MC decides to use copy_dir_dir() to perform the task. What you ask should be fully implemented from scratch. In fact move_dir_dir() is quite simplistic.
Comment 2 by Oswald Buddenhagen <ossi> at Mon 11 Jul 2005 05:09:14 PM UTC:
yes, indeed. i even started developing an algorithm to post here, but stopped because the existance checks and file/dir discrimination started turning the few lines into real work. :)= anyway, the basic idea is: when a move fails, if the source is a file, move via copy, otherwise create the target dir (if missing) and recursively call the move function for all files in the source dir. or something like that. :)
Comment 3 by Pavel Tsekov <ptsekov> at Tue 12 Jul 2005 11:53:46 AM UTC:
Does `bar/name/' contain any entries or is it empty ? I ask this question because of the following paragraph in the description of rename() in SUSv3: [...] If the old argument points to the pathname of a directory, the new argument shall not point to the pathname of a file that is not a directory. If the directory named by the new argument exists, it shall be removed and old renamed to new. In this case, a link named new shall exist throughout the renaming operation and shall refer either to the directory referred to by new or old before the operation began. If new names an existing directory, it shall be required to be an empty directory. [...] So if we have an empty destination directory we could perform an efficient move instead of copying . It is as simple as that.
Comment 4 by Oswald Buddenhagen <ossi> at Tue 12 Jul 2005 01:09:19 PM UTC:
> Does `bar/name/' contain any entries or is it empty ? > empty, but this should not matter. i don't think we want this susv3- compliant behavior. at the top level, if the target is an existing directory (empty or not), we want to move into this directory (like we currently do). once we started recursing, we just merge into existing directories. frankly, move should behave just like copy. i think it would even make sense to merge move into copy with an additional flag. if a real move succeeds, skip the recursion. if it fails, do a recursive copy+delete. because of the recursion, a real move is attempted at every level - exactly what we want.
Comment 5 by Pavel Tsekov <ptsekov>:
A really fast move can happen only under the circumstances described in the quoted text - everything else will be suboptimal. I don't want to block any attempts to move the directory if the existing directory is not empty, but it cannot be performed as fast. The more dupicate directories exist the performance will get worse (in large trees).
- Priority changed from major to minor
- Component changed from mc-core to vfs
- Version set to master
- Component changed from mc-vfs to mc-core