From a3486faac37680e3bcf7d0b3905f745765a823fd Mon Sep 17 00:00:00 2001 From: Andrew Borodin Date: Mon, 10 Nov 2014 10:32:34 +0300 Subject: [PATCH] Ticket #3297: don't lose file in case of preallocate space fail. Don't remove the destination file if it was retrieved incompletely but it was already exist and appended during copy/move operation. Signed-off-by: Andrew Borodin --- src/filemanager/file.c | 67 +++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/src/filemanager/file.c b/src/filemanager/file.c index 9fbf08154..3009ccf2a 100644 --- a/src/filemanager/file.c +++ b/src/filemanager/file.c @@ -1497,7 +1497,6 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, int open_flags; gboolean is_first_time = TRUE; vfs_path_t *src_vpath = NULL, *dst_vpath = NULL; - gboolean write_errno_nospace = FALSE; /* FIXME: We should not be using global variables! */ ctx->do_reget = 0; @@ -1739,28 +1738,39 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, goto ret; } - while (TRUE) + /* try preallocate space; if fail, try copy anyway */ + while (vfs_preallocate (dest_desc, file_size, ctx->do_append != 0 ? sb.st_size : 0) != 0) { - errno = vfs_preallocate (dest_desc, file_size, (ctx->do_append != 0) ? sb.st_size : 0); - if (errno == 0) - break; - if (ctx->skip_all) - return_status = FILE_SKIPALL; - else { - return_status = - file_error (_("Cannot preallocate space for target file \"%s\"\n%s"), dst_path); - if (return_status == FILE_RETRY) - continue; - if (return_status == FILE_SKIPALL) - ctx->skip_all = TRUE; + /* cannot allocate, start the file copying anyway */ + return_status = FILE_CONT; + break; } - mc_close (dest_desc); - dest_desc = -1; - mc_unlink (dst_vpath); - dst_status = DEST_NONE; - goto ret; + + return_status = + file_error (_("Cannot preallocate space for target file \"%s\"\n%s"), dst_path); + + if (return_status == FILE_SKIPALL) + ctx->skip_all = TRUE; + + if (ctx->skip_all || return_status == FILE_SKIP) + { + /* skip the space allocation error, start file copying */ + return_status = FILE_CONT; + break; + } + + if (return_status == FILE_ABORT) + { + mc_close (dest_desc); + dest_desc = -1; + mc_unlink (dst_vpath); + dst_status = DEST_NONE; + goto ret; + } + + /* return_status == FILE_RETRY -- try allocate space again */ } ctx->eta_secs = 0.0; @@ -1822,6 +1832,8 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, /* dst_write */ while ((n_written = mc_write (dest_desc, t, n_read)) < n_read) { + gboolean write_errno_nospace; + if (n_written > 0) { n_read -= n_written; @@ -1851,10 +1863,6 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, } if (return_status != FILE_RETRY) goto ret; - - /* User pressed "Retry". Will the next mc_write() call be successful? - * Reset error flag to be ready for that. */ - write_errno_nospace = FALSE; } } @@ -1933,16 +1941,9 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx, if (dst_status == DEST_SHORT) { - /* Remove short file */ - int result = 0; - - /* In case of copy/move to full partition, keep source file - * and remove incomplete destination one */ - if (!write_errno_nospace) - result = query_dialog (Q_ ("DialogTitle|Copy"), - _("Incomplete file was retrieved. Keep it?"), - D_ERROR, 2, _("&Delete"), _("&Keep")); - if (result == 0) + /* Query to remove short file */ + if (query_dialog (Q_ ("DialogTitle|Copy"), _("Incomplete file was retrieved. Keep it?"), + D_ERROR, 2, _("&Delete"), _("&Keep")) == 0) mc_unlink (dst_vpath); } else if (dst_status == DEST_FULL)