[BusyBox] mv is deleting files!

Rainer Weikusat rainer.weikusat at sncag.com
Thu Jul 14 14:10:26 UTC 2005


Josh Malone <jmalone at applieddata.net> writes:

[...]

> So - it only seems to happen to me when I cross filesystems.  Sounds
> like a clue.  Can anybody try this under a newer busybox to see if it
> has been fixed?

Ups ... I should have thought of that myself ... anyway, there is no
need to "try" this and the buggy code is this (from mv.c):

	else if ((source_exists = cp_mv_stat(*argv, &source_stat)) >= 0) {
		if (dest_exists) {
			if (dest_exists == 3) {
				if (source_exists != 3) {
					bb_error_msg(fmt, "", "non-");
					goto RET_1;
				}
			} else {
				if (source_exists == 3) {
					bb_error_msg(fmt, "non-", "");
					goto RET_1;
				}
			}
			if (unlink(dest) < 0) {
				bb_perror_msg("cannot remove `%s'", dest);
				goto RET_1;
			}
		}

cp_mv_stat returns -1 in case of an error, 3 if the stat'et path name
was a directory, 1 if it existed and was not a directory and 0 if
the stat failed with errno set to ENOENT. The unlink gets execute
if the cp_mv_stat-return value is 0 or greater. A quick fix would
be change the

	if (unlink(dest) < 0)

to

	if (source_exists && unlink(dest) < 0)

but IMHO this is still wrong, because

	a) source may go away before it is copied and after
           dest is removed

	b) the copy may fail for "other reasons"

I would suggest that the unlink should be removed and replaced
by a copy to a temporary file and an (atomic) ln-call that causes dest
to go away after a copy of source is actually in place. But this is
not entirely trivial to implement due to a couple of corner cases. I
will nevertheless do so and post the patch to the list 'somewhat
later'.

                     
        
        
				



More information about the busybox mailing list