From b8c416fe2ac37b3ba0124811cfeddf2015c8d31f Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 22 Jan 2009 18:04:17 +0100 Subject: [PATCH] s3:smbd: convert aio to use tevent_signal metze --- source3/include/proto.h | 18 +--- source3/modules/vfs_aio_fork.c | 3 +- source3/smbd/aio.c | 150 +++++++++++---------------------- source3/smbd/globals.c | 3 +- source3/smbd/globals.h | 3 +- 5 files changed, 54 insertions(+), 123 deletions(-) diff --git a/source3/include/proto.h b/source3/include/proto.h index d625f98186d8..dd5b601c2c70 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6475,8 +6475,6 @@ REGVAL_CTR *svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ); /* The following definitions come from smbd/aio.c */ -void aio_request_done(uint16_t mid); -bool aio_finished(void); void initialize_async_io_handler(void); bool schedule_aio_read_and_X(connection_struct *conn, struct smb_request *req, @@ -6487,23 +6485,9 @@ bool schedule_aio_write_and_X(connection_struct *conn, files_struct *fsp, char *data, SMB_OFF_T startpos, size_t numtowrite); -int process_aio_queue(void); int wait_for_aio_completion(files_struct *fsp); void cancel_aio_by_fsp(files_struct *fsp); -bool aio_finished(void); -void initialize_async_io_handler(void); -int process_aio_queue(void); -bool schedule_aio_read_and_X(connection_struct *conn, - struct smb_request *req, - files_struct *fsp, SMB_OFF_T startpos, - size_t smb_maxcnt); -bool schedule_aio_write_and_X(connection_struct *conn, - struct smb_request *req, - files_struct *fsp, char *data, - SMB_OFF_T startpos, - size_t numtowrite); -void cancel_aio_by_fsp(files_struct *fsp); -int wait_for_aio_completion(files_struct *fsp); +void smbd_aio_complete_mid(unsigned int mid); /* The following definitions come from smbd/blocking.c */ diff --git a/source3/modules/vfs_aio_fork.c b/source3/modules/vfs_aio_fork.c index 30b14f280f2a..e29ce5e7a8fe 100644 --- a/source3/modules/vfs_aio_fork.c +++ b/source3/modules/vfs_aio_fork.c @@ -406,8 +406,7 @@ static void handle_aio_completion(struct event_context *event_ctx, DEBUG(10, ("mid %d finished\n", (int)mid)); - aio_request_done(mid); - process_aio_queue(); + smbd_aio_complete_mid(mid); } static int aio_child_destructor(struct aio_child *child) diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index 54ae45a7892b..4ce43c95e80f 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -108,58 +108,6 @@ static struct aio_extra *find_aio_ex(uint16 mid) We can have these many aio buffers in flight. *****************************************************************************/ -/**************************************************************************** - Signal handler when an aio request completes. -*****************************************************************************/ - -void aio_request_done(uint16_t mid) -{ - if (aio_signals_received < aio_pending_size) { - aio_pending_array[aio_signals_received] = mid; - aio_signals_received++; - } - /* Else signal is lost. */ -} - -static void signal_handler(int sig, siginfo_t *info, void *unused) -{ - aio_request_done(info->si_value.sival_int); - sys_select_signal(RT_SIGNAL_AIO); -} - -/**************************************************************************** - Is there a signal waiting ? -*****************************************************************************/ - -bool aio_finished(void) -{ - return (aio_signals_received != 0); -} - -/**************************************************************************** - Initialize the signal handler for aio read/write. -*****************************************************************************/ - -void initialize_async_io_handler(void) -{ - struct sigaction act; - - aio_pending_size = lp_maxmux(); - aio_pending_array = SMB_MALLOC_ARRAY(uint16, aio_pending_size); - SMB_ASSERT(aio_pending_array != NULL); - - ZERO_STRUCT(act); - act.sa_sigaction = signal_handler; - act.sa_flags = SA_SIGINFO; - sigemptyset( &act.sa_mask ); - if (sigaction(RT_SIGNAL_AIO, &act, NULL) != 0) { - DEBUG(0,("Failed to setup RT_SIGNAL_AIO handler\n")); - } - - /* the signal can start off blocked due to a bug in bash */ - BlockSignals(False, RT_SIGNAL_AIO); -} - /**************************************************************************** Set up an aio request from a SMBreadX call. *****************************************************************************/ @@ -573,57 +521,47 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr) Returns non-zero errno if fail or zero if all ok. *****************************************************************************/ -int process_aio_queue(void) +void smbd_aio_complete_mid(unsigned int mid) { - int i; + files_struct *fsp = NULL; + struct aio_extra *aio_ex = find_aio_ex(mid); int ret = 0; - BlockSignals(True, RT_SIGNAL_AIO); - - DEBUG(10,("process_aio_queue: signals_received = %d\n", - (int)aio_signals_received)); - DEBUG(10,("process_aio_queue: outstanding_aio_calls = %d\n", - outstanding_aio_calls)); + DEBUG(10,("smbd_aio_complete_mid: mid[%u]\n", mid)); - if (!aio_signals_received) { - BlockSignals(False, RT_SIGNAL_AIO); - return 0; + if (!aio_ex) { + DEBUG(3,("smbd_aio_complete_mid: Can't find record to " + "match mid %u.\n", mid)); + srv_cancel_sign_response(mid); + return; } - /* Drain all the complete aio_reads. */ - for (i = 0; i < aio_signals_received; i++) { - uint16 mid = aio_pending_array[i]; - files_struct *fsp = NULL; - struct aio_extra *aio_ex = find_aio_ex(mid); - - if (!aio_ex) { - DEBUG(3,("process_aio_queue: Can't find record to " - "match mid %u.\n", (unsigned int)mid)); - srv_cancel_sign_response(mid); - continue; - } + fsp = aio_ex->fsp; + if (fsp == NULL) { + /* file was closed whilst I/O was outstanding. Just + * ignore. */ + DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst " + "aio outstanding (mid[%u]).\n", mid)); + srv_cancel_sign_response(mid); + return; + } - fsp = aio_ex->fsp; - if (fsp == NULL) { - /* file was closed whilst I/O was outstanding. Just - * ignore. */ - DEBUG( 3,( "process_aio_queue: file closed whilst " - "aio outstanding.\n")); - srv_cancel_sign_response(mid); - continue; - } + if (!handle_aio_completed(aio_ex, &ret)) { + return; + } - if (!handle_aio_completed(aio_ex, &ret)) { - continue; - } + TALLOC_FREE(aio_ex); +} - TALLOC_FREE(aio_ex); - } +static void smbd_aio_signal_handler(struct tevent_context *ev_ctx, + struct tevent_signal *se, + int signum, int count, + void *_info, void *private_data) +{ + siginfo_t *info = (siginfo_t *)_info; + unsigned int mid = (unsigned int)info->si_value.sival_int; - outstanding_aio_calls -= aio_signals_received; - aio_signals_received = 0; - BlockSignals(False, RT_SIGNAL_AIO); - return ret; + smbd_aio_complete_mid(mid); } /**************************************************************************** @@ -755,19 +693,28 @@ void cancel_aio_by_fsp(files_struct *fsp) } } -#else -bool aio_finished(void) -{ - return False; -} +/**************************************************************************** + Initialize the signal handler for aio read/write. +*****************************************************************************/ void initialize_async_io_handler(void) { + aio_signal_event = tevent_add_signal(smbd_event_context(), + smbd_event_context(), + RT_SIGNAL_AIO, SA_SIGINFO, + smbd_aio_signal_handler, + NULL); + if (!aio_signal_event) { + exit_server("Failed to setup RT_SIGNAL_AIO handler"); + } + + /* tevent supports 100 signal with SA_SIGINFO */ + aio_pending_size = 100; } -int process_aio_queue(void) +#else +void initialize_async_io_handler(void) { - return False; } bool schedule_aio_read_and_X(connection_struct *conn, @@ -795,4 +742,7 @@ int wait_for_aio_completion(files_struct *fsp) { return ENOSYS; } + +void smbd_aio_complete_mid(unsigned int mid); + #endif diff --git a/source3/smbd/globals.c b/source3/smbd/globals.c index d99f2b0680e2..28b5a709bde1 100644 --- a/source3/smbd/globals.c +++ b/source3/smbd/globals.c @@ -22,10 +22,9 @@ #if defined(WITH_AIO) struct aio_extra *aio_list_head = NULL; +struct tevent_signal *aio_signal_event = NULL; int aio_pending_size = 0; -sig_atomic_t aio_signals_received = 0; int outstanding_aio_calls = 0; -uint16 *aio_pending_array = NULL; #endif /* dlink list we store pending lock records on. */ diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 15085d9d3540..283425caf738 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -20,10 +20,9 @@ #if defined(WITH_AIO) struct aio_extra; extern struct aio_extra *aio_list_head; +extern struct tevent_signal *aio_signal_event; extern int aio_pending_size; -extern sig_atomic_t aio_signals_received; extern int outstanding_aio_calls; -extern uint16_t *aio_pending_array; #endif /* dlink list we store pending lock records on. */ -- 2.34.1