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 \
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

View file

@ -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;

View file

@ -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

View file

@ -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,14 +74,11 @@ 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);
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);
}

View file

@ -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:

View file

@ -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

View file

@ -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);
}

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.
*/
#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

View file

@ -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

View file

@ -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);
}