]> Zhao Yanbai Git Server - minix.git/commitdiff
Mostly bugfixes of bugs triggered by the test set.
authorBen Gras <ben@minix3.org>
Thu, 1 Feb 2007 17:50:02 +0000 (17:50 +0000)
committerBen Gras <ben@minix3.org>
Thu, 1 Feb 2007 17:50:02 +0000 (17:50 +0000)
bugfixes:
 SYSTEM:
 . removed
        rc->p_priv->s_flags = 0;
   for the priv struct shared by all user processes in get_priv(). this
   should only be done once. doing a SYS_PRIV_USER in sys_privctl()
   caused the flags of all user processes to be reset, so they were no
   longer PREEMPTIBLE. this happened when RS executed a policy script.
   (this broke test1 in the test set)

 VFS/MFS:
 . chown can change the mode of a file, and chmod arguments are only
   part of the full file mode so the full filemode is slightly magic.
   changed these calls so that the final modes are returned to VFS, so
   that the vnode can be kept up-to-date.
   (this broke test11 in the test set)

 MFS:
 . lookup() checked for sizeof(string) instead of sizeof(user_path),
   truncating long path names
   (caught by test 23)
 . truncate functions neglected to update ctime
   (this broke test16)

 VFS:
 . corner case of an empty filename lookup caused fields of a request
   not to be filled in in the lookup functions, not making it clear
   that the lookup had failed, causing messages to garbage processes,
   causing strange failures.
   (caught by test 30)
 . trust v_size in vnode when doing reads or writes on non-special
   files, truncating i/o where necessary; this is necessary for pipes,
   as MFS can't tell when a pipe has been truncated without it being
   told explicitly each time.
   when the last reader/writer on a pipe closes, tell FS about
   the new size using truncate_vn().
   (this broke test 25, among others)
 . permission check for chdir() had disappeared; added a
   forbidden() call
   (caught by test 23)

new code, shouldn't change anything:
 . introduced RTS_SET, RTS_UNSET, and RTS_ISSET macro's, and their
   LOCK variants. These macros set and clear the p_rts_flags field,
   causing a lot of duplicated logic like

       old_flags = rp->p_rts_flags;            /* save value of the flags */
       rp->p_rts_flags &= ~NO_PRIV;
       if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);

   to change into the simpler

       RTS_LOCK_UNSET(rp, NO_PRIV);

   so the macros take care of calling dequeue() and enqueue() (or lock_*()),
   as the case may be). This makes the code a bit more readable and a
   bit less fragile.
 . removed return code from do_clocktick in CLOCK as it currently
   never replies
 . removed some debug code from VFS
 . fixed grant debug message in device.c

preemptive checks, tests, changes:
 . added return code checks of receive() to SYSTEM and CLOCK
 . O_TRUNC should never arrive at MFS (added sanity check and removed
   O_TRUNC code)
 . user_path declared with PATH_MAX+1 to let it be null-terminated
 . checks in MFS to see if strings passed by VFS are null-terminated

 IS:
 . static irq name table thrown out

36 files changed:
kernel/clock.c
kernel/main.c
kernel/proc.c
kernel/proc.h
kernel/system.c
kernel/system/do_endksig.c
kernel/system/do_exec.c
kernel/system/do_exit.c
kernel/system/do_fork.c
kernel/system/do_getksig.c
kernel/system/do_newmap.c
kernel/system/do_nice.c
kernel/system/do_privctl.c
kernel/system/do_safecopy.c
kernel/system/do_setgrant.c
kernel/system/do_sigsend.c
kernel/system/do_trace.c
servers/is/dmp_kernel.c
servers/mfs/glo.h
servers/mfs/link.c
servers/mfs/open.c
servers/mfs/path.c
servers/mfs/protect.c
servers/vfs/device.c
servers/vfs/filedes.c
servers/vfs/glo.h
servers/vfs/main.c
servers/vfs/mount.c
servers/vfs/open.c
servers/vfs/path.c
servers/vfs/protect.c
servers/vfs/proto.h
servers/vfs/read.c
servers/vfs/request.c
servers/vfs/stadir.c
servers/vfs/utility.c

index b748a34959d18e2bc595b31d12e4f80ea4d8a96d..838f8959fcfb56aac1f39cb6ed3fbcb9c3ee9aa5 100755 (executable)
@@ -39,7 +39,7 @@
  */ 
 FORWARD _PROTOTYPE( void init_clock, (void) );
 FORWARD _PROTOTYPE( int clock_handler, (irq_hook_t *hook) );
-FORWARD _PROTOTYPE( int do_clocktick, (message *m_ptr) );
+FORWARD _PROTOTYPE( void do_clocktick, (message *m_ptr) );
 FORWARD _PROTOTYPE( void load_update, (void));
 
 /* The CLOCK's timers queue. The functions in <timers.h> operate on this. 
@@ -74,10 +74,13 @@ PUBLIC void clock_task()
        /* Go get a message. */
        result = receive(ANY, &m);
 
