diff options
-rw-r--r-- | source/client/client.c | 2 | ||||
-rw-r--r-- | source/client/smbmount.c | 2 | ||||
-rw-r--r-- | source/include/proto.h | 5 | ||||
-rw-r--r-- | source/lib/system.c | 70 | ||||
-rw-r--r-- | source/lib/util.c | 10 | ||||
-rw-r--r-- | source/libsmb/nmblib.c | 2 | ||||
-rw-r--r-- | source/nmbd/nmbd_packets.c | 2 | ||||
-rw-r--r-- | source/param/loadparm.c | 20 | ||||
-rw-r--r-- | source/smbd/filename.c | 20 | ||||
-rw-r--r-- | source/smbd/server.c | 2 |
10 files changed, 91 insertions, 44 deletions
diff --git a/source/client/client.c b/source/client/client.c index 396028358d5..9a4806b7a2f 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -3333,7 +3333,7 @@ static void wait_keyboard(char *buffer) timeout.tv_sec = 20; timeout.tv_usec = 0; - selrtn = sys_select(&fds,&timeout); + selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,&timeout); if (FD_ISSET(fileno(stdin),&fds)) return; diff --git a/source/client/smbmount.c b/source/client/smbmount.c index bd14b121e63..9bc7cba6f65 100644 --- a/source/client/smbmount.c +++ b/source/client/smbmount.c @@ -463,7 +463,7 @@ static void wait_keyboard(char *buffer) timeout.tv_sec = 20; timeout.tv_usec = 0; - selrtn = sys_select(&fds,&timeout); + selrtn = sys_select(MAX(Client,fileno(stdin))+1,&fds,&timeout); if (FD_ISSET(fileno(stdin),&fds)) return; diff --git a/source/include/proto.h b/source/include/proto.h index 85e00b375bc..6594ac6143a 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -162,8 +162,8 @@ int smbrun(char *cmd,char *outfile,BOOL shared); /*The following definitions come from lib/system.c */ -int sys_select(fd_set *fds,struct timeval *tval); -int sys_select(fd_set *fds,struct timeval *tval); +int sys_select(int maxfd, fd_set *fds,struct timeval *tval); +int sys_select(int maxfd, fd_set *fds,struct timeval *tval); int sys_unlink(char *fname); int sys_open(char *fname,int flags,int mode); DIR *sys_opendir(char *dname); @@ -992,6 +992,7 @@ int lp_lm_announce(void); int lp_lm_interval(void); int lp_machine_password_timeout(void); int lp_change_notify_timeout(void); +int lp_stat_cache_size(void); int lp_ldap_port(void); char *lp_preexec(int ); char *lp_postexec(int ); diff --git a/source/lib/system.c b/source/lib/system.c index 255b1c7b49b..d569b80a748 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -60,7 +60,7 @@ static int pollfd(int fd) return(r); } -int sys_select(fd_set *fds,struct timeval *tval) +int sys_select(int maxfd, fd_set *fds,struct timeval *tval) { fd_set fds2; int counter=0; @@ -69,41 +69,75 @@ int sys_select(fd_set *fds,struct timeval *tval) FD_ZERO(&fds2); while (1) - { - int i; - for (i=0;i<255;i++) { - if (FD_ISSET(i,fds) && pollfd(i)>0) { - found++; - FD_SET(i,&fds2); - } + { + int i; + for (i=0;i<maxfd;i++) { + if (FD_ISSET(i,fds) && pollfd(i)>0) { + found++; + FD_SET(i,&fds2); } + } - if (found) { - memcpy((void *)fds,(void *)&fds2,sizeof(fds2)); - return(found); - } + if (found) { + memcpy((void *)fds,(void *)&fds2,sizeof(fds2)); + return(found); + } - if (tval && tval->tv_sec < counter) return(0); + if (tval && tval->tv_sec < counter) return(0); sleep(1); counter++; - } + } } -#else -int sys_select(fd_set *fds,struct timeval *tval) +#else /* !NO_SELECT */ +int sys_select(int maxfd, fd_set *fds,struct timeval *tval) { +#ifdef USE_POLL + struct pollfd pfd[256]; + int i; + int maxpoll; + int timeout; + int pollrtn; + + maxpoll = 0; + for( i = 0; i < maxfd; i++) { + if(FD_ISSET(i,fds)) { + struct pollfd *pfdp = &pfd[maxpoll++]; + pfdp->fd = i; + pfdp->events = POLLIN; + pfdp->revents = 0; + } + } + + timeout = (tval != NULL) ? (tval->tv_sec * 1000) + (tval->tv_usec/1000) : + -1; + errno = 0; + do { + pollrtn = poll( &pfd[0], maxpoll, timeout); + } while (pollrtn<0 && errno == EINTR); + + FD_ZERO(fds); + + for( i = 0; i < maxpoll; i++) + if( pfd[i].revents & POLLIN ) + FD_SET(pfd[i].fd,fds); + + return pollrtn; +#else /* USE_POLL */ + struct timeval t2; int selrtn; do { if (tval) memcpy((void *)&t2,(void *)tval,sizeof(t2)); errno = 0; - selrtn = select(255,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL); + selrtn = select(maxfd,SELECT_CAST fds,NULL,NULL,tval?&t2:NULL); } while (selrtn<0 && errno == EINTR); return(selrtn); } -#endif +#endif /* USE_POLL */ +#endif /* NO_SELECT */ /******************************************************************* diff --git a/source/lib/util.c b/source/lib/util.c index 4604836f77d..414b54bd7c0 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1883,7 +1883,7 @@ int read_with_timeout(int fd,char *buf,int mincnt,int maxcnt,long time_out) FD_ZERO(&fds); FD_SET(fd,&fds); - selrtn = sys_select(&fds,&timeout); + selrtn = sys_select(fd+1,&fds,&timeout); /* Check if error */ if(selrtn == -1) { @@ -1943,7 +1943,7 @@ int read_max_udp(int fd,char *buffer,int bufsize,int maxtime) timeout.tv_sec = maxtime / 1000; timeout.tv_usec = (maxtime % 1000) * 1000; - selrtn = sys_select(&fds,maxtime>0?&timeout:NULL); + selrtn = sys_select(fd+1,&fds,maxtime>0?&timeout:NULL); if (!FD_ISSET(fd,&fds)) return 0; @@ -2269,7 +2269,7 @@ BOOL receive_local_message(int fd, char *buffer, int buffer_len, int timeout) to.tv_sec = timeout / 1000; to.tv_usec = (timeout % 1000) * 1000; - selrtn = sys_select(&fds,&to); + selrtn = sys_select(fd+1,&fds,&to); /* Check if error */ if(selrtn == -1) @@ -2437,7 +2437,7 @@ BOOL receive_message_or_smb(int smbfd, int oplock_fd, to.tv_sec = timeout / 1000; to.tv_usec = (timeout % 1000) * 1000; - selrtn = sys_select(&fds,timeout>0?&to:NULL); + selrtn = sys_select(MAX(smbfd,oplock_fd)+1,&fds,timeout>0?&to:NULL); /* Check if error */ if(selrtn == -1) { @@ -2601,7 +2601,7 @@ void msleep(int t) FD_ZERO(&fds); errno = 0; - sys_select(&fds,&tval); + sys_select(0,&fds,&tval); GetTimeOfDay(&t2); tdiff = TvalDiff(&t1,&t2); diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index 9390302ab23..81a9505d6b2 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -899,7 +899,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t) timeout.tv_sec = t/1000; timeout.tv_usec = 1000*(t%1000); - sys_select(&fds,&timeout); + sys_select(fd+1,&fds,&timeout); if (FD_ISSET(fd,&fds)) return(read_packet(fd,type)); diff --git a/source/nmbd/nmbd_packets.c b/source/nmbd/nmbd_packets.c index d557414a272..65d98c9a596 100644 --- a/source/nmbd/nmbd_packets.c +++ b/source/nmbd/nmbd_packets.c @@ -1773,7 +1773,7 @@ BOOL listen_for_packets(BOOL run_election) BlockSignals(False, SIGUSR2); #endif /* SIGUSR2 */ - selrtn = sys_select(&fds,&timeout); + selrtn = sys_select(256,&fds,&timeout); /* We can only take signals when we are in the select - block them again here. */ diff --git a/source/param/loadparm.c b/source/param/loadparm.c index f6c57697187..44db306d1b2 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -178,6 +178,7 @@ typedef struct int announce_as; /* This is initialised in init_globals */ int machine_password_timeout; int change_notify_timeout; + int stat_cache_size; #ifdef WITH_LDAP int ldap_port; #endif /* WITH_LDAP */ @@ -579,19 +580,20 @@ static struct parm_struct parm_table[] = {"Tuning Options", P_SEP, P_SEPARATOR}, {"change notify timeout", P_INTEGER, P_GLOBAL, &Globals.change_notify_timeout, NULL, NULL, 0}, - {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0}, - {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0}, + {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0}, {"getwd cache", P_BOOL, P_GLOBAL, &use_getwd_cache, NULL, NULL, 0}, - {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0}, - {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0}, {"keepalive", P_INTEGER, P_GLOBAL, &keepalive, NULL, NULL, 0}, - {"deadtime", P_INTEGER, P_GLOBAL, &Globals.deadtime, NULL, NULL, 0}, - {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0}, - {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0}, + {"lpq cache time", P_INTEGER, P_GLOBAL, &Globals.lpqcachetime, NULL, NULL, 0}, {"max connections", P_INTEGER, P_LOCAL, &sDefault.iMaxConnections, NULL, NULL, 0}, + {"max disk size", P_INTEGER, P_GLOBAL, &Globals.maxdisksize, NULL, NULL, 0}, {"min print space", P_INTEGER, P_LOCAL, &sDefault.iMinPrintSpace, NULL, NULL, 0}, - {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0}, + {"read prediction", P_BOOL, P_GLOBAL, &Globals.bReadPrediction, NULL, NULL, 0}, + {"read size", P_INTEGER, P_GLOBAL, &Globals.ReadSize, NULL, NULL, 0}, + {"shared mem size", P_INTEGER, P_GLOBAL, &Globals.shmem_size, NULL, NULL, 0}, + {"socket options", P_GSTRING, P_GLOBAL, user_socket_options, NULL, NULL, 0}, + {"stat cache size", P_INTEGER, P_GLOBAL, &Globals.stat_cache_size, NULL, NULL, 0}, {"strict sync", P_BOOL, P_LOCAL, &sDefault.bStrictSync, NULL, NULL, 0}, + {"sync always", P_BOOL, P_LOCAL, &sDefault.bSyncAlways, NULL, NULL, 0}, {"Printing Options", P_SEP, P_SEPARATOR}, {"load printers", P_BOOL, P_GLOBAL, &Globals.bLoadPrinters, NULL, NULL, 0}, @@ -827,6 +829,7 @@ static void init_globals(void) Globals.lm_announce = 2; /* = Auto: send only if LM clients found */ Globals.lm_interval = 60; Globals.shmem_size = SHMEM_SIZE; + Globals.stat_cache_size = 50; /* Number of stat translations we'll keep */ Globals.announce_as = ANNOUNCE_AS_NT; Globals.bUnixRealname = False; #if (defined(HAVE_NETGROUP) && defined(WITH_AUTOMOUNT)) @@ -1163,6 +1166,7 @@ FN_GLOBAL_INTEGER(lp_lm_announce,&Globals.lm_announce) FN_GLOBAL_INTEGER(lp_lm_interval,&Globals.lm_interval) FN_GLOBAL_INTEGER(lp_machine_password_timeout,&Globals.machine_password_timeout) FN_GLOBAL_INTEGER(lp_change_notify_timeout,&Globals.change_notify_timeout) +FN_GLOBAL_INTEGER(lp_stat_cache_size,&Globals.stat_cache_size) #ifdef WITH_LDAP FN_GLOBAL_INTEGER(lp_ldap_port,&Globals.ldap_port) diff --git a/source/smbd/filename.c b/source/smbd/filename.c index de4fef5189b..91128280928 100644 --- a/source/smbd/filename.c +++ b/source/smbd/filename.c @@ -115,7 +115,8 @@ typedef struct { static ubi_dlList stat_cache = { NULL, (ubi_dlNodePtr)&stat_cache, 0}; /**************************************************************************** - Compare two names in the stat cache. + Compare two names in the stat cache - to check if we already have such an + entry. *****************************************************************************/ static BOOL stat_name_equal( char *s1, char *s2) @@ -124,13 +125,20 @@ static BOOL stat_name_equal( char *s1, char *s2) } /**************************************************************************** - Compare two names in the stat cache. + Compare a pathname to a name in the stat cache - of a given length. + Note - this code always checks that the next character in the pathname + is either a '/' character, or a '\0' character - to ensure we only + match *full* pathname components. *****************************************************************************/ -static BOOL stat_name_equal_len( char *s1, char *s2, int len) +static BOOL stat_name_equal_len( char *stat_name, char *orig_name, int len) { - return (case_sensitive ? (strncmp( s1, s2, len) == 0) : - (StrnCaseCmp(s1, s2, len) == 0)); + BOOL matched = (case_sensitive ? (strncmp( stat_name, orig_name, len) == 0) : + (StrnCaseCmp(stat_name, orig_name, len) == 0)); + if(orig_name[len] != '/' && orig_name[len] != '\0') + return False; + + return matched; } /**************************************************************************** @@ -211,7 +219,7 @@ static void stat_cache_add( char *full_orig_name, char *orig_translated_path) DEBUG(10,("stat_cache_add: Added entry %s -> %s\n", scp->orig_name, scp->translated_name )); - if(ubi_dlCount(&stat_cache) > MAX_STAT_CACHE_SIZE) { + if(ubi_dlCount(&stat_cache) > lp_stat_cache_size()) { scp = (stat_cache_entry *)ubi_dlRemTail( &stat_cache ); free((char *)scp); return; diff --git a/source/smbd/server.c b/source/smbd/server.c index 4c38fb5f4b7..1bc6cf273f0 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -208,7 +208,7 @@ max can be %d\n", memcpy((char *)&lfds, (char *)&listen_set, sizeof(listen_set)); - num = sys_select(&lfds,NULL); + num = sys_select(256,&lfds,NULL); if (num == -1 && errno == EINTR) continue; |