mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-18 17:29:28 +03:00
Ticket #1983: support BTRFS's file clone operation.
Signed-off-by: Andrew Borodin <aborodin@vmail.ru>
This commit is contained in:
parent
5f80acde87
commit
0493a5e90e
@ -45,6 +45,13 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __linux__
|
||||||
|
#include <linux/fs.h>
|
||||||
|
#ifdef HAVE_SYS_IOCTL_H
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#endif /* HAVE_SYS_IOCTL_H */
|
||||||
|
#endif /* __linux__ */
|
||||||
|
|
||||||
#include "lib/global.h"
|
#include "lib/global.h"
|
||||||
#include "lib/strutil.h"
|
#include "lib/strutil.h"
|
||||||
#include "lib/util.h"
|
#include "lib/util.h"
|
||||||
@ -654,6 +661,40 @@ vfs_preallocate (int dest_vfs_fd, off_t src_fsize, off_t dest_fsize)
|
|||||||
return posix_fallocate (*(int *) dest_fd, dest_fsize, src_fsize - dest_fsize);
|
return posix_fallocate (*(int *) dest_fd, dest_fsize, src_fsize - dest_fsize);
|
||||||
|
|
||||||
#endif /* HAVE_POSIX_FALLOCATE */
|
#endif /* HAVE_POSIX_FALLOCATE */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
|
||||||
|
int
|
||||||
|
vfs_clone_file (int dest_vfs_fd, int src_vfs_fd)
|
||||||
|
{
|
||||||
|
#ifdef FICLONE
|
||||||
|
void *dest_fd = NULL;
|
||||||
|
void *src_fd = NULL;
|
||||||
|
struct vfs_class *dest_class;
|
||||||
|
struct vfs_class *src_class;
|
||||||
|
|
||||||
|
dest_class = vfs_class_find_by_handle (dest_vfs_fd, &dest_fd);
|
||||||
|
if (dest_fd == NULL || (dest_class->flags & VFSF_LOCAL) == 0)
|
||||||
|
{
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
src_class = vfs_class_find_by_handle (src_vfs_fd, &src_fd);
|
||||||
|
if (src_fd == NULL || (src_class->flags & VFSF_LOCAL) == 0)
|
||||||
|
{
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ioctl (*(int *) dest_fd, FICLONE, *(int *) src_fd);
|
||||||
|
#else
|
||||||
|
(void) dest_vfs_fd;
|
||||||
|
(void) src_vfs_fd;
|
||||||
|
errno = EOPNOTSUPP;
|
||||||
|
return (-1);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* --------------------------------------------------------------------------------------------- */
|
/* --------------------------------------------------------------------------------------------- */
|
||||||
|
@ -287,6 +287,8 @@ char *_vfs_get_cwd (void);
|
|||||||
|
|
||||||
int vfs_preallocate (int dest_desc, off_t src_fsize, off_t dest_fsize);
|
int vfs_preallocate (int dest_desc, off_t src_fsize, off_t dest_fsize);
|
||||||
|
|
||||||
|
int vfs_clone_file (int dest_vfs_fd, int src_vfs_fd);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface functions described in interface.c
|
* Interface functions described in interface.c
|
||||||
*/
|
*/
|
||||||
|
@ -2345,6 +2345,14 @@ copy_file_file (file_op_total_context_t * tctx, file_op_context_t * ctx,
|
|||||||
appending = ctx->do_append;
|
appending = ctx->do_append;
|
||||||
ctx->do_append = FALSE;
|
ctx->do_append = FALSE;
|
||||||
|
|
||||||
|
/* Try clone the file first. */
|
||||||
|
if (vfs_clone_file (dest_desc, src_desc) == 0)
|
||||||
|
{
|
||||||
|
dst_status = DEST_FULL;
|
||||||
|
return_status = FILE_CONT;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
/* Find out the optimal buffer size. */
|
/* Find out the optimal buffer size. */
|
||||||
while (mc_fstat (dest_desc, &dst_stat) != 0)
|
while (mc_fstat (dest_desc, &dst_stat) != 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user