* 0x1100 - 0x11FF USB
* 0x1200 - 0x12FF Devman
* 0x1300 - 0x13FF TTY Input
+ * 0x1400 - 0x14FF VFS-FS transaction IDs
*
* Zero and negative values are widely used for OK and error responses.
*/
#endif
+/*===========================================================================*
+ * VFS-FS TRANSACTION IDs *
+ *===========================================================================*/
+
+#define VFS_TRANSACTION_BASE 0x1400
+
+#define VFS_TRANSID (VFS_TRANSACTION_BASE + 1)
+#define IS_VFS_FS_TRANSID(type) (((type) & ~0xff) == VFS_TRANSACTION_BASE)
+
/* _MINIX_COM_H */
#define REQ_NEWNODE (VFS_BASE + 29)
#define REQ_RDLINK (VFS_BASE + 30)
#define REQ_GETDENTS (VFS_BASE + 31)
-#define REQ_STATVFS (VFS_BASE + 32)
+#define REQ_STATVFS (VFS_BASE + 32)
-#define NREQS 33
+#define NREQS 33
#define IS_VFS_RQ(type) (((type) & ~0xff) == VFS_BASE)
+#define TRNS_GET_ID(t) ((t) & 0xFFFF)
+#define TRNS_ADD_ID(t,id) (((t) << 16) | ((id) & 0xFFFF))
+#define TRNS_DEL_ID(t) ((short)((t) >> 16))
+
#define PFS_BASE (VFS_BASE + 100)
#define PFS_REQ_CHECK_PERMS (PFS_BASE + 1)
#include "inc.h"
FORWARD _PROTOTYPE( int get_work, (void) );
-FORWARD _PROTOTYPE( void send_reply, (int err) );
+FORWARD _PROTOTYPE( void send_reply, (int err, int transid) );
FORWARD _PROTOTYPE( void got_signal, (int signal) );
PRIVATE unsigned int inodes;
* sending the reply. The loop exits when the process is signaled to
* exit; due to limitations of SEF, it can not return to the caller.
*/
- int call_nr, err;
+ int call_nr, err, transid;
/* Use global variables to work around the inability to pass parameters
* through SEF to the initialization function..
sef_local_startup();
for (;;) {
- call_nr = get_work();
+ get_work();
+
+ transid = TRNS_GET_ID(fs_m_in.m_type);
+ fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
+ if (fs_m_in.m_type == 0) {
+ assert(!IS_VFS_FS_TRANSID(transid));
+ fs_m_in.m_type = transid; /* Backwards compat. */
+ transid = 0;
+ } else
+ assert(IS_VFS_FS_TRANSID(transid));
+
+ call_nr = fs_m_in.m_type;
if (fs_m_in.m_source != VFS_PROC_NR) {
if (vtreefs_hooks->message_hook != NULL) {
}
else err = EINVAL;
- send_reply(err);
+ send_reply(err, transid);
}
}
/*===========================================================================*
* send_reply *
*===========================================================================*/
-PRIVATE void send_reply(int err)
+PRIVATE void send_reply(int err, int transid)
{
/* Send a reply to the caller.
*/
int r;
fs_m_out.m_type = err;
+ if (IS_VFS_FS_TRANSID(transid)) {
+ fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
+ }
if ((r = send(fs_m_in.m_source, &fs_m_out)) != OK)
panic(__FILE__, "unable to send reply", r);
* three major activities: getting new work, processing the work, and
* sending the reply. The loop never terminates, unless a panic occurs.
*/
- int error, ind;
+ int error, ind, transid;
unsigned short test_endian = 1;
/* SEF local startup. */
/* Wait for request message. */
get_work(&fs_m_in);
+ transid = TRNS_GET_ID(fs_m_in.m_type);
+ fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
+ if (fs_m_in.m_type == 0) {
+ assert(!IS_VFS_FS_TRANSID(transid));
+ fs_m_in.m_type = transid; /* Backwards compat. */
+ transid = 0;
+ } else
+ assert(IS_VFS_FS_TRANSID(transid));
+
src = fs_m_in.m_source;
error = OK;
caller_uid = INVAL_UID; /* To trap errors */
}
fs_m_out.m_type = error;
+ if (IS_VFS_FS_TRANSID(transid)) {
+ /* If a transaction ID was set, reset it */
+ fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
+ }
reply(src, &fs_m_out);
if (error == OK)
#include <unistd.h>
#include <stdlib.h>
-FORWARD _PROTOTYPE( int get_work, (endpoint_t *who_e) );
-FORWARD _PROTOTYPE( void send_reply, (int err) );
+FORWARD _PROTOTYPE( void get_work, (endpoint_t *who_e) );
+FORWARD _PROTOTYPE( void send_reply, (int err, int transid) );
PRIVATE struct optset optset_table[] = {
{ "prefix", OPT_STRING, opt.prefix, sizeof(opt.prefix) },
* reply back to VFS.
*/
endpoint_t who_e;
- int call_nr, err;
+ int call_nr, err, transid;
env_setargs(argc, argv);
sef_local_startup();
for (;;) {
- call_nr = get_work(&who_e);
-
+ get_work(&who_e);
+
+ transid = TRNS_GET_ID(m_in.m_type);
+ m_in.m_type = TRNS_DEL_ID(m_in.m_type);
+ if (m_in.m_type == 0) {
+ assert(!IS_VFS_FS_TRANSID(transid));
+ m_in.m_type = transid; /* Backwards compat. */
+ transid = 0;
+ } else
+ assert(IS_VFS_FS_TRANSID(transid));
+
+ call_nr = m_in.m_type;
if (who_e != VFS_PROC_NR) {
continue;
}
}
else err = EINVAL;
- send_reply(err);
+ send_reply(err, transid);
}
return 0;
/*===========================================================================*
* get_work *
*===========================================================================*/
-PRIVATE int get_work(who_e)
+PRIVATE void get_work(who_e)
endpoint_t *who_e;
{
/* Receive a request message from VFS. Return the request call number.
panic("receive failed: %d", r);
*who_e = m_in.m_source;
-
- return m_in.m_type;
}
/*===========================================================================*
* send_reply *
*===========================================================================*/
-PRIVATE void send_reply(err)
+PRIVATE void send_reply(err, transid)
int err; /* resulting error code */
+int transid;
{
/* Send a reply message to the requesting party, with the given error code.
*/
int r;
m_out.m_type = err;
-
+ if (IS_VFS_FS_TRANSID(transid)) {
+ /* If a transaction ID was set, reset it */
+ m_out.m_type = TRNS_ADD_ID(m_out.m_type, transid);
+ }
if ((r = send(m_in.m_source, &m_out)) != OK)
printf("HGFS: send failed (%d)\n", r);
}
#include "inc.h"
#include <minix/vfsif.h>
+#include <assert.h>
#include "const.h"
#include "glo.h"
* main *
*===========================================================================*/
PUBLIC int main(void) {
- endpoint_t who_e, ind, error;
+ endpoint_t who_e;
+ int ind, error, transid;
/* SEF local startup. */
sef_local_startup();
/* Wait for request message. */
get_work(&fs_m_in);
+
+ transid = TRNS_GET_ID(fs_m_in.m_type);
+ fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
+ if (fs_m_in.m_type == 0) {
+ assert(!IS_VFS_FS_TRANSID(transid));
+ fs_m_in.m_type = transid; /* Backwards compat. */
+ transid = 0;
+ } else
+ assert(IS_VFS_FS_TRANSID(transid));
+
error = OK;
caller_uid = -1; /* To trap errors */
* the appropriate function. */
fs_m_out.m_type = error;
+ if (IS_VFS_FS_TRANSID(transid)) {
+ /* If a transaction ID was set, reset it */
+ fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
+ }
reply(who_e, &fs_m_out); /* returns the response to VFS */
}
}
iop->iov_size = (vir_bytes) fs_block_size;
}
r = block_dev_io(rw_flag == WRITING ? MFS_DEV_SCATTER : MFS_DEV_GATHER,
- dev, SELF_E, iovec,
- mul64u(bufq[0]->b_blocknr, fs_block_size), j);
+ dev, SELF_E, iovec,
+ mul64u(bufq[0]->b_blocknr, fs_block_size), j);
/* Harvest the results. Dev_io reports the first error it may have
* encountered, but we only care if it's the first block that failed.
/* Transfer failed. An error? Do we care? */
if (r != OK && i == 0) {
printf(
- "fs: I/O error on device %d/%d, block %lu\n",
+ "MFS: I/O error on device %d/%d, block %lu\n",
major(dev), minor(dev), bp->b_blocknr);
bp->b_dev = NO_DEV; /* invalidate block */
vm_forgetblocks();
* three major activities: getting new work, processing the work, and
* sending the reply. The loop never terminates, unless a panic occurs.
*/
- int error, ind;
+ int error, ind, transid;
/* SEF local startup. */
env_setargs(argc, argv);
/* Wait for request message. */
get_work(&fs_m_in);
+ transid = TRNS_GET_ID(fs_m_in.m_type);
+ fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
+ if (fs_m_in.m_type == 0) {
+ assert(!IS_VFS_FS_TRANSID(transid));
+ fs_m_in.m_type = transid; /* Backwards compat. */
+ transid = 0;
+ } else
+ assert(IS_VFS_FS_TRANSID(transid));
+
src = fs_m_in.m_source;
error = OK;
caller_uid = INVAL_UID; /* To trap errors */
ind = req_nr - VFS_BASE;
if (ind < 0 || ind >= NREQS) {
- printf("mfs: bad request %d\n", req_nr);
+ printf("MFS: bad request %d from %d\n", req_nr, src);
printf("ind = %d\n", ind);
- error = EINVAL;
+ error = EINVAL;
} else {
error = (*fs_call_vec[ind])();
/*cch_check();*/
}
fs_m_out.m_type = error;
+ if (IS_VFS_FS_TRANSID(transid)) {
+ /* If a transaction ID was set, reset it */
+ fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
+ }
reply(src, &fs_m_out);
if (error == OK)
FORWARD _PROTOTYPE( struct inode *new_node, (struct inode *ldirp,
char *string, mode_t bits, zone_t z0));
-
/*===========================================================================*
* fs_create *
*===========================================================================*/
PUBLIC int fs_create()
{
- phys_bytes len;
+ size_t len;
int r;
struct inode *ldirp;
struct inode *rip;
/* Copy the last component (i.e., file name) */
len = min( (unsigned) fs_m_in.REQ_PATH_LEN, sizeof(lastc));
err_code = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) fs_m_in.REQ_GRANT,
- (vir_bytes) 0, (vir_bytes) lastc, (size_t) len, D);
+ (vir_bytes) 0, (vir_bytes) lastc, len, D);
if (err_code != OK) return err_code;
NUL(lastc, len, sizeof(lastc));
fs_m_out.RES_MODE = rip->i_mode;
fs_m_out.RES_FILE_SIZE_LO = rip->i_size;
- /* This values are needed for the execution */
+ /* These values are needed for the execution */
fs_m_out.RES_UID = rip->i_uid;
fs_m_out.RES_GID = rip->i_gid;
* three major activities: getting new work, processing the work, and
* sending the reply. The loop never terminates, unless a panic occurs.
*/
- int ind;
+ int ind, transid;
message pfs_m_in;
message pfs_m_out;
/* Wait for request message. */
get_work(&pfs_m_in);
+ transid = TRNS_GET_ID(pfs_m_in.m_type);
+ pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type);
+ if (pfs_m_in.m_type == 0) {
+ assert(!IS_VFS_FS_TRANSID(transid));
+ pfs_m_in.m_type = transid;
+ transid = 0;
+ } else
+ assert(IS_VFS_FS_TRANSID(transid) || transid == 0);
+
src = pfs_m_in.m_source;
caller_uid = INVAL_UID; /* To trap errors */
caller_gid = INVAL_GID;
pfs_m_out.m_type = EINVAL;
}
+ if (IS_VFS_RQ(req_nr) && IS_VFS_FS_TRANSID(transid)) {
+ pfs_m_out.m_type = TRNS_ADD_ID(pfs_m_out.m_type, transid);
+ }
reply(src, &pfs_m_out);
}
return(OK);
endpoint_t who;
message *m_out; /* report result */
{
- if (OK != send(who, m_out)) /* send the message */
+ if (OK != send(who, m_out)) /* send the message */
printf("PFS(%d) was unable to send reply\n", SELF_E);
}