chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
verbs: fix typo in error message
[elogind.git]
/
src
/
shared
/
copy.c
diff --git
a/src/shared/copy.c
b/src/shared/copy.c
index f22a9409918a84c0eb3fb28f94db26077b844615..0c2cdc8d9490793d94730904621eae0ad412736f 100644
(file)
--- a/
src/shared/copy.c
+++ b/
src/shared/copy.c
@@
-25,14
+25,24
@@
#include "btrfs-util.h"
#include "copy.h"
#include "btrfs-util.h"
#include "copy.h"
-int copy_bytes(int fdf, int fdt, off_t max_bytes) {
+#define COPY_BUFFER_SIZE (16*1024)
+
+int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
bool try_sendfile = true;
bool try_sendfile = true;
+ int r;
assert(fdf >= 0);
assert(fdt >= 0);
assert(fdf >= 0);
assert(fdt >= 0);
+ /* Try btrfs reflinks first. */
+ if (try_reflink && max_bytes == (off_t) -1) {
+ r = btrfs_reflink(fdf, fdt);
+ if (r >= 0)
+ return r;
+ }
+
for (;;) {
for (;;) {
- size_t m =
PIPE_BUF
;
+ size_t m =
COPY_BUFFER_SIZE
;
ssize_t n;
if (max_bytes != (off_t) -1) {
ssize_t n;
if (max_bytes != (off_t) -1) {
@@
-64,7
+74,6
@@
int copy_bytes(int fdf, int fdt, off_t max_bytes) {
/* As a fallback just copy bits by hand */
{
char buf[m];
/* As a fallback just copy bits by hand */
{
char buf[m];
- int r;
n = read(fdf, buf, m);
if (n < 0)
n = read(fdf, buf, m);
if (n < 0)
@@
-72,10
+81,9
@@
int copy_bytes(int fdf, int fdt, off_t max_bytes) {
if (n == 0) /* EOF */
break;
if (n == 0) /* EOF */
break;
- r = loop_write(fdt, buf, n, false);
+ r = loop_write(fdt, buf,
(size_t)
n, false);
if (r < 0)
return r;
if (r < 0)
return r;
-
}
next:
}
next:
@@
-125,7
+133,7
@@
static int fd_copy_regular(int df, const char *from, const struct stat *st, int
if (fdt < 0)
return -errno;
if (fdt < 0)
return -errno;
- r = copy_bytes(fdf, fdt, (off_t) -1);
+ r = copy_bytes(fdf, fdt, (off_t) -1
, true
);
if (r < 0) {
unlinkat(dt, to, 0);
return r;
if (r < 0) {
unlinkat(dt, to, 0);
return r;
@@
-273,30
+281,34
@@
static int fd_copy_directory(
return r;
}
return r;
}
-int copy_tree
(const char *from
, const char *to, bool merge) {
+int copy_tree
_at(int fdf, const char *from, int fdt
, const char *to, bool merge) {
struct stat st;
assert(from);
assert(to);
struct stat st;
assert(from);
assert(to);
- if (
lstat(from, &st
) < 0)
+ if (
fstatat(fdf, from, &st, AT_SYMLINK_NOFOLLOW
) < 0)
return -errno;
if (S_ISREG(st.st_mode))
return -errno;
if (S_ISREG(st.st_mode))
- return fd_copy_regular(
AT_FDCWD, from, &st, AT_FDCWD
, to);
+ return fd_copy_regular(
fdf, from, &st, fdt
, to);
else if (S_ISDIR(st.st_mode))
else if (S_ISDIR(st.st_mode))
- return fd_copy_directory(
AT_FDCWD, from, &st, AT_FDCWD
, to, st.st_dev, merge);
+ return fd_copy_directory(
fdf, from, &st, fdt
, to, st.st_dev, merge);
else if (S_ISLNK(st.st_mode))
else if (S_ISLNK(st.st_mode))
- return fd_copy_symlink(
AT_FDCWD, from, &st, AT_FDCWD
, to);
+ return fd_copy_symlink(
fdf, from, &st, fdt
, to);
else if (S_ISFIFO(st.st_mode))
else if (S_ISFIFO(st.st_mode))
- return fd_copy_fifo(
AT_FDCWD, from, &st, AT_FDCWD
, to);
+ return fd_copy_fifo(
fdf, from, &st, fdt
, to);
else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode))
- return fd_copy_node(
AT_FDCWD, from, &st, AT_FDCWD
, to);
+ return fd_copy_node(
fdf, from, &st, fdt
, to);
else
return -ENOTSUP;
}
else
return -ENOTSUP;
}
-int copy_tree_fd(int dirfd, const char *to, bool merge) {
+int copy_tree(const char *from, const char *to, bool merge) {
+ return copy_tree_at(AT_FDCWD, from, AT_FDCWD, to, merge);
+}
+
+int copy_directory_fd(int dirfd, const char *to, bool merge) {
struct stat st;
struct stat st;
@@
-312,7
+324,7
@@
int copy_tree_fd(int dirfd, const char *to, bool merge) {
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
}
return fd_copy_directory(dirfd, NULL, &st, AT_FDCWD, to, st.st_dev, merge);
}
-int copy_file_fd(const char *from, int fdt) {
+int copy_file_fd(const char *from, int fdt
, bool try_reflink
) {
_cleanup_close_ int fdf = -1;
assert(from);
_cleanup_close_ int fdf = -1;
assert(from);
@@
-322,7
+334,7
@@
int copy_file_fd(const char *from, int fdt) {
if (fdf < 0)
return -errno;
if (fdf < 0)
return -errno;
- return copy_bytes(fdf, fdt, (off_t) -1);
+ return copy_bytes(fdf, fdt, (off_t) -1
, try_reflink
);
}
int copy_file(const char *from, const char *to, int flags, mode_t mode) {
}
int copy_file(const char *from, const char *to, int flags, mode_t mode) {
@@
-335,7
+347,7
@@
int copy_file(const char *from, const char *to, int flags, mode_t mode) {
if (fdt < 0)
return -errno;
if (fdt < 0)
return -errno;
- r = copy_file_fd(from, fdt);
+ r = copy_file_fd(from, fdt
, true
);
if (r < 0) {
close(fdt);
unlink(to);
if (r < 0) {
close(fdt);
unlink(to);