From: David van Moolenbroek Date: Sun, 24 Aug 2014 10:18:30 +0000 (+0000) Subject: PFS: use libfsdriver X-Git-Url: http://zhaoyanbai.com/repos/nsupdate.html?a=commitdiff_plain;h=f859061eafa7665d8241f2f3949ecb2ce461295c;p=minix.git PFS: use libfsdriver In order to avoid creating libfsdriver exceptions, two changes to VFS are necessary: - the returned position field for reads/writes is no longer abused to return the new pipe size; VFS is perfectly capable of updating the size itself; - during system startup, PFS is now sent a mount request, just like all other file systems. In proper "two steps forward, one step back" fashion, the latter point has the consequence that PFS can no longer drop its privileges at startup. This is probably best resolved with a more general solution for all boot image system services. The upside is that PFS no longer needs to be linked with libc. Change-Id: I92e2410cdb0d93d0e6107bae10bc08efc2dbb8b3 --- 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); - - 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); - } + /* The fsdriver library does the actual work here. */ + fsdriver_task(&pfs_table); + 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. */ - - if (busy) return(EBUSY); /* can't umount a busy file system */ +/* Mount Pipe File Server. */ - /* 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 (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 && 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 (r == OK) { - position += (signed) nrbytes; /* Update position */ - cum_io += nrbytes; + put_block(rip->i_dev, rip->i_num); - /* 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 (r != OK) + return r; - if (rw_flag == READING) rip->i_update |= ATIME; - if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME; - } + /* 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); - fs_m_out->m_fs_vfs_readwrite.nbytes = cum_io; - fs_m_out->m_fs_vfs_readwrite.seek_pos = rip->i_size; + /* 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_inode(rip); put_block(rip->i_dev, rip->i_num); - return(r); + 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; - - /* 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); + 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; + + 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 */