Skip to content

Commit

Permalink
dsync: Speed up timestamp and metadata updates
Browse files Browse the repository at this point in the history
This change speeds up the last stage in dsync, i.e.
updating timestamps on newly copied files.

Before this change, the mfu_flist_file_sync_meta function
has to walk through all files that have common existence in
both source and destination to check for difference
in metadata (uid, gid, perm, atime, and mtime), then
update the destination to match the source accordingly.

For large directory, metadata refresh spends a lot of
cycle time for a second walk through all the files.
As noted in dsync.c, this is not efficient, especially
if only a very small number of files require
metadata update.

This change updates dsync to leverage on existing
dsync_compare_metadata function do an earlier check on
the metadata (uid, gid and perm, atime, mtime) right
after the first walk, and include only those that
show DCMPS_DIFFER state (in either of DCMPF_UID, DCMPF_GID,
DCMPF_MTIME, DCMPF_ATIME or DCMPF_PERM field) to the
metadata_refresh array. Thus, the mfu_flist_file_sync_meta
function only needs to check and update as necessary on
a subset of files, instead of all the files again.

Signed-off-by: Honwai Leong <hleong@ddn.com>
  • Loading branch information
Honwai Leong authored and adammoody committed Sep 20, 2020
1 parent 2b8a2fe commit 49a332b
Showing 1 changed file with 24 additions and 3 deletions.
27 changes: 24 additions & 3 deletions src/dsync/dsync.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,11 @@ const char *dsync_default_outputs[] = {
"EXIST=COMMON@TYPE=COMMON",
"EXIST=DIFFER",
"EXIST=COMMON",
"EXIST=COMMON@UID=DIFFER",
"EXIST=COMMON@GID=DIFFER",
"EXIST=COMMON@PERM=DIFFER",
"EXIST=COMMON@ATIME=DIFFER",
"EXIST=COMMON@MTIME=DIFFER",
NULL,
};

Expand Down Expand Up @@ -1591,9 +1596,6 @@ static int dsync_strmap_compare(
continue;
}

/* add any item that is in both source and destination to meta
* refresh list */
strmap_setf(metadata_refresh, "%llu=%llu", src_index, dst_index);

/* item exists in both source and destination,
* so update our state to record that fact */
Expand All @@ -1605,6 +1607,25 @@ static int dsync_strmap_compare(
key);
assert(tmp_rc >= 0);

/* add any item that is in both source and destination to meta
* refresh list, only include those that have different metadata. */
dsync_state uid_state, gid_state, perm_state, atime_state, mtime_state;
tmp_rc = dsync_strmap_item_state(src_map, key, DCMPF_UID, &uid_state);
assert(tmp_rc == 0);
tmp_rc = dsync_strmap_item_state(src_map, key, DCMPF_GID, &gid_state);
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);
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) ||
(perm_state == DCMPS_DIFFER) || (atime_state == DCMPS_DIFFER) ||
(mtime_state == DCMPS_DIFFER)) {
strmap_setf(metadata_refresh, "%llu=%llu", src_index, dst_index);
}

/* Skip if no need to compare type.
* All the following comparison depends on type. */
if (!dsync_option_need_compare(DCMPF_TYPE)) {
Expand Down

0 comments on commit 49a332b

Please sign in to comment.