Mostly bugfixes of bugs triggered by the test set.

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
This commit is contained in:
Ben Gras 2007-02-01 17:50:02 +00:00
parent fa59af2bc0
commit 41e9fedf87
36 changed files with 282 additions and 201 deletions

View file

@ -39,7 +39,7 @@
*/ */
FORWARD _PROTOTYPE( void init_clock, (void) ); FORWARD _PROTOTYPE( void init_clock, (void) );
FORWARD _PROTOTYPE( int clock_handler, (irq_hook_t *hook) ); 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)); FORWARD _PROTOTYPE( void load_update, (void));
/* The CLOCK's timers queue. The functions in <timers.h> operate on this. /* 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. */ /* Go get a message. */
result = receive(ANY, &m); result = receive(ANY, &m);
if(result != OK)
panic("receive() failed", result);
/* Handle the request. Only clock ticks are expected. */ /* Handle the request. Only clock ticks are expected. */
switch (m.m_type) { switch (m.m_type) {
case HARD_INT: case HARD_INT:
result = do_clocktick(&m); /* handle clock tick */ do_clocktick(&m); /* handle clock tick */
break; break;
default: /* illegal request type */ default: /* illegal request type */
kprintf("CLOCK: illegal request %d from %d.\n", kprintf("CLOCK: illegal request %d from %d.\n",
@ -89,7 +92,7 @@ PUBLIC void clock_task()
/*===========================================================================* /*===========================================================================*
* do_clocktick * * do_clocktick *
*===========================================================================*/ *===========================================================================*/
PRIVATE int do_clocktick(m_ptr) PRIVATE void do_clocktick(m_ptr)
message *m_ptr; /* pointer to request message */ message *m_ptr; /* pointer to request message */
{ {
/* Despite its name, this routine is not called on every clock tick. It /* 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. * 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_ticks_left <= 0 && priv(prev_ptr)->s_flags & PREEMPTIBLE) {
if(prev_ptr->p_rts_flags == 0) /* if it was runnable .. */ if(prev_ptr->p_rts_flags == 0) { /* if it was runnable .. */
lock_dequeue(prev_ptr); /* take it off the queues */ lock_dequeue(prev_ptr); /* take it off the queues */
lock_enqueue(prev_ptr); /* and reinsert it again */ lock_enqueue(prev_ptr); /* and reinsert it again */
}
} }
/* Check if a clock timer expired and run its watchdog function. */ /* 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; TMR_NEVER : clock_timers->tmr_exp_time;
} }
/* Inhibit sending a reply. */ return;
return(EDONTREPLY);
} }
/*===========================================================================* /*===========================================================================*

View file

@ -150,12 +150,8 @@ PUBLIC void main()
} }
/* Set ready. The HARDWARE task is never ready. */ /* Set ready. The HARDWARE task is never ready. */
if (rp->p_nr != HARDWARE) { if (rp->p_nr == HARDWARE) RTS_LOCK_SET(rp, NO_PRIORITY);
rp->p_rts_flags = 0; /* runnable if no flags */ RTS_LOCK_UNSET(rp, SLOT_FREE); /* remove SLOT_FREE and schedule */
lock_enqueue(rp); /* add to scheduling queues */
} else {
rp->p_rts_flags = NO_PRIORITY; /* prevent from running */
}
/* Code and data segments must be allocated in protected mode. */ /* Code and data segments must be allocated in protected mode. */
alloc_segments(rp); alloc_segments(rp);

View file

@ -104,7 +104,7 @@ long bit_map; /* notification event set or flags */
vir_clicks vlo, vhi; /* virtual clicks containing message to send */ vir_clicks vlo, vhi; /* virtual clicks containing message to send */
#if 1 #if 1
if (caller_ptr->p_rts_flags & SLOT_FREE) if (RTS_ISSET(caller_ptr, SLOT_FREE))
{ {
kprintf("called by the dead?!?\n"); kprintf("called by the dead?!?\n");
return EINVAL; 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 /* Check whether the last process in the chain has a dependency. If it
* has not, the cycle cannot be closed and we are done. * 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; if(xp->p_getfrom_e == ANY) src_dst = ANY;
else okendpt(xp->p_getfrom_e, &src_dst); 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); okendpt(xp->p_sendto_e, &src_dst);
} else { } else {
return(0); /* not a deadlock */ return(0); /* not a deadlock */
@ -289,23 +289,22 @@ unsigned flags; /* system call flags */
dst_p = _ENDPOINT_P(dst_e); dst_p = _ENDPOINT_P(dst_e);
dst_ptr = proc_addr(dst_p); 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 /* Check if 'dst' is blocked waiting for this message. The destination's
* SENDING flag may be set when its SENDREC call blocked while sending. * 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 == ANY
|| dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) { || dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) {
/* Destination is indeed waiting for this message. */ /* Destination is indeed waiting for this message. */
CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr, CopyMess(caller_ptr->p_nr, caller_ptr, m_ptr, dst_ptr,
dst_ptr->p_messbuf); 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)) { } else if ( ! (flags & NON_BLOCKING)) {
/* Destination is not waiting. Block and dequeue caller. */ /* Destination is not waiting. Block and dequeue caller. */
caller_ptr->p_messbuf = m_ptr; caller_ptr->p_messbuf = m_ptr;
if (caller_ptr->p_rts_flags == 0) dequeue(caller_ptr); RTS_SET(caller_ptr, SENDING);
caller_ptr->p_rts_flags |= SENDING;
caller_ptr->p_sendto_e = dst_e; caller_ptr->p_sendto_e = dst_e;
/* Process is now blocked. Put in on the destination's queue. */ /* Process is now blocked. Put in on the destination's queue. */
@ -344,7 +343,7 @@ unsigned flags; /* system call flags */
else else
{ {
okendpt(src_e, &src_p); 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 * The caller's SENDING flag may be set if SENDREC couldn't send. If it is
* set, the process should be blocked. * 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. */ /* Check if there are pending notifications, except for SENDREC. */
if (! (caller_ptr->p_misc_flags & REPLY_PENDING)) { if (! (caller_ptr->p_misc_flags & REPLY_PENDING)) {
@ -386,7 +385,7 @@ unsigned flags; /* system call flags */
while (*xpp != NIL_PROC) { while (*xpp != NIL_PROC) {
if (src_e == ANY || src_p == proc_nr(*xpp)) { if (src_e == ANY || src_p == proc_nr(*xpp)) {
#if 1 #if 1
if ((*xpp)->p_rts_flags & SLOT_FREE) if (RTS_ISSET(*xpp, SLOT_FREE))
{ {
kprintf("listening to the dead?!?\n"); kprintf("listening to the dead?!?\n");
return EINVAL; return EINVAL;
@ -395,7 +394,7 @@ unsigned flags; /* system call flags */
/* Found acceptable message. Copy it and update status. */ /* Found acceptable message. Copy it and update status. */
CopyMess((*xpp)->p_nr, *xpp, (*xpp)->p_messbuf, caller_ptr, m_ptr); 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 */ *xpp = (*xpp)->p_q_link; /* remove from queue */
return(OK); /* report success */ return(OK); /* report success */
} }
@ -409,8 +408,7 @@ unsigned flags; /* system call flags */
if ( ! (flags & NON_BLOCKING)) { if ( ! (flags & NON_BLOCKING)) {
caller_ptr->p_getfrom_e = src_e; caller_ptr->p_getfrom_e = src_e;
caller_ptr->p_messbuf = m_ptr; caller_ptr->p_messbuf = m_ptr;
if (caller_ptr->p_rts_flags == 0) dequeue(caller_ptr); RTS_SET(caller_ptr, RECEIVING);
caller_ptr->p_rts_flags |= RECEIVING;
return(OK); return(OK);
} else { } else {
return(ENOTREADY); 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 /* Check to see if target is blocked waiting for this message. A process
* can be both sending and receiving during a SENDREC system call. * 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_misc_flags & REPLY_PENDING) &&
(dst_ptr->p_getfrom_e == ANY || (dst_ptr->p_getfrom_e == ANY ||
dst_ptr->p_getfrom_e == caller_ptr->p_endpoint)) { 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); BuildMess(&m, proc_nr(caller_ptr), dst_ptr);
CopyMess(proc_nr(caller_ptr), proc_addr(HARDWARE), &m, CopyMess(proc_nr(caller_ptr), proc_addr(HARDWARE), &m,
dst_ptr, dst_ptr->p_messbuf); dst_ptr, dst_ptr->p_messbuf);
dst_ptr->p_rts_flags &= ~RECEIVING; /* deblock destination */ RTS_UNSET(dst_ptr, RECEIVING);
if (dst_ptr->p_rts_flags == 0) enqueue(dst_ptr);
return(OK); return(OK);
} }

View file

@ -12,7 +12,7 @@
#include <minix/com.h> #include <minix/com.h>
#include "const.h" #include "const.h"
#include "priv.h" #include "priv.h"
struct proc { struct proc {
struct stackframe_s p_reg; /* process' registers saved in stack frame */ struct stackframe_s p_reg; /* process' registers saved in stack frame */
struct segframe p_seg; /* segment descriptors */ struct segframe p_seg; /* segment descriptors */
@ -60,6 +60,50 @@ struct proc {
#define NO_PRIV 0x80 /* keep forked system process from running */ #define NO_PRIV 0x80 /* keep forked system process from running */
#define NO_ENDPOINT 0x100 /* process cannot send or receive messages */ #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 */ /* Misc flags */
#define REPLY_PENDING 0x01 /* reply to IPC_REQUEST is pending */ #define REPLY_PENDING 0x01 /* reply to IPC_REQUEST is pending */
#define MF_VM 0x08 /* process uses VM */ #define MF_VM 0x08 /* process uses VM */

View file

@ -30,6 +30,7 @@
#include "debug.h" #include "debug.h"
#include "kernel.h" #include "kernel.h"
#include "system.h" #include "system.h"
#include "proc.h"
#include <stdlib.h> #include <stdlib.h>
#include <signal.h> #include <signal.h>
#include <unistd.h> #include <unistd.h>
@ -67,8 +68,9 @@ PUBLIC void sys_task()
initialize(); initialize();
while (TRUE) { while (TRUE) {
int r;
/* Get work. Block and wait until a request message arrives. */ /* 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; sys_call_code = (unsigned) m.m_type;
call_nr = sys_call_code - KERNEL_CALL; call_nr = sys_call_code - KERNEL_CALL;
who_e = m.m_source; who_e = m.m_source;
@ -216,7 +218,8 @@ int proc_type; /* system or user process flag */
} else { } else {
rc->p_priv = &priv[USER_PRIV_ID]; /* use shared slot */ 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_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); return(OK);
} }
@ -292,9 +295,8 @@ int sig_nr; /* signal to be sent, 1 to _NSIG */
rp = proc_addr(proc_nr); rp = proc_addr(proc_nr);
if (! sigismember(&rp->p_pending, sig_nr)) { if (! sigismember(&rp->p_pending, sig_nr)) {
sigaddset(&rp->p_pending, sig_nr); sigaddset(&rp->p_pending, sig_nr);
if (! (rp->p_rts_flags & SIGNALED)) { /* other pending */ if (! (RTS_ISSET(rp, SIGNALED))) { /* other pending */
if (rp->p_rts_flags == 0) lock_dequeue(rp); /* make not ready */ RTS_LOCK_SET(rp, SIGNALED | SIG_PENDING);
rp->p_rts_flags |= SIGNALED | SIG_PENDING; /* update flags */
send_sig(PM_PROC_NR, SIGKSIG); 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)); if(isemptyp(rc)) panic("clear_proc: empty process", proc_nr(rc));
/* Make sure that the exiting process is no longer scheduled. */ /* Make sure that the exiting process is no longer scheduled. */
if (rc->p_rts_flags == 0) lock_dequeue(rc); RTS_LOCK_SET(rc, NO_ENDPOINT);
rc->p_rts_flags |= NO_ENDPOINT;
/* If the process happens to be queued trying to send a /* If the process happens to be queued trying to send a
* message, then it must be removed from the message queues. * message, then it must be removed from the message queues.
*/ */
if (rc->p_rts_flags & SENDING) { if (RTS_ISSET(rc, SENDING)) {
int target_proc; int target_proc;
okendpt(rc->p_sendto_e, &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); unset_sys_bit(priv(rp)->s_notify_pending, priv(rc)->s_id);
/* Check if process is receiving from exiting process. */ /* 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_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 #if DEBUG_ENABLE_IPC_WARNINGS
kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc)); kprintf("Proc %d receive dead src %d\n", proc_nr(rp), proc_nr(rc));
#endif #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_reg.retreg = EDSTDIED; /* report destination died */
rp->p_rts_flags &= ~SENDING; /* no longer sending */ RTS_LOCK_UNSET(rp, SENDING);
#if DEBUG_ENABLE_IPC_WARNINGS #if DEBUG_ENABLE_IPC_WARNINGS
kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc)); kprintf("Proc %d send dead dst %d\n", proc_nr(rp), proc_nr(rc));
#endif #endif
if (rp->p_rts_flags == 0) lock_enqueue(rp);/* let process run again */
} }
} }
} }

View file

@ -31,12 +31,11 @@ message *m_ptr; /* pointer to request message */
return EINVAL; return EINVAL;
rp = proc_addr(proc); 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? */ /* PM has finished one kernel signal. Perhaps process is ready now? */
if (! (rp->p_rts_flags & SIGNALED)) /* new signal arrived */ if (!RTS_ISSET(rp, SIGNALED)) /* new signal arrived */
if ((rp->p_rts_flags &= ~SIG_PENDING)==0) /* remove pending flag */ RTS_LOCK_UNSET(rp, SIG_PENDING); /* remove pending flag */
lock_enqueue(rp); /* ready if no flags */
return(OK); return(OK);
} }

View 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])); (LDT_SIZE - EXTRA_LDT_INDEX) * sizeof(rp->p_seg.p_ldt[0]));
#endif #endif
rp->p_reg.pc = (reg_t) m_ptr->PR_IP_PTR; /* set pc */ 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 */ RTS_LOCK_UNSET(rp, RECEIVING); /* PM does not reply to EXEC call */
if (rp->p_rts_flags == 0) lock_enqueue(rp);
/* Save command name for debugging, ps(1) output, etc. */ /* Save command name for debugging, ps(1) output, etc. */
phys_name = numap_local(who_p, (vir_bytes) m_ptr->PR_NAME_PTR, phys_name = numap_local(who_p, (vir_bytes) m_ptr->PR_NAME_PTR,
(vir_bytes) P_NAME_LEN - 1); (vir_bytes) P_NAME_LEN - 1);

View file

@ -52,7 +52,6 @@ register struct proc *rc; /* slot of process to clean up */
register struct proc **xpp; /* iterate over caller queue */ register struct proc **xpp; /* iterate over caller queue */
int i; int i;
int sys_id; int sys_id;
char saved_rts_flags;
/* Don't clear if already cleared. */ /* Don't clear if already cleared. */
if(isemptyp(rc)) return; 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. */ /* Turn off any alarm timers at the clock. */
reset_timer(&priv(rc)->s_alarm_timer); reset_timer(&priv(rc)->s_alarm_timer);
/* Make sure that the exiting process is no longer scheduled. */ /* Make sure that the exiting process is no longer scheduled,
if (rc->p_rts_flags == 0) lock_dequeue(rc); * and mark slot as FREE.
*/
RTS_LOCK_SETFLAGS(rc, SLOT_FREE);
/* Check the table with IRQ hooks to see if hooks should be released. */ /* Check the table with IRQ hooks to see if hooks should be released. */
for (i=0; i < NR_IRQ_HOOKS; i++) { 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 * this point. All important fields are reinitialized when the
* slots are assigned to another, new process. * 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; if (priv(rc)->s_flags & SYS_PROC) priv(rc)->s_proc_nr = NONE;
/* Clean up virtual memory */ /* Clean up virtual memory */

View file

@ -26,7 +26,7 @@ register message *m_ptr; /* pointer to request message */
register struct proc *rpc; /* child process pointer */ register struct proc *rpc; /* child process pointer */
struct proc *rpp; /* parent process pointer */ struct proc *rpp; /* parent process pointer */
struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */ struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */
int i, gen; int i, gen, r;
int p_proc; int p_proc;
if(!isokendpt(m_ptr->PR_ENDPT, &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_nr = m_ptr->PR_SLOT; /* this was obliterated by copy */
rpc->p_endpoint = _ENDPOINT(gen, rpc->p_nr); /* new endpoint of slot */ 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_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_user_time = 0; /* set all the accounting times to 0 */
rpc->p_sys_time = 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; m_ptr->PR_ENDPT = rpc->p_endpoint;
/* Install new map */ /* 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 */ #endif /* USE_FORK */

View file

@ -29,12 +29,12 @@ message *m_ptr; /* pointer to request message */
/* Find the next process with pending signals. */ /* Find the next process with pending signals. */
for (rp = BEG_USER_ADDR; rp < END_PROC_ADDR; rp++) { 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 */ /* store signaled process' endpoint */
m_ptr->SIG_ENDPT = rp->p_endpoint; m_ptr->SIG_ENDPT = rp->p_endpoint;
m_ptr->SIG_MAP = rp->p_pending; /* pending signals map */ m_ptr->SIG_MAP = rp->p_pending; /* pending signals map */
sigemptyset(&rp->p_pending); /* ball is in PM's court */ 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); return(OK);
} }
} }

View file

@ -20,7 +20,6 @@ message *m_ptr; /* pointer to request message */
register struct proc *rp; /* process whose map is to be loaded */ register struct proc *rp; /* process whose map is to be loaded */
struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */ struct mem_map *map_ptr; /* virtual address of map inside caller (PM) */
phys_bytes src_phys; /* physical address of map at the PM */ phys_bytes src_phys; /* physical address of map at the PM */
int old_flags; /* value of flags before modification */
int proc; int proc;
map_ptr = (struct mem_map *) m_ptr->PR_MEM_PTR; 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. */ /* Fetch the memory map from PM. */
phys_bytes src_phys; /* physical address of map at the PM */ phys_bytes src_phys; /* physical address of map at the PM */
int old_flags; /* value of flags before modification */
int proc; int proc;
/* Copy the map from PM. */ /* 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)); (phys_bytes)sizeof(rp->p_memmap));
alloc_segments(rp); 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); return(OK);
} }

View file

@ -28,10 +28,8 @@ PUBLIC int do_nice(message *m_ptr)
rp = proc_addr(proc_nr); rp = proc_addr(proc_nr);
if (pri == PRIO_STOP) { if (pri == PRIO_STOP) {
/* Take process off the scheduling queues. */ /* Take process off the scheduling queues. */
if(rp->p_rts_flags == 0) lock_dequeue(rp); RTS_LOCK_SET(rp, NO_PRIORITY);
rp->p_rts_flags |= NO_PRIORITY;
return(OK); return(OK);
} }
else if (pri >= PRIO_MIN && pri <= PRIO_MAX) { 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. /* Make sure the process is not running while changing its priority.
* Put the process back in its new queue if it is runnable. * Put the process back in its new queue if it is runnable.
*/ */
if(rp->p_rts_flags == 0) lock_dequeue(rp); RTS_LOCK_SET(rp, NO_PRIORITY);
rp->p_rts_flags &= ~NO_PRIORITY;
rp->p_max_priority = rp->p_priority = new_q; 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); return(OK);
} }

