Add support for VFS-FS transaction IDs

This commit is contained in:
Thomas Veerman 2011-07-27 15:49:42 +00:00
parent ece4c9d565
commit 7588db2691
10 changed files with 124 additions and 31 deletions

View file

@ -24,6 +24,7 @@
* 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.
*/
@ -1225,4 +1226,13 @@
#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 */

View file

@ -113,12 +113,16 @@ typedef struct {
#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)

View file

@ -3,7 +3,7 @@
#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;
@ -53,7 +53,7 @@ PUBLIC void start_vtreefs(struct fs_hooks *hooks, unsigned int nr_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..
@ -66,7 +66,18 @@ PUBLIC void start_vtreefs(struct fs_hooks *hooks, unsigned int nr_inodes,
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) {
@ -90,7 +101,7 @@ PUBLIC void start_vtreefs(struct fs_hooks *hooks, unsigned int nr_inodes,
}
else err = EINVAL;
send_reply(err);
send_reply(err, transid);
}
}
@ -112,13 +123,16 @@ PRIVATE int get_work(void)
/*===========================================================================*
* 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);

View file

@ -46,7 +46,7 @@ PUBLIC int main(int argc, char *argv[])
* 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. */
@ -64,6 +64,15 @@ PUBLIC int main(int argc, char *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 */
@ -85,6 +94,10 @@ PUBLIC int main(int argc, char *argv[])
}
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)

View file

@ -15,8 +15,8 @@
#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) },
@ -124,14 +124,24 @@ char *argv[];
* 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;
}
@ -151,7 +161,7 @@ char *argv[];
}
else err = EINVAL;
send_reply(err);
send_reply(err, transid);
}
return 0;
@ -160,7 +170,7 @@ char *argv[];
/*===========================================================================*
* 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.
@ -171,22 +181,24 @@ endpoint_t *who_e;
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);
}

View file

@ -5,6 +5,7 @@
#include "inc.h"
#include <minix/vfsif.h>
#include <assert.h>
#include "const.h"
#include "glo.h"
@ -20,7 +21,8 @@ FORWARD _PROTOTYPE( void sef_cb_signal_handler, (int signo) );
* 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();
@ -29,6 +31,16 @@ PUBLIC int main(void) {
/* 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 */
@ -57,6 +69,10 @@ PUBLIC int main(void) {
* 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 */
}
}

View file

@ -468,8 +468,8 @@ PUBLIC void rw_scattered(
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.
@ -480,7 +480,7 @@ PUBLIC void rw_scattered(
/* 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();

View file

@ -30,7 +30,7 @@ PUBLIC int main(int argc, char *argv[])
* 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);
@ -42,6 +42,15 @@ PUBLIC int main(int argc, char *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 */
@ -55,15 +64,19 @@ PUBLIC int main(int argc, char *argv[])
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)

View file

@ -10,13 +10,12 @@
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;
@ -33,7 +32,7 @@ PUBLIC int fs_create()
/* 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));
@ -57,7 +56,7 @@ PUBLIC int fs_create()
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;

View file

@ -25,7 +25,7 @@ PUBLIC int main(int argc, char *argv[])
* 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;
@ -39,6 +39,15 @@ PUBLIC int main(int argc, char *argv[])
/* 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;
@ -66,6 +75,9 @@ PUBLIC int main(int argc, char *argv[])
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);
@ -158,6 +170,6 @@ PUBLIC void reply(who, m_out)
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);
}