diff options
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/server.c | 58 |
1 files changed, 57 insertions, 1 deletions
diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 01d379ebb3..3a12513454 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -3695,6 +3695,31 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de return(cnum); } +/**************************************************************************** + Attempt to break an oplock on a file (if oplocked). + Returns True if the file was closed as a result of + the oplock break, False otherwise. + Used as a last ditch attempt to free a space in the + file table when we have run out. +****************************************************************************/ + +static BOOL attempt_close_oplocked_file(files_struct *fp) +{ + + DEBUG(5,("attempt_close_oplocked_file: checking file %s.\n", fp->name)); + + if (fp->open && fp->granted_oplock && !fp->sent_oplock_break) { + + /* Try and break the oplock. */ + file_fd_struct *fsp = fp->fd_ptr; + if(oplock_break( fsp->dev, fsp->inode, &fp->open_time)) { + if(!fp->open) /* Did the oplock break close the file ? */ + return True; + } + } + + return False; +} /**************************************************************************** find first available file slot @@ -3734,6 +3759,32 @@ int find_free_file(void ) return(i); } + /* + * Before we give up, go through the open files + * and see if there are any files opened with a + * batch oplock. If so break the oplock and then + * re-use that entry (if it becomes closed). + * This may help as NT/95 clients tend to keep + * files batch oplocked for quite a long time + * after they have finished with them. + */ + for (i=first_file;i<MAX_OPEN_FILES;i++) { + if(attempt_close_oplocked_file( &Files[i])) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + return(i); + } + } + + for (i=1;i<MAX_OPEN_FILES;i++) { + if(attempt_close_oplocked_file( &Files[i])) { + memset(&Files[i], 0, sizeof(Files[i])); + first_file = i+1; + Files[i].reserved = True; + return(i); + } + } DEBUG(1,("ERROR! Out of file structures - perhaps increase MAX_OPEN_FILES?\n")); return(-1); @@ -5280,7 +5331,12 @@ static void usage(char *pname) { struct rlimit rlp; getrlimit(RLIMIT_NOFILE, &rlp); - rlp.rlim_cur = (MAX_OPEN_FILES>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES; + /* + * Set the fd limit to be MAX_OPEN_FILES + 10 to account for the + * extra fd we need to read directories, as well as the log files + * and standard handles etc. + */ + rlp.rlim_cur = (MAX_OPEN_FILES+10>rlp.rlim_max)? rlp.rlim_max:MAX_OPEN_FILES+10; setrlimit(RLIMIT_NOFILE, &rlp); getrlimit(RLIMIT_NOFILE, &rlp); DEBUG(3,("Maximum number of open files per session is %d\n",rlp.rlim_cur)); |