add swifi to the build/install.
[minix.git] / servers / vfs / fscall.c
blob9550585a7e1dcc41ccef9b08372bd1e4229b974f
1 /* This file handles nested counter-request calls to VFS sent by file system
2 * (FS) servers in response to VFS requests.
4 * The entry points into this file are
5 * nested_fs_call perform a nested call from a file system server
6 */
8 #include "fs.h"
9 #include "fproc.h"
10 #include <string.h>
11 #include <assert.h>
12 #include <minix/callnr.h>
13 #include <minix/endpoint.h>
15 /* maximum nested call stack depth */
16 #define MAX_DEPTH 1
18 /* global variables stack */
19 PRIVATE struct {
20 struct fproc *g_fp; /* pointer to caller process */
21 message g_m_in; /* request message */
22 message g_m_out; /* reply message */
23 int g_who_e; /* endpoint of caller process */
24 int g_who_p; /* slot number of caller process */
25 int g_call_nr; /* call number */
26 int g_super_user; /* is the caller root? */
27 char g_user_fullpath[PATH_MAX+1]; /* path to look up */
28 } globals[MAX_DEPTH];
30 PRIVATE int depth = 0; /* current globals stack level */
32 #if ENABLE_SYSCALL_STATS
33 EXTERN unsigned long calls_stats[NCALLS];
34 #endif
36 FORWARD _PROTOTYPE( int push_globals, (void) );
37 FORWARD _PROTOTYPE( void pop_globals, (void) );
38 FORWARD _PROTOTYPE( void set_globals, (message *m) );
40 /*===========================================================================*
41 * push_globals *
42 *===========================================================================*/
43 PRIVATE int push_globals()
45 /* Save the global variables of the current call onto the globals stack.
48 if (depth == MAX_DEPTH)
49 return EPERM;
51 globals[depth].g_fp = fp;
52 globals[depth].g_m_in = m_in;
53 globals[depth].g_m_out = m_out;
54 globals[depth].g_who_e = who_e;
55 globals[depth].g_who_p = who_p;
56 globals[depth].g_call_nr = call_nr;
57 globals[depth].g_super_user = super_user;
59 /* XXX is it safe to strcpy this? */
60 assert(sizeof(globals[0].g_user_fullpath) == sizeof(user_fullpath));
61 memcpy(globals[depth].g_user_fullpath, user_fullpath, sizeof(user_fullpath));
63 /* err_code is not used across blocking calls */
65 depth++;
67 return OK;
70 /*===========================================================================*
71 * pop_globals *
72 *===========================================================================*/
73 PRIVATE void pop_globals()
75 /* Restore the global variables of a call from the globals stack.
78 if (depth == 0)
79 panic("VFS", "Popping from empty globals stack!", NO_NUM);
81 depth--;
83 fp = globals[depth].g_fp;
84 m_in = globals[depth].g_m_in;
85 m_out = globals[depth].g_m_out;
86 who_e = globals[depth].g_who_e;
87 who_p = globals[depth].g_who_p;
88 call_nr = globals[depth].g_call_nr;
89 super_user = globals[depth].g_super_user;
91 memcpy(user_fullpath, globals[depth].g_user_fullpath, sizeof(user_fullpath));
94 /*===========================================================================*
95 * set_globals *
96 *===========================================================================*/
97 PRIVATE void set_globals(m)
98 message *m; /* request message */
100 /* Initialize global variables based on a request message.
103 m_in = *m;
104 who_e = m_in.m_source;
105 who_p = _ENDPOINT_P(who_e);
106 call_nr = m_in.m_type;
107 fp = &fproc[who_p];
108 super_user = (fp->fp_effuid == SU_UID ? TRUE : FALSE);
109 /* the rest need not be initialized */
112 /*===========================================================================*
113 * nested_fs_call *
114 *===========================================================================*/
115 PUBLIC void nested_fs_call(m)
116 message *m; /* request/reply message pointer */
118 /* Handle a nested call from a file system server.
120 int r;
122 /* Save global variables of the current call */
123 if ((r = push_globals()) != OK) {
124 printf("VFS: error saving global variables in call %d from FS %d\n",
125 m->m_type, m->m_source);
126 } else {
127 /* Initialize global variables for the nested call */
128 set_globals(m);
130 /* Perform the nested call */
131 if (call_nr < 0 || call_nr >= NCALLS) {
132 printf("VFS: invalid nested call %d from FS %d\n", call_nr,
133 who_e);
135 r = ENOSYS;
136 } else {
137 #if ENABLE_SYSCALL_STATS
138 calls_stats[call_nr]++;
139 #endif
141 r = (*call_vec[call_nr])();
144 /* Store the result, and restore original global variables */
145 *m = m_out;
147 pop_globals();
150 m->m_type = r;