minix/servers/vfs/fscall.c
Thomas Veerman 8f55767619 VFS: make m_in job local
By making m_in job local (i.e., each job has its own copy of m_in instead
of refering to the global m_in) we don't have to store and restore m_in
on every thread yield. This reduces overhead. Moreover, remove the
assumption that m_in is preserved. Do_XXX functions have to copy the
system call parameters as soon as possible and only pass those copies to
other functions.

Furthermore, this patch cleans up some code and uses better types in a lot
of places.
2012-04-13 12:50:38 +00:00

133 lines
3.5 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
* nested_dev_call perform a nested call from a device driver server
*
*/
#include "fs.h"
#include "fproc.h"
#include <string.h>
#include <assert.h>
#include <minix/callnr.h>
#include <minix/endpoint.h>
#include <minix/vfsif.h>
/* maximum nested call stack depth */
#define MAX_DEPTH 1
/* global variables stack */
static 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]; /* path to look up */
} globals[MAX_DEPTH];
static int depth = 0; /* current globals stack level */
static int push_globals(void);
static void pop_globals(void);
static void set_globals(message *m);
/*===========================================================================*
* push_globals *
*===========================================================================*/
static 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 = job_m_in;
globals[depth].g_m_out = m_out;
globals[depth].g_super_user = super_user;
/* err_code is not used across blocking calls */
depth++;
return(OK);
}
/*===========================================================================*
* pop_globals *
*===========================================================================*/
static 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;
job_m_in = globals[depth].g_m_in;
m_out = globals[depth].g_m_out;
}
/*===========================================================================*
* set_globals *
*===========================================================================*/
static void set_globals(m)
message *m; /* request message */
{
/* Initialize global variables based on a request message.
*/
int proc_p;
m_in = *m;
proc_p = _ENDPOINT_P(m_in.m_source);
fp = &fproc[proc_p];
/* the rest need not be initialized */
}
/*===========================================================================*
* nested_fs_call *
*===========================================================================*/
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 - only getsysinfo() is allowed right now */
if (job_call_nr == COMMON_GETSYSINFO) {
r = do_getsysinfo();
} else {
printf("VFS: invalid nested call %d from FS %d\n", job_call_nr,
who_e);
r = ENOSYS;
}
/* Store the result, and restore original global variables */
*m = m_out;
pop_globals();
}
m->m_type = r;
}