Added implementation for files space preallocation

Signed-off-by: Slava Zanko <slavazanko@gmail.com>
This commit is contained in:
Slava Zanko 2011-09-20 12:40:14 +03:00
parent 7fbdb87805
commit 323fedecd7
3 changed files with 62 additions and 0 deletions

View File

@ -594,3 +594,42 @@ vfs_change_encoding (vfs_path_t * vpath, const char *encoding)
}
/* --------------------------------------------------------------------------------------------- */
/**
* Preallocate space for file in new place for ensure that file
* will be fully copied with less fragmentation.
*
* @param dest_desc mc VFS file handler
* @param src_fsize source file size
* @param dest_fsize destination file size (if destination exists, otherwise should be 0)
*
* @return 0 if success and non-zero otherwise.
* Note: function doesn't touch errno global variable.
*/
int
vfs_preallocate (int dest_vfs_fd, off_t src_fsize, off_t dest_fsize)
{
#ifndef HAVE_POSIX_FALLOCATE
(void) dest_desc;
(void) src_fsize;
(void) dest_fsize;
return 0;
#else /* HAVE_POSIX_FALLOCATE */
int *dest_fd;
struct vfs_class *dest_class;
dest_class = vfs_class_find_by_handle (dest_vfs_fd);
if ((dest_class->flags & VFSF_LOCAL) == 0)
return 0;
dest_fd = (int *) vfs_class_data_find_by_handle (dest_vfs_fd);
if (dest_fd == NULL)
return 0;
return posix_fallocate (*dest_fd, dest_fsize, src_fsize - dest_fsize);
#endif /* HAVE_POSIX_FALLOCATE */
}
/* --------------------------------------------------------------------------------------------- */

View File

@ -268,6 +268,8 @@ char *_vfs_get_cwd (void);
vfs_path_t *vfs_change_encoding (vfs_path_t * vpath, const char *encoding);
int vfs_preallocate (int dest_desc, off_t src_fsize, off_t dest_fsize);
/**
* Interface functions described in interface.c
*/

View File

@ -1504,6 +1504,27 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
ctx->skip_all = TRUE;
goto ret;
}
while (TRUE)
{
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_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;
}
mc_close (dest_desc);
dest_desc = -1;
mc_unlink (dst_path);
dst_status = DEST_NONE;
goto ret;
}
ctx->eta_secs = 0.0;
ctx->bps = 0;