View file

@ -28,7 +28,6 @@ message *m_ptr; /* pointer to request message */
register struct priv *sp; register struct priv *sp;
int proc_nr; int proc_nr;
int priv_id; int priv_id;
int old_flags;
int i; int i;
phys_bytes caller_phys, kernel_phys; phys_bytes caller_phys, kernel_phys;
struct io_range io_range; struct io_range io_range;
@ -49,7 +48,7 @@ message *m_ptr; /* pointer to request message */
switch(m_ptr->CTL_REQUEST) switch(m_ptr->CTL_REQUEST)
{ {
case SYS_PRIV_INIT: 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 /* Make sure this process has its own privileges structure. This may
* fail, since there are only a limited number of system processes. * 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. */ /* Done. Privileges have been set. Allow process to run again. */
old_flags = rp->p_rts_flags; /* save value of the flags */ RTS_LOCK_UNSET(rp, NO_PRIV);
rp->p_rts_flags &= ~NO_PRIV;
if (old_flags != 0 && rp->p_rts_flags == 0) lock_enqueue(rp);
return(OK); return(OK);
case SYS_PRIV_USER: case SYS_PRIV_USER:
if (! (rp->p_rts_flags & NO_PRIV)) return(EPERM); /* Make this process an ordinary user process. */
if (!RTS_ISSET(rp, NO_PRIV)) return(EPERM);
/* Make this process an ordinary user process.
*/
if ((i=get_priv(rp, 0)) != OK) return(i); if ((i=get_priv(rp, 0)) != OK) return(i);
RTS_LOCK_UNSET(rp, NO_PRIV);
/* 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);
return(OK); return(OK);
case SYS_PRIV_ADD_IO: case SYS_PRIV_ADD_IO:
if (rp->p_rts_flags & NO_PRIV) if (RTS_ISSET(rp, NO_PRIV))
return(EPERM); return(EPERM);
/* Only system processes get I/O resources? */ /* Only system processes get I/O resources? */
@ -180,7 +171,7 @@ message *m_ptr; /* pointer to request message */
return OK; return OK;
case SYS_PRIV_ADD_MEM: case SYS_PRIV_ADD_MEM:
if (rp->p_rts_flags & NO_PRIV) if (RTS_ISSET(rp, NO_PRIV))
return(EPERM); return(EPERM);
/* Only system processes get memory resources? */ /* Only system processes get memory resources? */
@ -208,7 +199,7 @@ message *m_ptr; /* pointer to request message */
return OK; return OK;
case SYS_PRIV_ADD_IRQ: case SYS_PRIV_ADD_IRQ:
if (rp->p_rts_flags & NO_PRIV) if (RTS_ISSET(rp, NO_PRIV))
return(EPERM); return(EPERM);
/* Only system processes get IRQs? */ /* Only system processes get IRQs? */

View 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 * EINVAL for grant-out-of-range, in case this turns out to be
* interesting information.) * 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) { priv(granter_proc)->s_grant_table < 1) {
kprintf("grant verify failed in ep %d proc %d: " kprintf("grant verify failed in ep %d proc %d: "
"no priv table, or no grant table\n", "no priv table, or no grant table\n",

View file

@ -22,7 +22,7 @@ message *m_ptr;
rp = proc_addr(who_p); rp = proc_addr(who_p);
/* Copy grant table set in priv. struct. */ /* 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; r = EPERM;
} else { } else {
_K_SET_GRANT_TABLE(rp, _K_SET_GRANT_TABLE(rp,

View file

@ -93,10 +93,10 @@ message *m_ptr; /* pointer to request message */
rp->p_reg.pc = (reg_t) smsg.sm_sighandler; rp->p_reg.pc = (reg_t) smsg.sm_sighandler;
/* Reschedule if necessary. */ /* Reschedule if necessary. */
if(rp->p_rts_flags & NO_PRIORITY) { if(RTS_ISSET(rp, NO_PRIORITY))
rp->p_rts_flags &= ~NO_PRIORITY; RTS_LOCK_UNSET(rp, NO_PRIORITY);
if (rp->p_rts_flags == 0) lock_enqueue(rp); else
} else kprintf("system: warning: sigsend a running process\n"); kprintf("system: warning: sigsend a running process\n");
return(OK); return(OK);
} }

View file

@ -55,8 +55,7 @@ register message *m_ptr;
if (isemptyp(rp)) return(EIO); if (isemptyp(rp)) return(EIO);
switch (tr_request) { switch (tr_request) {
case T_STOP: /* stop process */ case T_STOP: /* stop process */
if (rp->p_rts_flags == 0) lock_dequeue(rp); RTS_LOCK_SET(rp, P_STOP);
rp->p_rts_flags |= P_STOP;
rp->p_reg.psw &= ~TRACEBIT; /* clear trace bit */ rp->p_reg.psw &= ~TRACEBIT; /* clear trace bit */
return(OK); return(OK);
@ -126,15 +125,13 @@ register message *m_ptr;
break; break;
case T_RESUME: /* resume execution */ case T_RESUME: /* resume execution */
rp->p_rts_flags &= ~P_STOP; RTS_LOCK_UNSET(rp, P_STOP);
if (rp->p_rts_flags == 0) lock_enqueue(rp);
m_ptr->CTL_DATA = 0; m_ptr->CTL_DATA = 0;
break; break;
case T_STEP: /* set trace bit */ case T_STEP: /* set trace bit */
rp->p_reg.psw |= TRACEBIT; rp->p_reg.psw |= TRACEBIT;
rp->p_rts_flags &= ~P_STOP; RTS_LOCK_UNSET(rp, P_STOP);
if (rp->p_rts_flags == 0) lock_enqueue(rp);
m_ptr->CTL_DATA = 0; m_ptr->CTL_DATA = 0;
break; break;

View file

@ -137,24 +137,6 @@ PUBLIC void irqtab_dmp()
struct irq_hook irq_hooks[NR_IRQ_HOOKS]; struct irq_hook irq_hooks[NR_IRQ_HOOKS];
int irq_actids[NR_IRQ_VECTORS]; int irq_actids[NR_IRQ_VECTORS];
struct irq_hook *e; /* irq tab entry */ 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) { if ((r = sys_getirqhooks(irq_hooks)) != OK) {
report("IS","warning: couldn't get copy of irq hooks", r); report("IS","warning: couldn't get copy of irq hooks", r);
@ -173,7 +155,7 @@ PUBLIC void irqtab_dmp()
#endif #endif
printf("IRQ policies dump shows use of kernel's IRQ hooks.\n"); 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++) { for (i=0; i<NR_IRQ_HOOKS; i++) {
e = &irq_hooks[i]; e = &irq_hooks[i];
printf("%3d", i); printf("%3d", i);
@ -182,7 +164,7 @@ PUBLIC void irqtab_dmp()
continue; continue;
} }
printf("%10d ", e->proc_nr_e); 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(" %s", (e->policy & IRQ_REENABLE) ? "reenable" : " - ");
printf(" %d", e->notify_id); printf(" %d", e->notify_id);
if (irq_actids[e->irq] & (1 << i)) if (irq_actids[e->irq] & (1 << i))

View file

@ -33,7 +33,7 @@ EXTERN int SELF_E;
EXTERN struct inode *chroot_dir; EXTERN struct inode *chroot_dir;
EXTERN short path_processed; /* number of characters processed */ 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 char *vfs_slink_storage;
EXTERN int symloop; EXTERN int symloop;

View file

@ -586,6 +586,7 @@ off_t newsize; /* inode must become this size */
/* Next correct the inode size. */ /* Next correct the inode size. */
if(!waspipe) rip->i_size = newsize; if(!waspipe) rip->i_size = newsize;
else wipe_inode(rip); /* Pipes can only be truncated to 0. */ else wipe_inode(rip); /* Pipes can only be truncated to 0. */
rip->i_update |= CTIME | MTIME;
rip->i_dirt = DIRTY; rip->i_dirt = DIRTY;
return OK; 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 ++) for(p = nextblock(start, zone_size)/zone_size; p < e; p ++)
write_map(rip, p*zone_size, NO_ZONE, WMAP_FREE); write_map(rip, p*zone_size, NO_ZONE, WMAP_FREE);
rip->i_update |= CTIME | MTIME;
rip->i_dirt = DIRTY;
return OK; return OK;
} }

