mirror of
https://github.com/samba-team/samba.git
synced 2024-12-24 21:34:56 +03:00
s3: Add aio_fsync to the aio_fork module
Signed-off-by: Jeremy Allison <jra@samba.org>
This commit is contained in:
parent
38dd5b24bb
commit
d6cb302988
@ -81,7 +81,8 @@ fail:
|
|||||||
|
|
||||||
enum cmd_type {
|
enum cmd_type {
|
||||||
READ_CMD,
|
READ_CMD,
|
||||||
WRITE_CMD
|
WRITE_CMD,
|
||||||
|
FSYNC_CMD
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *cmd_type_str(enum cmd_type cmd)
|
static const char *cmd_type_str(enum cmd_type cmd)
|
||||||
@ -95,6 +96,9 @@ static const char *cmd_type_str(enum cmd_type cmd)
|
|||||||
case WRITE_CMD:
|
case WRITE_CMD:
|
||||||
result = "WRITE";
|
result = "WRITE";
|
||||||
break;
|
break;
|
||||||
|
case FSYNC_CMD:
|
||||||
|
result = "FSYNC";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result = "<UNKNOWN>";
|
result = "<UNKNOWN>";
|
||||||
break;
|
break;
|
||||||
@ -388,6 +392,9 @@ static void aio_child_loop(int sockfd, struct mmap_area *map)
|
|||||||
fd, (void *)map->ptr, cmd_struct.n,
|
fd, (void *)map->ptr, cmd_struct.n,
|
||||||
cmd_struct.offset);
|
cmd_struct.offset);
|
||||||
break;
|
break;
|
||||||
|
case FSYNC_CMD:
|
||||||
|
ret_struct.size = fsync(fd);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
ret_struct.size = -1;
|
ret_struct.size = -1;
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
@ -782,6 +789,108 @@ static ssize_t aio_fork_pwrite_recv(struct tevent_req *req, int *err)
|
|||||||
return state->ret;
|
return state->ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct aio_fork_fsync_state {
|
||||||
|
struct aio_child *child;
|
||||||
|
ssize_t ret;
|
||||||
|
int err;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void aio_fork_fsync_done(struct tevent_req *subreq);
|
||||||
|
|
||||||
|
static struct tevent_req *aio_fork_fsync_send(
|
||||||
|
struct vfs_handle_struct *handle, TALLOC_CTX *mem_ctx,
|
||||||
|
struct tevent_context *ev, struct files_struct *fsp)
|
||||||
|
{
|
||||||
|
struct tevent_req *req, *subreq;
|
||||||
|
struct aio_fork_fsync_state *state;
|
||||||
|
struct rw_cmd cmd;
|
||||||
|
ssize_t written;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
req = tevent_req_create(mem_ctx, &state, struct aio_fork_fsync_state);
|
||||||
|
if (req == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = get_idle_child(handle, &state->child);
|
||||||
|
if (err != 0) {
|
||||||
|
tevent_req_error(req, err);
|
||||||
|
return tevent_req_post(req, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZERO_STRUCT(cmd);
|
||||||
|
cmd.cmd = FSYNC_CMD;
|
||||||
|
|
||||||
|
DEBUG(10, ("sending fd %d to child %d\n", fsp->fh->fd,
|
||||||
|
(int)state->child->pid));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Not making this async. We're writing into an empty unix
|
||||||
|
* domain socket. This should never block.
|
||||||
|
*/
|
||||||
|
written = write_fd(state->child->sockfd, &cmd, sizeof(cmd),
|
||||||
|
fsp->fh->fd);
|
||||||
|
if (written == -1) {
|
||||||
|
err = errno;
|
||||||
|
|
||||||
|
TALLOC_FREE(state->child);
|
||||||
|
|
||||||
|
DEBUG(10, ("write_fd failed: %s\n", strerror(err)));
|
||||||
|
tevent_req_error(req, err);
|
||||||
|
return tevent_req_post(req, ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
subreq = read_packet_send(state, ev, state->child->sockfd,
|
||||||
|
sizeof(struct rw_ret), NULL, NULL);
|
||||||
|
if (tevent_req_nomem(subreq, req)) {
|
||||||
|
TALLOC_FREE(state->child); /* we sent sth down */
|
||||||
|
return tevent_req_post(req, ev);
|
||||||
|
}
|
||||||
|
tevent_req_set_callback(subreq, aio_fork_fsync_done, req);
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void aio_fork_fsync_done(struct tevent_req *subreq)
|
||||||
|
{
|
||||||
|
struct tevent_req *req = tevent_req_callback_data(
|
||||||
|
subreq, struct tevent_req);
|
||||||
|
struct aio_fork_fsync_state *state = tevent_req_data(
|
||||||
|
req, struct aio_fork_fsync_state);
|
||||||
|
ssize_t nread;
|
||||||
|
uint8_t *buf;
|
||||||
|
int err;
|
||||||
|
struct rw_ret *retbuf;
|
||||||
|
|
||||||
|
nread = read_packet_recv(subreq, talloc_tos(), &buf, &err);
|
||||||
|
TALLOC_FREE(subreq);
|
||||||
|
if (nread == -1) {
|
||||||
|
TALLOC_FREE(state->child);
|
||||||
|
tevent_req_error(req, err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
state->child->busy = false;
|
||||||
|
|
||||||
|
retbuf = (struct rw_ret *)buf;
|
||||||
|
state->ret = retbuf->size;
|
||||||
|
state->err = retbuf->ret_errno;
|
||||||
|
tevent_req_done(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int aio_fork_fsync_recv(struct tevent_req *req, int *err)
|
||||||
|
{
|
||||||
|
struct aio_fork_fsync_state *state = tevent_req_data(
|
||||||
|
req, struct aio_fork_fsync_state);
|
||||||
|
|
||||||
|
if (tevent_req_is_unix_error(req, err)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (state->ret == -1) {
|
||||||
|
*err = state->err;
|
||||||
|
}
|
||||||
|
return state->ret;
|
||||||
|
}
|
||||||
|
|
||||||
static int aio_fork_connect(vfs_handle_struct *handle, const char *service,
|
static int aio_fork_connect(vfs_handle_struct *handle, const char *service,
|
||||||
const char *user)
|
const char *user)
|
||||||
{
|
{
|
||||||
@ -805,6 +914,8 @@ static struct vfs_fn_pointers vfs_aio_fork_fns = {
|
|||||||
.pread_recv_fn = aio_fork_pread_recv,
|
.pread_recv_fn = aio_fork_pread_recv,
|
||||||
.pwrite_send_fn = aio_fork_pwrite_send,
|
.pwrite_send_fn = aio_fork_pwrite_send,
|
||||||
.pwrite_recv_fn = aio_fork_pwrite_recv,
|
.pwrite_recv_fn = aio_fork_pwrite_recv,
|
||||||
|
.fsync_send_fn = aio_fork_fsync_send,
|
||||||
|
.fsync_recv_fn = aio_fork_fsync_recv,
|
||||||
};
|
};
|
||||||
|
|
||||||
NTSTATUS vfs_aio_fork_init(void);
|
NTSTATUS vfs_aio_fork_init(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user