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
12 #include <minix/callnr.h>
13 #include <minix/endpoint.h>
15 /* maximum nested call stack depth */
18 /* global variables stack */
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 */
30 PRIVATE
int depth
= 0; /* current globals stack level */
32 #if ENABLE_SYSCALL_STATS
33 EXTERN
unsigned long calls_stats
[NCALLS
];
36 FORWARD
_PROTOTYPE( int push_globals
, (void) );
37 FORWARD
_PROTOTYPE( void pop_globals
, (void) );
38 FORWARD
_PROTOTYPE( void set_globals
, (message
*m
) );
40 /*===========================================================================*
42 *===========================================================================*/
43 PRIVATE
int push_globals()
45 /* Save the global variables of the current call onto the globals stack.
48 if (depth
== MAX_DEPTH
)
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 */
70 /*===========================================================================*
72 *===========================================================================*/
73 PRIVATE
void pop_globals()
75 /* Restore the global variables of a call from the globals stack.
79 panic("VFS", "Popping from empty globals stack!", NO_NUM
);
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 /*===========================================================================*
96 *===========================================================================*/
97 PRIVATE
void set_globals(m
)
98 message
*m
; /* request message */
100 /* Initialize global variables based on a request message.
104 who_e
= m_in
.m_source
;
105 who_p
= _ENDPOINT_P(who_e
);
106 call_nr
= m_in
.m_type
;
108 super_user
= (fp
->fp_effuid
== SU_UID
? TRUE
: FALSE
);
109 /* the rest need not be initialized */
112 /*===========================================================================*
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.
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
);
127 /* Initialize global variables for the nested call */
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
,
137 #if ENABLE_SYSCALL_STATS
138 calls_stats
[call_nr
]++;
141 r
= (*call_vec
[call_nr
])();
144 /* Store the result, and restore original global variables */