View file

@ -91,6 +91,8 @@ printf("MFS(%d) get_inode by open() failed\n", SELF_E);
case I_REGULAR: case I_REGULAR:
/* Truncate regular file if O_TRUNC. */ /* Truncate regular file if O_TRUNC. */
if (oflags & O_TRUNC) { if (oflags & O_TRUNC) {
panic(__FILE__, "O_TRUNC in mfs.", oflags);
#if 0
if ((r = forbidden(rip, W_BIT)) !=OK) break; if ((r = forbidden(rip, W_BIT)) !=OK) break;
truncate_inode(rip, 0); truncate_inode(rip, 0);
wipe_inode(rip); wipe_inode(rip);
@ -99,6 +101,7 @@ printf("MFS(%d) get_inode by open() failed\n", SELF_E);
* cache flush. * cache flush.
*/ */
rw_inode(rip, WRITING); rw_inode(rip, WRITING);
#endif
} }
break; break;

View file

@ -43,7 +43,7 @@ PUBLIC int lookup()
/* Check length. */ /* Check length. */
len = fs_m_in.REQ_PATH_LEN; 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 */ if(len < 1) return EINVAL; /* too small for \0 */
/* Copy the pathname and set up caller's user and group id */ /* 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. */ /* 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; return EINVAL;
}
caller_uid = fs_m_in.REQ_UID; caller_uid = fs_m_in.REQ_UID;
caller_gid = fs_m_in.REQ_GID; caller_gid = fs_m_in.REQ_GID;

View file

@ -50,6 +50,9 @@ printf("MFS(%d) get_inode by fs_chmod() failed\n", SELF_E);
rip->i_update |= CTIME; rip->i_update |= CTIME;
rip->i_dirt = DIRTY; rip->i_dirt = DIRTY;
/* Return full new mode to caller. */
fs_m_out.RES_MODE = rip->i_mode;
put_inode(rip); put_inode(rip);
return(OK); return(OK);
} }
@ -94,7 +97,11 @@ printf("MFS(%d) get_inode by fs_chown() failed\n", SELF_E);
rip->i_dirt = DIRTY; 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); put_inode(rip);
return(r); return(r);
} }

