summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/client/client.c2
-rw-r--r--source/client/smbmount.c2
-rw-r--r--source/include/proto.h5
-rw-r--r--source/lib/system.c70
-rw-r--r--source/lib/util.c10
-rw-r--r--source/libsmb/nmblib.c2
-rw-r--r--source/nmbd/nmbd_packets.c2
-rw-r--r--source/param/loadparm.c20
-rw-r--r--source/smbd/filename.c20
-rw-r--r--source/smbd/server.c2
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;