minix/servers/vfs/fscall.c
Ben Gras 35a108b911 panic() cleanup.
this change
   - makes panic() variadic, doing full printf() formatting -
     no more NO_NUM, and no more separate printf() statements
     needed to print extra info (or something in hex) before panicing
   - unifies panic() - same panic() name and usage for everyone -
     vm, kernel and rest have different names/syntax currently
     in order to implement their own luxuries, but no longer
   - throws out the 1st argument, to make source less noisy.
     the panic() in syslib retrieves the server name from the kernel
     so it should be clear enough who is panicing; e.g.
         panic("sigaction failed: %d", errno);
     looks like:
         at_wini(73130): panic: sigaction failed: 0
         syslib:panic.c: stacktrace: 0x74dc 0x2025 0x100a
   - throws out report() - printf() is more convenient and powerful
   - harmonizes/fixes the use of panic() - there were a few places
     that used printf-style formatting (didn't work) and newlines
     (messes up the formatting) in panic()
   - throws out a few per-server panic() functions
   - cleans up a tie-in of tty with panic()

merging printf() and panic() statements to be done incrementally.
2010-03-05 15:05:11 +00:00

152 lines
4.1 KiB
C

/* This file handles nested counter-request calls to VFS sent by file system
* (FS) servers in response to VFS requests.
*
* The entry points into this file are
* nested_fs_call perform a nested call from a file system server
*/
#include "fs.h"
#include "fproc.h"
#include <string.h>
#include <assert.h>
#include <minix/callnr.h>
#include <minix/endpoint.h>
/* maximum nested call stack depth */
#define MAX_DEPTH 1
/* global variables stack */
PRIVATE struct {
struct fproc *g_fp; /* pointer to caller process */
message g_m_in; /* request message */
message g_m_out; /* reply message */
int g_who_e; /* endpoint of caller process */
int g_who_p; /* slot number of caller process */
int g_call_nr; /* call number */
int g_super_user; /* is the caller root? */
char g_user_fullpath[PATH_MAX+1]; /* path to look up */
} globals[MAX_DEPTH];
PRIVATE int depth = 0; /* current globals stack level */
#if ENABLE_SYSCALL_STATS
EXTERN unsigned long calls_stats[NCALLS];
#endif
FORWARD _PROTOTYPE( int push_globals, (void) );
FORWARD _PROTOTYPE( void pop_globals, (void) );
FORWARD _PROTOTYPE( void set_globals, (message *m) );
/*===========================================================================*
* push_globals *
*===========================================================================*/
PRIVATE int push_globals()
{
/* Save the global variables of the current call onto the globals stack.
*/
if (depth == MAX_DEPTH)
return EPERM;
globals[depth].g_fp = fp;
globals[depth].g_m_in = m_in;
globals[depth].g_m_out = m_out;
globals[depth].g_who_e = who_e;
globals[depth].g_who_p = who_p;
globals[depth].g_call_nr = call_nr;
globals[depth].g_super_user = super_user;
/* XXX is it safe to strcpy this? */
assert(sizeof(globals[0].g_user_fullpath) == sizeof(user_fullpath));
memcpy(globals[depth].g_user_fullpath, user_fullpath, sizeof(user_fullpath));
/* err_code is not used across blocking calls */
depth++;
return OK;
}
/*===========================================================================*
* pop_globals *
*===========================================================================*/
PRIVATE void pop_globals()
{
/* Restore the global variables of a call from the globals stack.
*/
if (depth == 0)
panic("Popping from empty globals stack!");
depth--;
fp = globals[depth].g_fp;
m_in = globals[depth].g_m_in;
m_out = globals[depth].g_m_out;
who_e = globals[depth].g_who_e;
who_p = globals[depth].g_who_p;
call_nr = globals[depth].g_call_nr;
super_user = globals[depth].g_super_user;
memcpy(user_fullpath, globals[depth].g_user_fullpath, sizeof(user_fullpath));
}
/*===========================================================================*
* set_globals *
*===========================================================================*/
PRIVATE void set_globals(m)
message *m; /* request message */
{
/* Initialize global variables based on a request message.
*/
m_in = *m;
who_e = m_in.m_source;
who_p = _ENDPOINT_P(who_e);
call_nr = m_in.m_type;
fp = &fproc[who_p];
super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);
/* the rest need not be initialized */
}
/*===========================================================================*
* nested_fs_call *
*===========================================================================*/
PUBLIC void nested_fs_call(m)
message *m; /* request/reply message pointer */
{
/* Handle a nested call from a file system server.
*/
int r;
/* Save global variables of the current call */
if ((r = push_globals()) != OK) {
printf("VFS: error saving global variables in call %d from FS %d\n",
m->m_type, m->m_source);
} else {
/* Initialize global variables for the nested call */
set_globals(m);
/* Perform the nested call */
if (call_nr < 0 || call_nr >= NCALLS) {
printf("VFS: invalid nested call %d from FS %d\n", call_nr,
who_e);
r = ENOSYS;
} else {
#if ENABLE_SYSCALL_STATS
calls_stats[call_nr]++;
#endif
r = (*call_vec[call_nr])();
}
/* Store the result, and restore original global variables */
*m = m_out;
pop_globals();
}
m->m_type = r;
}