+       if(result != OK)
+               panic("receive() failed", result);
+
        /* Handle the request. Only clock ticks are expected. */
        switch (m.m_type) {
        case HARD_INT:      
-               result = do_clocktick(&m); /* handle clock tick */
+               do_clocktick(&m); /* handle clock tick */
                break;
        default: /* illegal request type */
                kprintf("CLOCK: illegal request %d from %d.\n",
@@ -89,7 +92,7 @@ PUBLIC void clock_task()
 /*===========================================================================*
  *                             do_clocktick                                 *
  *===========================================================================*/
-PRIVATE int do_clocktick(m_ptr)
+PRIVATE void do_clocktick(m_ptr)
 message *m_ptr;                                /* pointer to request message */
 {
 /* Despite its name, this routine is not called on every clock tick. It
@@ -103,9 +106,10 @@ message *m_ptr;                            /* pointer to request message */
    * place in the queues.  As a side-effect a new process will be scheduled.
    */ 
   if (prev_ptr->p_ticks_left <= 0 && priv(prev_ptr)->s_flags & PREEMPTIBLE) {
-      if(prev_ptr->p_rts_flags == 0)   /* if it was runnable .. */
-             lock_dequeue(prev_ptr);   /* take it off the queues */
-      lock_enqueue(prev_ptr);          /* and reinsert it again */ 
+      if(prev_ptr->p_rts_flags == 0) { /* if it was runnable .. */
+       lock_dequeue(prev_ptr);         /* take it off the queues */
+       lock_enqueue(prev_ptr);         /* and reinsert it again */ 
+      }
   }
 
   /* Check if a clock timer expired and run its watchdog function. */
@@ -115,8 +119,7 @@ message *m_ptr;                             /* pointer to request message */
                 TMR_NEVER : clock_timers->tmr_exp_time;        
   }
 
-  /* Inhibit sending a reply. */
-  return(EDONTREPLY);
+  return;
 }
 
 /*===========================================================================*
index d0223980b18e04be0e41b381772edcebc5b4e757..1e93aefcbba3b8c8fe49aa29dfec441e57ffeb18 100755 (executable)
@@ -150,12 +150,8 @@ PUBLIC void main()
        }
        
        /* Set ready. The HARDWARE task is never ready. */
-       if (rp->p_nr != HARDWARE) {
-               rp->p_rts_flags = 0;            /* runnable if no flags */
-               lock_enqueue(rp);               /* add to scheduling queues */
-       } else {
-               rp->p_rts_flags = NO_PRIORITY;  /* prevent from running */
-       }
+       if (rp->p_nr == HARDWARE) RTS_LOCK_SET(rp, NO_PRIORITY);
+       RTS_LOCK_UNSET(rp, SLOT_FREE); /* remove SLOT_FREE and schedule */
 
        /* Code and data segments must be allocated in protected mode. */
        alloc_segments(rp);
index 2e6a717c9d6905a7f0953fe10ce70549c7ebe04e..dede6f9e4f479f939cac70f8b254a19e65560726 100755 (executable)
@@ -104,7 +104,7 @@ long bit_map;                       /* notification event set or flags */
   vir_clicks vlo, vhi;         /* virtual clicks containing message to send */
 
 #if 1
-  if (caller_ptr->p_rts_flags & SLOT_FREE)
+  if (RTS_ISSET(caller_ptr, SLOT_FREE))
   {
        kprintf("called by the dead?!?\n");
        return EINVAL;
@@ -243,10 +243,10 @@ int src_dst;                                      /* src or dst process */
       /* Check whether the last process in the chain has a dependency. If it 
        * has not, the cycle cannot be closed and we are done.
        */
-      if (xp->p_rts_flags & RECEIVING) {       /* xp has dependency */
+      if (RTS_ISSET(xp, RECEIVING)) {  /* xp has dependency */
          if(xp->p_getfrom_e == ANY) src_dst = ANY;
          else okendpt(xp->p_getfrom_e, &src_dst);
-      } else if (xp->p_rts_flags & SENDING) {  /* xp has dependency */
+      } else if (RTS_ISSET(xp, SENDING)) {     /* xp has dependency */
          okendpt(xp->p_sendto_e, &src_dst);
       } else {
          return(0);                            /* not a deadlock */
@@ -289,23 +289,22 @@ unsigned flags;                           /* system call flags */
   dst_p = _ENDPOINT_P(dst_e);
   dst_ptr = proc_addr(dst_p);
 
-  if (dst_ptr->p_rts_flags & NO_ENDPOINT) return EDSTDIED;
+  if (RTS_ISSET(dst_ptr, NO_ENDPOINT)) return EDSTDIED;
 
   /* Check if 'dst' is blocked waiting for this message. The destination's 
    * SENDING flag may be set when its SENDREC call blocked while sending.  
    */
-  if ( (dst_ptr->p_rts_flags & (RECEIVING | SENDING)) == RECEIVING &&
+  if ( (RTS_ISSET(dst_ptr, RECEIVING) && !RTS_ISSET(dst_ptr, SENDING)) &&
        (dst_ptr->p_getfrom_e == ANY
          || dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) {
        /* Destination is indeed waiting for this message. */
        CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr,
                 dst_ptr->p_messbuf);
-       if ((dst_ptr->p_rts_flags &= ~RECEIVING) == 0) enqueue(dst_ptr);
+       RTS_UNSET(dst_ptr, RECEIVING);
   } else if ( ! (flags & NON_BLOCKING)) {
        /* Destination is not waiting.  Block and dequeue caller. */
        caller_ptr->p_messbuf = m_ptr;
-       if (caller_ptr->p_rts_flags == 0) dequeue(caller_ptr);
-       caller_ptr->p_rts_flags |= SENDING;
+       RTS_SET(caller_ptr, SENDING);
        caller_ptr->p_sendto_e = dst_e;
 
        /* Process is now blocked.  Put in on the destination's queue. */
@@ -344,7 +343,7 @@ unsigned flags;                             /* system call flags */
   else
   {
        okendpt(src_e, &src_p);
-       if (proc_addr(src_p)->p_rts_flags & NO_ENDPOINT) return ESRCDIED;
+       if (RTS_ISSET(proc_addr(src_p), NO_ENDPOINT)) return ESRCDIED;
   }
 
 
@@ -352,7 +351,7 @@ unsigned flags;                             /* system call flags */
    * The caller's SENDING flag may be set if SENDREC couldn't send. If it is
    * set, the process should be blocked.
    */
-  if (!(caller_ptr->p_rts_flags & SENDING)) {
+  if (!RTS_ISSET(caller_ptr, SENDING)) {
 
     /* Check if there are pending notifications, except for SENDREC. */
     if (! (caller_ptr->p_misc_flags & REPLY_PENDING)) {
@@ -386,7 +385,7 @@ unsigned flags;                             /* system call flags */
     while (*xpp != NIL_PROC) {
         if (src_e == ANY || src_p == proc_nr(*xpp)) {
 #if 1
-           if ((*xpp)->p_rts_flags & SLOT_FREE)
+           if (RTS_ISSET(*xpp, SLOT_FREE))
            {
                kprintf("listening to the dead?!?\n");
                return EINVAL;
@@ -395,7 +394,7 @@ unsigned flags;                             /* system call flags */
 
            /* Found acceptable message. Copy it and update status. */
            CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr);
-            if (((*xpp)->p_rts_flags &= ~SENDING) == 0) enqueue(*xpp);
+           RTS_UNSET(*xpp, SENDING);
             *xpp = (*xpp)->p_q_link;           /* remove from queue */
             return(OK);                                /* report success */
        }
@@ -409,8 +408,7 @@ unsigned flags;                             /* system call flags */
   if ( ! (flags & NON_BLOCKING)) {
       caller_ptr->p_getfrom_e = src_e;         
       caller_ptr->p_messbuf = m_ptr;
-      if (caller_ptr->p_rts_flags == 0) dequeue(caller_ptr);
-      caller_ptr->p_rts_flags |= RECEIVING;            
+      RTS_SET(caller_ptr, RECEIVING);
       return(OK);
   } else {
       return(ENOTREADY);
@@ -431,7 +429,7 @@ int dst;                            /* which process to notify */
   /* Check to see if target is blocked waiting for this message. A process 
    * can be both sending and receiving during a SENDREC system call.
    */
-  if ((dst_ptr->p_rts_flags & (RECEIVING|SENDING)) == RECEIVING &&
+  if ( (RTS_ISSET(dst_ptr, RECEIVING) && !RTS_ISSET(dst_ptr, SENDING)) &&
       ! (dst_ptr->p_misc_flags & REPLY_PENDING) &&
       (dst_ptr->p_getfrom_e == ANY || 
       dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) {
@@ -443,8 +441,7 @@ int dst;                            /* which process to notify */
       BuildMess(&m, proc_nr(caller_ptr), dst_ptr);
       CopyMess(proc_nr(caller_ptr), proc_addr(HARDWARE), &m, 
           dst_ptr, dst_ptr->p_messbuf);
-      dst_ptr->p_rts_flags &= ~RECEIVING;      /* deblock destination */
-      if (dst_ptr->p_rts_flags == 0) enqueue(dst_ptr);
+      RTS_UNSET(dst_ptr, RECEIVING);
       return(OK);
   } 
 
index 9f0a264a46c8238765228a5b2917fdc1ebfda1be..4ce8cc6a40921d1dc55debb8256b8b92cc355ece 100755 (executable)
@@ -12,7 +12,7 @@
 #include <minix/com.h>
 #include "const.h"
 #include "priv.h"
+
 struct proc {
   struct stackframe_s p_reg;   /* process' registers saved in stack frame */
   struct segframe p_seg;       /* segment descriptors */
@@ -60,6 +60,50 @@ struct proc {
 #define NO_PRIV                0x80    /* keep forked system process from running */
 #define NO_ENDPOINT    0x100   /* process cannot send or receive messages */
 
+/* These runtime flags can be tested and manipulated by these macros. */
+
+#define RTS_ISSET(rp, f) (((rp)->p_rts_flags & (f)) == (f))
+
+
+/* Set flag and dequeue if the process was runnable. */
+#define RTS_SET(rp, f)                                                 \
+       do {                                                            \
+               if(!(rp)->p_rts_flags) { dequeue(rp); }                 \
+               (rp)->p_rts_flags |=  (f);                              \
+       } while(0)
+
+/* Clear flag and enqueue if the process was not runnable but is now. */
+#define RTS_UNSET(rp, f)                                               \
+       do {                                                            \
+               int rts;                                                \
+               rts = (rp)->p_rts_flags;                                        \
+               (rp)->p_rts_flags &= ~(f);                              \
+               if(rts && !(rp)->p_rts_flags) { enqueue(rp); }          \
+       } while(0)
+
+/* Set flag and dequeue if the process was runnable. */
+#define RTS_LOCK_SET(rp, f)                                            \
+       do {                                                            \
+               if(!(rp)->p_rts_flags) { lock_dequeue(rp); }            \
+               (rp)->p_rts_flags |=  (f);                              \
+       } while(0)
+
+/* Clear flag and enqueue if the process was not runnable but is now. */
+#define RTS_LOCK_UNSET(rp, f)                                          \
+       do {                                                            \
+               int rts;                                                \
+               rts = (rp)->p_rts_flags;                                        \
+               (rp)->p_rts_flags &= ~(f);                              \
+               if(rts && !(rp)->p_rts_flags) { lock_enqueue(rp); }     \
+       } while(0)
+
+/* Set flags to this value. */
+#define RTS_LOCK_SETFLAGS(rp, f)                                       \
+       do {                                                            \
+               if(!(rp)->p_rts_flags && (f)) { lock_dequeue(rp); }     \
+               (rp)->p_rts_flags = (f);                                        \
+       } while(0)
+
 /* Misc flags */
 #define REPLY_PENDING  0x01    /* reply to IPC_REQUEST is pending */
 #define MF_VM          0x08    /* process uses VM */
index 68d577d0b33007384e02e890d647594a202759ce..fc7f94f25bbd5eb01279f094c8851558ae9e1f49 100755 (executable)
@@ -30,6 +30,7 @@
 #include "debug.h"
 #include "kernel.h"
 #include "system.h"
+#include "proc.h"
 #include <stdlib.h>
 #include <signal.h>
 #include <unistd.h>
@@ -67,8 +68,9 @@ PUBLIC void sys_task()
   initialize();
 
   while (TRUE) {
+      int r;
       /* Get work. Block and wait until a request message arrives. */
-      receive(ANY, &m);                        
+      if((r=receive(ANY, &m)) != OK) panic("system: receive() failed", r);
       sys_call_code = (unsigned) m.m_type;
       call_nr = sys_call_code - KERNEL_CALL;   
       who_e = m.m_source;
@@ -216,7 +218,8 @@ int proc_type;                              /* system or user process flag */
   } else {
       rc->p_priv = &priv[USER_PRIV_ID];                /* use shared slot */
       rc->p_priv->s_proc_nr = INIT_PROC_NR;    /* set association */
-      rc->p_priv->s_flags = 0;                 /* no initial flags */
+
+      /* s_flags of this shared structure are to be once at system startup. */
   }
   return(OK);
 }
@@ -292,9 +295,8 @@ int sig_nr;                 /* signal to be sent, 1 to _NSIG */
   rp = proc_addr(proc_nr);
   if (! sigismember(&rp->p_pending, sig_nr)) {
       sigaddset(&rp->p_pending, sig_nr);
-      if (! (rp->p_rts_flags & SIGNALED)) {            /* other pending */
-          if (rp->p_rts_flags == 0) lock_dequeue(rp);  /* make not ready */
-          rp->p_rts_flags |= SIGNALED | SIG_PENDING;   /* update flags */
+      if (! (RTS_ISSET(rp, SIGNALED))) {               /* other pending */
+         RTS_LOCK_SET(rp, SIGNALED | SIG_PENDING);
           send_sig(PM_PROC_NR, SIGKSIG);
       }
   }
@@ -473,13 +475,12 @@ register struct proc *rc;         /* slot of process to clean up */
   if(isemptyp(rc)) panic("clear_proc: empty process", proc_nr(rc));
 
   /* Make sure that the exiting process is no longer scheduled. */
-  if (rc->p_rts_flags == 0) lock_dequeue(rc);
-  rc->p_rts_flags |= NO_ENDPOINT;
+  RTS_LOCK_SET(rc, NO_ENDPOINT);
 
   /* If the process happens to be queued trying to send a
    * message, then it must be removed from the message queues.
    */
-  if (rc->p_rts_flags & SENDING) {
+  if (RTS_ISSET(rc, SENDING)) {
       int target_proc;
 
       okendpt(rc->p_sendto_e, &target_proc);
@@ -511,21 +512,20 @@ register struct proc *rc;         /* slot of process to clean up */
       unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
 
       /* Check if process is receiving from exiting process. */
-      if ((rp->p_rts_flags & RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) {
+      if (RTS_ISSET(rp, RECEIVING) && rp->p_getfrom_e == rc->p_endpoint) {
           rp->p_reg.retreg = ESRCDIED;         /* report source died */
-         rp->p_rts_flags &= ~RECEIVING;        /* no longer receiving */
+         RTS_LOCK_UNSET(rp, RECEIVING);        /* no longer receiving */
 #if DEBUG_ENABLE_IPC_WARNINGS
          kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc));
 #endif
-         if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
       } 
-      if ((rp->p_rts_flags & SENDING) && rp->p_sendto_e == rc->p_endpoint) {
+      if (RTS_ISSET(rp, SENDING) &&
+         rp->p_sendto_e == rc->p_endpoint) {
           rp->p_reg.retreg = EDSTDIED;         /* report destination died */
-         rp->p_rts_flags &= ~SENDING;          /* no longer sending */
+         RTS_LOCK_UNSET(rp, SENDING);
 #if DEBUG_ENABLE_IPC_WARNINGS
          kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc));
 #endif
-         if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
       } 
   }
 }
index 642a77669b48a5f9a07681f1f4544e11d6823c60..1e62dc05b91f38a5990a249f2ac70b543d3ab499 100644 (file)
@@ -31,12 +31,11 @@ message *m_ptr;                     /* pointer to request message */
        return EINVAL;
 
   rp = proc_addr(proc);
-  if (! (rp->p_rts_flags & SIG_PENDING)) return(EINVAL);
+  if (!RTS_ISSET(rp, SIG_PENDING)) return(EINVAL);
 
   /* PM has finished one kernel signal. Perhaps process is ready now? */
-  if (! (rp->p_rts_flags & SIGNALED))          /* new signal arrived */
-     if ((rp->p_rts_flags &= ~SIG_PENDING)==0) /* remove pending flag */
-         lock_enqueue(rp);                     /* ready if no flags */
+  if (!RTS_ISSET(rp, SIGNALED))                /* new signal arrived */
+       RTS_LOCK_UNSET(rp, SIG_PENDING);        /* remove pending flag */
   return(OK);
 }
 
index 909d63f3e63a725cd0834ed7b66113c794f58299..dca66d9c1ae6ecf8c755cb88188a9866697cf2c5 100644 (file)
@@ -40,8 +40,7 @@ register message *m_ptr;      /* pointer to request message */
        (LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_seg.p_ldt[0]));
 #endif
   rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR;     /* set pc */
-  rp->p_rts_flags &= ~RECEIVING;       /* PM does not reply to EXEC call */
-  if (rp->p_rts_flags == 0) lock_enqueue(rp);
+  RTS_LOCK_UNSET(rp, RECEIVING);       /* PM does not reply to EXEC call */
   /* Save command name for debugging, ps(1) output, etc. */
   phys_name = numap_local(who_p, (vir_bytes) m_ptr->PR_NAME_PTR,
                                        (vir_bytes) P_NAME_LEN - 1);  
index 165ea855cd33d602196b1fb372e7f6664ac32c71..99d6d6c68d6f26251f5d542d96f6bab5c7225bc8 100644 (file)
@@ -52,7 +52,6 @@ register struct proc *rc;             /* slot of process to clean up */
   register struct proc **xpp;          /* iterate over caller queue */
   int i;
   int sys_id;
-  char saved_rts_flags;
 
   /* Don't clear if already cleared. */
   if(isemptyp(rc)) return;
@@ -63,8 +62,10 @@ register struct proc *rc;            /* slot of process to clean up */
   /* Turn off any alarm timers at the clock. */   
   reset_timer(&priv(rc)->s_alarm_timer);
 
-  /* Make sure that the exiting process is no longer scheduled. */
-  if (rc->p_rts_flags == 0) lock_dequeue(rc);
+  /* Make sure that the exiting process is no longer scheduled,
+   * and mark slot as FREE.
+   */
+  RTS_LOCK_SETFLAGS(rc, SLOT_FREE);
 
   /* Check the table with IRQ hooks to see if hooks should be released. */
   for (i=0; i < NR_IRQ_HOOKS; i++) {
@@ -80,8 +81,6 @@ register struct proc *rc;             /* slot of process to clean up */
    * this point. All important fields are reinitialized when the 
    * slots are assigned to another, new process. 
    */
-  saved_rts_flags = rc->p_rts_flags;
-  rc->p_rts_flags = SLOT_FREE;         
   if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
 
   /* Clean up virtual memory */
index b1daba701617d8977baec1836b37c217e6656b10..63016e1463b4f2dbc19f13f00948b841366b6abc 100644 (file)
@@ -26,7 +26,7 @@ register message *m_ptr;      /* pointer to request message */
   register struct proc *rpc;           /* child process pointer */
   struct proc *rpp;                    /* parent process pointer */
   struct mem_map *map_ptr;     /* virtual address of map inside caller (PM) */
-  int i, gen;
+  int i, gen, r;
   int p_proc;
 
   if(!isokendpt(m_ptr->PR_ENDPT, &p_proc))
@@ -51,10 +51,6 @@ register message *m_ptr;     /* pointer to request message */
   rpc->p_nr = m_ptr->PR_SLOT;          /* this was obliterated by copy */
   rpc->p_endpoint = _ENDPOINT(gen, rpc->p_nr); /* new endpoint of slot */
 
-  /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
-  rpc->p_rts_flags &= ~(SIGNALED | SIG_PENDING | P_STOP);
-  sigemptyset(&rpc->p_pending);
-
   rpc->p_reg.retreg = 0;       /* child sees pid = 0 to know it is child */
   rpc->p_user_time = 0;                /* set all the accounting times to 0 */
   rpc->p_sys_time = 0;
@@ -79,7 +75,13 @@ register message *m_ptr;     /* pointer to request message */
   m_ptr->PR_ENDPT = rpc->p_endpoint;
 
   /* Install new map */
-  return newmap(rpc, map_ptr);
+  r = newmap(rpc, map_ptr);
+
+  /* Only one in group should have SIGNALED, child doesn't inherit tracing. */
+  RTS_LOCK_UNSET(rpc, (SIGNALED | SIG_PENDING | P_STOP));
+  sigemptyset(&rpc->p_pending);
+
+  return r;
 }
 
 #endif /* USE_FORK */
index 95d85a50731f8f7c844cd785cef647fccb27d92c..1bf0e165fbbf565488c1d56b346bf31e2a7d2d24 100644 (file)
@@ -29,12 +29,12 @@ message *m_ptr;                     /* pointer to request message */
 
   /* Find the next process with pending signals. */
   for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) {
-      if (rp->p_rts_flags & SIGNALED) {
+      if (RTS_ISSET(rp, SIGNALED)) {
          /* store signaled process' endpoint */
           m_ptr->SIG_ENDPT = rp->p_endpoint;
           m_ptr->SIG_MAP = rp->p_pending;      /* pending signals map */
           sigemptyset(&rp->p_pending);                 /* ball is in PM's court */
-          rp->p_rts_flags &= ~SIGNALED;                /* blocked by SIG_PENDING */
+         RTS_LOCK_UNSET(rp, SIGNALED);         /* blocked by SIG_PENDING */
           return(OK);
       }
   }
index b595334a7f1d6b5ad3ac2e47810db6ab8307408e..a179f5631a8e1c9693372af7280a0f9f627ce61b 100644 (file)
@@ -20,7 +20,6 @@ message *m_ptr;                       /* pointer to request message */
   register struct proc *rp;    /* process whose map is to be loaded */
   struct mem_map *map_ptr;     /* virtual address of map inside caller (PM) */
   phys_bytes src_phys;         /* physical address of map at the PM */
-  int old_flags;               /* value of flags before modification */
   int proc;
 
   map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR;
@@ -41,7 +40,6 @@ struct mem_map *map_ptr;      /* virtual address of map inside caller (PM) */
 {
 /* Fetch the memory map from PM. */
   phys_bytes src_phys;         /* physical address of map at the PM */
-  int old_flags;               /* value of flags before modification */
   int proc;
 
   /* Copy the map from PM. */
@@ -52,8 +50,6 @@ struct mem_map *map_ptr;      /* virtual address of map inside caller (PM) */
        (phys_bytes)sizeof(rp->p_memmap));
 
   alloc_segments(rp);
-  old_flags = rp->p_rts_flags; /* save the previous value of the flags */
-  if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);
 
   return(OK);
 }
index 64a23ab7801e3342d6ec6cc835da3c82d8304dbb..e31403fc3c1e1f9365ee12a8ab4c498752387810 100644 (file)
@@ -28,10 +28,8 @@ PUBLIC int do_nice(message *m_ptr)
   rp = proc_addr(proc_nr);
 
   if (pri == PRIO_STOP) {
-
       /* Take process off the scheduling queues. */
-      if(rp->p_rts_flags == 0) lock_dequeue(rp);
-      rp->p_rts_flags |= NO_PRIORITY;
+      RTS_LOCK_SET(rp, NO_PRIORITY);
       return(OK);
   }
   else if (pri >= PRIO_MIN && pri <= PRIO_MAX) {
@@ -48,10 +46,9 @@ PUBLIC int do_nice(message *m_ptr)
       /* Make sure the process is not running while changing its priority. 
        * Put the process back in its new queue if it is runnable.
        */
-      if(rp->p_rts_flags == 0) lock_dequeue(rp);
-      rp->p_rts_flags &= ~NO_PRIORITY;
+      RTS_LOCK_SET(rp, NO_PRIORITY);
       rp->p_max_priority = rp->p_priority = new_q;
-      if (! rp->p_rts_flags) lock_enqueue(rp);
+      RTS_LOCK_UNSET(rp, NO_PRIORITY);
 
       return(OK);
   }
index 50231a458c6e16729cf306c2cf3a265502084734..d3ffe07d0e7f38293cc8620874b4d6ef488aa6d6 100644 (file)
@@ -28,7 +28,6 @@ message *m_ptr;                       /* pointer to request message */
   register struct priv *sp;
   int proc_nr;
   int priv_id;
-  int old_flags;
   int i;
   phys_bytes caller_phys, kernel_phys;
   struct io_range io_range;
@@ -49,7 +48,7 @@ message *m_ptr;                       /* pointer to request message */
   switch(m_ptr->CTL_REQUEST)
   {
   case SYS_PRIV_INIT:
-       if (! (rp->p_rts_flags & NO_PRIV)) return(EPERM);
+       if (! RTS_ISSET(rp, NO_PRIV)) return(EPERM);
 
        /* Make sure this process has its own privileges structure. This may
         * fail, since there are only a limited number of system processes.
@@ -136,25 +135,17 @@ message *m_ptr;                   /* pointer to request message */
        }
 
        /* Done. Privileges have been set. Allow process to run again. */
-       old_flags = rp->p_rts_flags;            /* save value of the flags */
-       rp->p_rts_flags &= ~NO_PRIV;            
-       if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);
+       RTS_LOCK_UNSET(rp, NO_PRIV);
        return(OK);
   case SYS_PRIV_USER:
-       if (! (rp->p_rts_flags & NO_PRIV)) return(EPERM);
-
-       /* Make this process an ordinary user process.
-        */
+       /* Make this process an ordinary user process. */
+       if (!RTS_ISSET(rp, NO_PRIV)) return(EPERM);
        if ((i=get_priv(rp, 0)) != OK) return(i);
-
-       /* Done. Privileges have been set. Allow process to run again. */
-       old_flags = rp->p_rts_flags;            /* save value of the flags */
-       rp->p_rts_flags &= ~NO_PRIV;            
-       if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);
+       RTS_LOCK_UNSET(rp, NO_PRIV);
        return(OK);
 
   case SYS_PRIV_ADD_IO:
-       if (rp->p_rts_flags & NO_PRIV)
+       if (RTS_ISSET(rp, NO_PRIV))
                return(EPERM);
 
        /* Only system processes get I/O resources? */
@@ -180,7 +171,7 @@ message *m_ptr;                     /* pointer to request message */
        return OK;
 
   case SYS_PRIV_ADD_MEM:
-       if (rp->p_rts_flags & NO_PRIV)
+       if (RTS_ISSET(rp, NO_PRIV))
                return(EPERM);
 
        /* Only system processes get memory resources? */
@@ -208,7 +199,7 @@ message *m_ptr;                     /* pointer to request message */
        return OK;
 
   case SYS_PRIV_ADD_IRQ:
-       if (rp->p_rts_flags & NO_PRIV)
+       if (RTS_ISSET(rp, NO_PRIV))
                return(EPERM);
 
        /* Only system processes get IRQs? */
index 38bc2b19b2ceb21b0f78fcc81cdbda1e05f7ef84..efe89395ac1bd60b6abdb03cf5393f4312427440 100644 (file)
@@ -61,7 +61,7 @@ endpoint_t *e_granter;                /* new granter (magic grants) */
         * EINVAL for grant-out-of-range, in case this turns out to be
         * interesting information.)
         */
-       if((granter_proc->p_rts_flags & NO_PRIV) || !(priv(granter_proc)) ||
+       if(RTS_ISSET(granter_proc, NO_PRIV) || !(priv(granter_proc)) ||
          priv(granter_proc)->s_grant_table < 1) {
                kprintf("grant verify failed in ep %d proc %d: "
                "no priv table, or no grant table\n",
index 7f353e33abdbc561f3887de7b43bdf7b9b42d3bb..39044bab478a93987369347721a5c427c53d894a 100644 (file)
@@ -22,7 +22,7 @@ message *m_ptr;
        rp = proc_addr(who_p);
 
        /* Copy grant table set in priv. struct. */
-       if ((rp->p_rts_flags & NO_PRIV) || !(priv(rp))) {
+       if (RTS_ISSET(rp, NO_PRIV) || !(priv(rp))) {
                r = EPERM;
        } else {
                _K_SET_GRANT_TABLE(rp, 
index b118edb340e0d66775e1e098a602acb4a8dc4c0c..0b37bac8958ffbda311d82b8524adec452427830 100644 (file)
@@ -93,10 +93,10 @@ message *m_ptr;                     /* pointer to request message */
   rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
 
   /* Reschedule if necessary. */
-  if(rp->p_rts_flags & NO_PRIORITY) {
-       rp->p_rts_flags &= ~NO_PRIORITY;
-       if (rp->p_rts_flags == 0) lock_enqueue(rp);
-  } else kprintf("system: warning: sigsend a running process\n");
+  if(RTS_ISSET(rp, NO_PRIORITY))
+       RTS_LOCK_UNSET(rp, NO_PRIORITY);
+  else
+       kprintf("system: warning: sigsend a running process\n");
 
   return(OK);
 }
index 19299b3aff4cb76e624f77c336caa77525821b21..0e12f0ba5fdacd0eb417b213827c54dbbe0c4c52 100644 (file)
@@ -55,8 +55,7 @@ register message *m_ptr;
   if (isemptyp(rp)) return(EIO);
   switch (tr_request) {
   case T_STOP:                 /* stop process */
-       if (rp->p_rts_flags == 0) lock_dequeue(rp);
-       rp->p_rts_flags |= P_STOP;
+       RTS_LOCK_SET(rp, P_STOP);
        rp->p_reg.psw &= ~TRACEBIT;     /* clear trace bit */
        return(OK);
 
@@ -126,15 +125,13 @@ register message *m_ptr;
        break;
 
   case T_RESUME:               /* resume execution */
-       rp->p_rts_flags &= ~P_STOP;
-       if (rp->p_rts_flags == 0) lock_enqueue(rp);
+       RTS_LOCK_UNSET(rp, P_STOP);
        m_ptr->CTL_DATA = 0;
        break;
 
   case T_STEP:                 /* set trace bit */
        rp->p_reg.psw |= TRACEBIT;
-       rp->p_rts_flags &= ~P_STOP;
-       if (rp->p_rts_flags == 0) lock_enqueue(rp);
+       RTS_LOCK_UNSET(rp, P_STOP);
        m_ptr->CTL_DATA = 0;
        break;
 
index 43c355d1a25221438b2e606afeedc78816b60c96..2ac0f3dafe2bc62f56d69625010cc54368dc19bb 100644 (file)
@@ -137,24 +137,6 @@ PUBLIC void irqtab_dmp()
   struct irq_hook irq_hooks[NR_IRQ_HOOKS];
   int irq_actids[NR_IRQ_VECTORS];
   struct irq_hook *e;  /* irq tab entry */
-  char *irq[] = {
-       "clock",        /* 00 */
-       "keyboard",     /* 01 */
-       "cascade",      /* 02 */
-       "rs232",        /* 03 */
-       "rs232",        /* 04 */
-       "NIC(eth)",     /* 05 */
-       "floppy",       /* 06 */
-       "printer",      /* 07 */
-       "",     /* 08 */
-       "",     /* 09 */
-       "",     /* 10 */
-       "",     /* 11 */
-       "",     /* 12 */
-       "",     /* 13 */
-       "at_wini_0",    /* 14 */
-       "at_wini_1",    /* 15 */
-  };
 
   if ((r = sys_getirqhooks(irq_hooks)) != OK) {
       report("IS","warning: couldn't get copy of irq hooks", r);
@@ -173,7 +155,7 @@ PUBLIC void irqtab_dmp()
 #endif
 
   printf("IRQ policies dump shows use of kernel's IRQ hooks.\n");
-  printf("-h.id- -proc.nr- -IRQ vector (nr.)- -policy- -notify id-\n");
+  printf("-h.id- -proc.nr- -irq nr- -policy- -notify id-\n");
   for (i=0; i<NR_IRQ_HOOKS; i++) {
        e = &irq_hooks[i];
        printf("%3d", i);
@@ -182,7 +164,7 @@ PUBLIC void irqtab_dmp()
            continue;
        }
        printf("%10d  ", e->proc_nr_e); 
-       printf("    %9.9s (%02d) ", irq[e->irq], e->irq); 
+       printf("    (%02d) ", e->irq); 
        printf("  %s", (e->policy & IRQ_REENABLE) ? "reenable" : "    -   ");
        printf("   %d", e->notify_id);
        if (irq_actids[e->irq] & (1 << i))
index 36cd88329401af6e7f7a3c512b20804ff3ffe629..01686272c863ac70a7f3fc81b823598702f76668 100644 (file)
@@ -33,7 +33,7 @@ EXTERN int SELF_E;
 EXTERN struct inode *chroot_dir;
 
 EXTERN short path_processed;      /* number of characters processed */
-EXTERN char user_path[PATH_MAX];  /* pathname to be processed */
+EXTERN char user_path[PATH_MAX+1];  /* pathname to be processed */
 EXTERN char *vfs_slink_storage;
 EXTERN int symloop;
 
index 0e76712b56ef8c986058f28918e2643cdccc74bc..13db3af031164d2274450ce530f40a4e03ce0ee4 100644 (file)
@@ -586,6 +586,7 @@ off_t newsize;                      /* inode must become this size */
   /* Next correct the inode size. */
   if(!waspipe) rip->i_size = newsize;
   else wipe_inode(rip);        /* Pipes can only be truncated to 0. */
+  rip->i_update |= CTIME | MTIME;
   rip->i_dirt = DIRTY;
 
   return OK;
@@ -642,6 +643,9 @@ off_t start, end;           /* range of bytes to free (end uninclusive) */
        for(p = nextblock(start, zone_size)/zone_size; p < e; p ++)
                write_map(rip, p*zone_size, NO_ZONE, WMAP_FREE);
 
+        rip->i_update |= CTIME | MTIME;
+        rip->i_dirt = DIRTY;
+
        return OK;
 }
 
index b2889e21d29fece0478165d5cfe90f6a2c5bdb4b..eb5245b9cec803f3d3057176f051100b3d0e5bf8 100644 (file)
@@ -91,6 +91,8 @@ printf("MFS(%d) get_inode by open() failed\n", SELF_E);
                   case I_REGULAR: 
                        /* Truncate regular file if O_TRUNC. */
                        if (oflags & O_TRUNC) {
+                               panic(__FILE__, "O_TRUNC in mfs.", oflags);
+#if 0
                                if ((r = forbidden(rip, W_BIT)) !=OK) break;
                                truncate_inode(rip, 0);
                                wipe_inode(rip);
@@ -99,6 +101,7 @@ printf("MFS(%d) get_inode by open() failed\n", SELF_E);
                                 * cache flush.
                                 */
                                rw_inode(rip, WRITING);
+#endif
                        }
                        break;
  
index e5459c3cf03156fb83cc55512d15a81ed22706f8..9158f8defd24cad916d52c0d0f8f45a9c527b86d 100644 (file)
@@ -43,7 +43,7 @@ PUBLIC int lookup()
   
   /* Check length. */
   len = fs_m_in.REQ_PATH_LEN;
-  if(len > sizeof(string)) return E2BIG;       /* too big for buffer */
+  if(len > sizeof(user_path)) return E2BIG;    /* too big for buffer */
   if(len < 1) return EINVAL;                   /* too small for \0 */
 
   /* Copy the pathname and set up caller's user and group id */
@@ -55,8 +55,10 @@ PUBLIC int lookup()
   }
 
   /* Verify this is a null-terminated path. */
-  if(user_path[len-1] != '\0')
+  if(user_path[len-1] != '\0') {
+       printf("mfs:lookup: didn't get null-terminated string.\n");
        return EINVAL;
+  }
 
   caller_uid = fs_m_in.REQ_UID;
   caller_gid = fs_m_in.REQ_GID;
index a2d1d609bc857dc6af6df4e210087cd4453dff74..ecf80c246054f951e53ce703268e2b565741df2e 100644 (file)
@@ -50,6 +50,9 @@ printf("MFS(%d) get_inode by fs_chmod() failed\n", SELF_E);
   rip->i_update |= CTIME;
   rip->i_dirt = DIRTY;
 
+  /* Return full new mode to caller. */
+  fs_m_out.RES_MODE = rip->i_mode;
+
   put_inode(rip);
   return(OK);
 }
@@ -94,7 +97,11 @@ printf("MFS(%d) get_inode by fs_chown() failed\n", SELF_E);
        rip->i_dirt = DIRTY;
   }
 
+  /* Update caller on current mode, as it may have changed. */
+  fs_m_out.RES_MODE = rip->i_mode;
+
   put_inode(rip);
+
   return(r);
 }
 
index 51d31e168ae703791b6703576aad96355a740572..13c207b1622be3bcefc310abd6139b9b9c4a7d6b 100644 (file)
@@ -142,8 +142,8 @@ PUBLIC void dev_status(message *m)
                                        if(endpt == NONE) {
                                                printf("FS: proc with "
                                        "grant %d from %d not found (revive)\n",
-                                       st.m_source,
-                                       st.REP_IO_GRANT);
+                                       st.REP_IO_GRANT,
+                                       st.m_source);
                                                continue;
                                        }
                                }
index b070e517d47177704db73db4b0033f08a365daef..2503d2a628430f9f7e12e11e615d174e31d4cbd3 100644 (file)
@@ -3,13 +3,14 @@
  * The entry points into this file are
  *   get_fd:    look for free file descriptor and free filp slots
  *   get_filp:  look up the filp entry for a given file descriptor
- *   find_filp:         find a filp slot that points to a given inode
+ *   find_filp:         find a filp slot that points to a given vnode
  *   inval_filp: invalidate a filp and associated fd's, only let close()
  *               happen on it
  */
 
 #include <sys/select.h>
 #include <minix/u64.h>
+#include <assert.h>
 
 #include "fs.h"
 #include "file.h"
@@ -30,8 +31,6 @@ PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt)
   register struct filp *f;
   register int i;
 
-  *k = -1;                     /* we need a way to tell if file desc found */
-
   /* Search the fproc fp_filp table for a free file descriptor. */
   for (i = start; i < OPEN_MAX; i++) {
        if (fp->fp_filp[i] == NIL_FILP && !FD_ISSET(i, &fp->fp_filp_inuse)) {
@@ -42,10 +41,11 @@ PUBLIC int get_fd(int start, mode_t bits, int *k, struct filp **fpt)
   }
 
   /* Check to see if a file descriptor has been found. */
-  if (*k < 0) return(EMFILE);  /* this is why we initialized k to -1 */
+  if (i >= OPEN_MAX) return(EMFILE);
 
   /* Now that a file descriptor has been found, look for a free filp slot. */
   for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
+       assert(f->filp_count >= 0);
        if (f->filp_count == 0) {
                f->filp_mode = bits;
                f->filp_pos = cvu64(0);
@@ -92,7 +92,7 @@ int fild;                     /* file descriptor */
  *===========================================================================*/
 PUBLIC struct filp *find_filp(register struct vnode *vp, mode_t bits)
 {
-/* Find a filp slot that refers to the inode 'rip' in a way as described
+/* Find a filp slot that refers to the vnode 'vp' in a way as described
  * by the mode bit 'bits'. Used for determining whether somebody is still
  * interested in either end of a pipe.  Also used when opening a FIFO to
  * find partners to share a filp field with (to shared the file position).
@@ -103,6 +103,7 @@ PUBLIC struct filp *find_filp(register struct vnode *vp, mode_t bits)
 
   for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
        if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){
+               assert(f->filp_count > 0);
                return(f);
        }
   }
index 454425cd73dc8692fc9c95d89103040dd973643c..829353b372070de2ef3918e97737a7d83779571a 100644 (file)
@@ -24,7 +24,7 @@ EXTERN int who_p, who_e;      /* caller's proc number, endpoint */
 EXTERN int call_nr;            /* system call number */
 EXTERN message mount_m_in;     /* the input message itself */
 
-EXTERN char user_fullpath[PATH_MAX];    /* storage for user path name */
+EXTERN char user_fullpath[PATH_MAX+1];    /* storage for user path name */
 EXTERN short cum_path_processed;        /* number of characters processed */
 
 /* The following variables are used for returning results to the caller. */
index 49a8233e7d1770382767b9728110f012e2db8a8c..47018444c12437727fc1d1e1c2618d3c1e7c4b76 100644 (file)
@@ -133,6 +133,8 @@ PUBLIC int main()
                panic(__FILE__, "check_vrefs failed at line", __LINE__);
        }
 #endif
+       
+       
   }
   return(OK);                          /* shouldn't come here */
 }
@@ -170,9 +172,10 @@ PRIVATE void get_work()
   }
 
   for(;;) {
+    int r;
     /* Normal case.  No one to revive. */
-    if (receive(ANY, &m_in) != OK)
-       panic(__FILE__,"fs receive error", NO_NUM);
+    if ((r=receive(ANY, &m_in)) != OK)
+       panic(__FILE__,"fs receive error", r);
     who_e = m_in.m_source;
     who_p = _ENDPOINT_P(who_e);
 
index 6eb207027d538e28452ab0df781bf759dc061f02..cfa34766504ce6c8717a355a6e400e6161c3e5e2 100644 (file)
@@ -491,7 +491,6 @@ Dev_t dev;
   }
 
   if (count > 1) {
-      printf("VFSunmount: %d filesystem is busy count: %d\n", dev, count);
       return(EBUSY);    /* can't umount a busy file system */
   }
 
index ae8756299992b834150286efad50966516b80fd1..42a05622e5e9d211453ba6a5c83b413b1db41358 100644 (file)
@@ -26,6 +26,7 @@
 #include "lock.h"
 #include "param.h"
 #include <dirent.h>
+#include <assert.h>
 
 #include <minix/vfsif.h>
 #include "vnode.h"
@@ -117,10 +118,6 @@ PRIVATE int common_open(register int oflags, mode_t omode)
 
   vp= NULL;
 
-#if 0
-  printf("common_open: for '%s'\n", user_fullpath);
-#endif
-
   /* Fill in lookup request fields */
   Xlookup_req.path = user_fullpath;
   Xlookup_req.lastc = Xlastc;
@@ -146,11 +143,18 @@ PRIVATE int common_open(register int oflags, mode_t omode)
   {
        if (pathrem == NULL)
                panic(__FILE__, "no pathrem", NO_NUM);
-       if (strchr(pathrem, '/') == 0)
+
+       /* If any path remains, but no '/', O_CREAT can continue.
+        * If no path remains, a null filename was provided so ENOENT
+        * remains.
+        */
+       if(*pathrem) {
+          if (strchr(pathrem, '/') == 0)
                r= OK;
-       else
-       {
+          else
+          {
                printf("common_open: / in pathrem\n");
+          }
        }
   }
 
@@ -278,8 +282,6 @@ PRIVATE int common_open(register int oflags, mode_t omode)
           break;
 
       case I_NAMED_PIPE:
-         printf("common_open: setting I_PIPE, inode %d on dev 0x%x\n",
-               vp->v_inode_nr, vp->v_dev);
          vp->v_pipe = I_PIPE;
                vp->v_isfifo= TRUE;
           oflags |= O_APPEND;  /* force append mode */
@@ -291,6 +293,7 @@ PRIVATE int common_open(register int oflags, mode_t omode)
                * file position will be automatically shared.
                */
               b = (bits & R_BIT ? R_BIT : W_BIT);
+             assert(fil_ptr->filp_count == 1);
               fil_ptr->filp_count = 0; /* don't find self */
               if ((filp2 = find_filp(vp, b)) != NIL_FILP) {
                   /* Co-reader or writer found. Use it.*/
@@ -428,15 +431,10 @@ struct vnode **vpp;
        break;
 
   case I_NAMED_PIPE:
-       printf("x_open (fifo): reference count %d, fd %d\n",
-               vp->v_ref_count, vp->v_fs_count);
        if (vp->v_ref_count == 1)
        {
-               printf("x_open (fifo): first reference, size %u\n",
-                       vp->v_size);
                if (vp->v_size != 0)
                {
-                       printf("x_open (fifo): clearing\n");
                        r= truncate_vn(vp, 0);
                        if (r != OK)
                        {
@@ -465,8 +463,6 @@ PRIVATE int pipe_open(register struct vnode *vp, register mode_t bits,
  *  processes hanging on the pipe.
  */
 
-         printf("pipe_open: setting I_PIPE, inode %d on dev 0x%x\n",
-               vp->v_inode_nr, vp->v_dev);
   vp->v_pipe = I_PIPE; 
 
   if((bits & (R_BIT|W_BIT)) == (R_BIT|W_BIT)) {
@@ -735,6 +731,12 @@ int fd_nr;
 
   /* If a write has been done, the inode is already marked as DIRTY. */
   if (--rfilp->filp_count == 0) {
+       if (vp->v_pipe == I_PIPE) {
+               /* Last reader or writer is going. Tell MFS about latest
+                * pipe size.
+                */
+               truncate_vn(vp, vp->v_size);
+       }
        if (vp->v_pipe == I_PIPE && vp->v_ref_count > 1) {
                /* Save the file position in the v-node in case needed later.
                 * The read and write positions are saved separately.  
index fa6051f97c025cf635808a5c50f8ea46a2ca0c9b..c005911d640dbaf521f26ad7816b1f33afd5926d 100644 (file)
@@ -43,6 +43,7 @@ node_details_t *node;
 
   /* Empty (start) path? */
   if (fullpath[0] == '\0') {
+      node->inode_nr = 0;
       return ENOENT;
   }
 
@@ -178,6 +179,8 @@ char **pathrem;
 
   /* Empty (start) path? */
   if (fullpath[0] == '\0') {
+      node->inode_nr = 0;
+      *pathrem = fullpath;
       return ENOENT;
   }
 
@@ -314,7 +317,7 @@ struct vnode **vpp;
   if (res.inode_nr == 0)
   {
        printf("lookup_vp: lookup returned no inode\n");
-       printf("lookup_res = %d, last = '%s'\n",
+       printf("lookup_res = %d, last = '%s'\n\n",
                lookup_res, lookup_req->lastc);
        *vpp= NULL;
        return lookup_res;
@@ -386,7 +389,7 @@ char **pathrem;
   if (res.inode_nr == 0)
   {
        printf("Xlookup_vp: lookup returned no inode\n");
-       printf("lookup_res = %d, last = '%s'\n",
+       printf("lookup_res = %d, last = '%s'\n\n",
                lookup_res, lookup_req->lastc);
        *vpp= NULL;
        return lookup_res;
index 093bc2200eb2808868e2229462797bd64941af51..3ac498b7269d2c9748eb84cb8ba8aacdcbbfa05d 100644 (file)
@@ -34,7 +34,8 @@ PUBLIC int do_chmod()
   struct chmod_req req;
   struct lookup_req lookup_req;
   struct node_details res;
-  int r;
+  struct vnode *vp;
+  int r, ch_mode;
     
   if (call_nr == CHMOD) {
       /* Perform the chmod(name, mode) system call. */
@@ -58,13 +59,21 @@ PUBLIC int do_chmod()
   }
   else panic(__FILE__, "do_chmod called with strange call_nr", call_nr);
 
+  /* Find vnode, if it's in use. */
+  vp = find_vnode(req.fs_e, req.inode_nr);
+
   /* Fill in request message fields.*/
   req.uid = fp->fp_effuid;
   req.gid = fp->fp_effgid;
   req.rmode = m_in.mode;
   
   /* Issue request */
-  return req_chmod(&req);
+  if((r = req_chmod(&req, &ch_mode)) != OK) return r;
+
+  if(vp != NIL_VNODE)
+       vp->v_mode = ch_mode;
+
+  return OK;
 }
 
 /*===========================================================================*
@@ -78,7 +87,8 @@ PUBLIC int do_chown()
   struct chown_req req;
   struct lookup_req lookup_req;
   struct node_details res;
-  int r;
+  struct vnode *vp;
+  int r, ch_mode;
   
   if (call_nr == CHOWN) {
       /* Perform the chmod(name, mode) system call. */
@@ -102,6 +112,9 @@ PUBLIC int do_chown()
   }
   else panic(__FILE__, "do_chmod called with strange call_nr", call_nr);
 
+  /* Find vnode, if it's in use. */
+  vp = find_vnode(req.fs_e, req.inode_nr);
+
   /* Fill in request message fields.*/
   req.uid = fp->fp_effuid;
   req.gid = fp->fp_effgid;
@@ -109,7 +122,15 @@ PUBLIC int do_chown()
   req.newgid = m_in.group;
   
   /* Issue request */
-  return req_chown(&req);
+  r = req_chown(&req, &ch_mode);
+
+  if(r == OK && vp) {
+       vp->v_uid = m_in.owner;
+       vp->v_gid = m_in.group;
+       vp->v_mode = ch_mode;
+  }
+
+  return r;
 }
 
 
@@ -207,7 +228,9 @@ PUBLIC int forbidden(struct vnode *vp, mode_t access_desired)
 
   /* If access desired is not a subset of what is allowed, it is refused. */
   r = OK;
-  if ((perm_bits | access_desired) != perm_bits) r = EACCES;
+  if ((perm_bits | access_desired) != perm_bits) {
+       r = EACCES;
+       }
 
   /* Check to see if someone is trying to write on a file system that is
    * mounted read-only.
index bfcca929f068b5eba5ada122e74ce666a381a868..1248f5f18a2ea6449884d47e9998149d0b0e3db6 100644 (file)
@@ -133,7 +133,8 @@ _PROTOTYPE( int do_getdents, (void)                                 );
 _PROTOTYPE( int read_write, (int rw_flag)                              );
 
 /* request.c */
-_PROTOTYPE( int req_getnode, (node_req_t *req, node_details_t *res)     );
+#define req_getnode(req, res) req_getnode_f(__FILE__, __LINE__, (req), (res))
+_PROTOTYPE( int req_getnode_f, (char *file, int line, node_req_t *req, node_details_t *res)     );
 _PROTOTYPE( int req_putnode, (int fs_e, ino_t inode_nr, int count)     );
 _PROTOTYPE( int req_open, (open_req_t *req, node_details_t *res)        ); 
 _PROTOTYPE( int req_create, (int fs_e, ino_t inode_nr, int omode,
@@ -144,8 +145,8 @@ _PROTOTYPE( int req_pipe, (pipe_req_t *req, node_details_t *res)        );
 _PROTOTYPE( int req_clone_opcl, (clone_opcl_req_t *req, 
             node_details_t *res)                                        );
 _PROTOTYPE( int req_ftrunc, (ftrunc_req_t *req)                         );
-_PROTOTYPE( int req_chown, (chown_req_t *req)                           );
-_PROTOTYPE( int req_chmod, (chmod_req_t *req)                           );
+_PROTOTYPE( int req_chown, (chown_req_t *req, int *mode)                );
+_PROTOTYPE( int req_chmod, (chmod_req_t *req, int *mode)                );
 _PROTOTYPE( int req_access, (access_req_t *req)                         );
 _PROTOTYPE( int req_mknod, (mknod_req_t *req)                           );
 _PROTOTYPE( int req_mkdir, (mkdir_req_t *req)                           );
@@ -240,3 +241,4 @@ _PROTOTYPE( void fs_expire_timers, (clock_t now)                    );
 _PROTOTYPE( void fs_cancel_timer, (timer_t *tp)                                );
 _PROTOTYPE( void fs_init_timer, (timer_t *tp)                          );
 
+
index d142d33dd1d41a7485f0a46055aee9d1794f2b67..54ef44cba2cece67b475311e5fddb5f95fb1cf2d 100644 (file)
@@ -21,6 +21,7 @@
 #include "fproc.h"
 #include "param.h"
 #include <dirent.h>
+#include <assert.h>
 
 #include <minix/vfsif.h>
 #include "vnode.h"
@@ -45,7 +46,7 @@ int rw_flag;                  /* READING or WRITING */
 /* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
   register struct filp *f;
   register struct vnode *vp;
-  off_t bytes_left, f_size;
+  off_t bytes_left;
   u64_t position;
   unsigned int off, cum_io;
   int op, oflags, r, chunk, usr, seg, block_spec, char_spec;
@@ -97,7 +98,6 @@ int rw_flag;                  /* READING or WRITING */
   oflags = f->filp_flags;
 
   vp = f->filp_vno;
-  f_size = vp->v_size;
 
   r = OK;
   if (vp->v_pipe == I_PIPE) {
@@ -119,7 +119,6 @@ int rw_flag;                        /* READING or WRITING */
   }
 
   if ((block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0))) {
-      f_size = ULONG_MAX;
       if (vp->v_sdev == NO_DEV)
           panic(__FILE__,"read_write tries to read from "
                   " block device NO_DEV", NO_NUM);
@@ -155,11 +154,11 @@ int rw_flag;                      /* READING or WRITING */
       position = res.new_pos;
       cum_io += res.cum_io;
   }
-  /* Regular files */
+  /* Regular files (and pipes) */
   else {
       if (rw_flag == WRITING && block_spec == 0) {
           /* Check for O_APPEND flag. */
-          if (oflags & O_APPEND) position = cvul64(f_size);
+          if (oflags & O_APPEND) position = cvul64(vp->v_size);
 
           /* Check in advance to see if file will grow too big. */
           if (cmp64ul(position, vp->v_vmnt->m_max_file_size - m_in.nbytes) > 0)
@@ -175,8 +174,9 @@ int rw_flag;                        /* READING or WRITING */
       }
 
       if (partial_cnt > 0) {
-          /* So taht we don't need to deal with partial count 
-           * in the FS process */
+          /* So that we don't need to deal with partial count 
+           * in the FS process.
+          */
           m_in.nbytes = MIN(m_in.nbytes, partial_cnt);
           partial_pipe = 1;
       }
@@ -192,11 +192,17 @@ int rw_flag;                      /* READING or WRITING */
       req.user_addr = m_in.buffer;
       req.inode_index = vp->v_index;
 
-      if (vp->v_isfifo)
-      {
-       printf("read_write: %s for FIFO @ %u size %u\n",
-               (rw_flag == READING) ? "read" : "write",
-               ex64lo(position), m_in.nbytes);
+      /* Truncate read request at size (mustn't do this for special files). */
+      if((rw_flag == READING) &&
+       cmp64ul(add64ul(position, req.num_of_bytes), vp->v_size) > 0) {
+       /* Position always should fit in an off_t (LONG_MAX). */
+       off_t pos32;
+       assert(cmp64ul(position, LONG_MAX) <= 0);
+       pos32 = cv64ul(position);
+       assert(pos32 >= 0);
+       assert(pos32 <= LONG_MAX);
+       req.num_of_bytes = vp->v_size - pos32;
+       assert(req.num_of_bytes >= 0);
       }
 
       /* Issue request */
@@ -215,7 +221,7 @@ int rw_flag;                        /* READING or WRITING */
   /* On write, update file size and access time. */
   if (rw_flag == WRITING) {
       if (regular || mode_word == I_DIRECTORY) {
-          if (cmp64ul(position, f_size) > 0)
+          if (cmp64ul(position, vp->v_size) > 0)
          {
                if (ex64hi(position) != 0)
                {
index 4f620911d970d8527b8f2aee30ed422b850651de..b4ca2810ebf08cc542d27d413af1a56f973b4a1c 100644 (file)
 #include "vnode.h"
 #include "param.h"
 
-FORWARD _PROTOTYPE(int fs_sendrec, (endpoint_t fs_e, message *reqm));
+FORWARD _PROTOTYPE(int fs_sendrec_f, (char *file, int line, endpoint_t fs_e, message *reqm));
+
+#define fs_sendrec(e, m) fs_sendrec_f(__FILE__, __LINE__, (e), (m))
 
 /*===========================================================================*
  *                             req_getnode                                  *
  *===========================================================================*/
-PUBLIC int req_getnode(req, res)
+PUBLIC int req_getnode_f(file, line, req, res)
+char *file;
+int line;
 node_req_t *req; 
 node_details_t *res;
 {
@@ -278,10 +282,12 @@ ftrunc_req_t *req;
 /*===========================================================================*
  *                             req_chmod                                    *
  *===========================================================================*/
-PUBLIC int req_chmod(req)
+PUBLIC int req_chmod(req, ch_mode)
 chmod_req_t *req;
+int *ch_mode;
 {
     message m;
+    int r;
 
     /* Fill in request message */
     m.m_type = REQ_CHMOD;
@@ -291,17 +297,24 @@ chmod_req_t *req;
     m.REQ_GID = req->gid;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(req->fs_e, &m);
+
+    /* Copy back actual mode. */
+    if(ch_mode) *ch_mode = m.RES_MODE;
+
+    return r;
 }
 
 
 /*===========================================================================*
  *                             req_chown                                    *
  *===========================================================================*/
-PUBLIC int req_chown(req)
+PUBLIC int req_chown(req, ch_mode)
 chown_req_t *req;
+int *ch_mode;
 {
     message m;
+    int r;
 
     /* Fill in request message */
     m.m_type = REQ_CHOWN;
@@ -312,7 +325,12 @@ chown_req_t *req;
     m.REQ_NEW_GID = req->newgid;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(req->fs_e, &m);
+
+    /* Return new mode to caller. */
+    if(ch_mode) *ch_mode = m.RES_MODE;
+
+    return r;
 }
 
 
@@ -955,7 +973,7 @@ _t *res;
 /*===========================================================================*
  *                             fs_sendrec                                   *
  *===========================================================================*/
-PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
+PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
 {
 /* This is the low level function that sends requests to FS processes.
  * It also handles driver recovery mechanism and reissuing the
@@ -964,7 +982,7 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
   int r, old_driver_e, new_driver_e;
   message origm, m;
   struct vmnt *vmp;
-  
+
   /* Make a copy of the request so that we can load it back in
    * case of a dead driver */
   origm = *reqm;
@@ -972,8 +990,8 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
   for (;;) {
       /* Do the actual send, receive */
       if (OK != (r=sendrec(fs_e, reqm))) {
-          printf("VFS: error sending message. FS_e: %d req_nr: %d err: %d\n", 
-                  fs_e, reqm->m_type, r);
+          printf("VFS:fs_sendrec:%s:%d: error sending message. FS_e: %d req_nr: %d err: %d\n", 
+                  file, line, fs_e, reqm->m_type, r);
       }
 
       if(r == OK) {
@@ -984,9 +1002,9 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
       /* Dead driver */
       if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
           old_driver_e = NONE;
-          /* Find old driver enpoint */
+          /* Find old driver by endpoint */
           for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
-              if (vmp->m_fs_e == reqm->m_source) {   /* found FS */
+              if (vmp->m_fs_e == fs_e) {   /* found FS */
                   old_driver_e = vmp->m_driver_e;
                   dmap_unmap_by_endpt(old_driver_e); /* unmap driver */
                   break;
@@ -994,10 +1012,8 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
           }
          
           /* No FS ?? */
-          if (old_driver_e == NONE) {
-              panic(__FILE__, "VFSdead_driver: couldn't find FS\n", 
-                             old_driver_e);
-          }
+          if (old_driver_e == NONE)
+              panic(__FILE__, "VFSdead_driver: couldn't find FS\n", fs_e);
 
           /* Wait for a new driver. */
           for (;;) {
index 2b90d2a818db994a24e6915bb8b839f0f296d063..544a315c8231e753e92d9740a02c9a176a6c2f0b 100644 (file)
@@ -141,7 +141,14 @@ int len;                   /* length of the directory name string */
       put_vnode(vp);
       return ENOTDIR;
   }
-  
+
+  /* Access check */
+  r = forbidden(vp, X_BIT);
+  if (r != OK) {
+        put_vnode(vp);
+       return r;
+  }
+
   return change_into(iip, vp);
 }
 
index b5410c3c5d1eacf5f5bf7d9f47e34b82fb2e855f..97f12a3d72d76363667eb2cd11ac20f02ccfbab2 100644 (file)
@@ -17,6 +17,7 @@
 #include "file.h"
 #include "fproc.h"
 #include "param.h"
+#include "vmnt.h"
 
 PRIVATE int panicking;         /* inhibits recursive panics during sync */
 
@@ -35,6 +36,11 @@ int flag;                    /* M3 means path may be in message */
   register char *rpu, *rpm;
   int r;
 
+  if (len > PATH_MAX) {
+       err_code = ENAMETOOLONG;
+       return(EGENERIC);
+  }
+
   if(len >= sizeof(user_fullpath)) {
        panic(__FILE__, "fetch_name: len too much for user_fullpath", len);
   }
@@ -42,11 +48,7 @@ int flag;                    /* M3 means path may be in message */
   /* Check name length for validity. */
   if (len <= 0) {
        err_code = EINVAL;
-       return(EGENERIC);
-  }
-
-  if (len > PATH_MAX) {
-       err_code = ENAMETOOLONG;
+       printf("vfs: fetch_name: len %d?\n", len);
        return(EGENERIC);
   }
 
@@ -100,7 +102,7 @@ int num;                    /* number to go with it */
   if (panicking) return;       /* do not panic during a sync */
   panicking = TRUE;            /* prevent another panic during the sync */
 
-  printf("FS panic (%s): %s ", who, mess);
+  printf("VFS panic (%s): %s ", who, mess);
   if (num != NO_NUM) printf("%d",num); 
   (void) do_sync();            /* flush everything to the disk */
   sys_exit(SELF);
@@ -148,4 +150,3 @@ PUBLIC time_t clock_time()
   return( (time_t) (boottime + (uptime/HZ)));
 }
 
-