In some places it was assumed that PATH_MAX does not include a terminating null character. Increases PATH_MAX to 1024 to get in sync with NetBSD. Required some rewriting in AVFS to keep memory usage low (the stack in use by a thread is very small).
		
			
				
	
	
		
			199 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			199 lines
		
	
	
		
			5.3 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 */
 | 
						|
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];	/* 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 - only getsysinfo() is allowed right now */
 | 
						|
	if (call_nr == COMMON_GETSYSINFO) {
 | 
						|
		r = do_getsysinfo();
 | 
						|
	} else {
 | 
						|
		printf("VFS: invalid nested call %d from FS %d\n", call_nr,
 | 
						|
			who_e);
 | 
						|
 | 
						|
		r = ENOSYS;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Store the result, and restore original global variables */
 | 
						|
	*m = m_out;
 | 
						|
 | 
						|
	pop_globals();
 | 
						|
  }
 | 
						|
 | 
						|
  m->m_type = r;
 | 
						|
}
 | 
						|
 | 
						|
/*===========================================================================*
 | 
						|
 *				nested_dev_call				     *
 | 
						|
 *===========================================================================*/
 | 
						|
PUBLIC void nested_dev_call(m)
 | 
						|
message *m;				/* request/reply message pointer */
 | 
						|
{
 | 
						|
/* Handle a nested call from a device driver server.
 | 
						|
 */
 | 
						|
  int r;
 | 
						|
 | 
						|
  /* Save global variables of the current call */
 | 
						|
  if ((r = push_globals()) != OK) {
 | 
						|
	printf("VFS: error saving globals in call %d from driver %d\n",
 | 
						|
		m->m_type, m->m_source);
 | 
						|
  } else {
 | 
						|
	/* Initialize global variables for the nested call */
 | 
						|
	set_globals(m);
 | 
						|
 | 
						|
	if (call_nr >= PFS_BASE) {
 | 
						|
		call_nr -= PFS_BASE;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Perform the nested call */
 | 
						|
	if (call_nr < 0 || call_nr >= PFS_NREQS) {
 | 
						|
 | 
						|
		printf("VFS: invalid nested call %d from driver %d\n",
 | 
						|
			call_nr, who_e);
 | 
						|
 | 
						|
		r = ENOSYS;
 | 
						|
	} else if (who_e == PFS_PROC_NR) {
 | 
						|
 | 
						|
		r = (*pfs_call_vec[call_nr])();
 | 
						|
	} else {
 | 
						|
 | 
						|
		printf("VFS: only the PFS device can make nested VFS calls\n");
 | 
						|
 | 
						|
		r = ENOSYS;
 | 
						|
	}
 | 
						|
 | 
						|
	/* Store the result, and restore original global variables */
 | 
						|
	*m = m_out;
 | 
						|
 | 
						|
	pop_globals();
 | 
						|
  }
 | 
						|
 | 
						|
  m->m_type = r;
 | 
						|
}
 |