Index: uspace/app/copy/copy.c
===================================================================
--- uspace/app/copy/copy.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/app/copy/copy.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -210,5 +210,5 @@
 
 	if (nonint)
-		return fmgt_exr_abort;
+		return fmgt_exr_fail;
 
 	if (prog_upd)
Index: uspace/lib/fmgt/include/types/fmgt.h
===================================================================
--- uspace/lib/fmgt/include/types/fmgt.h	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/include/types/fmgt.h	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -103,5 +103,7 @@
 	fmgt_exr_skip,
 	/** Abort */
-	fmgt_exr_abort
+	fmgt_exr_abort,
+	/** Fail */
+	fmgt_exr_fail
 } fmgt_exists_action_t;
 
@@ -159,13 +161,21 @@
 } fmgt_flist_entry_t;
 
+/** File system tree walk. */
+typedef struct {
+	/** Parameters */
+	struct fmgt_walk_params *params;
+	/** Stop walk. */
+	bool stop;
+} fmgt_walk_t;
+
 /** File system tree walk callbacks */
 typedef struct {
-	errno_t (*dir_enter)(void *, const char *, const char *);
-	errno_t (*dir_leave)(void *, const char *, const char *);
-	errno_t (*file)(void *, const char *, const char *);
+	errno_t (*dir_enter)(fmgt_walk_t *, const char *, const char *);
+	errno_t (*dir_leave)(fmgt_walk_t *, const char *, const char *);
+	errno_t (*file)(fmgt_walk_t *, const char *, const char *);
 } fmgt_walk_cb_t;
 
 /** File system tree walk parameters */
