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
This commit is contained in:
parent
1db80ce9d6
commit
ddeb562e1a
12 changed files with 646 additions and 1072 deletions
|
@ -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
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -15,6 +15,7 @@
|
|||
#include <sys/un.h>
|
||||
|
||||
#include <minix/endpoint.h>
|
||||
#include <minix/chardriver.h>
|
||||
|
||||
/* 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;
|
||||
cp_grant_id_t susp_grant;
|
||||
|
||||
/* is of i/o grant, saved for later use by suspended procs */
|
||||
size_t io_gr_size;
|
||||
/* size of request, saved for later use by suspended procs */
|
||||
size_t susp_size;
|
||||
|
||||
/* Save the call number so that uds_cancel() can unwind the
|
||||
* call properly.
|
||||
*/
|
||||
int call_nr;
|
||||
|
||||
/* Save the IOCTL so uds_cancel() knows what got cancelled. */
|
||||
int ioctl;
|
||||
|
||||
/* 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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue