Difference between cp and mv linux command

Hi,

I am facing one problem only with mv command not with cp command. I have a test program

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
#include <fcntl.h>
#include <errno.h>

int sync_file(char *file)
{
FILE *fp=NULL;
int fd;

printf("file is %s\n",file);
fp = fopen(file, "r");
if(!fp)
return -1;

fd = fileno(fp);
fflush(fp);
fsync(fd);
ioctl (fd, BLKFLSBUF, 0);
fclose(fp);
return 0;

}

int main()
{
int len=0;
FILE *fp = NULL;
char buf[1024];
char *fname = "/etc/test.conf";
char fname_tmp[129] = "";


len = sprintf(buf, "%s\n", "Newly added Line is there");

snprintf(fname_tmp, 128, "%s.tmp", fname);

if( (fp = fopen(fname_tmp,"a")) == NULL )
printf(" ERROR: open(), error - %s\n",strerror(errno));

fprintf(fp,"%s",buf);
fflush(fp);

fsync(fileno(fp));
fclose(fp);
system("cp -f /etc/test.conf.tmp /etc/test.conf");
// system("mv -f /etc/test.conf.tmp /etc/test.conf");
sync_file(fname);
return 0;
}

Here i am opening a tmp file for writing. Then i am copying/moving for original file. Then i do a fflush, fsync(), ioctl() to the original file. Then i run this binary in linux machine(ext2 file system, 2.6.23.5 kernel) after that immediately power off the machine. Then power on machine, the file is disappeared or written data lost or file gets corrupted if i move the tmp file to the original file. And there is a no problem if i copy the tmp file to original file. So i want to know the difference between the cp and mv command. Can you please give me suggestion on it?

Thanks,
Indira

mv takes the file and places it in a another directory, the entry in the old directory is removed. if you mv from filesyem1 to filesystem2, mv behaves like cp + rm old file.
The rename() C call does what mv does.

cp duplicates the file - you have two entries in directories, old and new.

Is that what you mean?

thanks for your replay. I know this. Actually I want to know file system data structure difference between cp and mv command. Because if copy the tmp file to original file then fsync() icotl()(seen in my source code) then power off machine there is no data loss. If i move the tmp file to original then there is a data loss. So i want to know what makes the difference between these.

Thanks,
Indira.

The mv command first deletes the target file if it exists. The cp command does not.

well, I suggest you read the source code for cp and mv

well, for a start, cp copies the file, so opens, reads and copies.
mv just moves or renames it. So the actual inode is not accessed,
only the Directory entries.

---------- Post updated at 12:16 PM ---------- Previous update was at 12:10 PM ----------

no that is wrong.

observe, if I mv (rename) a file the inode
does not change:

 
cat:$ls -i 1
82309 1
cat:$mv 1 2
cat:$ls -i 2
82309 2

if I do a cp the inodes actually change.

cat:$ls > 1
cat:$cp 1 2
cat:$ls -i 1 2
82964 1  82967 2

the inode is the physical disk block(s) where the file lives.
you have only updated the directory with a mv

cp creates another copy of the file on disk. On the other hand mv renames the file. The original file gets a new name.

mv also used to move a file or set of files to a directory.
ex: mv *.c dirname

command mv oldname newname just gives the new name to file oldname

This is the diff between cp and mv

As for your question. I believe calling fsync has nothing to do with the directory structure, which is entirely up to the file system modules in the kernel. So, I would guess when you mv and power off, the file system has not had a chance to flush its changes. As such, you lose the modifications it made to the directory structure. When you cp the file, it may flush the changes more immediately as it is creating a new file.... This is just a guess.... However, I do not believe your fix lies in the program you are writing, because I am not sure you can programatically control when the file system changes get flushed to disk.