+ /* Try a hard-link or a rename first. Using rename is not atomic, but
+ * is more efficient than forcing a copy for larger files when no hard-
+ * linking is possible. */
+ if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
+ goto success;
+ if (errno == EEXIST) {
+ STRUCT_STAT bakst;
+ if (do_lstat(buf, &bakst) == 0) {
+ int flags = get_del_for_flag(bakst.st_mode) | DEL_FOR_BACKUP | DEL_RECURSE;
+ if (delete_item(buf, bakst.st_mode, flags) != 0)
+ return 0;
+ }
+ if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
+ goto success;
+ } else if (backup_dir && errno == ENOENT) {
+ /* If the backup dir is missing, try again after making it. */
+ if (make_bak_dir(buf) != 0)
+ return 0;
+ if ((ret = link_or_rename(fname, buf, prefer_rename, &sx.st)) != 0)
+ goto success;
+ }
+
+ /* Fall back to making a copy. */
+ if (!(file = make_file(fname, NULL, &sx.st, 0, NO_FILTERS)))