Merge branch '2610_posix_fallocate'

* 2610_posix_fallocate:
  Documentation updated for describe preallocate feature
  Added configuration option 'preallocate_space' for toggle space preallocating behaviour.
  Added implementation for files space preallocation
  Ticket #2610: Use posix_fallocate() when copying files/moving to a new mount point
This commit is contained in:
Slava Zanko 2011-10-20 10:52:02 +03:00
commit 2013c92cbb
15 changed files with 148 additions and 38 deletions

View File

@ -980,7 +980,9 @@ está activada.
Sobreimpresiona una ventana de entrada con destino por defecto al directorio del
panel no seleccionado y copia el archivo actualmente seleccionado (o
los archivos marcados, si hay al menos uno marcado) al directorio especificado
por el usuario en la ventana. Durante este proceso, podemos pulsar
por el usuario en la ventana. Space for destination file may be preallocated
relative to preallocate_space configure option. Durante este proceso, podemos
pulsar
.IR Ctrl\-c " o " Esc
para anular la operación. Para más detalles sobre la máscara de origen
(que será normalmente * o ^\\(.*\\)$ dependiendo

View File

@ -914,7 +914,9 @@ ha a belső szerkesztő be van kapcsolva.
Egy beviteli ablakot jelenít meg, amely alapértelmezésben a nem
kiválasztott panel könyvtárát adja meg rendeltetési helyként, majd
átmásolja a kiválasztott fájlt (vagy kijelölt fájlokat, ha egynél több
fájlról van szó) a beviteli ablakban megadott könyvtárba. A folyamat
fájlról van szó) a beviteli ablakban megadott könyvtárba. Space for
destination file may be preallocated relative to preallocate_space
configure option. A folyamat
futását a C\-c, vagy ESC lenyomásával szakíthatod meg. A forrás maszk
beállításairól (ami általában a *, vagy a ^\\(.*\\)$ közül valamelyik.
Ezekről a "Shell kifejezések" beállításnál, illetve a

View File

@ -938,7 +938,9 @@ se l'opzione, "usa editor interno" è stata impostata.
Mostra una finestra di dialogo con destinazione predefinita alla
directory del pannello non selezionato, che copia il file selezionato (o
i file marcati, se ce n'è almeno uno) sulla directory specificata
dall'utente nella finestra di dialogo. Durante il processo è possibile
dall'utente nella finestra di dialogo. Space for destination
file may be preallocated relative to preallocate_space configure option.
Durante il processo è possibile
premere C\-c o ESC per abortire l'operazione. Per maggiori dettagli sulla
maschera sorgente (che sarà normalmente * o ^\\(.*\\)$ a seconda
dell'impostazione di "modelli della shell") o sui caratteri jolly sulla

View File

@ -1063,12 +1063,13 @@ if the use_internal_edit option is on.
.PP
Press F5 to pop up an input dialog to copy the currently selected file (or
the tagged files, if there is at least one file tagged) to the
directory/filename you specify in the input dialog. The destination
defaults to the directory in the non\-selected panel. During this
process, you can press C\-c or ESC to abort the operation. For details
about source mask (which will be usually either * or ^\\(.*\\)$ depending
on setting of Use shell patterns) and possible wildcards in the destination
see
directory/filename you specify in the input dialog. The destination
defaults to the directory in the non\-selected panel. Space for destination
file may be preallocated relative to preallocate_space configure option.
During this process, you can press C\-c or ESC to abort the operation.
For details about source mask (which will be usually either * or ^\\(.*\\)$
depending on setting of Use shell patterns) and possible wildcards in the
destination see
.\"LINK2"
Mask copy/rename\&.
.\"Mask Copy/Rename"

View File

@ -776,6 +776,8 @@ Włącza okno dialogowe, w którym standardowo znajduje się ścieżka do
katalogu w
nieaktywnym panelu, po czym kopiuje aktualny plik (lub wybrane
jeśli wybrano jakiekolwiek) do katalogu, który wybraliśmy w oknie dialogowym.
Space for destination file may be preallocated relative to preallocate_space
configure option.
Podczas procesu kopiowania możesz go w każdej chwili przerwać wciskając C\-c lub
Esc. Żeby dowiedzieć się czegoś więcej na temat jokerów w ścieżce źródłowej
(którymi najczęściej będą * lub ^\\(.*\\)$) i innych możliwych określeń w

View File

@ -1055,7 +1055,10 @@ F13, встроенная программа просмотра не выпол
подсвеченный файл из каталога, отображаемого в активной панели (или
группу отмеченных файлов, если в активной панели отмечен хотя бы один
файл) в каталог, отображаемый в пассивной панели. Имя каталога, в
который будет производиться копирование, можно изменить. О том, как
который будет производиться копирование, можно изменить. Можно
предварительно резервировать место под новые файлы в каталоге назначения,
выставив конфигурационную опцию preallocate_space.
О том, как
задать шаблон для имен копируемых файлов (обычно это * или ^\\(.*\\)$, в
зависимости от установки опции
.I Образцы в стиле shell (Shell Patterns),

View File

@ -904,7 +904,9 @@ half name | size:7 | type mode:3
Приказује дијалог за унос са одредиштем које је подразумевано
директоријум у неизабраном окну и копира тренутно изабрану датотеку
(или означене датотеке, ако је бар једна означена) у директоријум који
је корисник задао у дијалогу за унос. Током овог процеса можете
је корисник задао у дијалогу за унос. Space for destination
file may be preallocated relative to preallocate_space configure option.
Током овог процеса можете
притиснути пречицу C\-c или тастер ESC да бисте прекинули операцију. За
детаље о изворној масци (која је обично * или ^\\(.*\\)$, у зависности
од постављања избора `Користи обрасце љуске') и могућим џокерским

View File

@ -107,7 +107,8 @@ mc_global_t mc_global = {
.vfs =
{
.cd_symlinks = TRUE
.cd_symlinks = TRUE,
.preallocate_space = FALSE,
}
};

View File

@ -269,6 +269,10 @@ typedef struct
{
/* Set when cd symlink following is desirable (bash mode) */
gboolean cd_symlinks;
/* Preallocate space before file copying */
gboolean preallocate_space;
} vfs;
} mc_global_t;

View File

@ -594,3 +594,45 @@ 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;
if (!mc_global.vfs.preallocate_space)
return 0;
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

@ -635,6 +635,27 @@ AC_DEFUN([gl_FSTYPENAME],
])
])
dnl
dnl posix_allocate() function detection
dnl
AC_DEFUN([gl_POSIX_FALLOCATE], [
dnl * Old glibcs have broken posix_fallocate(). Make sure not to use it.
AC_TRY_COMPILE([
#define _XOPEN_SOURCE 600
#include <stdlib.h>
#if defined(__GLIBC__) && (__GLIBC__ < 2 || __GLIBC_MINOR__ < 7)
possibly broken posix_fallocate
#endif
],
[posix_fallocate(0, 0, 0);],
[AC_DEFINE(
[HAVE_POSIX_FALLOCATE],
[1],
[Define if you have a working posix_fallocate()])
])
])
dnl
dnl Filesystem information detection
dnl
@ -651,4 +672,5 @@ AC_DEFUN([AC_GET_FS_INFO], [
gl_FSUSAGE
gl_FSTYPENAME
gl_POSIX_FALLOCATE
])

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;

View File

@ -76,7 +76,7 @@ configure_callback (Dlg_head * h, Widget * sender, dlg_msg_t msg, int parm, void
{
case DLG_ACTION:
/* message from "Single press" checkbutton */
if (sender != NULL && sender->id == 17)
if (sender != NULL && sender->id == 18)
{
const gboolean not_single = !(((WCheck *) sender)->state & C_BOOL);
Widget *w;
@ -125,8 +125,11 @@ configure_box (void)
QUICK_BUTTON (38, dlg_width, dlg_height - 3, dlg_height, N_("&Cancel"), B_CANCEL, NULL),
QUICK_BUTTON (14, dlg_width, dlg_height - 3, dlg_height, N_("&OK"), B_ENTER, NULL),
/* other options */
QUICK_CHECKBOX (dlg_width / 2 + 2, dlg_width, 12, dlg_height, N_("A&uto save setup"),
QUICK_CHECKBOX (dlg_width / 2 + 2, dlg_width, 13, dlg_height, N_("A&uto save setup"),
&auto_save_setup),
QUICK_CHECKBOX (dlg_width / 2 + 2, dlg_width, 12, dlg_height,
N_("Preallocate &space before file copying"),
&mc_global.vfs.preallocate_space),
QUICK_CHECKBOX (dlg_width / 2 + 2, dlg_width, 11, dlg_height, N_("Sa&fe delete"),
&safe_delete),
QUICK_CHECKBOX (dlg_width / 2 + 2, dlg_width, 10, dlg_height, N_("Cd follows lin&ks"),
@ -191,14 +194,14 @@ configure_box (void)
/* buttons */
quick_widgets[i].u.button.text = _(quick_widgets[i].u.button.text);
break;
case 12:
case 14:
case 18:
case 23:
case 13:
case 15:
case 19:
case 24:
/* groupboxes */
quick_widgets[i].u.groupbox.title = _(quick_widgets[i].u.groupbox.title);
break;
case 13:
case 14:
{
/* radio button */
size_t j;
@ -206,10 +209,10 @@ configure_box (void)
pause_options[j] = _(pause_options[j]);
}
break;
case 15:
case 16:
/* input line */
break;
case 16:
case 17:
/* label */
quick_widgets[i].u.label.text = _(quick_widgets[i].u.label.text);
break;
@ -232,20 +235,20 @@ configure_box (void)
/* checkboxes within groupboxes */
c_len = 0;
for (i = 2; i < 23; i++)
if ((i < 12) || (i == 17) || (i > 18))
for (i = 2; i < 24; i++)
if ((i < 13) || (i == 18) || (i > 19))
c_len = max (c_len, str_term_width1 (quick_widgets[i].u.checkbox.text) + 3);
/* radiobuttons */
for (i = 0; i < (size_t) pause_options_num; i++)
c_len = max (c_len, str_term_width1 (pause_options[i]) + 3);
/* label + input */
l_len = str_term_width1 (quick_widgets[16].u.label.text);
l_len = str_term_width1 (quick_widgets[17].u.label.text);
c_len = max (c_len, l_len + 1 + 8);
/* groupboxes */
g_len = max (c_len + 2, str_term_width1 (quick_widgets[23].u.groupbox.title) + 4);
g_len = max (g_len, str_term_width1 (quick_widgets[18].u.groupbox.title) + 4);
g_len = max (g_len, str_term_width1 (quick_widgets[14].u.groupbox.title) + 4);
g_len = max (g_len, str_term_width1 (quick_widgets[12].u.groupbox.title) + 4);
g_len = max (c_len + 2, str_term_width1 (quick_widgets[24].u.groupbox.title) + 4);
g_len = max (g_len, str_term_width1 (quick_widgets[19].u.groupbox.title) + 4);
g_len = max (g_len, str_term_width1 (quick_widgets[15].u.groupbox.title) + 4);
g_len = max (g_len, str_term_width1 (quick_widgets[13].u.groupbox.title) + 4);
/* dialog width */
Quick_input.xlen = max (dlg_width, g_len * 2 + 9);
Quick_input.xlen = max (Quick_input.xlen, b_len + 2);
@ -257,19 +260,19 @@ configure_box (void)
quick_widgets[i].x_divisions = Quick_input.xlen;
/* groupboxes */
quick_widgets[14].u.groupbox.width =
quick_widgets[18].u.groupbox.width =
quick_widgets[23].u.groupbox.width = Quick_input.xlen / 2 - 4;
quick_widgets[12].u.groupbox.width = Quick_input.xlen / 2 - 3;
quick_widgets[15].u.groupbox.width =
quick_widgets[19].u.groupbox.width =
quick_widgets[24].u.groupbox.width = Quick_input.xlen / 2 - 4;
quick_widgets[13].u.groupbox.width = Quick_input.xlen / 2 - 3;
/* input */
quick_widgets[15].relative_x = quick_widgets[16].relative_x + l_len + 1;
quick_widgets[15].u.input.len = quick_widgets[18].u.groupbox.width - l_len - 4;
quick_widgets[16].relative_x = quick_widgets[17].relative_x + l_len + 1;
quick_widgets[16].u.input.len = quick_widgets[19].u.groupbox.width - l_len - 4;
/* right column */
quick_widgets[12].relative_x = Quick_input.xlen / 2;
for (i = 2; i < 12; i++)
quick_widgets[i].relative_x = quick_widgets[12].relative_x + 2;
quick_widgets[13].relative_x = Quick_input.xlen / 2;
for (i = 2; i < 13; i++)
quick_widgets[i].relative_x = quick_widgets[13].relative_x + 2;
/* buttons */
quick_widgets[1].relative_x = (Quick_input.xlen - b_len) / 3;
@ -278,7 +281,7 @@ configure_box (void)
g_snprintf (time_out, sizeof (time_out), "%d", old_esc_mode_timeout);
if (!old_esc_mode)
quick_widgets[15].options = quick_widgets[16].options = W_DISABLED;
quick_widgets[16].options = quick_widgets[17].options = W_DISABLED;
if (quick_dialog (&Quick_input) == B_ENTER)
old_esc_mode_timeout = atoi (time_out_new);

View File

@ -238,6 +238,7 @@ static const struct
{ "pause_after_run", &pause_after_run },
{ "shell_patterns", &easy_patterns },
{ "auto_save_setup", &auto_save_setup },
{ "preallocate_space", &mc_global.vfs.preallocate_space },
{ "auto_menu", &auto_menu },
{ "use_internal_view", &use_internal_view },
{ "use_internal_edit", &use_internal_edit },