mv: skipping file...it was replaced

Larry Reznick <[email protected]> Wed, 12 Feb 2003 13:00:57 -0800
Newsgroups gmane.comp.gnu.fileutils.bugs
Organization Interact Devices Inc
Message-ID <[email protected]>
We have Mosix version 1.9.0 running on Red Hat 8.0 with the Linux 2.4.20 
kernel. We now get an error from cp or mv complaining with the error 
message, "skipping file `[mfs-pathname]', as it was replaced while being 
copied". I've found and fixed the problem with a work-around, but 
there's a Mosix question you may want to look at.

The problem happens in fileutils-4.1.9-11, the current version. In 
sys2.h is a SAME_INODE() macro defined to compare both the st_ino and 
st_dev. If two statbufs passed to the macro compare the same for both 
components, the macro returns a TRUE. While that logic makes sense to me 
for comparing a source file with a destination file for cp or mv, there 
is one place in copy.c in the beginning of the function copy_reg() where 
the source file is compared with itself to see if a change has happened 
since the operation began. In copy_internal(), either stat() or lstat() 
is called on the source file to give the 1st statbuf. Later, 
copy_internal() calls copy_reg(), which immediately opens the source 
file then calls fstat() to give the 2nd statbuf.

Unfortunately, Mosix changes the st_dev when a file is opened on the 
/mfs filesystem. Therefore, what stat() & lstat() report is different 
from what fstat() reports, so cp & mv both think the source file has 
changed and abort the operation. I was able to correct the problem by 
using a different version of SAME_INODE() that compares only the st_ino 
at that stage, not st_dev. I can't think of any reason why a single file 
would change its device without changing its inode, so I think 
SAME_INODE() has been logically overused in copy.c.

I've added the following macro in sys2.h:

448a449,451
 > #define SAME_INODE_ONLY(Stat_buf_1, Stat_buf_2) \
 >   ((Stat_buf_1).st_ino == (Stat_buf_2).st_ino)
 >

Then, in copy.c, in the function copy_reg(), I've changed the first 
reference to SAME_INODE into SAME_INODE_ONLY:

239c239
<   if (! SAME_INODE (*src_sb, src_open_sb))
---
 >   if (! SAME_INODE_ONLY (*src_sb, src_open_sb))

With these in place, cp & mv work correctly on the Mosix /mfs 
filesystem. I have also reported this to the Mosix and openMosix teams, 
suggesting that they may not want to change the st_dev that fstat() 
reports from what stat() and lstat() reports.

--Larry

-- 
Larry Reznick			 Sr Software Developer
Interact Devices, Inc		     916-673-1860 x225
160 Blue Ravine Rd Suite B	      Fax 916-669-0035
Folsom, CA 95630-4718			   idicorp.net