bin/91134: [PATCH] Preserve access and modification time when cp to a smbfs destination path

Gilbert Cao hika at
Sat Dec 31 03:50:05 PST 2005

>Number:         91134
>Category:       bin
>Synopsis:       [PATCH] Preserve access and modification time when cp to a smbfs destination path
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Dec 31 11:50:02 GMT 2005
>Originator:     Gilbert Cao <hika at>
>Release:        FreeBSD 6.0-STABLE i386
On the smb client machine,
FreeBSD 6.0-STABLE FreeBSD 6.0-STABLE #0: Sun Nov 20 16:47:51 CET 2005 root at i386
cp utility program ($FreeBSD: src/bin/cp/utils.c,v 2005/11/12 21:21:45 csjp Exp $)

On the smb server machine,
FreeBSD bigfugu 5.4-STABLE FreeBSD 5.4-STABLE #6: Sat Aug 20 16:03:24 CEST 2005 root at bigfugu:/usr/obj/usr/src/sys/BIGFUGU i386
Samba port version : samba-3.0.8,1 or above

When I do a 'cp -p somefile /path/to/smbmountdir/anotherfolder', the
access time and modification time are not preserved, even if I use the -p
The user doing the copy with cp is the owner of /path/to/smbmountdir.

On the smb client side, simply
$ mount_smbfs //user at machine/share /path/to/smbmountdir
$ cp -p file /path/to/smbmountdir

and then, compare the file's modification time on both smb client and server side.
The modification time in the smb server side has been set to the current time,
not the source file's modification time.

The following patch has fixed the problem as I have finally found the problem in
the src/bin/cp source code, especially the utils.c file :
I have found out that utimes() does nothing on the newly created file, if its
file descriptor is not closed yet, and this is only the case in a SMB destination path.

--- patch_cp_utils.diff begins here ---
--- ./src/bin/cp/utils.c.orig	Sat Nov 12 22:21:45 2005
+++ ./src/bin/cp/utils.c	Fri Dec 30 19:23:04 2005
@@ -204,8 +204,6 @@
 	 * to remove it if we created it and its length is 0.
-	if (pflag && setfile(fs, to_fd))
-		rval = 1;
 	if (pflag && preserve_fd_acls(from_fd, to_fd) != 0)
 		rval = 1;
@@ -213,6 +211,14 @@
 		warn("%s", to.p_path);
 		rval = 1;
+	/*
+	 * To preserve times in SMB to.p_path, 
+	 * setfile() should be call *AFTER* we have closed the file
+	 * descriptors. As we have closed the descriptors, we should
+	 * pass -1 instead of the `to_fd` value
+	 */
+	if (pflag && setfile(fs, -1))
+		rval = 1;
 	return (rval);
--- patch_cp_utils.diff ends here ---


More information about the freebsd-bugs mailing list