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:
David van Moolenbroek 2013-09-03 02:00:20 +02:00 committed by Lionel Sambuc
parent 1db80ce9d6
commit ddeb562e1a
12 changed files with 646 additions and 1072 deletions

View file

@ -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 \ buffer.c read.c misc.c mount.c utility.c stadir.c \
uds.c dev_uds.c uds.c dev_uds.c
DPADD+= ${LIBSYS} DPADD+= ${LIBCHARDRIVER} ${LIBSYS}
LDADD+= -lsys LDADD+= -lchardriver -lsys
LDADD+= -lc LDADD+= -lc

File diff suppressed because it is too large Load diff

View file

@ -13,12 +13,7 @@
EXTERN int err_code; /* temporary storage for error number */ EXTERN int err_code; /* temporary storage for error number */
EXTERN int(*fs_call_vec[]) (message *fs_m_in, message *fs_m_out); 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 exitsignaled;
EXTERN int busy; EXTERN int busy;
EXTERN int unmountdone; EXTERN int unmountdone;

View file

@ -237,7 +237,7 @@ struct inode *rip; /* pointer to inode to be released */
/*===========================================================================* /*===========================================================================*
* alloc_inode * * 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. */ /* 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_mode = bits; /* set up RWX bits */
rip->i_nlinks = NO_LINK; /* initial no links */ rip->i_nlinks = NO_LINK; /* initial no links */
rip->i_uid = caller_uid; /* file's uid is owner's */ rip->i_uid = uid; /* set file user id */
rip->i_gid = caller_gid; /* ditto group id */ rip->i_gid = gid; /* ditto group id */
/* Fields not cleared already are cleared in wipe_inode(). They have /* Fields not cleared already are cleared in wipe_inode(). They have
* been put there because truncate() needs to clear the same fields if * been put there because truncate() needs to clear the same fields if

View file

@ -12,7 +12,7 @@
#include "inode.h" #include "inode.h"
#include "uds.h" #include "uds.h"
static void get_work(message *m_in); static void get_work(message *m_in, int *status);
/* SEF functions and variables. */ /* SEF functions and variables. */
static void sef_local_startup(void); 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 * three major activities: getting new work, processing the work, and
* sending the reply. The loop never terminates, unless a panic occurs. * 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_in;
message pfs_m_out; message pfs_m_out;
endpoint_t src;
/* SEF local startup. */ /* SEF local startup. */
env_setargs(argc, argv); env_setargs(argc, argv);
sef_local_startup(); sef_local_startup();
while(!unmountdone || !exitsignaled) { while(!unmountdone || !exitsignaled) {
endpoint_t src;
do_reply = 1;
/* Wait for request message. */ /* 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); transid = TRNS_GET_ID(pfs_m_in.m_type);
pfs_m_in.m_type = TRNS_DEL_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); assert(IS_VFS_FS_TRANSID(transid) || transid == 0);
src = pfs_m_in.m_source; src = pfs_m_in.m_source;
caller_uid = INVAL_UID; /* To trap errors */
caller_gid = INVAL_GID;
req_nr = pfs_m_in.m_type; req_nr = pfs_m_in.m_type;
if (IS_DEV_RQ(req_nr)) { if (IS_VFS_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)) {
ind = req_nr - VFS_BASE; ind = req_nr - VFS_BASE;
if (ind < 0 || ind >= FS_CALL_VEC_SIZE) { if (ind < 0 || ind >= FS_CALL_VEC_SIZE) {
printf("pfs: bad FS request %d\n", req_nr); printf("pfs: bad FS request %d\n", req_nr);
@ -85,14 +74,11 @@ int main(int argc, char *argv[])
pfs_m_out.m_type = EINVAL; pfs_m_out.m_type = EINVAL;
} }
if (do_reply) {
if (IS_VFS_RQ(req_nr) && IS_VFS_FS_TRANSID(transid)) { if (IS_VFS_RQ(req_nr) && IS_VFS_FS_TRANSID(transid)) {
pfs_m_out.m_type = TRNS_ADD_ID(pfs_m_out.m_type, pfs_m_out.m_type = TRNS_ADD_ID(pfs_m_out.m_type, transid);
transid);
} }
reply(src, &pfs_m_out); reply(src, &pfs_m_out);
} }
}
return(OK); return(OK);
} }
@ -145,8 +131,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
panic("unable to drop privileges"); panic("unable to drop privileges");
} }
SELF_E = getprocnr();
return(OK); return(OK);
} }
@ -165,15 +149,14 @@ static void sef_cb_signal_handler(int signo)
/*===========================================================================* /*===========================================================================*
* get_work * * get_work *
*===========================================================================*/ *===========================================================================*/
static void get_work(m_in) static void get_work(message * m_in, int *status)
message *m_in; /* pointer to message */
{ {
int r, srcok = 0, status; int r, srcok = 0;
endpoint_t src; endpoint_t src;
do { do {
/* wait for a message */ /* 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); panic("sef_receive_status failed: %d", r);
src = m_in->m_source; src = m_in->m_source;
@ -192,6 +175,8 @@ void reply(who, m_out)
endpoint_t who; endpoint_t who;
message *m_out; /* report result */ message *m_out; /* report result */
{ {
if (OK != send(who, m_out)) /* send the message */ int r;
printf("PFS(%d) was unable to send reply\n", SELF_E);
if (OK != (r = send(who, m_out))) /* send the message */
printf("PFS: unable to send reply: %d\n", r);
} }

View file

@ -13,15 +13,17 @@ int fs_newnode(message *fs_m_in, message *fs_m_out)
register int r = OK; register int r = OK;
pmode_t bits; pmode_t bits;
struct inode *rip; struct inode *rip;
uid_t uid;
gid_t gid;
dev_t dev; dev_t dev;
caller_uid = (uid_t) fs_m_in->REQ_UID; uid = (uid_t) fs_m_in->REQ_UID;
caller_gid = (gid_t) fs_m_in->REQ_GID; gid = (gid_t) fs_m_in->REQ_GID;
bits = (pmode_t) fs_m_in->REQ_MODE; bits = (pmode_t) fs_m_in->REQ_MODE;
dev = (dev_t) fs_m_in->REQ_DEV; dev = (dev_t) fs_m_in->REQ_DEV;
/* Try to allocate the inode */ /* 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) { switch (bits & S_IFMT) {
case S_IFBLK: case S_IFBLK:

View file

@ -17,7 +17,7 @@ void put_block(dev_t dev, pino_t inum);
void buf_pool(void); void buf_pool(void);
/* inode.c */ /* 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); void dup_inode(struct inode *ip);
struct inode *find_inode(pino_t numb); struct inode *find_inode(pino_t numb);
void free_inode(struct inode *rip); void free_inode(struct inode *rip);
@ -61,37 +61,12 @@ bit_t alloc_bit(void);
void free_bit(bit_t bit_returned); void free_bit(bit_t bit_returned);
/* dev_uds.c */ /* dev_uds.c */
int uds_open(message *dev_m_in, message *dev_m_out); void uds_request(message *m_ptr, int ipc_status);
int uds_close(message *dev_m_in, message *dev_m_out); void uds_unsuspend(devminor_t minor);
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);
/* uds.c */ /* uds.c */
void uds_init(void); void uds_init(void);
int do_accept(message *dev_m_in, message *dev_m_out); int uds_clear_fds(devminor_t minor, struct ancillary *data);
int do_connect(message *dev_m_in, message *dev_m_out); int uds_do_ioctl(devminor_t minor, unsigned long request, endpoint_t endpt,
int do_listen(message *dev_m_in, message *dev_m_out); cp_grant_id_t grant);
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);
#endif #endif

View file

@ -63,11 +63,11 @@ int fs_readwrite(message *fs_m_in, message *fs_m_out)
if (rw_flag == READING) { if (rw_flag == READING) {
/* Copy a chunk from the block buffer to user space. */ /* 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); (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
} else { } else {
/* Copy a chunk from user space to the block buffer. */ /* 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); (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
} }

View file

@ -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. * routines that perform them.
*/ */
#define _TABLE #define _TABLE
#include "inc.h"
#include "fs.h" #include "fs.h"
#include "inode.h" #include "inode.h"
#include "buf.h" #include "buf.h"
@ -12,7 +13,6 @@
/* File System Handlers (pfs) */ /* File System Handlers (pfs) */
int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = { int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = {
no_sys, /* 0 not used */ no_sys, /* 0 not used */
no_sys, /* 1 */ no_sys, /* 1 */
fs_putnode, /* 2 */ fs_putnode, /* 2 */
@ -47,34 +47,3 @@ int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = {
no_sys, /* 31 */ no_sys, /* 31 */
no_sys, /* 32 */ 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

View file

@ -15,6 +15,7 @@
#include <sys/un.h> #include <sys/un.h>
#include <minix/endpoint.h> #include <minix/endpoint.h>
#include <minix/chardriver.h>
/* max connection backlog for incoming connections */ /* max connection backlog for incoming connections */
#define UDS_SOMAXCONN 64 #define UDS_SOMAXCONN 64
@ -54,9 +55,6 @@ struct uds_fd {
/* Socket Owner */ /* Socket Owner */
endpoint_t owner; endpoint_t owner;
/* endpoint for suspend/resume */
endpoint_t endpoint;
/* Pipe Housekeeping */ /* Pipe Housekeeping */
/* inode number on PFS -- each descriptor is backed by 1 /* inode number on PFS -- each descriptor is backed by 1
@ -82,7 +80,6 @@ struct uds_fd {
/* Socket Info */ /* Socket Info */
/* socket type - SOCK_STREAM, SOCK_DGRAM, or SOCK_SEQPACKET /* socket type - SOCK_STREAM, SOCK_DGRAM, or SOCK_SEQPACKET
* Set by uds_ioctl(NWIOSUDSTYPE). It defaults to -1 in * Set by uds_ioctl(NWIOSUDSTYPE). It defaults to -1 in
* uds_open(). Any action on a socket with type -1 besides * uds_open(). Any action on a socket with type -1 besides
@ -144,7 +141,6 @@ struct uds_fd {
/* Suspend/Revive Housekeeping */ /* Suspend/Revive Housekeeping */
/* SUSPEND State Flags */ /* SUSPEND State Flags */
enum UDS_SUSPENDED { enum UDS_SUSPENDED {
@ -164,56 +160,27 @@ struct uds_fd {
UDS_SUSPENDED_ACCEPT = 8 UDS_SUSPENDED_ACCEPT = 8
} suspended; } suspended;
/* Flag (1 or 0) - thing socket was waiting for is ready. /* source endpoint, saved for later use by suspended procs */
* If 1, then uds_status() will attempt the operation that endpoint_t susp_endpt;
* the socket was blocked on.
*/
int ready_to_revive;
/* i/o grant, saved for later use by suspended procs */ /* 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 of request, saved for later use by suspended procs */
size_t io_gr_size; size_t susp_size;
/* Save the call number so that uds_cancel() can unwind the /* request ID, saved for later use by suspended procs */
* call properly. cdev_id_t susp_id;
*/
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;
/* select() */ /* 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 /* when a select is in progress, we notify() this endpoint
* of new data. * of new data.
*/ */
endpoint_t select_proc; endpoint_t sel_endpt;
/* Options (SEL_RD, SEL_WR, SEL_ERR) that are requested. */ /* Options (SEL_RD, SEL_WR, SEL_ERR) that are requested. */
int sel_ops_in; unsigned int sel_ops;
/* 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;
}; };
typedef struct uds_fd uds_fd_t; 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 */ /* File Descriptor Table -- Defined in uds.c */
EXTERN uds_fd_t uds_fd_table[NR_FDS]; 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 #endif

View file

@ -7,7 +7,7 @@
int no_sys(message *pfs_m_in, message *pfs_m_out) int no_sys(message *pfs_m_in, message *pfs_m_out)
{ {
/* Somebody has used an illegal system call number */ /* 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); return(EINVAL);
} }