The Samba-Bugzilla – Attachment 12912 Details for
Bug 12033
smbd should support copy_file_range() for FSCTL_SRV_COPYCHUNK
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
patch for master
samba-copy_file_range.patch (text/plain), 5.61 KB, created by
Björn Jacke
on 2017-02-09 08:13:29 UTC
(
hide
)
Description:
patch for master
Filename:
MIME Type:
Creator:
Björn Jacke
Created:
2017-02-09 08:13:29 UTC
Size:
5.61 KB
patch
obsolete
>From 6a1cddf41c39f9b297cb5428a8ef19edc68337a1 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Thu, 19 Jan 2017 22:13:03 +0100 >Subject: wscript: check for copy_file_range syscall > >this one came with Linux kernel 4.5 > >Signed-off-by: Bjoern Jacke <bj@sernet.de> >--- > source3/wscript | 9 +++++++++ > 1 file changed, 9 insertions(+) > >diff --git a/source3/wscript b/source3/wscript >index b09e372..de0b1da 100644 >--- a/source3/wscript >+++ b/source3/wscript >@@ -1204,6 +1204,15 @@ ssize_t err = posix_fadvise(0,0,0x80000,POSIX_FADV_WILLNEED); > msg='Checking whether sysconf(%s) is available' % v) > > conf.CHECK_CODE(''' >+#include <stdlib.h> >+#include <sys/syscall.h> >+#include <unistd.h> >+syscall(SYS_copy_file_range,0,NULL,0,NULL,0,0); >+ ''', >+ 'HAVE_SYSCALL_COPY_FILE_RANGE', >+ msg='Checking whether we have copy_file_range system call') >+ >+ conf.CHECK_CODE(''' > #include <sys/syscall.h> > #include <unistd.h> > syscall(SYS_initgroups, 16, NULL, NULL, 0); >-- >2.7.4 > > >From e9921beeacbeef904c91e57c9f3d3bfd02432a29 Mon Sep 17 00:00:00 2001 >From: =?UTF-8?q?Bj=C3=B6rn=20Jacke?= <bj@sernet.de> >Date: Fri, 27 Jan 2017 15:27:44 +0100 >Subject: vfs_default: add copy_file_range support for copy chunk > >we try to use the copy_file_range syscall first, which can ideally be a >zero-copy operation. We fall back to userspace read/write if copy_file_range >is not available. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12033 > >Signed-off-by: Bjoern Jacke <bj@sernet.de> >--- > source3/modules/vfs_default.c | 102 ++++++++++++++++++++++++++++++++++++------ > 1 file changed, 88 insertions(+), 14 deletions(-) > >diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c >index d4610f7..c9ad0be 100644 >--- a/source3/modules/vfs_default.c >+++ b/source3/modules/vfs_default.c >@@ -33,6 +33,10 @@ > #include "lib/util/tevent_ntstatus.h" > #include "lib/util/sys_rw.h" > #include "lib/pthreadpool/pthreadpool_tevent.h" >+#ifdef HAVE_SYS_SYSCALL_H >+#include <sys/syscall.h> >+#endif >+ > > #undef DBGC_CLASS > #define DBGC_CLASS DBGC_VFS >@@ -1607,21 +1611,15 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand > struct tevent_req *req; > struct vfs_cc_state *vfs_cc_state; > NTSTATUS status; >- >- DEBUG(10, ("performing server side copy chunk of length %lu\n", >- (unsigned long)num)); >+ ssize_t ret; >+ struct lock_struct lck; >+ int saved_errno; > > req = tevent_req_create(mem_ctx, &vfs_cc_state, struct vfs_cc_state); > if (req == NULL) { > return NULL; > } > >- vfs_cc_state->buf = talloc_array(vfs_cc_state, uint8_t, >- MIN(num, 8*1024*1024)); >- if (tevent_req_nomem(vfs_cc_state->buf, req)) { >- return tevent_req_post(req, ev); >- } >- > status = vfs_stat_fsp(src_fsp); > if (tevent_req_nterror(req, status)) { > return tevent_req_post(req, ev); >@@ -1640,13 +1638,89 @@ static struct tevent_req *vfswrap_copy_chunk_send(struct vfs_handle_struct *hand > tevent_req_nterror(req, NT_STATUS_INVALID_VIEW_SIZE); > return tevent_req_post(req, ev); > } >+#ifdef HAVE_SYSCALL_COPY_FILE_RANGE >+ /* copy_file_range optimized call */ >+ DEBUG(5, ("performing server side copy chunk " >+ "(copy_file_range) of length %lu at offsets " >+ "%lu/%lu\n", (unsigned long)num, >+ (unsigned long)src_off, (unsigned long)dest_off)); >+ if (src_fsp->op == NULL || dest_fsp->op == NULL) { >+ tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); >+ return tevent_req_post(req, ev); >+ } > >- /* could use 2.6.33+ sendfile here to do this in kernel */ >- while (vfs_cc_state->copied < num) { >- ssize_t ret; >- struct lock_struct lck; >- int saved_errno; >+ init_strict_lock_struct(src_fsp, >+ src_fsp->op->global->open_persistent_id, >+ src_off, >+ num, >+ READ_LOCK, >+ &lck); >+ >+ if (!SMB_VFS_STRICT_LOCK(src_fsp->conn, src_fsp, &lck)) { >+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); >+ return tevent_req_post(req, ev); >+ } >+ >+ init_strict_lock_struct(dest_fsp, >+ dest_fsp->op->global->open_persistent_id, >+ dest_off, >+ num, >+ WRITE_LOCK, >+ &lck); >+ >+ if (!SMB_VFS_STRICT_LOCK(dest_fsp->conn, dest_fsp, &lck)) { >+ tevent_req_nterror(req, NT_STATUS_FILE_LOCK_CONFLICT); >+ return tevent_req_post(req, ev); >+ } >+ >+ ret = syscall(SYS_copy_file_range, >+ src_fsp->fh->fd, &src_off, >+ dest_fsp->fh->fd, &dest_off, >+ num, 0); >+ >+ if (ret == -1) { >+ saved_errno = errno; >+ } >+ SMB_VFS_STRICT_UNLOCK(src_fsp->conn, src_fsp, &lck); >+ SMB_VFS_STRICT_UNLOCK(dest_fsp->conn, dest_fsp, &lck); >+ >+ if (ret == -1) { >+ DEBUG(1, ("failed copy_file_range: %s\n", >+ strerror(errno) )); >+ errno = saved_errno; >+ if (errno != EXDEV && >+ errno != ENOTSUP && >+ errno != ENOSYS) { >+ /* fail for sure - no rw fallback path */ >+ tevent_req_nterror(req, map_nt_error_from_unix(errno)); >+ return tevent_req_post(req, ev); >+ } else { >+ /* continue rw fallback path */ >+ goto manualcopy; >+ } >+ } >+ >+ if (ret != num) { >+ /* zero tolerance for short copies */ >+ tevent_req_nterror(req, NT_STATUS_IO_DEVICE_ERROR); >+ return tevent_req_post(req, ev); >+ } > >+ /* all done well if we ended up here */ >+ tevent_req_done(req); >+ return tevent_req_post(req, ev); >+#endif >+manualcopy: >+ DEBUG(5, ("performing server side copy chunk " >+ "(rw) of length %lu at offsets " >+ "%lu/%lu\n", (unsigned long)num, >+ (unsigned long)src_off, (unsigned long)dest_off)); >+ vfs_cc_state->buf = talloc_array(vfs_cc_state, uint8_t, >+ MIN(num, 8*1024*1024)); >+ if (tevent_req_nomem(vfs_cc_state->buf, req)) { >+ return tevent_req_post(req, ev); >+ } >+ while (vfs_cc_state->copied < num) { > off_t this_num = MIN(talloc_array_length(vfs_cc_state->buf), > num - vfs_cc_state->copied); > >-- >2.7.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 12033
:
12912
|
15729
|
16669
|
16670
|
16671
|
16672