View file

@ -142,8 +142,8 @@ PUBLIC void dev_status(message *m)
if(endpt == NONE) { if(endpt == NONE) {
printf("FS: proc with " printf("FS: proc with "
"grant %d from %d not found (revive)\n", "grant %d from %d not found (revive)\n",
st.m_source, st.REP_IO_GRANT,
st.REP_IO_GRANT); st.m_source);
continue; continue;
} }
} }

View file

@ -3,13 +3,14 @@
* The entry points into this file are * The entry points into this file are
* get_fd: look for free file descriptor and free filp slots * get_fd: look for free file descriptor and free filp slots
* get_filp: look up the filp entry for a given file descriptor * 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() * inval_filp: invalidate a filp and associated fd's, only let close()
* happen on it * happen on it
*/ */
#include <sys/select.h> #include <sys/select.h>
#include <minix/u64.h> #include <minix/u64.h>
#include <assert.h>
#include "fs.h" #include "fs.h"
#include "file.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 struct filp *f;
register int i; 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. */ /* Search the fproc fp_filp table for a free file descriptor. */
for (i = start; i < OPEN_MAX; i++) { for (i = start; i < OPEN_MAX; i++) {
if (fp->fp_filp[i] == NIL_FILP && !FD_ISSET(i, &fp->fp_filp_inuse)) { 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. */ /* 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. */ /* Now that a file descriptor has been found, look for a free filp slot. */
for (f = &filp[0]; f < &filp[NR_FILPS]; f++) { for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
assert(f->filp_count >= 0);
if (f->filp_count == 0) { if (f->filp_count == 0) {
f->filp_mode = bits; f->filp_mode = bits;
f->filp_pos = cvu64(0); 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) 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 * 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 * 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). * 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++) { for (f = &filp[0]; f < &filp[NR_FILPS]; f++) {
if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){ if (f->filp_count != 0 && f->filp_vno == vp && (f->filp_mode & bits)){
assert(f->filp_count > 0);
return(f); return(f);
} }
} }

View file

@ -24,7 +24,7 @@ EXTERN int who_p, who_e; /* caller's proc number, endpoint */
EXTERN int call_nr; /* system call number */ EXTERN int call_nr; /* system call number */
EXTERN message mount_m_in; /* the input message itself */ 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 */ EXTERN short cum_path_processed; /* number of characters processed */
/* The following variables are used for returning results to the caller. */ /* The following variables are used for returning results to the caller. */

View file

@ -133,6 +133,8 @@ PUBLIC int main()
panic(__FILE__, "check_vrefs failed at line", __LINE__); panic(__FILE__, "check_vrefs failed at line", __LINE__);
} }
#endif #endif
} }
return(OK); /* shouldn't come here */ return(OK); /* shouldn't come here */
} }
@ -170,9 +172,10 @@ PRIVATE void get_work()
} }
for(;;) { for(;;) {
int r;
/* Normal case. No one to revive. */ /* Normal case. No one to revive. */
if (receive(ANY, &m_in) != OK) if ((r=receive(ANY, &m_in)) != OK)
panic(__FILE__,"fs receive error", NO_NUM); panic(__FILE__,"fs receive error", r);
who_e = m_in.m_source; who_e = m_in.m_source;
who_p = _ENDPOINT_P(who_e); who_p = _ENDPOINT_P(who_e);

View file

@ -491,7 +491,6 @@ Dev_t dev;
} }
if (count > 1) { if (count > 1) {
printf("VFSunmount: %d filesystem is busy count: %d\n", dev, count);
return(EBUSY); /* can't umount a busy file system */ return(EBUSY); /* can't umount a busy file system */
} }

