Я использовал эту кучу (по общему мнению, быстрых и грязных) oneliners для проверки вашей проблемы в моей системе - Mandriva Linux 2010.1 (x86-64):
seq 1 1000 | while read f; do sleep 0.01; touch test-$f-0; done
seq 1 1000 | while read f; do touch -a -d "$(stat -c %x test-$f-0 | sed 's|^2010|2012|')" test-$f-1; done
seq 1 1000 | while read f; do A="$(stat -c %x test-$f-0)"; B="$(stat -c %x test-$f-1)"; if [[ ! "${A#2010}" = "${B#2012}" ]]; then echo test-$f; fi; done
Мне не удалось воспроизвести вашу проблему ни разу. Звучит так, будто прикосновение не получает ожидаемую метку времени в параметре -d, но что-то вычисляется иначе.
Конечно, проблема может быть связана с системой, и в этом случае нам потребуется дополнительная информация о вашей системе (процессор, 32-разрядная или 64-разрядная ОС, версии kernel / glibc / coreutils и т. Д.).
UPDATE:
Я попробовал то же самое с 32-битными версиями stat и touch. Никаких проблем не возникло. Ядро все еще было 64-битным.
UPDATE2:
Я также попробовал этот набор oneliners, который больше фокусируется на atime:
$ seq 1 1000 | while read f; do sleep 0.01; touch test-$f-0; done
$ seq 1 1000 | while read f; do sleep 0.01; touch test-$f-1; done
$ seq 1 1000 | while read f; do sleep 0.01; cat test-$f-0; done
$ seq 1 1000 | while read f; do touch -a -d "$(stat -c %x test-$f-0 | sed 's|^2010|2012|')" test-$f-1; done
$ seq 1 1000 | while read f; do A="$(stat -c %x test-$f-0)"; B="$(stat -c %x test-$f-1)"; if [[ ! "${A#2010}" = "${B#2012}" ]]; then echo test-$f; fi; done
Опять проблема не обнаружена. Я пробовал это с опциями монтирования relaytime и strictatime.
Update3:
Я только что выполнил вышеописанные тесты на своем ноутбуке Mandriva i686. Кажется, у меня тоже нет проблем с точностью до наносекунды. Я также проверил на другой 32-битной системе, что если точность наносекунды не поддерживается (например, на ext3), поле наносекунды в выходных данных статистики становится равным нулю.