From 959748a0a536e469435ad32f59c23a47a3477e36 Mon Sep 17 00:00:00 2001 From: Brock Johnson Date: Thu, 25 Sep 2025 16:02:59 -0400 Subject: [PATCH] dsync: add ignore-atime option Some commercial NFS appliances silently ignore atime updates, which causes dsync to want to always attempt to resync file metadata when running syncs between 2 directory trees repeatedly. Add an --ignore-atime option to dsync to ignore atime differences and avoid the overhead of the unnecessary metadata sync. Signed-off-by: Brock Johnson --- src/common/mfu_flist_copy.c | 3 +++ src/common/mfu_param_path.h | 1 + src/dsync/dsync.c | 18 ++++++++++++++++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/common/mfu_flist_copy.c b/src/common/mfu_flist_copy.c index c7b3638c..8d209be7 100644 --- a/src/common/mfu_flist_copy.c +++ b/src/common/mfu_flist_copy.c @@ -3571,6 +3571,9 @@ mfu_copy_opts_t* mfu_copy_opts_new(void) /* By default, don't use O_NOATIME. */ opts->open_noatime = false; + /* By default, compare atime. */ + opts->ignore_atime = false; + /* By default, don't use sparse file. */ opts->sparse = false; diff --git a/src/common/mfu_param_path.h b/src/common/mfu_param_path.h index f6600463..ac9293cd 100644 --- a/src/common/mfu_param_path.h +++ b/src/common/mfu_param_path.h @@ -137,6 +137,7 @@ typedef struct { int no_dereference; /* if true, don't dereference source symbolic links */ bool direct; /* whether to use O_DIRECT */ bool open_noatime; /* whether to use O_NOATIME */ + bool ignore_atime; /* whether to compare and update atime differences */ bool sparse; /* whether to create sparse files */ size_t chunk_size; /* size to chunk files by */ size_t buf_size; /* buffer size to read/write to file system */ diff --git a/src/dsync/dsync.c b/src/dsync/dsync.c index 2b4276f4..24eba09e 100644 --- a/src/dsync/dsync.c +++ b/src/dsync/dsync.c @@ -76,6 +76,7 @@ static void print_usage(void) printf(" -P, --no-dereference - don't follow links in source\n"); printf(" -s, --direct - open files with O_DIRECT\n"); printf(" --open-noatime - open files with O_NOATIME\n"); + printf(" --ignore-atime - don't compare atime for metadata updates\n"); printf(" --link-dest - hardlink to files in DIR when unchanged\n"); printf(" -S, --sparse - create sparse files when possible\n"); printf(" --progress - print progress every N seconds\n"); @@ -1696,8 +1697,14 @@ static int dsync_strmap_compare( assert(tmp_rc == 0); tmp_rc = dsync_strmap_item_state(src_map, key, DCMPF_PERM, &perm_state); assert(tmp_rc == 0); - tmp_rc = dsync_strmap_item_state(src_map, key, DCMPF_ATIME, &atime_state); - assert(tmp_rc == 0); + if (copy_opts->ignore_atime == true) { + /* override the state so we don't update things */ + tmp_rc = dsync_state_from_string("COMMON", &atime_state); + assert(tmp_rc == 0); + } else { + tmp_rc = dsync_strmap_item_state(src_map, key, DCMPF_ATIME, &atime_state); + assert(tmp_rc == 0); + } tmp_rc = dsync_strmap_item_state(src_map, key, DCMPF_MTIME, &mtime_state); assert(tmp_rc == 0); if ((uid_state == DCMPS_DIFFER) || (gid_state == DCMPS_DIFFER) || @@ -3082,6 +3089,7 @@ int main(int argc, char **argv) {"no-dereference", 0, 0, 'P'}, {"direct", 0, 0, 's'}, {"open-noatime", 0, 0, 'U'}, + {"ignore-atime", 0, 0, 'T'}, {"output", 1, 0, 'o'}, // undocumented {"debug", 0, 0, 'd'}, // undocumented {"link-dest", 1, 0, 'l'}, @@ -3191,6 +3199,12 @@ int main(int argc, char **argv) MFU_LOG(MFU_LOG_INFO, "Using O_NOATIME"); } break; + case 'T': + copy_opts->ignore_atime = true; + if(rank == 0) { + MFU_LOG(MFU_LOG_INFO, "Ignoring atime differences between files"); + } + break; case 'l': options.link_dest = MFU_STRDUP(optarg); break;