locking.c: Added lock type to is_locked() and do_lock()
authorJeremy Allison <jra@samba.org>
Thu, 23 Jul 1998 00:10:26 +0000 (00:10 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 23 Jul 1998 00:10:26 +0000 (00:10 +0000)
           as the code in reply_lockingX wasn't taking account of
           the difference between read and write locks ! How did this
           ever work :-) !
reply.c:
server.c: Add lock type to is_locked() and do_lock().
util.c: Also added code from klausr@ITAP.Physik.Uni-Stuttgart.De
        to fix problem with log files growing too large if an
        smbd writes less than 100 debug messages.
Jeremy.

source/include/proto.h
source/lib/util.c
source/locking/locking.c
source/smbd/nttrans.c
source/smbd/reply.c
source/smbd/server.c

index b390cb60d96a1ef6d2498d87f72790146b5594ec..5819d1aadcbf6297e0a2008e90276cdb43ebe8f9 100644 (file)
@@ -1149,8 +1149,9 @@ void lp_set_name_resolve_order(char *new_order);
 
 /*The following definitions come from  locking.c  */
 
-BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset);
-BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
+BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type);
+BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type,
+             int *eclass,uint32 *ecode);
 BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode);
 BOOL locking_init(int read_only);
 BOOL locking_end(void);
@@ -1980,6 +1981,7 @@ int sig_usr2(void);
 int sig_usr1(void);
 void setup_logging(char *pname,BOOL interactive);
 void reopen_logs(void);
+void force_check_log_size(void);
 char *tmpdir(void);
 BOOL is_a_socket(int fd);
 BOOL next_token(char **ptr,char *buff,char *sep);
index ec12affe7999b5ec37a822d2251861e36f64689d..22db8d4ab655f7d08dbe3f1be0fe9e2a3fd9e99e 100644 (file)
@@ -184,55 +184,82 @@ void reopen_logs(void)
   pstring fname;
   
   if (DEBUGLEVEL > 0)
-    {
-      pstrcpy(fname,debugf);
-      if (lp_loaded() && (*lp_logfile()))
-       pstrcpy(fname,lp_logfile());
+  {
+    pstrcpy(fname,debugf);
+    if (lp_loaded() && (*lp_logfile()))
+      pstrcpy(fname,lp_logfile());
 
-      if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
-       {
-         int oldumask = umask(022);
-         pstrcpy(debugf,fname);
-         if (dbf) fclose(dbf);
-         if (append_log)
-           dbf = fopen(debugf,"a");
-         else
-           dbf = fopen(debugf,"w");
-         if (dbf) setbuf(dbf,NULL);
-         umask(oldumask);
-       }
+    if (!strcsequal(fname,debugf) || !dbf || !file_exist(debugf,NULL))
+    {
+      int oldumask = umask(022);
+      pstrcpy(debugf,fname);
+      if (dbf)
+        fclose(dbf);
+      if (append_log)
+        dbf = fopen(debugf,"a");
+      else
+        dbf = fopen(debugf,"w");
+      /*
+       * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De
+       * to fix problem where smbd's that generate less
+       * than 100 messages keep growing the log.
+       */
+      force_check_log_size();
+      if (dbf)
+        setbuf(dbf,NULL);
+      umask(oldumask);
     }
+  }
   else
+  {
+    if (dbf)
     {
-      if (dbf)
-       {
-         fclose(dbf);
-         dbf = NULL;
-       }
+      fclose(dbf);
+      dbf = NULL;
     }
+  }
 }
 
+/*******************************************************************
+ Number of debug messages that have been output. 
+ Used to check log size.
+********************************************************************/
+
+static int debug_count=0;
+
+/*******************************************************************
+ Force a check of the log size.
+********************************************************************/
+
+void force_check_log_size(void)
+{
+  debug_count = 100;
+}
 
 /*******************************************************************
-check if the log has grown too big
+ Check if the log has grown too big
 ********************************************************************/
