mirror of
https://github.com/samba-team/samba.git
synced 2025-01-26 10:04:02 +03:00
s3-aio: Make the strict sync after write async
This restores cb405947caa9f4bdb962483860a9093a364ecbf2, which was lost during the refactoring of aio.c and vfs_aio_pthread.c. Signed-off-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
56aae9f754
commit
ed31e20115
@ -22,6 +22,7 @@
|
|||||||
#include "smbd/smbd.h"
|
#include "smbd/smbd.h"
|
||||||
#include "smbd/globals.h"
|
#include "smbd/globals.h"
|
||||||
#include "../lib/util/tevent_ntstatus.h"
|
#include "../lib/util/tevent_ntstatus.h"
|
||||||
|
#include "../lib/util/tevent_unix.h"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
The buffer we keep around whilst an aio request is in process.
|
The buffer we keep around whilst an aio request is in process.
|
||||||
@ -311,6 +312,99 @@ static void aio_pread_smb1_done(struct tevent_req *req)
|
|||||||
TALLOC_FREE(aio_ex);
|
TALLOC_FREE(aio_ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct pwrite_fsync_state {
|
||||||
|
struct tevent_context *ev;
|
||||||
|
files_struct *fsp;
|
||||||
|
bool write_through;
|
||||||
|
ssize_t nwritten;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void pwrite_fsync_write_done(struct tevent_req *subreq);
|
||||||
|
static void pwrite_fsync_sync_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
static struct tevent_req *pwrite_fsync_send(TALLOC_CTX *mem_ctx,
|
||||||
|
struct tevent_context *ev,
|
||||||
|
struct files_struct *fsp,
|
||||||
|
const void *data,
|
||||||
|
size_t n, off_t offset,
|
||||||
|
bool write_through)
|
||||||
|
{
|
||||||
|
struct tevent_req *req, *subreq;
|
||||||
|
struct pwrite_fsync_state *state;
|
||||||
|
|
||||||
|
req = tevent_req_create(mem_ctx, &state, struct pwrite_fsync_state);
|
||||||
|
if (req == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
state->ev = ev;
|
||||||
|
state->fsp = fsp;
|
||||||
|
state->write_through = write_through;
|
||||||
|
|
||||||
|
subreq = SMB_VFS_PWRITE_SEND(state, ev, fsp, data, n, offset);
|
||||||
|
if (tevent_req_nomem(subreq, req)) {
|
||||||
|
return tevent_req_post(req, ev);
|
||||||
|
}
|
||||||
|
tevent_req_set_callback(subreq, pwrite_fsync_write_done, req);
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pwrite_fsync_write_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
struct tevent_req *req = tevent_req_callback_data(
|
||||||
|
subreq, struct tevent_req);
|
||||||
|
struct pwrite_fsync_state *state = tevent_req_data(
|
||||||
|
req, struct pwrite_fsync_state);
|
||||||
|
connection_struct *conn = state->fsp->conn;
|
||||||
|
int err;
|
||||||
|
bool do_sync;
|
||||||
|
|
||||||
|
state->nwritten = SMB_VFS_PWRITE_RECV(subreq, &err);
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
if (state->nwritten == -1) {
|
||||||
|
tevent_req_error(req, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
do_sync = (lp_strict_sync(SNUM(conn)) &&
|
||||||
|
(lp_syncalways(SNUM(conn)) || state->write_through));
|
||||||
|
if (!do_sync) {
|
||||||
|
tevent_req_done(req);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
subreq = SMB_VFS_FSYNC_SEND(state, state->ev, state->fsp);
|
||||||
|
if (tevent_req_nomem(subreq, req)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tevent_req_set_callback(subreq, pwrite_fsync_sync_done, req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pwrite_fsync_sync_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
struct tevent_req *req = tevent_req_callback_data(
|
||||||
|
subreq, struct tevent_req);
|
||||||
|
int ret, err;
|
||||||
|
|
||||||
|
ret = SMB_VFS_FSYNC_RECV(subreq, &err);
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
if (ret == -1) {
|
||||||
|
tevent_req_error(req, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tevent_req_done(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t pwrite_fsync_recv(struct tevent_req *req, int *perr)
|
||||||
|
{
|
||||||
|
struct pwrite_fsync_state *state = tevent_req_data(
|
||||||
|
req, struct pwrite_fsync_state);
|
||||||
|
|
||||||
|
if (tevent_req_is_unix_error(req, perr)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return state->nwritten;
|
||||||
|
}
|
||||||
|
|
||||||
static void aio_pwrite_smb1_done(struct tevent_req *req);
|
static void aio_pwrite_smb1_done(struct tevent_req *req);
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -388,8 +482,9 @@ NTSTATUS schedule_aio_write_and_X(connection_struct *conn,
|
|||||||
aio_ex->nbyte = numtowrite;
|
aio_ex->nbyte = numtowrite;
|
||||||
aio_ex->offset = startpos;
|
aio_ex->offset = startpos;
|
||||||
|
|
||||||
req = SMB_VFS_PWRITE_SEND(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
|
req = pwrite_fsync_send(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
|
||||||
data, numtowrite, startpos);
|
data, numtowrite, startpos,
|
||||||
|
aio_ex->write_through);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. "
|
DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. "
|
||||||
"Error %s\n", strerror(errno) ));
|
"Error %s\n", strerror(errno) ));
|
||||||
@ -450,7 +545,7 @@ static void aio_pwrite_smb1_done(struct tevent_req *req)
|
|||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
nwritten = SMB_VFS_PWRITE_RECV(req, &err);
|
nwritten = pwrite_fsync_recv(req, &err);
|
||||||
TALLOC_FREE(req);
|
TALLOC_FREE(req);
|
||||||
|
|
||||||
DEBUG(10, ("pwrite_recv returned %d, err = %s\n", (int)nwritten,
|
DEBUG(10, ("pwrite_recv returned %d, err = %s\n", (int)nwritten,
|
||||||
@ -507,8 +602,6 @@ static void aio_pwrite_smb1_done(struct tevent_req *req)
|
|||||||
ERROR_NT(map_nt_error_from_unix(err));
|
ERROR_NT(map_nt_error_from_unix(err));
|
||||||
srv_set_message(outbuf,0,0,true);
|
srv_set_message(outbuf,0,0,true);
|
||||||
} else {
|
} else {
|
||||||
NTSTATUS status;
|
|
||||||
|
|
||||||
SSVAL(outbuf,smb_vwv2,nwritten);
|
SSVAL(outbuf,smb_vwv2,nwritten);
|
||||||
SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
|
SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
|
||||||
if (nwritten < (ssize_t)numtowrite) {
|
if (nwritten < (ssize_t)numtowrite) {
|
||||||
@ -518,15 +611,6 @@ static void aio_pwrite_smb1_done(struct tevent_req *req)
|
|||||||
|
|
||||||
DEBUG(3,("handle_aio_write: %s, num=%d wrote=%d\n",
|
DEBUG(3,("handle_aio_write: %s, num=%d wrote=%d\n",
|
||||||
fsp_fnum_dbg(fsp), (int)numtowrite, (int)nwritten));
|
fsp_fnum_dbg(fsp), (int)numtowrite, (int)nwritten));
|
||||||
status = sync_file(fsp->conn,fsp, aio_ex->write_through);
|
|
||||||
if (!NT_STATUS_IS_OK(status)) {
|
|
||||||
ERROR_BOTH(map_nt_error_from_unix(errno),
|
|
||||||
ERRHRD, ERRdiskfull);
|
|
||||||
srv_set_message(outbuf,0,0,true);
|
|
||||||
DEBUG(5, ("handle_aio_write: sync_file for %s "
|
|
||||||
"returned %s\n",
|
|
||||||
fsp_str_dbg(fsp), nt_errstr(status)));
|
|
||||||
}
|
|
||||||
|
|
||||||
aio_ex->fsp->fh->pos = aio_ex->offset + nwritten;
|
aio_ex->fsp->fh->pos = aio_ex->offset + nwritten;
|
||||||
}
|
}
|
||||||
@ -793,8 +877,9 @@ NTSTATUS schedule_aio_smb2_write(connection_struct *conn,
|
|||||||
aio_ex->nbyte = in_data.length;
|
aio_ex->nbyte = in_data.length;
|
||||||
aio_ex->offset = in_offset;
|
aio_ex->offset = in_offset;
|
||||||
|
|
||||||
req = SMB_VFS_PWRITE_SEND(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
|
req = pwrite_fsync_send(aio_ex, fsp->conn->sconn->ev_ctx, fsp,
|
||||||
in_data.data, in_data.length, in_offset);
|
in_data.data, in_data.length, in_offset,
|
||||||
|
write_through);
|
||||||
if (req == NULL) {
|
if (req == NULL) {
|
||||||
DEBUG(3, ("smb2: SMB_VFS_PWRITE_SEND failed. "
|
DEBUG(3, ("smb2: SMB_VFS_PWRITE_SEND failed. "
|
||||||
"Error %s\n", strerror(errno)));
|
"Error %s\n", strerror(errno)));
|
||||||
@ -849,7 +934,7 @@ static void aio_pwrite_smb2_done(struct tevent_req *req)
|
|||||||
ssize_t nwritten;
|
ssize_t nwritten;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
nwritten = SMB_VFS_PWRITE_RECV(req, &err);
|
nwritten = pwrite_fsync_recv(req, &err);
|
||||||
TALLOC_FREE(req);
|
TALLOC_FREE(req);
|
||||||
|
|
||||||
DEBUG(10, ("pwrite_recv returned %d, err = %s\n", (int)nwritten,
|
DEBUG(10, ("pwrite_recv returned %d, err = %s\n", (int)nwritten,
|
||||||
@ -866,7 +951,7 @@ static void aio_pwrite_smb2_done(struct tevent_req *req)
|
|||||||
/* Unlock now we're done. */
|
/* Unlock now we're done. */
|
||||||
SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &aio_ex->lock);
|
SMB_VFS_STRICT_UNLOCK(fsp->conn, fsp, &aio_ex->lock);
|
||||||
|
|
||||||
status = smb2_write_complete(subreq, nwritten, err);
|
status = smb2_write_complete_nosync(subreq, nwritten, err);
|
||||||
|
|
||||||
DEBUG(10, ("smb2: scheduled aio_write completed "
|
DEBUG(10, ("smb2: scheduled aio_write completed "
|
||||||
"for file %s, offset %.0f, requested %u, "
|
"for file %s, offset %.0f, requested %u, "
|
||||||
|
Loading…
x
Reference in New Issue
Block a user