View file

@ -26,6 +26,7 @@
#include "lock.h" #include "lock.h"
#include "param.h" #include "param.h"
#include <dirent.h> #include <dirent.h>
#include <assert.h>
#include <minix/vfsif.h> #include <minix/vfsif.h>
#include "vnode.h" #include "vnode.h"
@ -117,10 +118,6 @@ PRIVATE int common_open(register int oflags, mode_t omode)
vp= NULL; vp= NULL;
#if 0
printf("common_open: for '%s'\n", user_fullpath);
#endif
/* Fill in lookup request fields */ /* Fill in lookup request fields */
Xlookup_req.path = user_fullpath; Xlookup_req.path = user_fullpath;
Xlookup_req.lastc = Xlastc; Xlookup_req.lastc = Xlastc;
@ -146,11 +143,18 @@ PRIVATE int common_open(register int oflags, mode_t omode)
{ {
if (pathrem == NULL) if (pathrem == NULL)
panic(__FILE__, "no pathrem", NO_NUM); 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; r= OK;
else else
{ {
printf("common_open: / in pathrem\n"); printf("common_open: / in pathrem\n");
}
} }
} }
@ -278,8 +282,6 @@ PRIVATE int common_open(register int oflags, mode_t omode)
break; break;
case I_NAMED_PIPE: 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_pipe = I_PIPE;
vp->v_isfifo= TRUE; vp->v_isfifo= TRUE;
oflags |= O_APPEND; /* force append mode */ 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. * file position will be automatically shared.
*/ */
b = (bits & R_BIT ? R_BIT : W_BIT); b = (bits & R_BIT ? R_BIT : W_BIT);
assert(fil_ptr->filp_count == 1);
fil_ptr->filp_count = 0; /* don't find self */ fil_ptr->filp_count = 0; /* don't find self */
if ((filp2 = find_filp(vp, b)) != NIL_FILP) { if ((filp2 = find_filp(vp, b)) != NIL_FILP) {
/* Co-reader or writer found. Use it.*/ /* Co-reader or writer found. Use it.*/
@ -428,15 +431,10 @@ struct vnode **vpp;
break; break;
case I_NAMED_PIPE: 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) if (vp->v_ref_count == 1)
{ {
printf("x_open (fifo): first reference, size %u\n",
vp->v_size);
if (vp->v_size != 0) if (vp->v_size != 0)
{ {
printf("x_open (fifo): clearing\n");
r= truncate_vn(vp, 0); r= truncate_vn(vp, 0);
if (r != OK) if (r != OK)
{ {
@ -465,8 +463,6 @@ PRIVATE int pipe_open(register struct vnode *vp, register mode_t bits,
* processes hanging on the pipe. * 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; vp->v_pipe = I_PIPE;
if((bits & (R_BIT|W_BIT)) == (R_BIT|W_BIT)) { 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 a write has been done, the inode is already marked as DIRTY. */
if (--rfilp->filp_count == 0) { 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) { if (vp->v_pipe == I_PIPE && vp->v_ref_count > 1) {
/* Save the file position in the v-node in case needed later. /* Save the file position in the v-node in case needed later.
* The read and write positions are saved separately. * The read and write positions are saved separately.

View file

@ -43,6 +43,7 @@ node_details_t *node;
/* Empty (start) path? */ /* Empty (start) path? */
if (fullpath[0] == '\0') { if (fullpath[0] == '\0') {
node->inode_nr = 0;
return ENOENT; return ENOENT;
} }
@ -178,6 +179,8 @@ char **pathrem;
/* Empty (start) path? */ /* Empty (start) path? */
if (fullpath[0] == '\0') { if (fullpath[0] == '\0') {
node->inode_nr = 0;
*pathrem = fullpath;
return ENOENT; return ENOENT;
} }
@ -314,7 +317,7 @@ struct vnode **vpp;
if (res.inode_nr == 0) if (res.inode_nr == 0)
{ {
printf("lookup_vp: lookup returned no inode\n"); 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); lookup_res, lookup_req->lastc);
*vpp= NULL; *vpp= NULL;
return lookup_res; return lookup_res;
@ -386,7 +389,7 @@ char **pathrem;
if (res.inode_nr == 0) if (res.inode_nr == 0)
{ {
printf("Xlookup_vp: lookup returned no inode\n"); 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); lookup_res, lookup_req->lastc);
*vpp= NULL; *vpp= NULL;
return lookup_res; return lookup_res;

View file

@ -34,7 +34,8 @@ PUBLIC int do_chmod()
struct chmod_req req; struct chmod_req req;
struct lookup_req lookup_req; struct lookup_req lookup_req;
struct node_details res; struct node_details res;
int r; struct vnode *vp;
int r, ch_mode;
if (call_nr == CHMOD) { if (call_nr == CHMOD) {
/* Perform the chmod(name, mode) system call. */ /* 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); 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.*/ /* Fill in request message fields.*/
req.uid = fp->fp_effuid; req.uid = fp->fp_effuid;
req.gid = fp->fp_effgid; req.gid = fp->fp_effgid;
req.rmode = m_in.mode; req.rmode = m_in.mode;
/* Issue request */ /* 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 chown_req req;
struct lookup_req lookup_req; struct lookup_req lookup_req;
struct node_details res; struct node_details res;
int r; struct vnode *vp;
int r, ch_mode;
if (call_nr == CHOWN) { if (call_nr == CHOWN) {
/* Perform the chmod(name, mode) system call. */ /* 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); 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.*/ /* Fill in request message fields.*/
req.uid = fp->fp_effuid; req.uid = fp->fp_effuid;
req.gid = fp->fp_effgid; req.gid = fp->fp_effgid;
@ -109,7 +122,15 @@ PUBLIC int do_chown()
req.newgid = m_in.group; req.newgid = m_in.group;
/* Issue request */ /* 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. */ /* If access desired is not a subset of what is allowed, it is refused. */
r = OK; 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 /* Check to see if someone is trying to write on a file system that is
* mounted read-only. * mounted read-only.

View file

@ -133,7 +133,8 @@ _PROTOTYPE( int do_getdents, (void) );
_PROTOTYPE( int read_write, (int rw_flag) ); _PROTOTYPE( int read_write, (int rw_flag) );
/* request.c */ /* 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_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_open, (open_req_t *req, node_details_t *res) );
_PROTOTYPE( int req_create, (int fs_e, ino_t inode_nr, int omode, _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, _PROTOTYPE( int req_clone_opcl, (clone_opcl_req_t *req,
node_details_t *res) ); node_details_t *res) );
_PROTOTYPE( int req_ftrunc, (ftrunc_req_t *req) ); _PROTOTYPE( int req_ftrunc, (ftrunc_req_t *req) );
_PROTOTYPE( int req_chown, (chown_req_t *req) ); _PROTOTYPE( int req_chown, (chown_req_t *req, int *mode) );
_PROTOTYPE( int req_chmod, (chmod_req_t *req) ); _PROTOTYPE( int req_chmod, (chmod_req_t *req, int *mode) );
_PROTOTYPE( int req_access, (access_req_t *req) ); _PROTOTYPE( int req_access, (access_req_t *req) );
_PROTOTYPE( int req_mknod, (mknod_req_t *req) ); _PROTOTYPE( int req_mknod, (mknod_req_t *req) );
_PROTOTYPE( int req_mkdir, (mkdir_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_cancel_timer, (timer_t *tp) );
_PROTOTYPE( void fs_init_timer, (timer_t *tp) ); _PROTOTYPE( void fs_init_timer, (timer_t *tp) );

View file

@ -21,6 +21,7 @@
#include "fproc.h" #include "fproc.h"
#include "param.h" #include "param.h"
#include <dirent.h> #include <dirent.h>
#include <assert.h>
#include <minix/vfsif.h> #include <minix/vfsif.h>
#include "vnode.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. */ /* Perform read(fd, buffer, nbytes) or write(fd, buffer, nbytes) call. */
register struct filp *f; register struct filp *f;
register struct vnode *vp; register struct vnode *vp;
off_t bytes_left, f_size; off_t bytes_left;
u64_t position; u64_t position;
unsigned int off, cum_io; unsigned int off, cum_io;
int op, oflags, r, chunk, usr, seg, block_spec, char_spec; 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; oflags = f->filp_flags;
vp = f->filp_vno; vp = f->filp_vno;
f_size = vp->v_size;
r = OK; r = OK;
if (vp->v_pipe == I_PIPE) { 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))) { if ((block_spec = (mode_word == I_BLOCK_SPECIAL ? 1 : 0))) {
f_size = ULONG_MAX;
if (vp->v_sdev == NO_DEV) if (vp->v_sdev == NO_DEV)
panic(__FILE__,"read_write tries to read from " panic(__FILE__,"read_write tries to read from "
" block device NO_DEV", NO_NUM); " block device NO_DEV", NO_NUM);
@ -155,11 +154,11 @@ int rw_flag; /* READING or WRITING */
position = res.new_pos; position = res.new_pos;
cum_io += res.cum_io; cum_io += res.cum_io;
} }
/* Regular files */ /* Regular files (and pipes) */
else { else {
if (rw_flag == WRITING && block_spec == 0) { if (rw_flag == WRITING && block_spec == 0) {
/* Check for O_APPEND flag. */ /* 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. */ /* 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) 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) { if (partial_cnt > 0) {
/* So taht we don't need to deal with partial count /* So that we don't need to deal with partial count
* in the FS process */ * in the FS process.
*/
m_in.nbytes = MIN(m_in.nbytes, partial_cnt); m_in.nbytes = MIN(m_in.nbytes, partial_cnt);
partial_pipe = 1; partial_pipe = 1;
} }
@ -192,11 +192,17 @@ int rw_flag; /* READING or WRITING */
req.user_addr = m_in.buffer; req.user_addr = m_in.buffer;
req.inode_index = vp->v_index; req.inode_index = vp->v_index;
if (vp->v_isfifo) /* Truncate read request at size (mustn't do this for special files). */
{ if((rw_flag == READING) &&
printf("read_write: %s for FIFO @ %u size %u\n", cmp64ul(add64ul(position, req.num_of_bytes), vp->v_size) > 0) {
(rw_flag == READING) ? "read" : "write", /* Position always should fit in an off_t (LONG_MAX). */
ex64lo(position), m_in.nbytes); 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 */ /* Issue request */
@ -215,7 +221,7 @@ int rw_flag; /* READING or WRITING */
/* On write, update file size and access time. */ /* On write, update file size and access time. */
if (rw_flag == WRITING) { if (rw_flag == WRITING) {
if (regular || mode_word == I_DIRECTORY) { if (regular || mode_word == I_DIRECTORY) {
if (cmp64ul(position, f_size) > 0) if (cmp64ul(position, vp->v_size) > 0)
{ {
if (ex64hi(position) != 0) if (ex64hi(position) != 0)
{ {

View file

@ -28,12 +28,16 @@
#include "vnode.h" #include "vnode.h"
#include "param.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 * * 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_req_t *req;
node_details_t *res; node_details_t *res;
{ {
@ -278,10 +282,12 @@ ftrunc_req_t *req;
/*===========================================================================* /*===========================================================================*
* req_chmod * * req_chmod *
*===========================================================================*/ *===========================================================================*/
PUBLIC int req_chmod(req) PUBLIC int req_chmod(req, ch_mode)
chmod_req_t *req; chmod_req_t *req;
int *ch_mode;
{ {
message m; message m;
int r;
/* Fill in request message */ /* Fill in request message */
m.m_type = REQ_CHMOD; m.m_type = REQ_CHMOD;
@ -291,17 +297,24 @@ chmod_req_t *req;
m.REQ_GID = req->gid; m.REQ_GID = req->gid;
/* Send/rec request */ /* 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 * * req_chown *
*===========================================================================*/ *===========================================================================*/
PUBLIC int req_chown(req) PUBLIC int req_chown(req, ch_mode)
chown_req_t *req; chown_req_t *req;
int *ch_mode;
{ {
message m; message m;
int r;
/* Fill in request message */ /* Fill in request message */
m.m_type = REQ_CHOWN; m.m_type = REQ_CHOWN;
@ -312,7 +325,12 @@ chown_req_t *req;
m.REQ_NEW_GID = req->newgid; m.REQ_NEW_GID = req->newgid;
/* Send/rec request */ /* 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 * * 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. /* This is the low level function that sends requests to FS processes.
* It also handles driver recovery mechanism and reissuing the * 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; int r, old_driver_e, new_driver_e;
message origm, m; message origm, m;
struct vmnt *vmp; struct vmnt *vmp;
/* Make a copy of the request so that we can load it back in /* Make a copy of the request so that we can load it back in
* case of a dead driver */ * case of a dead driver */
origm = *reqm; origm = *reqm;
@ -972,8 +990,8 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
for (;;) { for (;;) {
/* Do the actual send, receive */ /* Do the actual send, receive */
if (OK != (r=sendrec(fs_e, reqm))) { if (OK != (r=sendrec(fs_e, reqm))) {
printf("VFS: error sending message. FS_e: %d req_nr: %d err: %d\n", printf("VFS:fs_sendrec:%s:%d: error sending message. FS_e: %d req_nr: %d err: %d\n",
fs_e, reqm->m_type, r); file, line, fs_e, reqm->m_type, r);
} }
if(r == OK) { if(r == OK) {
@ -984,9 +1002,9 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
/* Dead driver */ /* Dead driver */
if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) { if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
old_driver_e = NONE; old_driver_e = NONE;
/* Find old driver enpoint */ /* Find old driver by endpoint */
for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) { 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; old_driver_e = vmp->m_driver_e;
dmap_unmap_by_endpt(old_driver_e); /* unmap driver */ dmap_unmap_by_endpt(old_driver_e); /* unmap driver */
break; break;
@ -994,10 +1012,8 @@ PRIVATE int fs_sendrec(endpoint_t fs_e, message *reqm)
} }
/* No FS ?? */ /* No FS ?? */
if (old_driver_e == NONE) { if (old_driver_e == NONE)
panic(__FILE__, "VFSdead_driver: couldn't find FS\n", panic(__FILE__, "VFSdead_driver: couldn't find FS\n", fs_e);
old_driver_e);
}
/* Wait for a new driver. */ /* Wait for a new driver. */
for (;;) { for (;;) {

View file

@ -141,7 +141,14 @@ int len; /* length of the directory name string */
put_vnode(vp); put_vnode(vp);
return ENOTDIR; return ENOTDIR;
} }
/* Access check */
r = forbidden(vp, X_BIT);
if (r != OK) {
put_vnode(vp);
return r;
}
return change_into(iip, vp); return change_into(iip, vp);
} }

View file

@ -17,6 +17,7 @@
#include "file.h" #include "file.h"
#include "fproc.h" #include "fproc.h"
#include "param.h" #include "param.h"
#include "vmnt.h"
PRIVATE int panicking; /* inhibits recursive panics during sync */ 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; register char *rpu, *rpm;
int r; int r;
if (len > PATH_MAX) {
err_code = ENAMETOOLONG;
return(EGENERIC);
}
if(len >= sizeof(user_fullpath)) { if(len >= sizeof(user_fullpath)) {
panic(__FILE__, "fetch_name: len too much for user_fullpath", len); 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. */ /* Check name length for validity. */
if (len <= 0) { if (len <= 0) {
err_code = EINVAL; err_code = EINVAL;
return(EGENERIC); printf("vfs: fetch_name: len %d?\n", len);
}
if (len > PATH_MAX) {
err_code = ENAMETOOLONG;
return(EGENERIC); return(EGENERIC);
} }
@ -100,7 +102,7 @@ int num; /* number to go with it */
if (panicking) return; /* do not panic during a sync */ if (panicking) return; /* do not panic during a sync */
panicking = TRUE; /* prevent another panic during the 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); if (num != NO_NUM) printf("%d",num);
(void) do_sync(); /* flush everything to the disk */ (void) do_sync(); /* flush everything to the disk */
sys_exit(SELF); sys_exit(SELF);
@ -148,4 +150,3 @@ PUBLIC time_t clock_time()
return( (time_t) (boottime + (uptime/HZ))); return( (time_t) (boottime + (uptime/HZ)));
} }