-typedef struct {
+typedef struct fmgt_walk_params {
 	/** List of files or directories (walk roots) */
 	fmgt_flist_t *flist;
Index: uspace/lib/fmgt/private/fsops.h
===================================================================
--- uspace/lib/fmgt/private/fsops.h	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/private/fsops.h	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -44,5 +44,5 @@
 
 errno_t fmgt_open(fmgt_t *, const char *, int *);
-errno_t fmgt_create_file(fmgt_t *, const char *, int *, bool *);
+errno_t fmgt_create_file(fmgt_t *, const char *, int *, fmgt_exists_action_t *);
 errno_t fmgt_create_dir(fmgt_t *, const char *);
 errno_t fmgt_read(fmgt_t *, int, const char *, aoff64_t *, void *, size_t,
Index: uspace/lib/fmgt/src/copy.c
===================================================================
--- uspace/lib/fmgt/src/copy.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/src/copy.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -43,6 +43,6 @@
 #include "../private/fsops.h"
 
-static errno_t fmgt_copy_dir_enter(void *, const char *, const char *);
-static errno_t fmgt_copy_file(void *, const char *, const char *);
+static errno_t fmgt_copy_dir_enter(fmgt_walk_t *, const char *, const char *);
+static errno_t fmgt_copy_file(fmgt_walk_t *, const char *, const char *);
 
 static fmgt_walk_cb_t fmgt_copy_cb = {
@@ -53,12 +53,13 @@
 /** Copy operation - enter directory.
  *
- * @param arg Argument (fmgt_t *)
+ * @param walk Walk
  * @param fname Source directory name
  * @param dest Destination directory name
  * @return EOK on success or an error code
  */
-static errno_t fmgt_copy_dir_enter(void *arg, const char *src, const char *dest)
+static errno_t fmgt_copy_dir_enter(fmgt_walk_t *walk, const char *src,
+    const char *dest)
 {
-	fmgt_t *fmgt = (fmgt_t *)arg;
+	fmgt_t *fmgt = (fmgt_t *)walk->params->arg;
 
 	(void)dest;
@@ -68,12 +69,14 @@
 /** Copy single file.
  *
- * @param arg Argument (fmgt_t *)
+ * @param walk Walk
  * @param fname Source file name
  * @param dest Destination file name
  * @return EOK on success or an error code
  */
-static errno_t fmgt_copy_file(void *arg, const char *src, const char *dest)
+static errno_t fmgt_copy_file(fmgt_walk_t *walk, const char *src,
+    const char *dest)
 {
-	fmgt_t *fmgt = (fmgt_t *)arg;
+	fmgt_t *fmgt = (fmgt_t *)walk->params->arg;
+	fmgt_exists_action_t exaction;
 	int rfd;
 	int wfd;
@@ -82,5 +85,4 @@
 	aoff64_t wpos = 0;
 	char *buffer;
-	bool skip;
 	errno_t rc;
 
@@ -95,12 +97,15 @@
 	}
 
-	rc = fmgt_create_file(fmgt, dest, &wfd, &skip);
+	rc = fmgt_create_file(fmgt, dest, &wfd, &exaction);
 	if (rc != EOK) {
 		free(buffer);
 		vfs_put(rfd);
 
-		/* User decided to skip and continue. */
-		if (rc == EEXIST && skip)
+		if (rc == EEXIST && exaction != fmgt_exr_fail) {
+			if (exaction == fmgt_exr_abort)
+				walk->stop = true;
 			return EOK;
+		}
+
 		return rc;
 	}
Index: uspace/lib/fmgt/src/fsops.c
===================================================================
--- uspace/lib/fmgt/src/fsops.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/src/fsops.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -81,8 +81,9 @@
  * @param fname Destination file name
  * @param rfd Place to store file descriptor
- * @param rskip If @c true, skip existing file and continue
- * @return EOK on success or an error code
- */
-errno_t fmgt_create_file(fmgt_t *fmgt, const char *fname, int *rfd, bool *rskip)
+ * @param raction If return value is EEXIST, fills in the action to take.
+ * @return EOK on success or an error code
+ */
+errno_t fmgt_create_file(fmgt_t *fmgt, const char *fname, int *rfd,
+    fmgt_exists_action_t *raction)
 {
 	fmgt_io_error_t err;
@@ -93,6 +94,4 @@
 	unsigned flags;
 	errno_t rc;
-
-	*rskip = false;
 
 	do {
@@ -110,6 +109,5 @@
 			fmgt_timer_start(fmgt);
 
-			if (exaction == fmgt_exr_skip)
-				*rskip = true;
+			*raction = exaction;
 			if (exaction != fmgt_exr_overwrite)
 				break;
Index: uspace/lib/fmgt/src/verify.c
===================================================================
--- uspace/lib/fmgt/src/verify.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/src/verify.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2025 Jiri Svoboda
+ * Copyright (c) 2026 Jiri Svoboda
  * All rights reserved.
  *
@@ -42,5 +42,5 @@
 #include "../private/fmgt.h"
 
-static errno_t fmgt_verify_file(void *, const char *, const char *);
+static errno_t fmgt_verify_file(fmgt_walk_t *, const char *, const char *);
 
 static fmgt_walk_cb_t fmgt_verify_cb = {
@@ -50,13 +50,13 @@
 /** Verify a single file.
  *
- * @param arg Argument (fmgt_t *)
+ * @param walk Walk
  * @param fname File name
  * @param unused Unused
  * @return EOK on success or an error code
  */
-static errno_t fmgt_verify_file(void *arg, const char *fname,
+static errno_t fmgt_verify_file(fmgt_walk_t *walk, const char *fname,
     const char *unused)
 {
-	fmgt_t *fmgt = (fmgt_t *)arg;
+	fmgt_t *fmgt = (fmgt_t *)walk->params->arg;
 	int fd;
 	size_t nr;
Index: uspace/lib/fmgt/src/walk.c
===================================================================
--- uspace/lib/fmgt/src/walk.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/src/walk.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -1,4 +1,4 @@
 /*
- * Copyright (c) 2025 Jiri Svoboda
+ * Copyright (c) 2026 Jiri Svoboda
  * All rights reserved.
  *
@@ -46,6 +46,5 @@
 #include "fmgt/walk.h"
 
-static errno_t fmgt_walk_subtree(fmgt_walk_params_t *, const char *,
-    const char *);
+static errno_t fmgt_walk_subtree(fmgt_walk_t *, const char *, const char *);
 
 /** Initialize walk parameters.
@@ -63,5 +62,5 @@
 /** Walk file (invoke file callback).
  *
- * @param params Walk parameters
+ * @param walk Walk
  * @param fname Source path
  * @param dest Destination path
@@ -69,9 +68,9 @@
  * @return EOK on success or an error code
  */
-static errno_t fmgt_walk_file(fmgt_walk_params_t *params, const char *fname,
-    const char *dest)
-{
-	if (params->cb->file != NULL)
-		return params->cb->file(params->arg, fname, dest);
+static errno_t fmgt_walk_file(fmgt_walk_t *walk, const char *fname,
+    const char *dest)
+{
+	if (walk->params->cb->file != NULL)
+		return walk->params->cb->file(walk, fname, dest);
 	else
 		return EOK;
@@ -80,14 +79,14 @@
 /** Enter directory (invoke directory entry callback).
  *
- * @param params Walk parameters
+ * @param walk Walk
  * @param dname Source directory
  * @param dest Destination path
  * @return EOK on success or an error code
  */
-static errno_t fmgt_walk_dir_enter(fmgt_walk_params_t *params,
-    const char *dname, const char *dest)
-{
-	if (params->cb->dir_enter != NULL)
-		return params->cb->dir_enter(params->arg, dname, dest);
+static errno_t fmgt_walk_dir_enter(fmgt_walk_t *walk, const char *dname,
+    const char *dest)
+{
+	if (walk->params->cb->dir_enter != NULL)
+		return walk->params->cb->dir_enter(walk, dname, dest);
 	else
 		return EOK;
@@ -96,14 +95,14 @@
 /** Leave directory (invoke directory exit callback).
  *
- * @param params Walk parameters
+ * @param walk Walk
  * @param dname Directory path
  * @param dest Destination path
  * @return EOK on success or an error code
  */
-static errno_t fmgt_walk_dir_leave(fmgt_walk_params_t *params,
-    const char *dname, const char *dest)
-{
-	if (params->cb->dir_leave != NULL)
-		return params->cb->dir_leave(params->arg, dname, dest);
+static errno_t fmgt_walk_dir_leave(fmgt_walk_t *walk, const char *dname,
+    const char *dest)
+{
+	if (walk->params->cb->dir_leave != NULL)
+		return walk->params->cb->dir_leave(walk, dname, dest);
 	else
 		return EOK;
@@ -112,10 +111,10 @@
 /** Walk directory.
  *
- * @param params Walk parameters
+ * @param walk Walk
  * @param dname Directory name
  * @param dest Destination path or @c NULL
  * @return EOK on success or an error code
  */
-static errno_t fmgt_walk_dir(fmgt_walk_params_t *params, const char *dname,
+static errno_t fmgt_walk_dir(fmgt_walk_t *walk, const char *dname,
     const char *dest)
 {
@@ -127,5 +126,5 @@
 	int rv;
 
-	rc = fmgt_walk_dir_enter(params, dname, dest);
+	rc = fmgt_walk_dir_enter(walk, dname, dest);
 	if (rc != EOK)
 		goto error;
@@ -138,5 +137,5 @@
 
 	de = readdir(dir);
-	while (de != NULL) {
+	while (!walk->stop && de != NULL) {
 		rv = asprintf(&srcpath, "%s/%s", dname, de->d_name);
 		if (rv < 0) {
@@ -154,5 +153,5 @@
 		}
 
-		rc = fmgt_walk_subtree(params, srcpath, destpath);
+		rc = fmgt_walk_subtree(walk, srcpath, destpath);
 		if (rc != EOK) {
 			free(srcpath);
@@ -168,5 +167,5 @@
 	}
 
-	rc = fmgt_walk_dir_leave(params, dname, dest);
+	rc = fmgt_walk_dir_leave(walk, dname, dest);
 	if (rc != EOK)
 		return rc;
@@ -182,11 +181,11 @@
 /** Walk subtree.
  *
- * @param params Walk parameters.
- * @param fname Subtree path.
+ * @param walk Walk
+ * @param fname Subtree path
  * @param dest Destination path
  *
  * @return EOK on success or an error code.
  */
-static errno_t fmgt_walk_subtree(fmgt_walk_params_t *params, const char *fname,
+static errno_t fmgt_walk_subtree(fmgt_walk_t *walk, const char *fname,
     const char *dest)
 {
@@ -200,10 +199,10 @@
 	if (stat.is_directory) {
 		/* Directory */
-		rc = fmgt_walk_dir(params, fname, dest);
+		rc = fmgt_walk_dir(walk, fname, dest);
 		if (rc != EOK)
 			return rc;
 	} else {
 		/* Not a directory */
-		rc = fmgt_walk_file(params, fname, dest);
+		rc = fmgt_walk_file(walk, fname, dest);
 		if (rc != EOK)
 			return rc;
@@ -225,10 +224,14 @@
 {
 	fmgt_flist_entry_t *entry;
+	fmgt_walk_t walk;
 	char *destname;
 	errno_t rc;
 	int rv;
 
+	walk.params = params;
+	walk.stop = false;
+
 	entry = fmgt_flist_first(params->flist);
-	while (entry != NULL) {
+	while (!walk.stop && entry != NULL) {
 		if (params->into_dest) {
 			rv = asprintf(&destname, "%s/%s",
@@ -240,5 +243,5 @@
 		}
 
-		rc = fmgt_walk_subtree(params, entry->fname,
+		rc = fmgt_walk_subtree(&walk, entry->fname,
 		    destname != NULL ? destname : params->dest);
 		if (rc != EOK)
Index: uspace/lib/fmgt/test/fsops.c
===================================================================
--- uspace/lib/fmgt/test/fsops.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/test/fsops.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -86,17 +86,16 @@
 	int fd;
 	int rv;
-	bool skip;
-	errno_t rc;
-
-	/* Create name for temporary file */
-	p = tmpnam(buf);
-	PCUT_ASSERT_NOT_NULL(p);
-
-	rc = fmgt_create(&fmgt);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-
-	rc = fmgt_create_file(fmgt, p, &fd, &skip);
-	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
-	PCUT_ASSERT_FALSE(skip);
+	fmgt_exists_action_t exaction;
+	errno_t rc;
+
+	/* Create name for temporary file */
+	p = tmpnam(buf);
+	PCUT_ASSERT_NOT_NULL(p);
+
+	rc = fmgt_create(&fmgt);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
+
+	rc = fmgt_create_file(fmgt, p, &fd, &exaction);
+	PCUT_ASSERT_ERRNO_VAL(EOK, rc);
 
 	fmgt_destroy(fmgt);
Index: uspace/lib/fmgt/test/walk.c
===================================================================
--- uspace/lib/fmgt/test/walk.c	(revision 857fba8068af413e8b0a6912f94f3be0b183e9d9)
+++ uspace/lib/fmgt/test/walk.c	(revision 59ed424e90d86012aab2cf8150d0ea23830de273)
@@ -39,7 +39,7 @@
 PCUT_TEST_SUITE(walk);
 
-static errno_t test_walk_dir_enter(void *, const char *, const char *);
-static errno_t test_walk_dir_leave(void *, const char *, const char *);
-static errno_t test_walk_file(void *, const char *, const char *);
+static errno_t test_walk_dir_enter(fmgt_walk_t *, const char *, const char *);
+static errno_t test_walk_dir_leave(fmgt_walk_t *, const char *, const char *);
+static errno_t test_walk_file(fmgt_walk_t *, const char *, const char *);
 
 static fmgt_walk_cb_t test_walk_cb = {
@@ -207,7 +207,8 @@
 }
 
-errno_t test_walk_dir_enter(void *arg, const char *fname, const char *dest)
-{
-	test_resp_t *resp = (test_resp_t *)arg;
+errno_t test_walk_dir_enter(fmgt_walk_t *walk, const char *fname,
+    const char *dest)
+{
+	test_resp_t *resp = (test_resp_t *)walk->params->arg;
 	resp->dir_enter = true;
 	resp->dirname = str_dup(fname);
@@ -216,7 +217,8 @@
 }
 
-errno_t test_walk_dir_leave(void *arg, const char *fname, const char *dest)
-{
-	test_resp_t *resp = (test_resp_t *)arg;
+errno_t test_walk_dir_leave(fmgt_walk_t *walk, const char *fname,
+    const char *dest)
+{
+	test_resp_t *resp = (test_resp_t *)walk->params->arg;
 	resp->dir_leave = true;
 	resp->dl_dest = (dest != NULL) ? str_dup(dest) : NULL;
@@ -224,7 +226,7 @@
 }
 
-errno_t test_walk_file(void *arg, const char *fname, const char *dest)
-{
-	test_resp_t *resp = (test_resp_t *)arg;
+errno_t test_walk_file(fmgt_walk_t *walk, const char *fname, const char *dest)
+{
+	test_resp_t *resp = (test_resp_t *)walk->params->arg;
 	resp->file_proc = true;
 	resp->fname = str_dup(fname);
