From ddeb562e1a57d52d3fa9e5fcd694fa74a5351e88 Mon Sep 17 00:00:00 2001 From: David van Moolenbroek Date: Tue, 3 Sep 2013 02:00:20 +0200 Subject: [PATCH] PFS: use libchardriver; clean up - simplify and repair UDS request handling state machine; - simplify interface used between internal modules; - implement missing support for nonblocking I/O; - fix select implementation; - clean up global variables. Change-Id: Ia82c5c6f05cc3f0a498efc9a26de14b1cde6eace --- servers/pfs/Makefile | 4 +- servers/pfs/dev_uds.c | 879 +++++++++++++----------------------------- servers/pfs/glo.h | 5 - servers/pfs/inode.c | 6 +- servers/pfs/main.c | 59 ++- servers/pfs/open.c | 8 +- servers/pfs/proto.h | 37 +- servers/pfs/read.c | 4 +- servers/pfs/table.c | 35 +- servers/pfs/uds.c | 522 +++++++++++++------------ servers/pfs/uds.h | 79 +--- servers/pfs/utility.c | 2 +- 12 files changed, 607 insertions(+), 1033 deletions(-) diff --git a/servers/pfs/Makefile b/servers/pfs/Makefile index f4b0cb699..ef3d013e9 100644 --- a/servers/pfs/Makefile +++ b/servers/pfs/Makefile @@ -4,8 +4,8 @@ SRCS= open.c table.c inode.c main.c super.c link.c \ buffer.c read.c misc.c mount.c utility.c stadir.c \ uds.c dev_uds.c -DPADD+= ${LIBSYS} -LDADD+= -lsys +DPADD+= ${LIBCHARDRIVER} ${LIBSYS} +LDADD+= -lchardriver -lsys LDADD+= -lc diff --git a/servers/pfs/dev_uds.c b/servers/pfs/dev_uds.c index a12f8ac32..0caba400c 100644 --- a/servers/pfs/dev_uds.c +++ b/servers/pfs/dev_uds.c @@ -4,18 +4,11 @@ * * The entry points into this file are... * - * uds_open: handles the open(2) syscall on /dev/uds - * uds_close: handles the close(2) syscall on /dev/uds - * uds_select: handles the select(2) syscall on /dev/uds - * uds_read: handles the read(2) syscall on /dev/uds - * uds_write: handles the write(2) syscall on /dev/uds - * uds_ioctl: handles the ioctl(2) syscall on /dev/uds - * uds_status: handles status requests. - * uds_cancel: handles cancelled syscalls. + * uds_request: process a character device request * * Also See... * - * table.c, uds.c, uds.h + * uds.c, uds.h * * Overview * @@ -32,23 +25,50 @@ #include "glo.h" #include "uds.h" -static int uds_perform_read(int minor, endpoint_t m_source, size_t - size, int pretend); -static int uds_perform_write(int minor, endpoint_t m_source, size_t - size, int pretend); +static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int pretend); +static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int pretend); + +static int uds_open(devminor_t orig_minor, int access, endpoint_t user_endpt); +static int uds_close(devminor_t minor); +static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); +static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, cdev_id_t id); +static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, + cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id); +static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id); +static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt); + +static struct chardriver uds_tab = { + .cdr_open = uds_open, + .cdr_close = uds_close, + .cdr_read = uds_read, + .cdr_write = uds_write, + .cdr_ioctl = uds_ioctl, + .cdr_cancel = uds_cancel, + .cdr_select = uds_select +}; + +void uds_request(message *m_ptr, int ipc_status) +{ + /* Use libchardriver to process character device requests. */ + chardriver_process(&uds_tab, m_ptr, ipc_status); +} -int uds_open(message *dev_m_in, message *dev_m_out) +static int uds_open(devminor_t UNUSED(orig_minor), int access, + endpoint_t user_endpt) { message fs_m_in, fs_m_out; struct uucred ucred; + devminor_t minor; int rc, i; - int minor; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_open() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x\n", dev_m_in->USER_ENDPT); + printf("(uds) [-] uds_open() call_count=%d\n", ++call_count); + printf("Endpoint: 0x%x\n", user_endpt); #endif /* @@ -68,13 +88,8 @@ int uds_open(message *dev_m_in, message *dev_m_out) } } - if (minor == -1) { - - /* descriptor table full */ - uds_set_reply(dev_m_out, DEV_OPEN_REPL, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, ENFILE); + if (minor == -1) return ENFILE; - } /* * We found a slot in uds_fd_table, now initialize the descriptor @@ -85,21 +100,12 @@ int uds_open(message *dev_m_in, message *dev_m_out) */ uds_fd_table[minor].state = UDS_INUSE; - /* track the system call we are performing in case it gets cancelled */ - uds_fd_table[minor].call_nr = dev_m_in->m_type; - uds_fd_table[minor].ioctl = 0; - uds_fd_table[minor].syscall_done = 0; - /* set the socket owner */ - uds_fd_table[minor].owner = dev_m_in->USER_ENDPT; - uds_fd_table[minor].endpoint = dev_m_in->USER_ENDPT; + uds_fd_table[minor].owner = user_endpt; /* setup select(2) framework */ - uds_fd_table[minor].selecting = 0; - uds_fd_table[minor].select_proc = 0; - uds_fd_table[minor].sel_ops_in = 0; - uds_fd_table[minor].sel_ops_out = 0; - uds_fd_table[minor].status_updated = 0; + uds_fd_table[minor].sel_endpt = NONE; + uds_fd_table[minor].sel_ops = 0; /* initialize the data pointer (pos) to the start of the PIPE */ uds_fd_table[minor].pos = 0; @@ -151,26 +157,15 @@ int uds_open(message *dev_m_in, message *dev_m_out) /* Initially the socket isn't suspended. */ uds_fd_table[minor].suspended = UDS_NOT_SUSPENDED; - /* and the socket doesn't have an I/O grant initially */ - uds_fd_table[minor].io_gr = GRANT_INVALID; - - /* since there is no I/O grant it effectively has no size either */ - uds_fd_table[minor].io_gr_size = 0; - - /* The process isn't suspended so we don't flag it as revivable */ - uds_fd_table[minor].ready_to_revive = 0; - /* get the effective user id and effective group id from the endpoint */ /* this is needed in the REQ_NEWNODE request to PFS. */ - rc = getnucred(uds_fd_table[minor].endpoint, &ucred); + rc = getnucred(user_endpt, &ucred); if (rc == -1) { /* roll back the changes we made to the descriptor */ memset(&(uds_fd_table[minor]), '\0', sizeof(uds_fd_t)); /* likely error: invalid endpoint / proc doesn't exist */ - uds_set_reply(dev_m_out, DEV_OPEN_REPL, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, errno); - return errno; + return EIO; } /* Prepare Request to the FS side of PFS */ @@ -189,52 +184,34 @@ int uds_open(message *dev_m_in, message *dev_m_out) memset(&(uds_fd_table[minor]), '\0', sizeof(uds_fd_t)); /* likely error: get_block() failed */ - uds_set_reply(dev_m_out, DEV_OPEN_REPL, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, rc); return rc; } /* Process the response */ - uds_fd_table[minor].inode_nr = fs_m_out.RES_INODE_NR; - /* prepare the reply */ - - uds_fd_table[minor].syscall_done = 1; - uds_set_reply(dev_m_out, DEV_OPEN_REPL, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, minor); - return minor; + return minor; /* cloned! */ } -int uds_close(message *dev_m_in, message *dev_m_out) +static int uds_close(devminor_t minor) { - int minor; message fs_m_in, fs_m_out; int rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_close() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x\n", dev_m_in->USER_ENDPT); + printf("(uds) [%d] uds_close() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); + if (minor < 0 || minor >= NR_FDS) return ENXIO; if (uds_fd_table[minor].state != UDS_INUSE) { /* attempted to close a socket that hasn't been opened -- * something is very wrong :( */ - uds_set_reply(dev_m_out, DEV_CLOSE_REPL, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, EINVAL); return EINVAL; } - /* no need to track the syscall in case of cancellation. close() is - * atomic and can't be cancelled. no need to update the endpoint here, - * we won't be needing it to kill the socket - */ - /* if the socket is connected, disconnect it */ if (uds_fd_table[minor].peer != -1) { int peer = uds_fd_table[minor].peer; @@ -246,14 +223,12 @@ int uds_close(message *dev_m_in, message *dev_m_out) uds_fd_table[peer].err = ECONNRESET; /* if peer was blocked on I/O revive peer */ - if (uds_fd_table[peer].suspended) { - uds_fd_table[peer].ready_to_revive = 1; - uds_unsuspend(dev_m_in->m_source, peer); - } + if (uds_fd_table[peer].suspended != UDS_NOT_SUSPENDED) + uds_unsuspend(peer); } if (uds_fd_table[minor].ancillary_data.nfiledes > 0) { - clear_fds(minor, &(uds_fd_table[minor].ancillary_data)); + uds_clear_fds(minor, &uds_fd_table[minor].ancillary_data); } /* Prepare Request to the FS side of PFS */ @@ -269,90 +244,84 @@ int uds_close(message *dev_m_in, message *dev_m_out) rc = fs_putnode(&fs_m_in, &fs_m_out); if (rc != OK) { - perror("fs_putnode"); - /* likely error: get_block() failed */ + printf("PFS: fs_putnode returned %d\n", rc); + return rc; } - uds_set_reply(dev_m_out, DEV_CLOSE_REPL, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, OK); return OK; } -int uds_select(message *dev_m_in, message *dev_m_out) +static int uds_select(devminor_t minor, unsigned int ops, endpoint_t endpt) { - int i, bytes; - int minor; + unsigned int ready_ops; + int i, bytes, watch; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_select() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x\n", dev_m_in->USER_ENDPT); + printf("(uds) [%d] uds_select() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); + if (minor < 0 || minor >= NR_FDS) return ENXIO; if (uds_fd_table[minor].state != UDS_INUSE) { - - /* attempted to close a socket that hasn't been opened -- + /* attempted to select on a socket that hasn't been opened -- * something is very wrong :( */ - - uds_sel_reply(dev_m_out, DEV_SEL_REPL1, minor, EINVAL); return EINVAL; } - /* setup select(2) framework */ - uds_fd_table[minor].selecting = 1; - uds_fd_table[minor].select_proc = dev_m_in->m_source; - - /* track the system call we are performing in case it gets cancelled */ - uds_fd_table[minor].call_nr = dev_m_in->m_type; - uds_fd_table[minor].ioctl = 0; - uds_fd_table[minor].syscall_done = 0; - - /* Can't update the process endpoint here, no info. */ + watch = (ops & SEL_NOTIFY); + ops &= (SEL_RD | SEL_WR | SEL_ERR); - uds_fd_table[minor].sel_ops_in = dev_m_in->USER_ENDPT; - uds_fd_table[minor].sel_ops_out = 0; + ready_ops = 0; /* check if there is data available to read */ - bytes = uds_perform_read(minor, dev_m_in->m_source, 1, 1); - if (bytes > 0) { - - /* there is data in the pipe for us to read */ - uds_fd_table[minor].sel_ops_out |= SEL_RD; - - } else if (uds_fd_table[minor].listening == 1) { - - /* check for pending connections */ - for (i = 0; i < uds_fd_table[minor].backlog_size; i++) { - if (uds_fd_table[minor].backlog[i] != -1) { - uds_fd_table[minor].sel_ops_out |= SEL_RD; - break; + if (ops & SEL_RD) { + bytes = uds_perform_read(minor, NONE, GRANT_INVALID, 1, 1); + if (bytes > 0) { + /* there is data in the pipe for us to read */ + ready_ops |= SEL_RD; + } else if (uds_fd_table[minor].listening == 1) { + /* check for pending connections */ + for (i = 0; i < uds_fd_table[minor].backlog_size; i++) + { + if (uds_fd_table[minor].backlog[i] != -1) { + ready_ops |= SEL_RD; + break; + } } + } else if (bytes != SUSPEND) { + ready_ops |= SEL_RD; } - } else if (bytes != SUSPEND) { - uds_fd_table[minor].sel_ops_out |= SEL_RD; } /* check if we can write without blocking */ - bytes = uds_perform_write(minor, dev_m_in->m_source, PIPE_BUF, 1); - if (bytes != 0 && bytes != SUSPEND) { - /* There is room to write or there is an error condition */ - uds_fd_table[minor].sel_ops_out |= SEL_WR; + if (ops & SEL_WR) { + bytes = uds_perform_write(minor, NONE, GRANT_INVALID, PIPE_BUF, + 1); + if (bytes != 0 && bytes != SUSPEND) { + /* There is room to write or there is an error + * condition. + */ + ready_ops |= SEL_WR; + } } - uds_fd_table[minor].syscall_done = 1; - uds_sel_reply(dev_m_out, DEV_SEL_REPL1, minor, - uds_fd_table[minor].sel_ops_out); + /* If not all requested ops were ready, and the caller requests to be + * notified about changes, we add the remaining ops to the saved set. + */ + ops &= ~ready_ops; + if (ops && watch) { + uds_fd_table[minor].sel_endpt = endpt; + uds_fd_table[minor].sel_ops |= ops; + } - return uds_fd_table[minor].sel_ops_out; + return ready_ops; } -static int uds_perform_read(int minor, endpoint_t m_source, - size_t size, int pretend) +static ssize_t uds_perform_read(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int pretend) { int rc, peer; message fs_m_in; @@ -366,20 +335,18 @@ static int uds_perform_read(int minor, endpoint_t m_source, peer = uds_fd_table[minor].peer; + /* skip reads and writes of 0 (or less!) bytes */ if (size <= 0) { return 0; } /* check if we are allowed to read */ if (!(uds_fd_table[minor].mode & S_IRUSR)) { - /* socket is shutdown for reading */ return EPIPE; } - /* skip reads and writes of 0 (or less!) bytes */ if (uds_fd_table[minor].size == 0) { - if (peer == -1) { /* We're not connected. That's only a problem when this * socket is connection oriented. */ @@ -400,7 +367,6 @@ static int uds_perform_read(int minor, endpoint_t m_source, return 0; } - if (pretend) { return SUSPEND; } @@ -408,10 +374,9 @@ static int uds_perform_read(int minor, endpoint_t m_source, /* maybe a process is blocked waiting to write? if * needed revive the writer */ - if (peer != -1 && uds_fd_table[peer].suspended) { - uds_fd_table[peer].ready_to_revive = 1; - uds_unsuspend(m_source, peer); - } + if (peer != -1 && + uds_fd_table[peer].suspended == UDS_SUSPENDED_WRITE) + uds_unsuspend(peer); #if DEBUG == 1 printf("(uds) [%d] suspending read request\n", minor); @@ -419,21 +384,19 @@ static int uds_perform_read(int minor, endpoint_t m_source, /* Process is reading from an empty pipe, * suspend it so some bytes can be written */ - uds_fd_table[minor].suspended = UDS_SUSPENDED_READ; - return SUSPEND; + return EDONTREPLY; } if (pretend) { - return (size > uds_fd_table[minor].size) ? uds_fd_table[minor].size : size; } - /* Prepare Request to the FS side of PFS */ + fs_m_in.m_source = endpt; fs_m_in.m_type = REQ_READ; fs_m_in.REQ_INODE_NR = uds_fd_table[minor].inode_nr; - fs_m_in.REQ_GRANT = uds_fd_table[minor].io_gr; + fs_m_in.REQ_GRANT = grant; fs_m_in.REQ_SEEK_POS_HI = 0; fs_m_in.REQ_SEEK_POS_LO = uds_fd_table[minor].pos; fs_m_in.REQ_NBYTES = (size > uds_fd_table[minor].size) ? @@ -442,7 +405,7 @@ static int uds_perform_read(int minor, endpoint_t m_source, /* perform the read */ rc = fs_readwrite(&fs_m_in, &fs_m_out); if (rc != OK) { - perror("fs_readwrite"); + printf("PFS: fs_readwrite returned %d\n", rc); return rc; } @@ -469,35 +432,26 @@ static int uds_perform_read(int minor, endpoint_t m_source, /* maybe a big write was waiting for us to read some data, if * needed revive the writer */ - if (peer != -1 && uds_fd_table[peer].suspended) { - uds_fd_table[peer].ready_to_revive = 1; - uds_unsuspend(m_source, peer); - } + if (peer != -1 && uds_fd_table[peer].suspended == UDS_SUSPENDED_WRITE) + uds_unsuspend(peer); - /* see if peer is blocked on select() and a write is possible - * (from peer to minor) + /* see if peer is blocked on select() and a write is possible (from + * peer to minor); if the peer wants to know about write being possible + * and it doesn't know about it already, then let the peer know. */ - if (peer != -1 && uds_fd_table[peer].selecting == 1 && + if (peer != -1 && (uds_fd_table[peer].sel_ops & SEL_WR) && (uds_fd_table[minor].size+uds_fd_table[minor].pos + 1 < PIPE_BUF)){ - - /* if the peer wants to know about write being possible - * and it doesn't know about it already, then let the peer know. - */ - if (peer != -1 && (uds_fd_table[peer].sel_ops_in & SEL_WR) && - !(uds_fd_table[peer].sel_ops_out & SEL_WR)) { - - /* a write on peer is possible now */ - uds_fd_table[peer].sel_ops_out |= SEL_WR; - uds_fd_table[peer].status_updated = 1; - uds_unsuspend(m_source, peer); - } + /* a write on peer is possible now */ + chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer, + SEL_WR); + uds_fd_table[peer].sel_ops &= ~SEL_WR; } return fs_m_out.RES_NBYTES; /* return number of bytes read */ } -static int uds_perform_write(int minor, endpoint_t m_source, - size_t size, int pretend) +static ssize_t uds_perform_write(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int pretend) { int rc, peer, i; message fs_m_in; @@ -516,20 +470,17 @@ static int uds_perform_write(int minor, endpoint_t m_source, /* check if we are allowed to write */ if (!(uds_fd_table[minor].mode & S_IWUSR)) { - /* socket is shutdown for writing */ return EPIPE; } if (size > PIPE_BUF) { - /* message is too big to ever write to the PIPE */ return EMSGSIZE; } if (uds_fd_table[minor].type == SOCK_STREAM || uds_fd_table[minor].type == SOCK_SEQPACKET) { - /* if we're writing with a connection oriented socket, * then it needs a peer to write to */ @@ -542,12 +493,9 @@ static int uds_perform_write(int minor, endpoint_t m_source, return ENOTCONN; } } else { - peer = uds_fd_table[minor].peer; } - } else /* uds_fd_table[minor].type == SOCK_DGRAM */ { - peer = -1; /* locate the "peer" we want to write to */ @@ -601,10 +549,8 @@ static int uds_perform_write(int minor, endpoint_t m_source, } /* if needed revive the reader */ - if (uds_fd_table[peer].suspended) { - uds_fd_table[peer].ready_to_revive = 1; - uds_unsuspend(m_source, peer); - } + if (uds_fd_table[peer].suspended == UDS_SUSPENDED_READ) + uds_unsuspend(peer); #if DEBUG == 1 printf("(uds) [%d] suspending write request\n", minor); @@ -613,8 +559,7 @@ static int uds_perform_write(int minor, endpoint_t m_source, /* Process is reading from an empty pipe, * suspend it so some bytes can be written */ - uds_fd_table[minor].suspended = UDS_SUSPENDED_WRITE; - return SUSPEND; + return EDONTREPLY; } if (pretend) { @@ -622,9 +567,10 @@ static int uds_perform_write(int minor, endpoint_t m_source, } /* Prepare Request to the FS side of PFS */ + fs_m_in.m_source = endpt; fs_m_in.m_type = REQ_WRITE; fs_m_in.REQ_INODE_NR = uds_fd_table[peer].inode_nr; - fs_m_in.REQ_GRANT = uds_fd_table[minor].io_gr; + fs_m_in.REQ_GRANT = grant; fs_m_in.REQ_SEEK_POS_HI = 0; fs_m_in.REQ_SEEK_POS_LO = uds_fd_table[peer].pos + uds_fd_table[peer].size; @@ -633,7 +579,7 @@ static int uds_perform_write(int minor, endpoint_t m_source, /* Request the write */ rc = fs_readwrite(&fs_m_in, &fs_m_out); if (rc != OK) { - perror("fs_readwrite"); + printf("PFS: fs_readwrite returned %d\n", rc); return rc; } @@ -644,7 +590,6 @@ static int uds_perform_write(int minor, endpoint_t m_source, /* increase the count of unread bytes */ uds_fd_table[peer].size += fs_m_out.RES_NBYTES; - /* fill in the source address to be returned by recvfrom & recvmsg */ if (uds_fd_table[minor].type == SOCK_DGRAM) { memcpy(&uds_fd_table[peer].source, &uds_fd_table[minor].addr, @@ -652,541 +597,269 @@ static int uds_perform_write(int minor, endpoint_t m_source, } /* revive peer that was waiting for us to write */ - if (uds_fd_table[peer].suspended) { - uds_fd_table[peer].ready_to_revive = 1; - uds_unsuspend(m_source, peer); - } - - /* see if peer is blocked on select()*/ - if (uds_fd_table[peer].selecting == 1 && fs_m_out.RES_NBYTES > 0) { - - /* if the peer wants to know about data ready to read - * and it doesn't know about it already, then let the peer - * know we have data for it. - */ - if ((uds_fd_table[peer].sel_ops_in & SEL_RD) && - !(uds_fd_table[peer].sel_ops_out & SEL_RD)) { + if (uds_fd_table[peer].suspended == UDS_SUSPENDED_READ) + uds_unsuspend(peer); - /* a read on peer is possible now */ - uds_fd_table[peer].sel_ops_out |= SEL_RD; - uds_fd_table[peer].status_updated = 1; - uds_unsuspend(m_source, peer); - } + /* see if peer is blocked on select(); if the peer wants to know about + * data ready to read and it doesn't know about it already, then let + * the peer know we have data for it. + */ + if ((uds_fd_table[peer].sel_ops & SEL_RD) && fs_m_out.RES_NBYTES > 0) { + /* a read on peer is possible now */ + chardriver_reply_select(uds_fd_table[peer].sel_endpt, peer, + SEL_RD); + uds_fd_table[peer].sel_ops &= ~SEL_RD; } return fs_m_out.RES_NBYTES; /* return number of bytes written */ } -int uds_read(message *dev_m_in, message *dev_m_out) +static ssize_t uds_read(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, cdev_id_t id) { - int bytes; - int minor; + ssize_t rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_read() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x | Position 0x%x\n", dev_m_in->USER_ENDPT, - dev_m_in->POSITION); + printf("(uds) [%d] uds_read() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); + if (minor < 0 || minor >= NR_FDS) return ENXIO; if (uds_fd_table[minor].state != UDS_INUSE) { - - /* attempted to close a socket that hasn't been opened -- + /* attempted to read from a socket that hasn't been opened -- * something is very wrong :( */ - uds_set_reply(dev_m_out, DEV_REVIVE, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, EINVAL); - return EINVAL; } - /* track the system call we are performing in case it gets cancelled */ - uds_fd_table[minor].call_nr = dev_m_in->m_type; - uds_fd_table[minor].ioctl = 0; - uds_fd_table[minor].syscall_done = 0; + rc = uds_perform_read(minor, endpt, grant, size, 0); - /* Update the process endpoint. */ - uds_fd_table[minor].endpoint = dev_m_in->USER_ENDPT; - - /* setup select(2) framework */ - uds_fd_table[minor].selecting = 0; - - /* save I/O Grant info */ - uds_fd_table[minor].io_gr = (cp_grant_id_t) dev_m_in->IO_GRANT; - uds_fd_table[minor].io_gr_size = dev_m_in->COUNT; + /* If the call couldn't complete, suspend the caller. */ + if (rc == EDONTREPLY) { + uds_fd_table[minor].suspended = UDS_SUSPENDED_READ; + uds_fd_table[minor].susp_endpt = endpt; + uds_fd_table[minor].susp_grant = grant; + uds_fd_table[minor].susp_size = size; + uds_fd_table[minor].susp_id = id; - bytes = uds_perform_read(minor, dev_m_in->m_source, - uds_fd_table[minor].io_gr_size, 0); + /* If the call wasn't supposed to block, cancel immediately. */ + if (flags & FLG_OP_NONBLOCK) { + uds_cancel(minor, endpt, id); - uds_set_reply(dev_m_out, DEV_REVIVE, uds_fd_table[minor].endpoint, - uds_fd_table[minor].io_gr, bytes); + rc = EAGAIN; + } + } - return bytes; + return rc; } -int uds_write(message *dev_m_in, message *dev_m_out) +static ssize_t uds_write(devminor_t minor, u64_t position, endpoint_t endpt, + cp_grant_id_t grant, size_t size, int flags, cdev_id_t id) { - int bytes; - int minor; + ssize_t rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_write() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x | Position 0x%x\n", dev_m_in->USER_ENDPT, - dev_m_in->POSITION); + printf("(uds) [%d] uds_write() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); + if (minor < 0 || minor >= NR_FDS) return ENXIO; if (uds_fd_table[minor].state != UDS_INUSE) { - /* attempted to write to a socket that hasn't been opened -- * something is very wrong :( */ - uds_set_reply(dev_m_out, DEV_REVIVE, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, EINVAL); - return EINVAL; } - /* track the system call we are performing in case it gets cancelled */ - uds_fd_table[minor].call_nr = dev_m_in->m_type; - uds_fd_table[minor].ioctl = 0; - uds_fd_table[minor].syscall_done = 0; - - /* Update the process endpoint. */ - uds_fd_table[minor].endpoint = dev_m_in->USER_ENDPT; - - /* setup select(2) framework */ - uds_fd_table[minor].selecting = 0; + rc = uds_perform_write(minor, endpt, grant, size, 0); - /* save I/O Grant info */ - uds_fd_table[minor].io_gr = (cp_grant_id_t) dev_m_in->IO_GRANT; - uds_fd_table[minor].io_gr_size = dev_m_in->COUNT; + /* If the call couldn't complete, suspend the caller. */ + if (rc == EDONTREPLY) { + uds_fd_table[minor].suspended = UDS_SUSPENDED_WRITE; + uds_fd_table[minor].susp_endpt = endpt; + uds_fd_table[minor].susp_grant = grant; + uds_fd_table[minor].susp_size = size; + uds_fd_table[minor].susp_id = id; - bytes = uds_perform_write(minor, dev_m_in->m_source, - uds_fd_table[minor].io_gr_size, 0); + /* If the call wasn't supposed to block, cancel immediately. */ + if (flags & FLG_OP_NONBLOCK) { + uds_cancel(minor, endpt, id); - uds_set_reply(dev_m_out, DEV_REVIVE, uds_fd_table[minor].endpoint, - uds_fd_table[minor].io_gr, bytes); + rc = EAGAIN; + } + } - return bytes; + return rc; } -int uds_ioctl(message *dev_m_in, message *dev_m_out) +static int uds_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, + cp_grant_id_t grant, int flags, endpoint_t user_endpt, cdev_id_t id) { - int rc, minor; + int rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_ioctl() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x | Position 0x%x\n", dev_m_in->USER_ENDPT, - dev_m_in->POSITION); + printf("(uds) [%d] uds_ioctl() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); + if (minor < 0 || minor >= NR_FDS) return ENXIO; if (uds_fd_table[minor].state != UDS_INUSE) { - - /* attempted to close a socket that hasn't been opened -- - * something is very wrong :( + /* attempted to perform I/O control on a socket that hasn't + * been opened -- something is very wrong :( */ - uds_set_reply(dev_m_out, DEV_REVIVE, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, EINVAL); - return EINVAL; } - /* track the system call we are performing in case it gets cancelled */ - uds_fd_table[minor].call_nr = dev_m_in->m_type; - uds_fd_table[minor].ioctl = dev_m_in->COUNT; - uds_fd_table[minor].syscall_done = 0; - - /* setup select(2) framework */ - uds_fd_table[minor].selecting = 0; - - /* update the owner endpoint - yes it's really stored in POSITION */ - uds_fd_table[minor].owner = dev_m_in->POSITION; - - /* update the process endpoint, which may well be different */ - uds_fd_table[minor].endpoint = dev_m_in->USER_ENDPT; - - /* save I/O Grant info */ - uds_fd_table[minor].io_gr = (cp_grant_id_t) dev_m_in->IO_GRANT; - uds_fd_table[minor].io_gr_size = 0; /* should not be used here */ - - switch (dev_m_in->COUNT) { /* Handle the ioctl(2) command */ - - case NWIOSUDSCONN: - - /* connect to a listening socket -- connect() */ - rc = do_connect(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSACCEPT: - - /* accept an incoming connection -- accept() */ - rc = do_accept(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSBLOG: - - /* set the backlog_size and put the socket into the - * listening state -- listen() - */ - rc = do_listen(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSTYPE: - - /* set the type for this socket (i.e. - * SOCK_STREAM, SOCK_DGRAM, etc) -- socket() - */ - rc = do_socket(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSADDR: - - /* set the address for this socket -- bind() */ - rc = do_bind(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSADDR: - - /* get the address for this socket -- getsockname() */ - rc = do_getsockname(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSPADDR: - - /* get the address for the peer -- getpeername() */ - rc = do_getpeername(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSSHUT: - - /* shutdown a socket for reading, writing, or - * both -- shutdown() - */ - rc = do_shutdown(dev_m_in, dev_m_out); + /* update the owner endpoint */ + uds_fd_table[minor].owner = user_endpt; - break; - - case NWIOSUDSPAIR: - - /* connect two sockets -- socketpair() */ - rc = do_socketpair(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSSOTYPE: + /* let the UDS subsystem handle the actual request */ + rc = uds_do_ioctl(minor, request, endpt, grant); - /* get socket type -- getsockopt(SO_TYPE) */ - rc = do_getsockopt_sotype(dev_m_in, dev_m_out); - - break; + /* If the call couldn't complete, suspend the caller. */ + if (rc == EDONTREPLY) { + /* The suspension type is already set by the IOCTL handler. */ + if (uds_fd_table[minor].suspended == UDS_NOT_SUSPENDED) + panic("IOCTL did not actually suspend?"); + uds_fd_table[minor].susp_endpt = endpt; + uds_fd_table[minor].susp_grant = grant; + uds_fd_table[minor].susp_size = 0; /* irrelevant */ + uds_fd_table[minor].susp_id = id; - case NWIOGUDSPEERCRED: - - /* get peer endpoint -- getsockopt(SO_PEERCRED) */ - rc = do_getsockopt_peercred(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSTADDR: - - /* set target address -- sendto() */ - rc = do_sendto(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSFADDR: - - /* get from address -- recvfrom() */ - rc = do_recvfrom(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSSNDBUF: - - /* get the send buffer size -- getsockopt(SO_SNDBUF) */ - rc = do_getsockopt_sndbuf(dev_m_in, dev_m_out); - - break; + /* If the call wasn't supposed to block, cancel immediately. */ + if (flags & FLG_OP_NONBLOCK) { + uds_cancel(minor, endpt, id); - case NWIOSUDSSNDBUF: - - /* set the send buffer size -- setsockopt(SO_SNDBUF) */ - rc = do_setsockopt_sndbuf(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSRCVBUF: - - /* get the send buffer size -- getsockopt(SO_SNDBUF) */ - rc = do_getsockopt_rcvbuf(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSRCVBUF: - - /* set the send buffer size -- setsockopt(SO_SNDBUF) */ - rc = do_setsockopt_rcvbuf(dev_m_in, dev_m_out); - - break; - - case NWIOSUDSCTRL: - - /* set the control data -- sendmsg() */ - rc = do_sendmsg(dev_m_in, dev_m_out); - - break; - - case NWIOGUDSCTRL: - - /* set the control data -- recvmsg() */ - rc = do_recvmsg(dev_m_in, dev_m_out); - - break; - - default: - - /* the IOCTL command is not valid for /dev/uds -- - * this happens a lot and is normal. a lot of - * libc functions determine the socket type with - * IOCTLs. Any not for us simply get a EBADIOCTL - * response. - */ - - rc = EBADIOCTL; + rc = EAGAIN; + } } - if (rc != SUSPEND) - uds_fd_table[minor].syscall_done = 1; - - uds_set_reply(dev_m_out, DEV_REVIVE, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, rc); - return rc; } -int uds_unsuspend(endpoint_t m_source, int minor) +void uds_unsuspend(devminor_t minor) { - int r = OK, bytes; - message m_out; + int r; uds_fd_t *fdp; fdp = &uds_fd_table[minor]; - if (fdp->status_updated == 1) { - - /* clear the status_updated flag */ - fdp->status_updated = 0; - fdp->selecting = 0; + switch (fdp->suspended) { + case UDS_SUSPENDED_READ: + r = uds_perform_read(minor, fdp->susp_endpt, fdp->susp_grant, + fdp->susp_size, 0); - /* prepare the response */ - uds_sel_reply(&m_out, DEV_SEL_REPL2, minor, fdp->sel_ops_out); - } else if (fdp->ready_to_revive == 1) { + if (r == EDONTREPLY) + return; - /* clear the ready to revive flag */ - fdp->ready_to_revive = 0; + break; - switch (fdp->suspended) { + case UDS_SUSPENDED_WRITE: + r = uds_perform_write(minor, fdp->susp_endpt, fdp->susp_grant, + fdp->susp_size, 0); - case UDS_SUSPENDED_READ: + if (r == EDONTREPLY) + return; - bytes = uds_perform_read(minor, m_source, - fdp->io_gr_size, 0); - - if (bytes == SUSPEND) { - r = SUSPEND; - break; - } + break; - fdp->suspended = UDS_NOT_SUSPENDED; - - uds_set_reply(&m_out, DEV_REVIVE, fdp->endpoint, - fdp->io_gr, bytes); - - break; - - case UDS_SUSPENDED_WRITE: - - bytes = uds_perform_write(minor, m_source, - fdp->io_gr_size, 0); - - if (bytes == SUSPEND) { - r = SUSPEND; - break; - } - - fdp->suspended = UDS_NOT_SUSPENDED; - - uds_set_reply(&m_out, DEV_REVIVE, fdp->endpoint, - fdp->io_gr, bytes); - - break; - - case UDS_SUSPENDED_CONNECT: - case UDS_SUSPENDED_ACCEPT: - - /* In both cases, the process - * that send the notify() - * already performed the connection. - * The only thing to do here is - * unblock. - */ - - fdp->suspended = UDS_NOT_SUSPENDED; - - uds_set_reply(&m_out, DEV_REVIVE, fdp->endpoint, - fdp->io_gr, OK); - - break; + case UDS_SUSPENDED_CONNECT: + case UDS_SUSPENDED_ACCEPT: + /* In both cases, the caller already set up the connection. + * The only thing to do here is unblock. + */ + r = OK; - default: - return(OK); - } + break; + default: + panic("unknown suspension type %d", fdp->suspended); } - if (r == OK) reply(m_source, &m_out); - return(r); + chardriver_reply_task(fdp->susp_endpt, fdp->susp_id, r); + + fdp->suspended = UDS_NOT_SUSPENDED; } -int uds_cancel(message *dev_m_in, message *dev_m_out) +static int uds_cancel(devminor_t minor, endpoint_t endpt, cdev_id_t id) { + uds_fd_t *fdp; int i, j; - int minor; - /* XXX: should become a noop? */ + #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] uds_cancel() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); - printf("Endpoint: 0x%x\n", dev_m_in->USER_ENDPT); + printf("(uds) [%d] uds_cancel() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); + if (minor < 0 || minor >= NR_FDS) return EDONTREPLY; - if (uds_fd_table[minor].state != UDS_INUSE) { - /* attempted to cancel an unknown request - this happens */ - return SUSPEND; - } + fdp = &uds_fd_table[minor]; - /* Update the process endpoint. */ - uds_fd_table[minor].endpoint = dev_m_in->USER_ENDPT; + if (fdp->state != UDS_INUSE) { + printf("PFS: cancel request for closed minor %d\n", minor); + return EDONTREPLY; + } - /* setup select(2) framework */ - uds_fd_table[minor].selecting = 0; + /* Make sure the cancel request is for a request we're hanging on. */ + if (fdp->suspended == UDS_NOT_SUSPENDED || fdp->susp_endpt != endpt || + fdp->susp_id != id) { + return EDONTREPLY; /* this happens. */ + } - /* the system call was cancelled, so if the socket was suspended - * (which is likely the case), then it is not suspended anymore. + /* The system call was cancelled, so the socket is not suspended + * anymore. */ - uds_fd_table[minor].suspended = UDS_NOT_SUSPENDED; - - /* If there is a system call and it isn't complete, roll back */ - if (uds_fd_table[minor].call_nr && !uds_fd_table[minor].syscall_done) { - - - if (uds_fd_table[minor].call_nr == DEV_IOCTL_S) { - - switch (uds_fd_table[minor].ioctl) { - - case NWIOSUDSACCEPT: /* accept() */ - - /* partial accept() only changes - * uds_fd_table[minorparent].child - */ - - for (i = 0; i < NR_FDS; i++) { - if (uds_fd_table[i].child == - minor) { - - uds_fd_table[i].child = -1; - - } - } - - break; - - case NWIOSUDSCONN: /* connect() */ + switch (fdp->suspended) { + case UDS_SUSPENDED_ACCEPT: /* accept() */ + /* partial accept() only changes + * uds_fd_table[minorparent].child + */ + for (i = 0; i < NR_FDS; i++) { + if (uds_fd_table[i].child == minor) { + uds_fd_table[i].child = -1; + } + } - /* partial connect() sets addr - * and adds minor to server backlog - */ + break; - for (i = 0; i < NR_FDS; i++) { + case UDS_SUSPENDED_CONNECT: /* connect() */ + /* partial connect() sets addr and adds minor to server backlog + */ - /* find a socket that is in - * use. - */ - if (uds_fd_table[i].state == - UDS_INUSE) { + for (i = 0; i < NR_FDS; i++) { + /* find a socket that is in use. */ + if (uds_fd_table[i].state != UDS_INUSE) + continue; - /* see if minor is in - * the backlog - */ + /* see if minor is in the backlog */ for (j = 0; j < uds_fd_table[i].backlog_size; j++) { - if (uds_fd_table[i].backlog[j] == minor) { /* remove from backlog */ uds_fd_table[i].backlog[j] = -1; } } + } - } - } - - /* clear the address */ - memset(&(uds_fd_table[minor].addr), - '\0', - sizeof(struct sockaddr_un)); - - break; + /* clear the address */ + memset(&(uds_fd_table[minor].addr), '\0', + sizeof(struct sockaddr_un)); - case NWIOSUDSTADDR: /* sendto() */ - case NWIOSUDSADDR: /* bind() */ - case NWIOGUDSADDR: /* getsockname() */ - case NWIOGUDSPADDR: /* getpeername() */ - case NWIOSUDSTYPE: /* socket() */ - case NWIOSUDSBLOG: /* listen() */ - case NWIOSUDSSHUT: /* shutdown() */ - case NWIOSUDSPAIR: /* socketpair() */ - case NWIOGUDSSOTYPE: /* SO_TYPE */ - case NWIOGUDSPEERCRED: /* SO_PEERCRED */ - default: - /* these are atomic, never suspend, - * and can't be cancelled once called - */ - break; - } + break; - } - - /* DEV_READ_S or DEV_WRITE_S don't need to do anything - * when cancelled. DEV_OPEN, DEV_REOPEN, DEV_SELECT, - * DEV_CLOSE are atomic, never suspend, and can't - * be cancelled once called. - */ + case UDS_SUSPENDED_READ: + case UDS_SUSPENDED_WRITE: + /* Nothing more to do. */ + break; - uds_fd_table[minor].syscall_done = 1; + default: + panic("unknown suspension type %d", fdp->suspended); } - uds_set_reply(dev_m_out, DEV_REVIVE, dev_m_in->USER_ENDPT, - (cp_grant_id_t) dev_m_in->IO_GRANT, EINTR); + fdp->suspended = UDS_NOT_SUSPENDED; - return EINTR; + return EINTR; /* reply to the original request */ } diff --git a/servers/pfs/glo.h b/servers/pfs/glo.h index fd0db9075..96ca9c42e 100644 --- a/servers/pfs/glo.h +++ b/servers/pfs/glo.h @@ -13,12 +13,7 @@ EXTERN int err_code; /* temporary storage for error number */ EXTERN int(*fs_call_vec[]) (message *fs_m_in, message *fs_m_out); -EXTERN int(*dev_call_vec[]) (message *fs_m_in, message *fs_m_out); -EXTERN uid_t caller_uid; -EXTERN gid_t caller_gid; -EXTERN int req_nr; -EXTERN int SELF_E; EXTERN int exitsignaled; EXTERN int busy; EXTERN int unmountdone; diff --git a/servers/pfs/inode.c b/servers/pfs/inode.c index 7045d118e..e81cad202 100644 --- a/servers/pfs/inode.c +++ b/servers/pfs/inode.c @@ -237,7 +237,7 @@ struct inode *rip; /* pointer to inode to be released */ /*===========================================================================* * alloc_inode * *===========================================================================*/ -struct inode *alloc_inode(dev_t dev, pmode_t bits) +struct inode *alloc_inode(dev_t dev, pmode_t bits, uid_t uid, gid_t gid) { /* Allocate a free inode on 'dev', and return a pointer to it. */ @@ -267,8 +267,8 @@ struct inode *alloc_inode(dev_t dev, pmode_t bits) rip->i_mode = bits; /* set up RWX bits */ rip->i_nlinks = NO_LINK; /* initial no links */ - rip->i_uid = caller_uid; /* file's uid is owner's */ - rip->i_gid = caller_gid; /* ditto group id */ + rip->i_uid = uid; /* set file user id */ + rip->i_gid = gid; /* ditto group id */ /* Fields not cleared already are cleared in wipe_inode(). They have * been put there because truncate() needs to clear the same fields if diff --git a/servers/pfs/main.c b/servers/pfs/main.c index f88fe0cb2..72b987597 100644 --- a/servers/pfs/main.c +++ b/servers/pfs/main.c @@ -12,7 +12,7 @@ #include "inode.h" #include "uds.h" -static void get_work(message *m_in); +static void get_work(message *m_in, int *status); /* SEF functions and variables. */ static void sef_local_startup(void); @@ -28,20 +28,25 @@ 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, do_reply, transid; + int ind, transid, req_nr, ipc_status; message pfs_m_in; message pfs_m_out; + endpoint_t src; /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); while(!unmountdone || !exitsignaled) { - endpoint_t src; - - do_reply = 1; /* Wait for request message. */ - get_work(&pfs_m_in); + get_work(&pfs_m_in, &ipc_status); + + /* If this is a UDS device request, process it and continue. */ + if (IS_DEV_RQ(pfs_m_in.m_type)) { + uds_request(&pfs_m_in, ipc_status); + + continue; + } transid = TRNS_GET_ID(pfs_m_in.m_type); pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type); @@ -53,25 +58,9 @@ int main(int argc, char *argv[]) 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; req_nr = pfs_m_in.m_type; - if (IS_DEV_RQ(req_nr)) { - ind = req_nr - DEV_RQ_BASE; - if (ind < 0 || ind >= DEV_CALL_VEC_SIZE) { - printf("pfs: bad DEV request %d\n", req_nr); - pfs_m_out.m_type = EINVAL; - } else { - int result; - result = (*dev_call_vec[ind])(&pfs_m_in, &pfs_m_out); - if (pfs_m_out.REP_STATUS == SUSPEND || - result == SUSPEND) { - /* Nothing to tell, so not replying */ - do_reply = 0; - } - } - } else if (IS_VFS_RQ(req_nr)) { + if (IS_VFS_RQ(req_nr)) { ind = req_nr - VFS_BASE; if (ind < 0 || ind >= FS_CALL_VEC_SIZE) { printf("pfs: bad FS request %d\n", req_nr); @@ -85,13 +74,10 @@ int main(int argc, char *argv[]) pfs_m_out.m_type = EINVAL; } - if (do_reply) { - 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); + 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); } @@ -145,8 +131,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info) panic("unable to drop privileges"); } - SELF_E = getprocnr(); - return(OK); } @@ -165,15 +149,14 @@ static void sef_cb_signal_handler(int signo) /*===========================================================================* * get_work * *===========================================================================*/ -static void get_work(m_in) -message *m_in; /* pointer to message */ +static void get_work(message * m_in, int *status) { - int r, srcok = 0, status; + int r, srcok = 0; endpoint_t src; do { /* wait for a message */ - if ((r = sef_receive_status(ANY, m_in, &status)) != OK) + if ((r = sef_receive_status(ANY, m_in, status)) != OK) panic("sef_receive_status failed: %d", r); src = m_in->m_source; @@ -192,6 +175,8 @@ void reply(who, m_out) endpoint_t who; message *m_out; /* report result */ { - if (OK != send(who, m_out)) /* send the message */ - printf("PFS(%d) was unable to send reply\n", SELF_E); + int r; + + if (OK != (r = send(who, m_out))) /* send the message */ + printf("PFS: unable to send reply: %d\n", r); } diff --git a/servers/pfs/open.c b/servers/pfs/open.c index 1a6c33b77..b7fc0a57f 100644 --- a/servers/pfs/open.c +++ b/servers/pfs/open.c @@ -13,15 +13,17 @@ int fs_newnode(message *fs_m_in, message *fs_m_out) register int r = OK; pmode_t bits; struct inode *rip; + uid_t uid; + gid_t gid; dev_t dev; - caller_uid = (uid_t) fs_m_in->REQ_UID; - caller_gid = (gid_t) fs_m_in->REQ_GID; + uid = (uid_t) fs_m_in->REQ_UID; + gid = (gid_t) fs_m_in->REQ_GID; bits = (pmode_t) fs_m_in->REQ_MODE; dev = (dev_t) fs_m_in->REQ_DEV; /* Try to allocate the inode */ - if( (rip = alloc_inode(dev, bits) ) == NULL) return(err_code); + if( (rip = alloc_inode(dev, bits, uid, gid) ) == NULL) return(err_code); switch (bits & S_IFMT) { case S_IFBLK: diff --git a/servers/pfs/proto.h b/servers/pfs/proto.h index 1491cc272..b6dc5a9c4 100644 --- a/servers/pfs/proto.h +++ b/servers/pfs/proto.h @@ -17,7 +17,7 @@ void put_block(dev_t dev, pino_t inum); void buf_pool(void); /* inode.c */ -struct inode *alloc_inode(dev_t dev, pmode_t mode); +struct inode *alloc_inode(dev_t dev, pmode_t mode, uid_t uid, gid_t gid); void dup_inode(struct inode *ip); struct inode *find_inode(pino_t numb); void free_inode(struct inode *rip); @@ -61,37 +61,12 @@ bit_t alloc_bit(void); void free_bit(bit_t bit_returned); /* dev_uds.c */ -int uds_open(message *dev_m_in, message *dev_m_out); -int uds_close(message *dev_m_in, message *dev_m_out); -int uds_read(message *dev_m_in, message *dev_m_out); -int uds_write(message *dev_m_in, message *dev_m_out); -int uds_ioctl(message *dev_m_in, message *dev_m_out); -int uds_select(message *dev_m_in, message *dev_m_out); -int uds_unsuspend(endpoint_t m_source, int minor); -int uds_cancel(message *dev_m_in, message *dev_m_out); +void uds_request(message *m_ptr, int ipc_status); +void uds_unsuspend(devminor_t minor); /* uds.c */ void uds_init(void); -int do_accept(message *dev_m_in, message *dev_m_out); -int do_connect(message *dev_m_in, message *dev_m_out); -int do_listen(message *dev_m_in, message *dev_m_out); -int do_socket(message *dev_m_in, message *dev_m_out); -int do_bind(message *dev_m_in, message *dev_m_out); -int do_getsockname(message *dev_m_in, message *dev_m_out); -int do_getpeername(message *dev_m_in, message *dev_m_out); -int do_shutdown(message *dev_m_in, message *dev_m_out); -int do_socketpair(message *dev_m_in, message *dev_m_out); -int do_getsockopt_sotype(message *dev_m_in, message *dev_m_out); -int do_getsockopt_peercred(message *dev_m_in, message *dev_m_out); -int do_getsockopt_sndbuf(message *dev_m_in, message *dev_m_out); -int do_setsockopt_sndbuf(message *dev_m_in, message *dev_m_out); -int do_getsockopt_rcvbuf(message *dev_m_in, message *dev_m_out); -int do_setsockopt_rcvbuf(message *dev_m_in, message *dev_m_out); -int do_sendto(message *dev_m_in, message *dev_m_out); -int do_recvfrom(message *dev_m_in, message *dev_m_out); -int do_sendmsg(message *dev_m_in, message *dev_m_out); -int do_recvmsg(message *dev_m_in, message *dev_m_out); -int perform_connection(message *dev_m_in, message *dev_m_out, struct - sockaddr_un *addr, int minorx, int minory); -int clear_fds(int minor, struct ancillary *data); +int uds_clear_fds(devminor_t minor, struct ancillary *data); +int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, + cp_grant_id_t grant); #endif diff --git a/servers/pfs/read.c b/servers/pfs/read.c index a4a5af325..f5359a096 100644 --- a/servers/pfs/read.c +++ b/servers/pfs/read.c @@ -63,11 +63,11 @@ int fs_readwrite(message *fs_m_in, message *fs_m_out) if (rw_flag == READING) { /* Copy a chunk from the block buffer to user space. */ - r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0, + r = sys_safecopyto(fs_m_in->m_source, gid, (vir_bytes) 0, (vir_bytes) (bp->b_data+position), (size_t) nrbytes); } else { /* Copy a chunk from user space to the block buffer. */ - r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) 0, + r = sys_safecopyfrom(fs_m_in->m_source, gid, (vir_bytes) 0, (vir_bytes) (bp->b_data+position), (size_t) nrbytes); } diff --git a/servers/pfs/table.c b/servers/pfs/table.c index af1e754ca..0169b0b25 100644 --- a/servers/pfs/table.c +++ b/servers/pfs/table.c @@ -1,10 +1,11 @@ -/* This file contains the table used to map system call numbers onto the +/* This file contains the table used to map VFS/FS call numbers onto the * routines that perform them. */ #define _TABLE +#include "inc.h" #include "fs.h" #include "inode.h" #include "buf.h" @@ -12,7 +13,6 @@ /* File System Handlers (pfs) */ int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = { - no_sys, /* 0 not used */ no_sys, /* 1 */ fs_putnode, /* 2 */ @@ -47,34 +47,3 @@ int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = { no_sys, /* 31 */ no_sys, /* 32 */ }; - -/* Device Handlers (/dev/uds) */ -int (*dev_call_vec[])(message *dev_m_in, message *dev_m_out) = { - - uds_cancel, /* 0 CANCEL */ - no_sys, /* 1 */ - no_sys, /* 2 */ - no_sys, /* 3 */ - no_sys, /* 4 */ - no_sys, /* 5 */ - uds_open, /* 6 DEV_OPEN */ - uds_close, /* 7 DEV_CLOSE */ - no_sys, /* 8 */ - no_sys, /* 9 */ - no_sys, /* 10 */ - no_sys, /* 11 */ - uds_select, /* 12 DEV_SELECT */ - no_sys, /* 13 */ - uds_open, /* 14 DEV_REOPEN */ - no_sys, /* 15 */ - no_sys, /* 16 */ - no_sys, /* 17 */ - no_sys, /* 18 */ - no_sys, /* 19 */ - uds_read, /* 20 DEV_READ_S */ - uds_write, /* 21 DEV_WRITE_S */ - no_sys, /* 22 DEV_SCATTER_S */ - no_sys, /* 23 DEV_GATHER_S */ - uds_ioctl, /* 24 DEV_IOCTL_S */ - no_sys, /* 25 DEV_MMAP_S */ -}; diff --git a/servers/pfs/uds.c b/servers/pfs/uds.c index 9142a87bb..b6d6b17cc 100644 --- a/servers/pfs/uds.c +++ b/servers/pfs/uds.c @@ -6,31 +6,12 @@ * The entry points into this file are... * * uds_init: initialize the descriptor table. - * do_accept: handles the accept(2) syscall. - * do_connect: handles the connect(2) syscall. - * do_listen: handles the listen(2) syscall. - * do_socket: handles the socket(2) syscall. - * do_bind: handles the bind(2) syscall. - * do_getsockname: handles the getsockname(2) syscall. - * do_getpeername: handles the getpeername(2) syscall. - * do_shutdown: handles the shutdown(2) syscall. - * do_socketpair: handles the socketpair(2) syscall. - * do_getsockopt_sotype: handles the getsockopt(2) syscall. - * do_getsockopt_peercred: handles the getsockopt(2) syscall. - * do_getsockopt_sndbuf: handles the getsockopt(2) syscall. - * do_setsockopt_sndbuf: handles the setsockopt(2) syscall. - * do_getsockopt_rcvbuf: handles the getsockopt(2) syscall. - * do_setsockopt_rcvbuf: handles the setsockopt(2) syscall. - * do_sendto: handles the sendto(2) syscall. - * do_recvfrom: handles the recvfrom(2) syscall. - * do_sendmsg: handles the sendmsg(2) syscall. - * do_recvmsg: handles the recvmsg(2) syscall. - * perform_connection: performs the connection of two descriptors. - * clear_fds: calls put_filp for undelivered FDs. + * uds_do_ioctl: process an IOCTL request. + * uds_clear_fds: calls put_filp for undelivered FDs. * * Also see... * - * table.c, dev_uds.c, uds.h + * dev_uds.c, uds.h */ #define DEBUG 0 @@ -54,7 +35,7 @@ void uds_init(void) } /* check the permissions of a socket file */ -static int check_perms(int minor, struct sockaddr_un *addr) +static int check_perms(devminor_t minor, struct sockaddr_un *addr) { int rc; message vfs_m; @@ -126,7 +107,7 @@ static int set_filp(filp_id_t sfilp) #if DEBUG == 1 static int call_count = 0; - printf("(uds) set_filp(0x%x) call_count=%d\n", sfilp, ++call_count); + printf("(uds) set_filp(%p) call_count=%d\n", sfilp, ++call_count); #endif memset(&vfs_m, '\0', sizeof(message)); @@ -154,7 +135,7 @@ static int copy_filp(endpoint_t to_ep, filp_id_t cfilp) #if DEBUG == 1 static int call_count = 0; - printf("(uds) copy_filp(%d, 0x%x) call_count=%d\n",to_ep, cfilp, + printf("(uds) copy_filp(%d, %p) call_count=%d\n",to_ep, cfilp, ++call_count); #endif @@ -184,7 +165,7 @@ static int put_filp(filp_id_t pfilp) #if DEBUG == 1 static int call_count = 0; - printf("(uds) put_filp(0x%x) call_count=%d\n", pfilp, ++call_count); + printf("(uds) put_filp(%p) call_count=%d\n", pfilp, ++call_count); #endif memset(&vfs_m, '\0', sizeof(message)); @@ -234,8 +215,8 @@ static int cancel_fd(endpoint_t ep, int fd) return vfs_m.m_type; /* return reply code OK, ELOOP, etc. */ } -int perform_connection(message *dev_m_in, message *dev_m_out, - struct sockaddr_un *addr, int minorx, int minory) +static int perform_connection(devminor_t minorx, devminor_t minory, + struct sockaddr_un *addr) { /* there are several places were a connection is established. */ /* accept(2), connect(2), uds_status(2), socketpair(2) */ @@ -244,8 +225,8 @@ int perform_connection(message *dev_m_in, message *dev_m_out, #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] perform_connection() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] perform_connection() call_count=%d\n", minorx, + ++call_count); #endif /* only connection oriented types are acceptable and only like @@ -270,19 +251,16 @@ int perform_connection(message *dev_m_in, message *dev_m_out, return OK; } - -int do_accept(message *dev_m_in, message *dev_m_out) +static int do_accept(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; - int minorparent; /* minor number of parent (server) */ - int minorpeer; + devminor_t minorparent; /* minor number of parent (server) */ + devminor_t minorpeer; int rc, i; struct sockaddr_un addr; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_accept() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_accept() call_count=%d\n", minor, ++call_count); #endif /* Somewhat weird logic is used in this function, so here's an @@ -294,16 +272,14 @@ int do_accept(message *dev_m_in, message *dev_m_out) * connection or suspend and wait for a connect(). */ - minor = uds_minor(dev_m_in); - if (uds_fd_table[minor].type != -1) { /* this IOCTL must be called on a 'fresh' socket */ return EINVAL; } /* Get the server's address */ - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &addr, sizeof(struct sockaddr_un)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr, + sizeof(struct sockaddr_un)); if (rc != OK) { return EIO; @@ -313,7 +289,6 @@ int do_accept(message *dev_m_in, message *dev_m_out) rc = -1; /* to trap error */ for (i = 0; i < NR_FDS; i++) { - if (uds_fd_table[i].addr.sun_family == AF_UNIX && !strncmp(addr.sun_path, uds_fd_table[i].addr.sun_path, @@ -364,7 +339,7 @@ int do_accept(message *dev_m_in, message *dev_m_out) */ uds_fd_table[minor].suspended = UDS_SUSPENDED_ACCEPT; - return SUSPEND; + return EDONTREPLY; } #if DEBUG == 1 @@ -372,7 +347,7 @@ int do_accept(message *dev_m_in, message *dev_m_out) minorpeer, minorparent); #endif - rc = perform_connection(dev_m_in, dev_m_out, &addr, minor, minorpeer); + rc = perform_connection(minor, minorpeer, &addr); if (rc != OK) { #if DEBUG == 1 printf("(uds) [%d] {do_accept} connection not performed\n", @@ -389,27 +364,23 @@ int do_accept(message *dev_m_in, message *dev_m_out) printf("(uds) [%d] {do_accept} revive %d\n", minor, minorpeer); #endif - uds_fd_table[minorpeer].ready_to_revive = 1; - uds_unsuspend(dev_m_in->m_source, minorpeer); + uds_unsuspend(minorpeer); } return OK; } -int do_connect(message *dev_m_in, message *dev_m_out) +static int do_connect(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor, child; + int child; struct sockaddr_un addr; int rc, i, j; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_connect() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); + printf("(uds) [%d] do_connect() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); - /* only connection oriented sockets can connect */ if (uds_fd_table[minor].type != SOCK_STREAM && uds_fd_table[minor].type != SOCK_SEQPACKET) { @@ -421,9 +392,8 @@ int do_connect(message *dev_m_in, message *dev_m_out) return EISCONN; } - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &addr, - sizeof(struct sockaddr_un)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr, + sizeof(struct sockaddr_un)); if (rc != OK) { return EIO; @@ -439,7 +409,6 @@ int do_connect(message *dev_m_in, message *dev_m_out) * address we want to connect to */ for (i = 0; i < NR_FDS; i++) { - if (uds_fd_table[minor].type == uds_fd_table[i].type && uds_fd_table[i].listening && uds_fd_table[i].addr.sun_family == AF_UNIX && @@ -452,11 +421,9 @@ int do_connect(message *dev_m_in, message *dev_m_out) * perform connection to the child */ - rc = perform_connection(dev_m_in, dev_m_out, - &addr, minor, child); + rc = perform_connection(minor, child, &addr); if (rc == OK) { - uds_fd_table[i].child = -1; #if DEBUG == 1 @@ -464,16 +431,11 @@ int do_connect(message *dev_m_in, message *dev_m_out) #endif /* wake the parent (server) */ - uds_fd_table[child].ready_to_revive = - 1; - uds_unsuspend(dev_m_in->m_source, - child); + uds_unsuspend(child); } return rc; - } else { - #if DEBUG == 1 printf("(uds) [%d] adding to %d's backlog\n", minor, i); @@ -497,33 +459,23 @@ int do_connect(message *dev_m_in, message *dev_m_out) } if (rc == -1) { - /* backlog is full */ break; } /* see if the server is blocked on select() */ - if (uds_fd_table[i].selecting == 1) { - - /* if the server wants to know - * about data ready to read and - * it doesn't know about it - * already, then let the server - * know we have data for it. + if (uds_fd_table[i].sel_ops & SEL_RD) { + /* if the server wants to know about + * data ready to read and it doesn't + * doesn't know about it already, then + * let the server know we have data for + * it. */ - if ((uds_fd_table[i].sel_ops_in & - SEL_RD) && - !(uds_fd_table[i].sel_ops_out & - SEL_RD)) { - - uds_fd_table[i].sel_ops_out |= - SEL_RD; - uds_fd_table[i].status_updated - = 1; - - uds_unsuspend( - dev_m_in->m_source, i); - } + chardriver_reply_select( + uds_fd_table[i].sel_endpt, i, + SEL_RD); + + uds_fd_table[i].sel_ops &= ~SEL_RD; } /* we found our server */ @@ -554,23 +506,19 @@ int do_connect(message *dev_m_in, message *dev_m_out) uds_fd_table[minor].suspended = UDS_SUSPENDED_CONNECT; - return SUSPEND; + return EDONTREPLY; } -int do_listen(message *dev_m_in, message *dev_m_out) +static int do_listen(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; int rc; int backlog_size; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_listen() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); + printf("(uds) [%d] do_listen() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); - /* ensure the socket has a type and is bound */ if (uds_fd_table[minor].type == -1 || uds_fd_table[minor].addr.sun_family != AF_UNIX) { @@ -594,8 +542,8 @@ int do_listen(message *dev_m_in, message *dev_m_out) * let it happen, but if listen() has already been called, we * don't allow the backlog to shrink */ - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &backlog_size, sizeof(int)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &backlog_size, + sizeof(int)); if (rc != OK) { return EIO; @@ -637,19 +585,15 @@ int do_listen(message *dev_m_in, message *dev_m_out) return OK; } -int do_socket(message *dev_m_in, message *dev_m_out) +static int do_socket(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { int rc; - int minor; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_socket() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); + printf("(uds) [%d] do_socket() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); - /* see if this socket already has a type */ if (uds_fd_table[minor].type != -1) { /* socket type can only be set once */ @@ -657,12 +601,10 @@ int do_socket(message *dev_m_in, message *dev_m_out) } /* get the requested type */ - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &(uds_fd_table[minor].type), - sizeof(int)); + rc = sys_safecopyfrom(endpt, grant, 0, + (vir_bytes) &uds_fd_table[minor].type, sizeof(int)); if (rc != OK) { - /* something went wrong and we couldn't get the type */ return EIO; } @@ -672,12 +614,10 @@ int do_socket(message *dev_m_in, message *dev_m_out) case SOCK_STREAM: case SOCK_DGRAM: case SOCK_SEQPACKET: - /* the type is one of the 3 valid socket types */ return OK; default: - /* if the type isn't one of the 3 valid socket * types, then it must be invalid. */ @@ -689,20 +629,16 @@ int do_socket(message *dev_m_in, message *dev_m_out) } } -int do_bind(message *dev_m_in, message *dev_m_out) +static int do_bind(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; struct sockaddr_un addr; int rc, i; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_bind() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); + printf("(uds) [%d] do_bind() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); - if ((uds_fd_table[minor].type == -1) || (uds_fd_table[minor].addr.sun_family == AF_UNIX && uds_fd_table[minor].type != SOCK_DGRAM)) { @@ -713,8 +649,8 @@ int do_bind(message *dev_m_in, message *dev_m_out) return EINVAL; } - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &addr, sizeof(struct sockaddr_un)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr, + sizeof(struct sockaddr_un)); if (rc != OK) { return EIO; @@ -722,13 +658,11 @@ int do_bind(message *dev_m_in, message *dev_m_out) /* do some basic sanity checks on the address */ if (addr.sun_family != AF_UNIX) { - /* bad family */ return EAFNOSUPPORT; } if (addr.sun_path[0] == '\0') { - /* bad address */ return ENOENT; } @@ -756,45 +690,41 @@ int do_bind(message *dev_m_in, message *dev_m_out) return OK; } -int do_getsockname(message *dev_m_in, message *dev_m_out) +static int do_getsockname(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { - int minor; int rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_getsockname() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_getsockname() call_count=%d\n", minor, + ++call_count); #endif - minor = uds_minor(dev_m_in); - /* Unconditionally send the address we have assigned to this socket. * The POSIX standard doesn't say what to do if the address * hasn't been set. If the address isn't currently set, then * the user will get NULL bytes. Note: libc depends on this * behavior. */ - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &(uds_fd_table[minor].addr), + rc = sys_safecopyto(endpt, grant, 0, + (vir_bytes) &uds_fd_table[minor].addr, sizeof(struct sockaddr_un)); return rc ? EIO : OK; } -int do_getpeername(message *dev_m_in, message *dev_m_out) +static int do_getpeername(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { - int minor; int rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_getpeername() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_getpeername() call_count=%d\n", minor, + ++call_count); #endif - minor = uds_minor(dev_m_in); - /* check that the socket is connected with a valid peer */ if (uds_fd_table[minor].peer != -1) { int peer_minor; @@ -802,9 +732,8 @@ int do_getpeername(message *dev_m_in, message *dev_m_out) peer_minor = uds_fd_table[minor].peer; /* copy the address from the peer */ - rc = sys_safecopyto(VFS_PROC_NR, - (cp_grant_id_t) dev_m_in->IO_GRANT, (vir_bytes) 0, - (vir_bytes) &(uds_fd_table[peer_minor].addr), + rc = sys_safecopyto(endpt, grant, 0, + (vir_bytes) &uds_fd_table[peer_minor].addr, sizeof(struct sockaddr_un)); return rc ? EIO : OK; @@ -819,19 +748,16 @@ int do_getpeername(message *dev_m_in, message *dev_m_out) } } -int do_shutdown(message *dev_m_in, message *dev_m_out) +static int do_shutdown(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; int rc, how; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_shutdown() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_shutdown() call_count=%d\n", minor, + ++call_count); #endif - minor = uds_minor(dev_m_in); - if (uds_fd_table[minor].type != SOCK_STREAM && uds_fd_table[minor].type != SOCK_SEQPACKET) { @@ -849,8 +775,7 @@ int do_shutdown(message *dev_m_in, message *dev_m_out) } /* get the 'how' parameter from the process */ - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &how, sizeof(int)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &how, sizeof(int)); if (rc != OK) { return EIO; @@ -880,25 +805,23 @@ int do_shutdown(message *dev_m_in, message *dev_m_out) return OK; } -int do_socketpair(message *dev_m_in, message *dev_m_out) +static int do_socketpair(devminor_t minorx, endpoint_t endpt, + cp_grant_id_t grant) { int rc; dev_t minorin; - int minorx, minory; + devminor_t minory; struct sockaddr_un addr; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_socketpair() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_socketpair() call_count=%d\n", minorx, + ++call_count); #endif - /* first ioctl param is the first socket */ - minorx = uds_minor(dev_m_in); - - /* third ioctl param is the minor number of the second socket */ - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &minorin, sizeof(dev_t)); + /* ioctl argument is the minor number of the second socket */ + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &minorin, + sizeof(dev_t)); if (rc != OK) { return EIO; @@ -912,7 +835,6 @@ int do_socketpair(message *dev_m_in, message *dev_m_out) /* security check - both sockets must have the same endpoint (owner) */ if (uds_fd_table[minorx].owner != uds_fd_table[minory].owner) { - /* we won't allow you to magically connect your socket to * someone elses socket */ @@ -923,53 +845,46 @@ int do_socketpair(message *dev_m_in, message *dev_m_out) addr.sun_path[0] = 'X'; addr.sun_path[1] = '\0'; - uds_fd_table[minorx].syscall_done = 1; - return perform_connection(dev_m_in, dev_m_out, &addr, minorx, minory); + return perform_connection(minorx, minory, &addr); } -int do_getsockopt_sotype(message *dev_m_in, message *dev_m_out) +static int do_getsockopt_sotype(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { - int minor; int rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_getsockopt_sotype() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_getsockopt_sotype() call_count=%d\n", minor, + ++call_count); #endif - minor = uds_minor(dev_m_in); - if (uds_fd_table[minor].type == -1) { - /* the type hasn't been set yet. instead of returning an * invalid type, we fail with EINVAL */ return EINVAL; } - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &(uds_fd_table[minor].type), - sizeof(int)); + rc = sys_safecopyto(endpt, grant, 0, + (vir_bytes) &uds_fd_table[minor].type, sizeof(int)); return rc ? EIO : OK; } -int do_getsockopt_peercred(message *dev_m_in, message *dev_m_out) +static int do_getsockopt_peercred(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { - int minor; int peer_minor; int rc; struct uucred cred; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_getsockopt_peercred() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_getsockopt_peercred() call_count=%d\n", minor, + ++call_count); #endif - minor = uds_minor(dev_m_in); - if (uds_fd_table[minor].peer == -1) { if (uds_fd_table[minor].err == ECONNRESET) { @@ -990,43 +905,44 @@ int do_getsockopt_peercred(message *dev_m_in, message *dev_m_out) return errno; } - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &cred, sizeof(struct uucred)); + rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &cred, + sizeof(struct uucred)); return rc ? EIO : OK; } -int do_getsockopt_sndbuf(message *dev_m_in, message *dev_m_out) +static int do_getsockopt_sndbuf(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { int rc; size_t sndbuf = PIPE_BUF; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_getsockopt_sndbuf() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_getsockopt_sndbuf() call_count=%d\n", minor, + ++call_count); #endif - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &(sndbuf), sizeof(size_t)); + rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &sndbuf, + sizeof(size_t)); return rc ? EIO : OK; } -int do_setsockopt_sndbuf(message *dev_m_in, message *dev_m_out) +static int do_setsockopt_sndbuf(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { int rc; size_t sndbuf; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_setsockopt_rcvbuf() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_setsockopt_rcvbuf() call_count=%d\n", minor, + ++call_count); #endif - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &sndbuf, - sizeof(size_t)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &sndbuf, + sizeof(size_t)); if (rc != OK) { return EIO; @@ -1043,37 +959,38 @@ int do_setsockopt_sndbuf(message *dev_m_in, message *dev_m_out) return OK; } -int do_getsockopt_rcvbuf(message *dev_m_in, message *dev_m_out) +static int do_getsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { int rc; size_t rcvbuf = PIPE_BUF; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_getsockopt_rcvbuf() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_getsockopt_rcvbuf() call_count=%d\n", minor, + ++call_count); #endif - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &(rcvbuf), sizeof(size_t)); + rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &rcvbuf, + sizeof(size_t)); return rc ? EIO : OK; } -int do_setsockopt_rcvbuf(message *dev_m_in, message *dev_m_out) +static int do_setsockopt_rcvbuf(devminor_t minor, endpoint_t endpt, + cp_grant_id_t grant) { int rc; size_t rcvbuf; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_setsockopt_rcvbuf() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_setsockopt_rcvbuf() call_count=%d\n", minor, + ++call_count); #endif - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &rcvbuf, - sizeof(size_t)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &rcvbuf, + sizeof(size_t)); if (rc != OK) { return EIO; @@ -1090,28 +1007,23 @@ int do_setsockopt_rcvbuf(message *dev_m_in, message *dev_m_out) return OK; } - -int do_sendto(message *dev_m_in, message *dev_m_out) +static int do_sendto(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; int rc; struct sockaddr_un addr; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_sendto() call_count=%d\n", uds_minor(dev_m_in), - ++call_count); + printf("(uds) [%d] do_sendto() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); - if (uds_fd_table[minor].type != SOCK_DGRAM) { /* This IOCTL is only for SOCK_DGRAM sockets */ return EINVAL; } - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &addr, sizeof(struct sockaddr_un)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &addr, + sizeof(struct sockaddr_un)); if (rc != OK) { return EIO; @@ -1134,28 +1046,25 @@ int do_sendto(message *dev_m_in, message *dev_m_out) return OK; } -int do_recvfrom(message *dev_m_in, message *dev_m_out) +static int do_recvfrom(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; int rc; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_recvfrom() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_recvfrom() call_count=%d\n", minor, + ++call_count); #endif - minor = uds_minor(dev_m_in); - - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &(uds_fd_table[minor].source), + rc = sys_safecopyto(endpt, grant, 0, + (vir_bytes) &uds_fd_table[minor].source, sizeof(struct sockaddr_un)); return rc ? EIO : OK; } -int msg_control_read(struct msg_control *msg_ctrl, struct ancillary *data, - int minor) +static int msg_control_read(struct msg_control *msg_ctrl, + struct ancillary *data, devminor_t minor) { int rc; struct msghdr msghdr; @@ -1213,7 +1122,7 @@ int msg_control_read(struct msg_control *msg_ctrl, struct ancillary *data, return OK; } -static int send_fds(int minor, struct ancillary *data) +static int send_fds(devminor_t minor, struct ancillary *data) { int rc, i, j; @@ -1247,7 +1156,7 @@ static int send_fds(int minor, struct ancillary *data) return OK; } -int clear_fds(int minor, struct ancillary *data) +int uds_clear_fds(devminor_t minor, struct ancillary *data) { /* This function calls put_filp() for all of the FDs in data. * This is used when a Unix Domain Socket is closed and there @@ -1258,14 +1167,14 @@ int clear_fds(int minor, struct ancillary *data) #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] recv_fds() call_count=%d\n", minor, + printf("(uds) [%d] uds_clear_fds() call_count=%d\n", minor, ++call_count); #endif for (i = 0; i < data->nfiledes; i++) { put_filp(data->filps[i]); #if DEBUG == 1 - printf("(uds) clear_fds() => %d\n", data->fds[i]); + printf("(uds) uds_clear_fds() => %d\n", data->fds[i]); #endif data->fds[i] = -1; data->filps[i] = NULL; @@ -1276,7 +1185,7 @@ int clear_fds(int minor, struct ancillary *data) return OK; } -static int recv_fds(int minor, struct ancillary *data, +static int recv_fds(devminor_t minor, struct ancillary *data, struct msg_control *msg_ctrl) { int rc, i, j; @@ -1332,7 +1241,7 @@ static int recv_fds(int minor, struct ancillary *data, return OK; } -static int recv_cred(int minor, struct ancillary *data, +static int recv_cred(devminor_t minor, struct ancillary *data, struct msg_control *msg_ctrl) { struct msghdr msghdr; @@ -1360,24 +1269,20 @@ static int recv_cred(int minor, struct ancillary *data, return OK; } -int do_sendmsg(message *dev_m_in, message *dev_m_out) +static int do_sendmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor, peer, rc, i; + int peer, rc, i; struct msg_control msg_ctrl; #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_sendmsg() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); + printf("(uds) [%d] do_sendmsg() call_count=%d\n", minor, ++call_count); #endif - minor = uds_minor(dev_m_in); - memset(&msg_ctrl, '\0', sizeof(struct msg_control)); - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &msg_ctrl, - sizeof(struct msg_control)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &msg_ctrl, + sizeof(struct msg_control)); if (rc != OK) { return EIO; @@ -1434,9 +1339,8 @@ int do_sendmsg(message *dev_m_in, message *dev_m_out) return send_fds(minor, &uds_fd_table[peer].ancillary_data); } -int do_recvmsg(message *dev_m_in, message *dev_m_out) +static int do_recvmsg(devminor_t minor, endpoint_t endpt, cp_grant_id_t grant) { - int minor; int rc; struct msg_control msg_ctrl; socklen_t controllen_avail = 0; @@ -1445,14 +1349,7 @@ int do_recvmsg(message *dev_m_in, message *dev_m_out) #if DEBUG == 1 static int call_count = 0; - printf("(uds) [%d] do_sendmsg() call_count=%d\n", - uds_minor(dev_m_in), ++call_count); -#endif - - minor = uds_minor(dev_m_in); - - -#if DEBUG == 1 + printf("(uds) [%d] do_sendmsg() call_count=%d\n", minor, ++call_count); printf("(uds) [%d] CREDENTIALS {pid:%d,uid:%d,gid:%d}\n", minor, uds_fd_table[minor].ancillary_data.cred.pid, uds_fd_table[minor].ancillary_data.cred.uid, @@ -1464,9 +1361,8 @@ int do_recvmsg(message *dev_m_in, message *dev_m_out) /* get the msg_control from the user, it will include the * amount of space the user has allocated for control data. */ - rc = sys_safecopyfrom(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &msg_ctrl, - sizeof(struct msg_control)); + rc = sys_safecopyfrom(endpt, grant, 0, (vir_bytes) &msg_ctrl, + sizeof(struct msg_control)); if (rc != OK) { return EIO; @@ -1501,9 +1397,147 @@ int do_recvmsg(message *dev_m_in, message *dev_m_out) } /* send the user the control data */ - rc = sys_safecopyto(VFS_PROC_NR, (cp_grant_id_t) dev_m_in->IO_GRANT, - (vir_bytes) 0, (vir_bytes) &msg_ctrl, + rc = sys_safecopyto(endpt, grant, 0, (vir_bytes) &msg_ctrl, sizeof(struct msg_control)); return rc ? EIO : OK; } + +int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt, + cp_grant_id_t grant) +{ + int rc; + + switch (request) { /* Handle the ioctl(2) command */ + case NWIOSUDSCONN: + /* connect to a listening socket -- connect() */ + rc = do_connect(minor, endpt, grant); + + break; + + case NWIOSUDSACCEPT: + /* accept an incoming connection -- accept() */ + rc = do_accept(minor, endpt, grant); + + break; + + case NWIOSUDSBLOG: + /* set the backlog_size and put the socket into the listening + * state -- listen() + */ + rc = do_listen(minor, endpt, grant); + + break; + + case NWIOSUDSTYPE: + /* set the type for this socket (i.e. SOCK_STREAM, SOCK_DGRAM, + * etc) -- socket() + */ + rc = do_socket(minor, endpt, grant); + + break; + + case NWIOSUDSADDR: + /* set the address for this socket -- bind() */ + rc = do_bind(minor, endpt, grant); + + break; + + case NWIOGUDSADDR: + /* get the address for this socket -- getsockname() */ + rc = do_getsockname(minor, endpt, grant); + + break; + + case NWIOGUDSPADDR: + /* get the address for the peer -- getpeername() */ + rc = do_getpeername(minor, endpt, grant); + + break; + + case NWIOSUDSSHUT: + /* shutdown a socket for reading, writing, or both -- + * shutdown() + */ + rc = do_shutdown(minor, endpt, grant); + + break; + + case NWIOSUDSPAIR: + /* connect two sockets -- socketpair() */ + rc = do_socketpair(minor, endpt, grant); + + break; + + case NWIOGUDSSOTYPE: + /* get socket type -- getsockopt(SO_TYPE) */ + rc = do_getsockopt_sotype(minor, endpt, grant); + + break; + + case NWIOGUDSPEERCRED: + /* get peer endpoint -- getsockopt(SO_PEERCRED) */ + rc = do_getsockopt_peercred(minor, endpt, grant); + + break; + + case NWIOSUDSTADDR: + /* set target address -- sendto() */ + rc = do_sendto(minor, endpt, grant); + + break; + + case NWIOGUDSFADDR: + /* get from address -- recvfrom() */ + rc = do_recvfrom(minor, endpt, grant); + + break; + + case NWIOGUDSSNDBUF: + /* get the send buffer size -- getsockopt(SO_SNDBUF) */ + rc = do_getsockopt_sndbuf(minor, endpt, grant); + + break; + + case NWIOSUDSSNDBUF: + /* set the send buffer size -- setsockopt(SO_SNDBUF) */ + rc = do_setsockopt_sndbuf(minor, endpt, grant); + + break; + + case NWIOGUDSRCVBUF: + /* get the send buffer size -- getsockopt(SO_SNDBUF) */ + rc = do_getsockopt_rcvbuf(minor, endpt, grant); + + break; + + case NWIOSUDSRCVBUF: + /* set the send buffer size -- setsockopt(SO_SNDBUF) */ + rc = do_setsockopt_rcvbuf(minor, endpt, grant); + + break; + + case NWIOSUDSCTRL: + /* set the control data -- sendmsg() */ + rc = do_sendmsg(minor, endpt, grant); + + break; + + case NWIOGUDSCTRL: + /* set the control data -- recvmsg() */ + rc = do_recvmsg(minor, endpt, grant); + + break; + + default: + /* the IOCTL command is not valid for /dev/uds -- this happens + * a lot and is normal. a lot of libc functions determine the + * socket type with IOCTLs. Any not for us simply get an ENOTTY + * response. + */ + + rc = ENOTTY; + } + + return rc; +} diff --git a/servers/pfs/uds.h b/servers/pfs/uds.h index 93b2ee347..cc51efdcc 100644 --- a/servers/pfs/uds.h +++ b/servers/pfs/uds.h @@ -15,6 +15,7 @@ #include #include +#include /* max connection backlog for incoming connections */ #define UDS_SOMAXCONN 64 @@ -54,9 +55,6 @@ struct uds_fd { /* Socket Owner */ endpoint_t owner; - /* endpoint for suspend/resume */ - endpoint_t endpoint; - /* Pipe Housekeeping */ /* inode number on PFS -- each descriptor is backed by 1 @@ -82,7 +80,6 @@ struct uds_fd { /* Socket Info */ - /* socket type - SOCK_STREAM, SOCK_DGRAM, or SOCK_SEQPACKET * Set by uds_ioctl(NWIOSUDSTYPE). It defaults to -1 in * uds_open(). Any action on a socket with type -1 besides @@ -144,7 +141,6 @@ struct uds_fd { /* Suspend/Revive Housekeeping */ - /* SUSPEND State Flags */ enum UDS_SUSPENDED { @@ -164,56 +160,27 @@ struct uds_fd { UDS_SUSPENDED_ACCEPT = 8 } suspended; - /* Flag (1 or 0) - thing socket was waiting for is ready. - * If 1, then uds_status() will attempt the operation that - * the socket was blocked on. - */ - int ready_to_revive; + /* source endpoint, saved for later use by suspended procs */ + endpoint_t susp_endpt; /* i/o grant, saved for later use by suspended procs */ - cp_grant_id_t io_gr; - - /* is of i/o grant, saved for later use by suspended procs */ - size_t io_gr_size; - - /* Save the call number so that uds_cancel() can unwind the - * call properly. - */ - int call_nr; + cp_grant_id_t susp_grant; - /* Save the IOCTL so uds_cancel() knows what got cancelled. */ - int ioctl; + /* size of request, saved for later use by suspended procs */ + size_t susp_size; - /* Flag (1 or 0) - the system call completed. - * A doc I read said DEV_CANCEL might be called even though - * the operation is finished. We use this variable to - * determine if we should rollback the changes or not. - */ - int syscall_done; + /* request ID, saved for later use by suspended procs */ + cdev_id_t susp_id; /* select() */ - /* Flag (1 or 0) - the process blocked on select(2). When - * selecting is 1 and I/O happens on this socket, then - * select_proc should be notified. - */ - int selecting; - /* when a select is in progress, we notify() this endpoint * of new data. */ - endpoint_t select_proc; + endpoint_t sel_endpt; /* Options (SEL_RD, SEL_WR, SEL_ERR) that are requested. */ - int sel_ops_in; - - /* Options that are available for this socket. */ - int sel_ops_out; - - /* Flag (1 or 0) to be set to one before calling notify(). - * uds_status() will use the flag to locate this descriptor. - */ - int status_updated; + unsigned int sel_ops; }; typedef struct uds_fd uds_fd_t; @@ -221,30 +188,4 @@ typedef struct uds_fd uds_fd_t; /* File Descriptor Table -- Defined in uds.c */ EXTERN uds_fd_t uds_fd_table[NR_FDS]; -/* - * Take message m and get the index in uds_fd_table. - */ -#define uds_minor(m) (minor((dev_t) m->DEVICE)) - -/* - * Fill in a reply message. - */ -#define uds_set_reply(msg,type,endpoint,io_gr,status) \ - do { \ - (msg)->m_type = type; \ - (msg)->REP_ENDPT = endpoint; \ - (msg)->REP_IO_GRANT = io_gr; \ - (msg)->REP_STATUS = status; \ - } while (0) - -#define uds_sel_reply(msg,type,minor,ops) \ - do { \ - (msg)->m_type = type; \ - (msg)->DEV_MINOR = minor; \ - (msg)->DEV_SEL_OPS = ops; \ - } while (0) - - - - #endif diff --git a/servers/pfs/utility.c b/servers/pfs/utility.c index f1c4849ab..4109d83d0 100644 --- a/servers/pfs/utility.c +++ b/servers/pfs/utility.c @@ -7,7 +7,7 @@ int no_sys(message *pfs_m_in, message *pfs_m_out) { /* Somebody has used an illegal system call number */ - printf("no_sys: invalid call 0x%x to pfs\n", req_nr); + printf("no_sys: invalid call 0x%x to pfs\n", pfs_m_in->m_type); return(EINVAL); } -- 2.44.0