# 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 <minix.service.mk>
#include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
static struct buf *new_block(dev_t dev, ino_t inum);
#include <sys/types.h>
#include <minix/const.h>
#include <minix/type.h>
-#include <minix/dmap.h>
-#include <minix/vfsif.h>
#include <lib.h>
-#include <limits.h>
-#include <errno.h>
#include <minix/syslib.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <minix/sysutil.h>
+#include <minix/fsdriver.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <assert.h>
+
#include "const.h"
#include "proto.h"
#include "glo.h"
+#include "buf.h"
+#include "inode.h"
#endif
#define EXTERN
#endif
-#include <minix/vfsif.h>
-
/* 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)];
*/
#include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <minix/vfsif.h>
static void addhash_inode(struct inode * const node);
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");
* 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);
}
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 */
/* inode hashtable */
EXTERN LIST_HEAD(inodelist, inode) hash_inodes[INODE_HASH_SIZE];
-
#endif
#include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <minix/vfsif.h>
/*===========================================================================*
- * 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);
}
#include "fs.h"
-#include <assert.h>
-#include <signal.h>
-#include <minix/dmap.h>
-#include <minix/driver.h>
-#include <minix/endpoint.h>
-#include <minix/rs.h>
-#include <minix/vfsif.h>
-#include <sys/types.h>
-#include <pwd.h>
-#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);
*===========================================================================*/
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);
}
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 */
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);
}
/* 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();
}
#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;
}
/*===========================================================================*
- * 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 */
+}
#include "fs.h"
-#include <sys/stat.h>
-#include "buf.h"
-#include "inode.h"
-#include <minix/vfsif.h>
/*===========================================================================*
* 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 */
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);
/* 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 */
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);
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);
#include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <minix/com.h>
-#include <string.h>
/*===========================================================================*
- * 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);
}
#include "fs.h"
-#include "inode.h"
-#include <string.h>
-#include <sys/stat.h>
/*===========================================================================*
- * 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);
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);
}
*/
#include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include "const.h"
/*===========================================================================*
#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
};
+++ /dev/null
-#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);
-}
message mess;
struct rprocpub rprocpub[NR_BOOT_PROCS];
- receive_from = ANY;
+ receive_from = NONE;
self = NULL;
verbose = 0;
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*/);
*===========================================================================*/
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);
}
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);
*===========================================================================*/
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");
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;
}
/*===========================================================================*
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 */