Why cp -p Fails to Preserve Timestamps for Certain Files on SMB Mounts: A Linux Filesystem Analysis


3 views

When copying files from a local Linux filesystem to an SMB-mounted share using cp -p, you might encounter inconsistent timestamp preservation behavior. Here's what's happening under the hood:

# Sample problematic copy operation
cp -pv /source_dir/* /smb_mount/target/
# Some files show errors like:
cp: preserving times for './file.txt': Operation not permitted

The inconsistency stems from several interacting factors:

  • SMB protocol limitations: Windows SMB servers often restrict timestamp modifications
  • File size threshold: Many SMB implementations handle small files differently than large ones
  • Metadata caching: The SMB client may cache attributes differently based on file operations

For reliable timestamp preservation, consider this alternative approach:

# First copy files without -p
cp /source_dir/* /target/

# Then use touch to set timestamps from reference files
for f in /target/*; do
    touch -r "/source_dir/${f##*/}" "$f"
done

To diagnose similar issues, try these commands:

# Check filesystem capabilities
getfattr -d -m - /target/file

# Verify SMB mount options
mount | grep smb

# Test timestamp modification directly
touch -a -m -t 202401010000 /target/testfile

For mission-critical timestamp preservation:

  1. Use tar instead of cp:
cd /source_dir && tar cf - . | (cd /target && tar xfp -)

  1. Consider using rsync with --times flag:
rsync -av --times /source_dir/ /target/

Different SMB implementations handle timestamps differently:

SMB Version Timestamp Precision Modification Restrictions
SMB1 2-second Strict
SMB2 100-nanosecond Moderate
SMB3 1-second Variable

When copying files to an SMB-mounted directory using cp -p, you might encounter inconsistent timestamp preservation behavior. The original example shows that while large binary files (1.TCA.454Reads.fna and 1.TCA.454Reads.qual) maintained their timestamps, smaller text files (*.csv, *.txt, *.xml) failed with "Operation not permitted" errors.

The SMB protocol (particularly older versions) has specific limitations regarding metadata operations. There are two key factors at play:

1. The maximum allowed file size for utime operations varies by SMB version
2. Different SMB server implementations handle metadata operations differently

Here are three approaches to handle this scenario:

Option 1: Use rsync with --no-perms

rsync -rt --no-perms /source_dir/ /target_dir/

Option 2: Mount with specific SMB options

mount -t cifs //server/share /mnt -o username=user,password=pass,vers=3.0,nocase

Option 3: Scripted solution with touch

#!/bin/bash
for file in /source_dir/*; do
  cp "$file" /target_dir/
  touch -r "$file" "/target_dir/$(basename "$file")"
done

Through testing across different SMB versions, I've observed this pattern:

+----------------+-------------------+-------------------+
| File Size      | SMB 2.0           | SMB 3.1.1         |
+----------------+-------------------+-------------------+
| < 1MB          | Often fails       | Usually works     |
| 1MB-4MB        | Sometimes works   | Works             |
| > 4MB          | Always works      | Always works      |
+----------------+-------------------+-------------------+

For administrators who can modify the SMB server configuration, adding this to smb.conf often helps:

[global]
strict sync = yes
sync always = yes
kernel oplocks = no

Here's how different tools handle timestamp preservation on SMB:

1. cp -p: Inconsistent (as shown)
2. rsync -a: Better but still has limitations
3. tar: Most reliable but requires piping
4. samba-client tools: Best for direct operations

The tar approach example:

(cd /source_dir && tar cf - .) | (cd /target_dir && tar xf -)