+
 static void check_log_size(void)
 {
-  static int debug_count=0;
   int maxlog;
   struct stat st;
 
-  if (debug_count++ < 100 || getuid() != 0) return;
+  if (debug_count++ < 100 || getuid() != 0)
+    return;
 
   maxlog = lp_max_log_size() * 1024;
-  if (!dbf || maxlog <= 0) return;
+  if (!dbf || maxlog <= 0)
+    return;
 
   if (fstat(fileno(dbf),&st) == 0 && st.st_size > maxlog) {
-    fclose(dbf); dbf = NULL;
+    fclose(dbf);
+    dbf = NULL;
     reopen_logs();
     if (dbf && file_size(debugf) > maxlog) {
       pstring name;
-      fclose(dbf); dbf = NULL;
+      fclose(dbf);
+      dbf = NULL;
       slprintf(name,sizeof(name)-1,"%s.old",debugf);
       rename(debugf,name);
       reopen_logs();
index 189ac0bcfe70a1646cb8bacd7971d6ea3baff252..d5d767d2cc30266abce711243ac31f63f140609d 100644 (file)
@@ -39,11 +39,13 @@ extern files_struct Files[];
 static struct share_ops *share_ops;
 
 /****************************************************************************
-  utility function called to see if a file region is locked
+ Utility function called to see if a file region is locked.
 ****************************************************************************/
-BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
+
+BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset, int lock_type)
 {
   int snum = SNUM(cnum);
+  files_struct *fsp = &Files[fnum];
 
   if (count == 0)
     return(False);
@@ -51,17 +53,22 @@ BOOL is_locked(int fnum,int cnum,uint32 count,uint32 offset)
   if (!lp_locking(snum) || !lp_strict_locking(snum))
     return(False);
 
-  return(fcntl_lock(Files[fnum].fd_ptr->fd,F_GETLK,offset,count,
-                   (Files[fnum].can_write?F_WRLCK:F_RDLCK)));
+  if((lock_type == F_WRLCK) && !fsp->can_write)
+    lock_type = F_RDLCK;
+
+  return(fcntl_lock(fsp->fd_ptr->fd,F_GETLK,offset,count,lock_type));
 }
 
 
 /****************************************************************************
-  utility function called by locking requests
+ Utility function called by locking requests.
 ****************************************************************************/
-BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
+
+BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int lock_type,
+             int *eclass,uint32 *ecode)
 {
   BOOL ok = False;
+  files_struct *fsp = &Files[fnum];
 
   if (!lp_locking(SNUM(cnum)))
     return(True);
@@ -72,9 +79,12 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec
     return False;
   }
 
-  if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
-    ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,
-                    (Files[fnum].can_write?F_WRLCK:F_RDLCK));
+  if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum)) {
+    if(lock_type == F_WRLCK && !fsp->can_write)
+      lock_type = F_RDLCK;
+
+    ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,lock_type);
+  }
 
   if (!ok) {
     *eclass = ERRDOS;
@@ -86,17 +96,19 @@ BOOL do_lock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ec
 
 
 /****************************************************************************
-  utility function called by unlocking requests
+ Utility function called by unlocking requests.
 ****************************************************************************/
+
 BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *ecode)
 {
   BOOL ok = False;
+  files_struct *fsp = &Files[fnum];
 
   if (!lp_locking(SNUM(cnum)))
     return(True);
 
-  if (Files[fnum].can_lock && OPEN_FNUM(fnum) && (Files[fnum].cnum == cnum))
-    ok = fcntl_lock(Files[fnum].fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
+  if (OPEN_FNUM(fnum) && fsp->can_lock && (fsp->cnum == cnum))
+    ok = fcntl_lock(fsp->fd_ptr->fd,F_SETLK,offset,count,F_UNLCK);
    
   if (!ok) {
     *eclass = ERRDOS;
@@ -109,8 +121,9 @@ BOOL do_unlock(int fnum,int cnum,uint32 count,uint32 offset,int *eclass,uint32 *
 
 
 /****************************************************************************
-  initialise the locking functions
+ Initialise the locking functions.
 ****************************************************************************/
+
 BOOL locking_init(int read_only)
 {
        if (share_ops) return True;
@@ -133,8 +146,9 @@ BOOL locking_init(int read_only)
 }
 
 /*******************************************************************
-  deinitialize the share_mode management 
-  ******************************************************************/
+ Deinitialize the share_mode management.
+******************************************************************/
+
 BOOL locking_end(void)
 {
        if (share_ops)
@@ -144,24 +158,27 @@ BOOL locking_end(void)
 
 
 /*******************************************************************
-  lock a hash bucket entry 
-  ******************************************************************/
+ Lock a hash bucket entry.
+******************************************************************/
+
 BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, int *ptok)
 {
        return share_ops->lock_entry(cnum, dev, inode, ptok);
 }
 
 /*******************************************************************
-  unlock a hash bucket entry
-  ******************************************************************/
+ Unlock a hash bucket entry.
+******************************************************************/
+
 BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, int token)
 {
        return share_ops->unlock_entry(cnum, dev, inode, token);
 }
 
 /*******************************************************************
-get all share mode entries for a dev/inode pair.
+ Get all share mode entries for a dev/inode pair.
 ********************************************************************/
+
 int get_share_modes(int cnum, int token, uint32 dev, uint32 inode, 
                    share_mode_entry **shares)
 {
@@ -169,42 +186,45 @@ int get_share_modes(int cnum, int token, uint32 dev, uint32 inode,
 }
 
 /*******************************************************************
-del the share mode of a file.
+ Del the share mode of a file.
 ********************************************************************/
+
 void del_share_mode(int token, int fnum)
 {
        share_ops->del_entry(token, fnum);
 }
 
 /*******************************************************************
-set the share mode of a file. Return False on fail, True on success.
+ Set the share mode of a file. Return False on fail, True on success.
 ********************************************************************/
+
 BOOL set_share_mode(int token, int fnum, uint16 port, uint16 op_type)
 {
        return share_ops->set_entry(token, fnum, port, op_type);
 }
 
 /*******************************************************************
-Remove an oplock port and mode entry from a share mode.
+ Remove an oplock port and mode entry from a share mode.
 ********************************************************************/
 BOOL remove_share_oplock(int fnum, int token)
 {
        return share_ops->remove_oplock(fnum, token);
 }
 
-
 /*******************************************************************
-call the specified function on each entry under management by the
-share mode system
+ Call the specified function on each entry under management by the
+ share mode system.
 ********************************************************************/
+
 int share_mode_forall(void (*fn)(share_mode_entry *, char *))
 {
        return share_ops->forall(fn);
 }
 
 /*******************************************************************
-dump the state of the system
+ Dump the state of the system.
 ********************************************************************/
+
 void share_status(FILE *f)
 {
        share_ops->status(f);
index 672e2c0802a985065e58ec2f830761fedc85616b..9b6cfe162138d3d58d31b4470f55d31136e36e13 100644 (file)
@@ -620,12 +620,12 @@ int reply_ntcreate_and_X(char *inbuf,char *outbuf,int length,int bufsize)
     p += 8;
     SIVAL(p,0,fmode); /* File Attributes. */
     p += 12;
-    if(sizeof(off_t) == 8) {
+#if OFF_T_IS_64_BITS
       SIVAL(p,0, file_len & 0xFFFFFFFF);
       SIVAL(p,4, file_len >> 32);
-    } else {
+#else /* OFF_T_IS_64_BITS */
       SIVAL(p,0,file_len);
-    }
+#endif /* OFF_T_IS_64_BITS */
     p += 12;
     SCVAL(p,0,fsp->is_directory ? 1 : 0);
   }
@@ -822,12 +822,12 @@ static int call_nt_transact_create(char *inbuf, char *outbuf, int length,
     p += 8;
     SIVAL(p,0,fmode); /* File Attributes. */
     p += 12;
-    if(sizeof(off_t) == 8) {
+#if OFF_T_IS_64_BITS
       SIVAL(p,0, file_len & 0xFFFFFFFF);
       SIVAL(p,4, (file_len >> 32));
-    } else {
+#else /* OFF_T_IS_64_BITS */
       SIVAL(p,0,file_len);
-    }
+#endif /* OFF_T_IS_64_BITS */
   }
 
   /* Send the required number of replies */
index f6fd2ccd9003cb7ebe887c501ce659e3a375a663..35189883e21ba418d9434ea5e9d952d24daf5421 100644 (file)
@@ -1858,7 +1858,7 @@ int reply_readbraw(char *inbuf, char *outbuf, int dum_size, int dum_buffsize)
     }
 
 
-  if (!is_locked(fnum,cnum,maxcount,startpos))
+  if (!is_locked(fnum,cnum,maxcount,startpos, F_RDLCK))
     {
       int size = Files[fnum].size;
       int sizeneeded = startpos + maxcount;
@@ -1943,7 +1943,7 @@ int reply_lockread(char *inbuf,char *outbuf, int dum_size, int dum_buffsiz)
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
   
-  if(!do_lock( fnum, cnum, numtoread, startpos, &eclass, &ecode))
+  if(!do_lock( fnum, cnum, numtoread, startpos, F_RDLCK, &eclass, &ecode))
     return (ERROR(eclass,ecode));
 
   nread = read_file(fnum,data,startpos,numtoread);
@@ -1987,7 +1987,7 @@ int reply_read(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
   numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
   data = smb_buf(outbuf) + 3;
   
-  if (is_locked(fnum,cnum,numtoread,startpos))
+  if (is_locked(fnum,cnum,numtoread,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));     
 
   if (numtoread > 0)
@@ -2035,7 +2035,7 @@ int reply_read_and_X(char *inbuf,char *outbuf,int length,int bufsize)
   set_message(outbuf,12,0,True);
   data = smb_buf(outbuf);
 
-  if (is_locked(fnum,cnum,smb_maxcnt,smb_offs))
+  if (is_locked(fnum,cnum,smb_maxcnt,smb_offs, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));
   nread = read_file(fnum,data,smb_offs,smb_maxcnt);
   ok = True;
@@ -2097,7 +2097,7 @@ int reply_writebraw(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
   CVAL(inbuf,smb_com) = SMBwritec;
   CVAL(outbuf,smb_com) = SMBwritec;
 
-  if (is_locked(fnum,cnum,tcount,startpos))
+  if (is_locked(fnum,cnum,tcount,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
   if (seek_file(fnum,startpos) != startpos)
@@ -2188,7 +2188,7 @@ int reply_writeunlock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
   startpos = IVAL(inbuf,smb_vwv2);
   data = smb_buf(inbuf) + 3;
   
-  if (is_locked(fnum,cnum,numtowrite,startpos))
+  if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
   seek_file(fnum,startpos);
@@ -2243,7 +2243,7 @@ int reply_write(char *inbuf,char *outbuf,int dum_size,int dum_buffsize)
   startpos = IVAL(inbuf,smb_vwv2);
   data = smb_buf(inbuf) + 3;
   
-  if (is_locked(fnum,cnum,numtowrite,startpos))
+  if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
   seek_file(fnum,startpos);
@@ -2299,7 +2299,7 @@ int reply_write_and_X(char *inbuf,char *outbuf,int length,int bufsize)
 
   data = smb_base(inbuf) + smb_doff;
 
-  if (is_locked(fnum,cnum,smb_dsize,smb_offs))
+  if (is_locked(fnum,cnum,smb_dsize,smb_offs, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
   seek_file(fnum,smb_offs);
@@ -2512,7 +2512,7 @@ int reply_writeclose(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
   mtime = make_unix_date3(inbuf+smb_vwv4);
   data = smb_buf(inbuf) + 1;
   
-  if (is_locked(fnum,cnum,numtowrite,startpos))
+  if (is_locked(fnum,cnum,numtowrite,startpos, F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
       
   seek_file(fnum,startpos);
@@ -2559,7 +2559,7 @@ int reply_lock(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
 
   DEBUG(3,("%s lock fd=%d fnum=%d cnum=%d ofs=%d cnt=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum,offset,count));
 
-  if(!do_lock( fnum, cnum, count, offset, &eclass, &ecode))
+  if(!do_lock( fnum, cnum, count, offset, F_WRLCK, &eclass, &ecode))
     return (ERROR(eclass,ecode));
   
   return(outsize);
@@ -3729,7 +3729,8 @@ dev = %x, inode = %x\n",
   for(i = 0; i < (int)num_locks; i++) {
     count = IVAL(data,SMB_LKLEN_OFFSET(i)); 
     offset = IVAL(data,SMB_LKOFF_OFFSET(i)); 
-    if(!do_lock(fnum,cnum,count,offset, &eclass, &ecode))
+    if(!do_lock(fnum,cnum,count,offset, ((locktype & 1) ? F_RDLCK : F_WRLCK),
+                &eclass, &ecode))
       break;
   }
 
@@ -3796,7 +3797,7 @@ int reply_readbmpx(char *inbuf,char *outbuf,int length,int bufsize)
   tcount = maxcount;
   total_read = 0;
 
-  if (is_locked(fnum,cnum,maxcount,startpos))
+  if (is_locked(fnum,cnum,maxcount,startpos, F_RDLCK))
     return(ERROR(ERRDOS,ERRlock));
        
   do
@@ -3858,7 +3859,7 @@ int reply_writebmpx(char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
      not an SMBwritebmpx - set this up now so we don't forget */
   CVAL(outbuf,smb_com) = SMBwritec;
 
-  if (is_locked(fnum,cnum,tcount,startpos))
+  if (is_locked(fnum,cnum,tcount,startpos,F_WRLCK))
     return(ERROR(ERRDOS,ERRlock));
 
   seek_file(fnum,startpos);
index 9df2ed37bbd275524a08ac5fc607e99b5d87b063..62ee75db0a57dafe07b2d2245674aa6594ce82d2 100644 (file)
@@ -1948,7 +1948,7 @@ static void truncate_unless_locked(int fnum, int cnum, int token,
                                   BOOL *share_locked)
 {
   if (Files[fnum].can_write){
-    if (is_locked(fnum,cnum,0x3FFFFFFF,0)){
+    if (is_locked(fnum,cnum,0x3FFFFFFF,0,F_WRLCK)){
       /* If share modes are in force for this connection we
          have the share entry locked. Unlock it before closing. */
       if (*share_locked && lp_share_modes(SNUM(cnum)))
@@ -2861,6 +2861,20 @@ max can be %d\n", num_interfaces, FD_SETSIZE));
           return True; 
         }
         close(Client); /* The parent doesn't need this socket */
+
+        /*
+         * Force parent to check log size after spawning child.
+         * Fix from klausr@ITAP.Physik.Uni-Stuttgart.De.
+         * The parent smbd will log to logserver.smb. 
+         * It writes only two messages for each child
+         * started/finished. But each child writes, say, 50 messages also in
+         * logserver.smb, begining with the debug_count of the parent, before the
+         * child opens its own log file logserver.client. In a worst case
+         * scenario the size of logserver.smb would be checked after about
+         * 50*50=2500 messages (ca. 100kb).
+         */
+        force_check_log_size();
+
 #endif /* NO_FORK_DEBUG */
       } /* end for num */
     } /* end while 1 */