diff --git a/minix/fs/pfs/Makefile b/minix/fs/pfs/Makefile index 48619fee0..d1841c193 100644 --- a/minix/fs/pfs/Makefile +++ b/minix/fs/pfs/Makefile @@ -1,11 +1,9 @@ # Makefile for Pipe File System (PFS) PROG= pfs 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 stadir.c -DPADD+= ${LIBCHARDRIVER} ${LIBSYS} -LDADD+= -lchardriver -lsys - -LDADD+= -lc +DPADD+= ${LIBFSDRIVER} ${LIBSYS} +LDADD+= -lfsdriver -lsys .include diff --git a/minix/fs/pfs/buffer.c b/minix/fs/pfs/buffer.c index 825ca1b52..746aebd8a 100644 --- a/minix/fs/pfs/buffer.c +++ b/minix/fs/pfs/buffer.c @@ -1,9 +1,4 @@ #include "fs.h" -#include "buf.h" -#include "inode.h" -#include -#include -#include static struct buf *new_block(dev_t dev, ino_t inum); diff --git a/minix/fs/pfs/fs.h b/minix/fs/pfs/fs.h index a5e0ca40f..417e30fc5 100644 --- a/minix/fs/pfs/fs.h +++ b/minix/fs/pfs/fs.h @@ -11,20 +11,23 @@ #include #include #include -#include -#include #include -#include -#include #include -#include -#include -#include #include +#include + +#include +#include +#include +#include +#include + #include "const.h" #include "proto.h" #include "glo.h" +#include "buf.h" +#include "inode.h" #endif diff --git a/minix/fs/pfs/glo.h b/minix/fs/pfs/glo.h index 96ca9c42e..77bff50ef 100644 --- a/minix/fs/pfs/glo.h +++ b/minix/fs/pfs/glo.h @@ -7,16 +7,12 @@ #define EXTERN #endif -#include - /* The following variables are used for returning results to the caller. */ EXTERN int err_code; /* temporary storage for error number */ -EXTERN int(*fs_call_vec[]) (message *fs_m_in, message *fs_m_out); +extern struct fsdriver pfs_table; -EXTERN int exitsignaled; EXTERN int busy; -EXTERN int unmountdone; /* Inode map. */ EXTERN bitchunk_t inodemap[FS_BITMAP_CHUNKS(PFS_NR_INODES)]; diff --git a/minix/fs/pfs/inode.c b/minix/fs/pfs/inode.c index 442f824dc..b5918fbae 100644 --- a/minix/fs/pfs/inode.c +++ b/minix/fs/pfs/inode.c @@ -15,9 +15,6 @@ */ #include "fs.h" -#include "buf.h" -#include "inode.h" -#include static void addhash_inode(struct inode * const node); static void unhash_inode(struct inode * const node); @@ -26,29 +23,21 @@ static void unhash_inode(struct inode * const node); /*===========================================================================* * fs_putnode * *===========================================================================*/ -int fs_putnode(message *fs_m_in, message *fs_m_out) +int fs_putnode(ino_t ino_nr, unsigned int count) { /* Find the inode specified by the request message and decrease its counter.*/ - struct inode *rip; - int count; dev_t dev; - ino_t inum; - rip = find_inode(fs_m_in->m_vfs_fs_putnode.inode); + rip = find_inode(ino_nr); if(!rip) { - printf("%s:%d put_inode: inode #%llu not found\n", __FILE__, - __LINE__, fs_m_in->m_vfs_fs_putnode.inode); - panic("fs_putnode failed"); + printf("%s:%d put_inode: inode #%llu not found\n", __FILE__, + __LINE__, ino_nr); + panic("fs_putnode failed"); } - count = fs_m_in->m_vfs_fs_putnode.count; - if (count <= 0) { - printf("%s:%d put_inode: bad value for count: %d\n", __FILE__, - __LINE__, count); - panic("fs_putnode failed"); - } else if(count > rip->i_count) { + if (count > rip->i_count) { printf("%s:%d put_inode: count too high: %d > %d\n", __FILE__, __LINE__, count, rip->i_count); panic("fs_putnode failed"); @@ -58,9 +47,8 @@ int fs_putnode(message *fs_m_in, message *fs_m_out) * put_inode(). */ rip->i_count -= count - 1; dev = rip->i_dev; - inum = rip->i_num; put_inode(rip); - if (rip->i_count == 0) put_block(dev, inum); + if (rip->i_count == 0) put_block(dev, ino_nr); return(OK); } diff --git a/minix/fs/pfs/inode.h b/minix/fs/pfs/inode.h index 897ba7aca..75689c9e3 100644 --- a/minix/fs/pfs/inode.h +++ b/minix/fs/pfs/inode.h @@ -11,12 +11,11 @@ EXTERN struct inode { nlink_t i_nlinks; /* how many links to this file */ uid_t i_uid; /* user id of the file's owner */ gid_t i_gid; /* group number */ - off_t i_size; /* current file size in bytes */ + size_t i_size; /* current file size in bytes */ time_t i_atime; /* time of last access (V2 only) */ time_t i_mtime; /* when was file data last changed */ time_t i_ctime; /* when was inode itself changed (V2 only)*/ - /* The following items are not present on the disk. */ dev_t i_dev; /* which device is the inode on */ dev_t i_rdev; /* which special device is the inode on */ ino_t i_num; /* inode number on its (minor) device */ @@ -35,5 +34,4 @@ EXTERN TAILQ_HEAD(unused_inodes_t, inode) unused_inodes; /* inode hashtable */ EXTERN LIST_HEAD(inodelist, inode) hash_inodes[INODE_HASH_SIZE]; - #endif diff --git a/minix/fs/pfs/link.c b/minix/fs/pfs/link.c index 7b1286d51..d8c7d1a77 100644 --- a/minix/fs/pfs/link.c +++ b/minix/fs/pfs/link.c @@ -1,22 +1,15 @@ #include "fs.h" -#include "buf.h" -#include "inode.h" -#include /*===========================================================================* - * fs_ftrunc * + * fs_trunc * *===========================================================================*/ -int fs_ftrunc(message *fs_m_in, message *fs_m_out) +int fs_trunc(ino_t ino_nr, off_t start, off_t end) { struct inode *rip; - off_t start; - ino_t inumb; - inumb = fs_m_in->m_vfs_fs_ftrunc.inode; + if( (rip = find_inode(ino_nr)) == NULL) return(EINVAL); - if( (rip = find_inode(inumb)) == NULL) return(EINVAL); - - start = fs_m_in->m_vfs_fs_ftrunc.trc_start; + if (end != 0) return(EINVAL); /* creating holes is not supported */ return truncate_inode(rip, start); } diff --git a/minix/fs/pfs/main.c b/minix/fs/pfs/main.c index 09b96dc1a..09d7dde79 100644 --- a/minix/fs/pfs/main.c +++ b/minix/fs/pfs/main.c @@ -1,17 +1,4 @@ #include "fs.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "buf.h" -#include "inode.h" - -static void get_work(message *m_in, int *status); /* SEF functions and variables. */ static void sef_local_startup(void); @@ -23,54 +10,15 @@ static void sef_cb_signal_handler(int signo); *===========================================================================*/ int main(int argc, char *argv[]) { -/* This is the main routine of this service. The main loop consists of - * three major activities: getting new work, processing the work, and - * sending the reply. The loop never terminates, unless a panic occurs. - */ - int ind, transid, req_nr, ipc_status; - message pfs_m_in; - message pfs_m_out; - endpoint_t src; +/* This is the main routine of this service. */ /* SEF local startup. */ env_setargs(argc, argv); sef_local_startup(); - while(!unmountdone || !exitsignaled) { - /* Wait for request message. */ - get_work(&pfs_m_in, &ipc_status); + /* The fsdriver library does the actual work here. */ + fsdriver_task(&pfs_table); - transid = TRNS_GET_ID(pfs_m_in.m_type); - pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type); - if (pfs_m_in.m_type == 0) { - assert(!IS_VFS_FS_TRANSID(transid)); - pfs_m_in.m_type = transid; - transid = 0; - } else - assert(IS_VFS_FS_TRANSID(transid) || transid == 0); - - src = pfs_m_in.m_source; - req_nr = pfs_m_in.m_type; - - if (IS_FS_RQ(req_nr)) { - ind = req_nr - FS_BASE; - if (ind < 0 || ind >= FS_CALL_VEC_SIZE) { - printf("pfs: bad FS request %d\n", req_nr); - pfs_m_out.m_type = EINVAL; - } else { - pfs_m_out.m_type = - (*fs_call_vec[ind])(&pfs_m_in, &pfs_m_out); - } - } else { - printf("pfs: bad request %d\n", req_nr); - pfs_m_out.m_type = EINVAL; - } - - if (IS_FS_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); } @@ -102,7 +50,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info) struct passwd *pw; /* Initialize main loop parameters. */ - exitsignaled = 0; /* No exit request seen yet. */ busy = 0; /* Server is not 'busy' (i.e., inodes in use). */ /* Init inode table */ @@ -113,14 +60,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info) init_inode_cache(); buf_pool(); - /* Drop root privileges */ - if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) { - printf("PFS: unable to retrieve uid of SERVICE_LOGIN, " - "still running as root"); - } else if (setuid(pw->pw_uid) != 0) { - panic("unable to drop privileges"); - } - return(OK); } @@ -132,41 +71,5 @@ static void sef_cb_signal_handler(int signo) /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - - exitsignaled = 1; -} - -/*===========================================================================* - * get_work * - *===========================================================================*/ -static void get_work(message * m_in, int *status) -{ - int r, srcok = 0; - endpoint_t src; - - do { - /* wait for a message */ - if ((r = sef_receive_status(ANY, m_in, status)) != OK) - panic("sef_receive_status failed: %d", r); - src = m_in->m_source; - - if(src == VFS_PROC_NR) { - srcok = 1; /* Normal FS request. */ - } else - printf("PFS: unexpected source %d\n", src); - } while(!srcok); -} - - -/*===========================================================================* - * reply * - *===========================================================================*/ -void reply(who, m_out) -endpoint_t who; -message *m_out; /* report result */ -{ - int r; - - if (OK != (r = ipc_send(who, m_out))) /* send the message */ - printf("PFS: unable to send reply: %d\n", r); + fsdriver_terminate(); } diff --git a/minix/fs/pfs/misc.c b/minix/fs/pfs/misc.c index 0ba9b7c06..24aeb89cc 100644 --- a/minix/fs/pfs/misc.c +++ b/minix/fs/pfs/misc.c @@ -1,28 +1,17 @@ #include "fs.h" -#include "inode.h" -/*===========================================================================* - * fs_sync * - *===========================================================================*/ -int fs_sync(message *fs_m_in, message *fs_m_out) -{ -/* Perform the sync() system call. No-op on this FS. */ - - return(OK); /* sync() can't fail */ -} - /*===========================================================================* * fs_chmod * *===========================================================================*/ -int fs_chmod(message *fs_m_in, message *fs_m_out) +int fs_chmod(ino_t ino_nr, mode_t *mode) { struct inode *rip; /* target inode */ - mode_t mode = fs_m_in->m_vfs_fs_chmod.mode; - if( (rip = find_inode(fs_m_in->m_vfs_fs_chmod.inode)) == NULL) return(EINVAL); - get_inode(rip->i_dev, rip->i_num); /* mark inode in use */ - rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES); - put_inode(rip); /* release the inode */ + if( (rip = find_inode(ino_nr)) == NULL) return(EINVAL); + + rip->i_mode = (rip->i_mode & ~ALL_MODES) | (*mode & ALL_MODES); + + *mode = rip->i_mode; /* return new mode */ return OK; } diff --git a/minix/fs/pfs/mount.c b/minix/fs/pfs/mount.c index 3bb52d9d6..35636338b 100644 --- a/minix/fs/pfs/mount.c +++ b/minix/fs/pfs/mount.c @@ -3,16 +3,33 @@ /*===========================================================================* - * fs_unmount * + * fs_mount * *===========================================================================*/ -int fs_unmount(message *fs_m_in, message *fs_m_out) +int fs_mount(dev_t __unused dev, unsigned int __unused flags, + struct fsdriver_node *node, unsigned int *res_flags) { -/* Unmount Pipe File Server. */ +/* Mount Pipe File Server. */ - if (busy) return(EBUSY); /* can't umount a busy file system */ - - /* Finish off the unmount. */ - unmountdone = TRUE; + /* This function does not do much. PFS has no root node, and VFS will ignore + * the returned node details anyway. The whole idea is to provide symmetry + * with other file systems, thus keeping libfsdriver simple and free of + * special cases. Everything else (e.g., mounting PFS in VFS) is already an + * exception anyway. + */ + memset(node, 0, sizeof(*node)); + *res_flags = 0; return(OK); } + + +/*===========================================================================* + * fs_unmount * + *===========================================================================*/ +void fs_unmount(void) +{ +/* Unmount Pipe File Server. */ + + if (busy) + printf("PFS: unmounting while busy!\n"); /* nothing we can do anyway */ +} diff --git a/minix/fs/pfs/open.c b/minix/fs/pfs/open.c index b3f17643c..e3308fc81 100644 --- a/minix/fs/pfs/open.c +++ b/minix/fs/pfs/open.c @@ -1,31 +1,19 @@ #include "fs.h" -#include -#include "buf.h" -#include "inode.h" -#include /*===========================================================================* * fs_newnode * *===========================================================================*/ -int fs_newnode(message *fs_m_in, message *fs_m_out) +int fs_newnode(mode_t mode, uid_t uid, gid_t gid, dev_t dev, + struct fsdriver_node *node) { register int r = OK; - mode_t bits; struct inode *rip; - uid_t uid; - gid_t gid; - dev_t dev; - - uid = fs_m_in->m_vfs_fs_newnode.uid; - gid = fs_m_in->m_vfs_fs_newnode.gid; - bits = fs_m_in->m_vfs_fs_newnode.mode; - dev = fs_m_in->m_vfs_fs_newnode.device; /* Try to allocate the inode */ - if( (rip = alloc_inode(dev, bits, uid, gid) ) == NULL) return(err_code); + if( (rip = alloc_inode(dev, mode, uid, gid) ) == NULL) return(err_code); - switch (bits & S_IFMT) { + switch (mode & S_IFMT) { case S_IFBLK: case S_IFCHR: rip->i_rdev = dev; /* Major/minor dev numbers */ @@ -42,12 +30,12 @@ int fs_newnode(message *fs_m_in, message *fs_m_out) free_inode(rip); } else { /* Fill in the fields of the response message */ - fs_m_out->m_fs_vfs_newnode.inode = rip->i_num; - fs_m_out->m_fs_vfs_newnode.mode = rip->i_mode; - fs_m_out->m_fs_vfs_newnode.file_size = rip->i_size; - fs_m_out->m_fs_vfs_newnode.uid = rip->i_uid; - fs_m_out->m_fs_vfs_newnode.gid = rip->i_gid; - fs_m_out->m_fs_vfs_newnode.device = dev; + node->fn_ino_nr = rip->i_num; + node->fn_mode = rip->i_mode; + node->fn_size = rip->i_size; + node->fn_uid = rip->i_uid; + node->fn_gid = rip->i_gid; + node->fn_dev = dev; } return(r); diff --git a/minix/fs/pfs/proto.h b/minix/fs/pfs/proto.h index 6a5bc90d5..3569551e5 100644 --- a/minix/fs/pfs/proto.h +++ b/minix/fs/pfs/proto.h @@ -10,8 +10,6 @@ struct inode; /* buffer.c */ struct buf *get_block(dev_t dev, ino_t inum); void put_block(dev_t dev, ino_t inum); - -/* cache.c */ void buf_pool(void); /* inode.c */ @@ -19,7 +17,7 @@ struct inode *alloc_inode(dev_t dev, mode_t mode, uid_t uid, gid_t gid); void dup_inode(struct inode *ip); struct inode *find_inode(ino_t numb); void free_inode(struct inode *rip); -int fs_putnode(message *fs_m_in, message *fs_m_out); +int fs_putnode(ino_t ino_nr, unsigned int count); void init_inode_cache(void); struct inode *get_inode(dev_t dev, ino_t numb); void put_inode(struct inode *rip); @@ -27,30 +25,29 @@ void update_times(struct inode *rip); void wipe_inode(struct inode *rip); /* link.c */ -int fs_ftrunc(message *fs_m_in, message *fs_m_out); +int fs_trunc(ino_t ino_nr, off_t start, off_t end); int truncate_inode(struct inode *rip, off_t newsize); -/* main.c */ -void reply(endpoint_t who, message *m_out); - /* misc.c */ -int fs_sync(message *fs_m_in, message *fs_m_out); -int fs_chmod(message *fs_m_in, message *fs_m_out); +int fs_chmod(ino_t ino_nr, mode_t *mode); /* mount.c */ -int fs_unmount(message *fs_m_in, message *fs_m_out); +int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *node, + unsigned int *res_flags); +void fs_unmount(void); /* open.c */ -int fs_newnode(message *fs_m_in, message *fs_m_out); +int fs_newnode(mode_t mode, uid_t uid, gid_t gid, dev_t dev, + struct fsdriver_node *node); /* read.c */ -int fs_readwrite(message *fs_m_in, message *fs_m_out); - -/* utility.c */ -int no_sys(message *pfs_m_in, message *pfs_m_out); +ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t pos, int call); +ssize_t fs_write(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t pos, int call); /* stadir.c */ -int fs_stat(message *fs_m_in, message *fs_m_out); +int fs_stat(ino_t ino_nr, struct stat *statbuf); /* super.c */ bit_t alloc_bit(void); diff --git a/minix/fs/pfs/read.c b/minix/fs/pfs/read.c index d7a8ff877..db4b77600 100644 --- a/minix/fs/pfs/read.c +++ b/minix/fs/pfs/read.c @@ -1,97 +1,85 @@ #include "fs.h" -#include "buf.h" -#include "inode.h" -#include -#include /*===========================================================================* - * fs_readwrite * + * fs_read * *===========================================================================*/ -int fs_readwrite(message *fs_m_in, message *fs_m_out) +ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t __unused pos, int call) { - int r, rw_flag; + int r; struct buf *bp; - cp_grant_id_t gid; - off_t position, f_size; - size_t nrbytes, cum_io; - mode_t mode_word; struct inode *rip; - ino_t inumb; - - r = OK; - cum_io = 0; - inumb = fs_m_in->m_vfs_fs_readwrite.inode; /* Find the inode referred */ - if ((rip = find_inode(inumb)) == NULL) return(EINVAL); + if ((rip = find_inode(ino_nr)) == NULL) return(EINVAL); - mode_word = rip->i_mode & I_TYPE; - if (mode_word != I_NAMED_PIPE) return(EIO); - f_size = rip->i_size; + if (!S_ISFIFO(rip->i_mode)) return(EIO); - /* Get the values from the request message */ - rw_flag = (fs_m_in->m_type == REQ_READ ? READING : WRITING); - gid = fs_m_in->m_vfs_fs_readwrite.grant; - nrbytes = fs_m_in->m_vfs_fs_readwrite.nbytes; + /* We can't read or write beyond the max file position */ + if (bytes > PIPE_BUF) return(EFBIG); - /* We can't read beyond the max file position */ - if (nrbytes > PIPE_BUF) return(EFBIG); + if (bytes > rip->i_size) { + /* There aren't that many bytes to read */ + bytes = rip->i_size; + } - /* Mark inode in use */ - if ((get_inode(rip->i_dev, rip->i_num)) == NULL) return(err_code); + /* Copy a chunk from the block buffer to user space. */ if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code); - if (rw_flag == WRITING) { - /* Check in advance to see if file will grow too big. */ - /* Casting nrbytes to signed is safe, because it's guaranteed not to - * be beyond max signed value (i.e., MAX_FILE_POS). - */ - position = rip->i_size; - if ((unsigned) position + nrbytes > PIPE_BUF) { - put_inode(rip); - put_block(rip->i_dev, rip->i_num); - return(EFBIG); - } - } else { - position = 0; - if (nrbytes > rip->i_size) { - /* There aren't that many bytes to read */ - nrbytes = rip->i_size; - } + r = fsdriver_copyout(data, 0, bp->b_data, bytes); + + if (r == OK && rip->i_size > bytes) { + /* Move any remaining data to the front of the buffer. */ + /* FIXME: see if this really is the optimal strategy. */ + memmove(bp->b_data, bp->b_data + bytes, rip->i_size - bytes); } - if (rw_flag == READING) { - /* Copy a chunk from the block buffer to user space. */ - 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(fs_m_in->m_source, gid, (vir_bytes) 0, - (vir_bytes) (bp->b_data+position), (size_t) nrbytes); - } - - if (r == OK) { - position += (signed) nrbytes; /* Update position */ - cum_io += nrbytes; - - /* On write, update file size and access time. */ - if (rw_flag == WRITING) { - rip->i_size = position; - } else { - memmove(bp->b_data, bp->b_data+nrbytes, rip->i_size - nrbytes); - rip->i_size -= nrbytes; - } - - if (rw_flag == READING) rip->i_update |= ATIME; - if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; - } - - fs_m_out->m_fs_vfs_readwrite.nbytes = cum_io; - fs_m_out->m_fs_vfs_readwrite.seek_pos = rip->i_size; - - put_inode(rip); put_block(rip->i_dev, rip->i_num); - return(r); + if (r != OK) + return r; + + /* Update file size and access time. */ + rip->i_size -= bytes; + rip->i_update |= ATIME; + + return(bytes); +} + + +/*===========================================================================* + * fs_write * + *===========================================================================*/ +ssize_t fs_write(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t __unused pos, int __unused call) +{ + int r; + struct buf *bp; + struct inode *rip; + + /* Find the inode referred */ + if ((rip = find_inode(ino_nr)) == NULL) return(EINVAL); + + if (!S_ISFIFO(rip->i_mode)) return(EIO); + + /* Check in advance to see if file will grow too big. */ + if (rip->i_size + bytes > PIPE_BUF) + return(EFBIG); + + /* Copy the data from user space to the block buffer. */ + if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code); + + r = fsdriver_copyin(data, 0, bp->b_data + rip->i_size, bytes); + + put_block(rip->i_dev, rip->i_num); + + if (r != OK) + return r; + + /* Update file size and file times. */ + rip->i_size += bytes; + rip->i_update |= CTIME | MTIME; + + return(bytes); } diff --git a/minix/fs/pfs/stadir.c b/minix/fs/pfs/stadir.c index c6aa2aad0..127ff60bf 100644 --- a/minix/fs/pfs/stadir.c +++ b/minix/fs/pfs/stadir.c @@ -1,23 +1,17 @@ #include "fs.h" -#include "inode.h" -#include -#include /*===========================================================================* - * stat_inode * + * fs_stat * *===========================================================================*/ -static int stat_inode( - register struct inode *rip, /* pointer to inode to stat */ - endpoint_t who_e, /* Caller endpoint */ - cp_grant_id_t gid /* grant for the stat buf */ -) +int fs_stat(ino_t ino_nr, struct stat *statbuf) { -/* Common code for stat and fstat system calls. */ + struct inode *rip; mode_t type; - struct stat statbuf; u32_t blocks; /* The unit of this is 512 */ - int r, s; + int s; + + if ((rip = find_inode(ino_nr)) == NULL) return(EINVAL); type = rip->i_mode & I_TYPE; s = (type == I_CHAR_SPECIAL || type == I_BLOCK_SPECIAL); @@ -29,42 +23,20 @@ static int stat_inode( if (rip->i_size % S_BLKSIZE != 0) blocks += 1; - memset(&statbuf, 0, sizeof(struct stat)); + statbuf->st_dev = rip->i_dev; + statbuf->st_ino = rip->i_num; + statbuf->st_mode = rip->i_mode; + statbuf->st_nlink = rip->i_nlinks; + statbuf->st_uid = rip->i_uid; + statbuf->st_gid = (short int) rip->i_gid; + statbuf->st_rdev = (s ? rip->i_rdev : NO_DEV); + statbuf->st_size = rip->i_size; + if (!s) statbuf->st_mode &= ~I_REGULAR;/* wipe out I_REGULAR bit for pipes */ + statbuf->st_atime = rip->i_atime; + statbuf->st_mtime = rip->i_mtime; + statbuf->st_ctime = rip->i_ctime; + statbuf->st_blksize = PIPE_BUF; + statbuf->st_blocks = blocks; - statbuf.st_dev = rip->i_dev; - statbuf.st_ino = rip->i_num; - statbuf.st_mode = rip->i_mode; - statbuf.st_nlink = rip->i_nlinks; - statbuf.st_uid = rip->i_uid; - statbuf.st_gid = (short int) rip->i_gid; - statbuf.st_rdev = (s ? rip->i_rdev : NO_DEV); - statbuf.st_size = rip->i_size; - if (!s) statbuf.st_mode &= ~I_REGULAR;/* wipe out I_REGULAR bit for pipes */ - statbuf.st_atime = rip->i_atime; - statbuf.st_mtime = rip->i_mtime; - statbuf.st_ctime = rip->i_ctime; - statbuf.st_blksize = PIPE_BUF; - statbuf.st_blocks = blocks; - - /* Copy the struct to user space. */ - r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf, - (size_t) sizeof(statbuf)); - - return(r); -} - - -/*===========================================================================* - * fs_stat * - *===========================================================================*/ -int fs_stat(message *fs_m_in, message *fs_m_out) -{ - register int r; /* return value */ - register struct inode *rip; /* target inode */ - - if( (rip = find_inode(fs_m_in->m_vfs_fs_stat.inode)) == NULL) return(EINVAL); - get_inode(rip->i_dev, rip->i_num); /* mark inode in use */ - r = stat_inode(rip, fs_m_in->m_source, fs_m_in->m_vfs_fs_stat.grant); - put_inode(rip); /* release the inode */ - return(r); + return(OK); } diff --git a/minix/fs/pfs/super.c b/minix/fs/pfs/super.c index dc022946d..d10702fa0 100644 --- a/minix/fs/pfs/super.c +++ b/minix/fs/pfs/super.c @@ -9,9 +9,6 @@ */ #include "fs.h" -#include "buf.h" -#include "inode.h" -#include "const.h" /*===========================================================================* diff --git a/minix/fs/pfs/table.c b/minix/fs/pfs/table.c index d90e70252..5cad1c172 100644 --- a/minix/fs/pfs/table.c +++ b/minix/fs/pfs/table.c @@ -6,42 +6,16 @@ #define _TABLE #include "fs.h" -#include "inode.h" -#include "buf.h" /* 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 */ - no_sys, /* 3 */ - fs_ftrunc, /* 4 */ - no_sys, /* 5 */ - fs_chmod, /* 6 */ - no_sys, /* 7 */ - fs_stat, /* 8 */ - no_sys, /* 9 */ - no_sys, /* 10 */ - no_sys, /* 11 */ - no_sys, /* 12 */ - no_sys, /* 13 */ - no_sys, /* 14 */ - fs_unmount, /* 15 */ - fs_sync, /* 16 */ - no_sys, /* 17 */ - no_sys, /* 18 */ - fs_readwrite, /* 19 */ - fs_readwrite, /* 20 */ - no_sys, /* 21 */ - no_sys, /* 22 */ - no_sys, /* 23 */ - no_sys, /* 24 */ - no_sys, /* 25 */ - no_sys, /* 26 */ - no_sys, /* 27 */ - no_sys, /* 28 */ - fs_newnode, /* 29 */ - no_sys, /* 30 */ - no_sys, /* 31 */ - no_sys, /* 32 */ +struct fsdriver pfs_table = { + .fdr_mount = fs_mount, + .fdr_unmount = fs_unmount, + .fdr_newnode = fs_newnode, + .fdr_putnode = fs_putnode, + .fdr_read = fs_read, + .fdr_write = fs_write, + .fdr_trunc = fs_trunc, + .fdr_stat = fs_stat, + .fdr_chmod = fs_chmod }; diff --git a/minix/fs/pfs/utility.c b/minix/fs/pfs/utility.c deleted file mode 100644 index 468f46d9e..000000000 --- a/minix/fs/pfs/utility.c +++ /dev/null @@ -1,12 +0,0 @@ -#include "fs.h" - - -/*===========================================================================* - * no_sys * - *===========================================================================*/ -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", pfs_m_in->m_type); - return(EINVAL); -} diff --git a/minix/servers/vfs/main.c b/minix/servers/vfs/main.c index 4e3fd3630..c092404f7 100644 --- a/minix/servers/vfs/main.c +++ b/minix/servers/vfs/main.c @@ -289,7 +289,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info) message mess; struct rprocpub rprocpub[NR_BOOT_PROCS]; - receive_from = ANY; + receive_from = NONE; self = NULL; verbose = 0; @@ -379,10 +379,8 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info) init_vmnts(); /* init vmnt structures */ init_select(); /* init select() structures */ init_filps(); /* Init filp structures */ - mount_pfs(); /* mount Pipe File Server */ - /* Mount initial ramdisk as file system root. */ - receive_from = MFS_PROC_NR; + /* Mount PFS and initial file system root. */ worker_start(fproc_addr(VFS_PROC_NR), do_init_root, &mess /*unused*/, FALSE /*use_spare*/); @@ -394,9 +392,19 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info) *===========================================================================*/ static void do_init_root(void) { + char *mount_type, *mount_label; int r; - char *mount_type = "mfs"; /* FIXME: use boot image process name instead */ - char *mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */ + + /* Mount the pipe file server. */ + receive_from = PFS_PROC_NR; + + mount_pfs(); + + /* Mount the root file system. */ + receive_from = MFS_PROC_NR; + + mount_type = "mfs"; /* FIXME: use boot image process name instead */ + mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */ r = mount_fs(DEV_IMGRD, "bootramdisk", "/", MFS_PROC_NR, 0, mount_type, mount_label); @@ -485,6 +493,8 @@ static void get_work() } for(;;) { + assert(receive_from != NONE); + /* Normal case. No one to revive. Get a useful request. */ if ((r = sef_receive(receive_from, &m_in)) != OK) { panic("VFS: sef_receive error: %d", r); diff --git a/minix/servers/vfs/mount.c b/minix/servers/vfs/mount.c index 17ef918dc..2506f7ecd 100644 --- a/minix/servers/vfs/mount.c +++ b/minix/servers/vfs/mount.c @@ -390,11 +390,16 @@ char mount_label[LABEL_MAX] ) *===========================================================================*/ void mount_pfs(void) { -/* Mount the Pipe File Server. It's not really mounted onto the file system, - but it's necessary it has a vmnt entry to make locking easier */ - +/* Mount the Pipe File Server. We treat it as a regular file system to a + * certain extent, to prevent creating too many exceptions all over the place. + * For example, it has a vmnt entry to make locking easier, and it gets sent + * a mount request to keep the fsdriver library happy. + */ dev_t dev; struct vmnt *vmp; + struct node_details res; + unsigned int fs_flags; + int r; if ((dev = find_free_nonedev()) == NO_DEV) panic("VFS: no nonedev to initialize PFS"); @@ -410,6 +415,13 @@ void mount_pfs(void) strlcpy(vmp->m_label, "pfs", LABEL_MAX); strlcpy(vmp->m_mount_path, "pipe", PATH_MAX); strlcpy(vmp->m_mount_dev, "none", PATH_MAX); + + /* Ask PFS to acknowledge being mounted. Ignore the returned node details. */ + r = req_readsuper(vmp, "", dev, FALSE, FALSE, &res, &fs_flags); + if (r != OK) + printf("VFS: unable to mount PFS (%d)\n", r); + else + vmp->m_fs_flags = fs_flags; } /*===========================================================================* diff --git a/minix/servers/vfs/read.c b/minix/servers/vfs/read.c index f772b06d3..203c606b3 100644 --- a/minix/servers/vfs/read.c +++ b/minix/servers/vfs/read.c @@ -355,7 +355,10 @@ size_t req_size; buf += cum_io_incr; req_size -= cum_io_incr; - vp->v_size = new_pos; + if (rw_flag == READING) + vp->v_size -= cum_io_incr; + else + vp->v_size += cum_io_incr; if (partial_pipe) { /* partial write on pipe with */