diff --git a/minix/fs/hgfs/Makefile b/minix/fs/hgfs/Makefile index 5fb1d3000..774a2925d 100644 --- a/minix/fs/hgfs/Makefile +++ b/minix/fs/hgfs/Makefile @@ -2,7 +2,7 @@ PROG= hgfs SRCS= hgfs.c -DPADD+= ${LIBSFFS} ${LIBHGFS} ${LIBSYS} -LDADD+= -lsffs -lhgfs -lsys +DPADD+= ${LIBSFFS} ${LIBHGFS} ${LIBFSDRIVER} ${LIBSYS} +LDADD+= -lsffs -lhgfs -lfsdriver -lsys .include diff --git a/minix/fs/vbfs/Makefile b/minix/fs/vbfs/Makefile index 90e0f0a0e..41b6b22a3 100644 --- a/minix/fs/vbfs/Makefile +++ b/minix/fs/vbfs/Makefile @@ -2,7 +2,7 @@ PROG= vbfs SRCS= vbfs.c -DPADD+= ${LIBSFFS} ${LIBVBOXFS} ${LIBSYS} -LDADD+= -lsffs -lvboxfs -lsys +DPADD+= ${LIBSFFS} ${LIBVBOXFS} ${LIBFSDRIVER} ${LIBSYS} +LDADD+= -lsffs -lvboxfs -lfsdriver -lsys .include diff --git a/minix/lib/libsffs/Makefile b/minix/lib/libsffs/Makefile index 4fb0b80b0..647ea3dbf 100644 --- a/minix/lib/libsffs/Makefile +++ b/minix/lib/libsffs/Makefile @@ -1,13 +1,13 @@ -NOGCCERROR=yes -NOCLANGERROR=yes -CPPFLAGS+= -D_MINIX_SYSTEM - # Makefile for libsffs .include +NOGCCERROR=yes + +CPPFLAGS+= -D_MINIX_SYSTEM + LIB= sffs SRCS= dentry.c handle.c inode.c link.c lookup.c main.c misc.c mount.c \ - name.c path.c read.c stat.c table.c util.c verify.c write.c + name.c path.c read.c stat.c table.c verify.c write.c .include diff --git a/minix/lib/libsffs/dentry.c b/minix/lib/libsffs/dentry.c index 45b0d7c5d..d90c2b419 100644 --- a/minix/lib/libsffs/dentry.c +++ b/minix/lib/libsffs/dentry.c @@ -14,7 +14,6 @@ static LIST_HEAD(hash_head, inode) hash_table[NUM_HASH_SLOTS]; -static void del_one_dentry(struct inode *ino); static unsigned int hash_dentry(struct inode *parent, char *name); /*===========================================================================* diff --git a/minix/lib/libsffs/glo.h b/minix/lib/libsffs/glo.h index d0ef5d98f..2ec5e942c 100644 --- a/minix/lib/libsffs/glo.h +++ b/minix/lib/libsffs/glo.h @@ -10,10 +10,8 @@ EXTERN char *sffs_name; /* file server name */ EXTERN const struct sffs_table *sffs_table; /* call table */ EXTERN struct sffs_params *sffs_params; /* parameters */ -EXTERN message m_in; /* request message */ -EXTERN message m_out; /* reply message */ EXTERN struct state state; /* global state */ -extern int(*call_vec[]) (void); +extern struct fsdriver sffs_dtable; /* driver table */ #endif /* _SFFS_GLO_H */ diff --git a/minix/lib/libsffs/inc.h b/minix/lib/libsffs/inc.h index cffad59da..61d537f08 100644 --- a/minix/lib/libsffs/inc.h +++ b/minix/lib/libsffs/inc.h @@ -2,6 +2,7 @@ #define _SFFS_INC_H #include +#include #include #include #include diff --git a/minix/lib/libsffs/inode.c b/minix/lib/libsffs/inode.c index 937e6453f..f28cb260b 100644 --- a/minix/lib/libsffs/inode.c +++ b/minix/lib/libsffs/inode.c @@ -273,19 +273,16 @@ int have_used_inode(void) /*===========================================================================* * do_putnode * *===========================================================================*/ -int do_putnode(void) +int do_putnode(ino_t ino_nr, unsigned int count) { /* Decrease an inode's reference count. */ struct inode *ino; - int count; - if ((ino = find_inode(m_in.m_vfs_fs_putnode.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; - count = m_in.m_vfs_fs_putnode.count; - - if (count <= 0 || count > ino->i_ref) return EINVAL; + if (count > ino->i_ref) return EINVAL; ino->i_ref -= count - 1; diff --git a/minix/lib/libsffs/link.c b/minix/lib/libsffs/link.c index 11d89accd..e1a01ad92 100644 --- a/minix/lib/libsffs/link.c +++ b/minix/lib/libsffs/link.c @@ -15,16 +15,15 @@ #include -static int force_remove(char *path, int dir); - /*===========================================================================* * do_create * *===========================================================================*/ -int do_create(void) +int do_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid, + struct fsdriver_node *node) { /* Create a new file. */ - char path[PATH_MAX], name[NAME_MAX+1]; + char path[PATH_MAX]; struct inode *parent, *ino; struct sffs_attr attr; sffs_file_t handle; @@ -34,13 +33,7 @@ int do_create(void) if (state.s_read_only) return EROFS; - /* Get path, name, parent inode and possibly inode for the given path. */ - if ((r = get_name(m_in.m_vfs_fs_create.grant, m_in.m_vfs_fs_create.path_len, name)) != OK) - return r; - - if (!strcmp(name, ".") || !strcmp(name, "..")) return EEXIST; - - if ((parent = find_inode(m_in.m_vfs_fs_create.inode)) == NULL) + if ((parent = find_inode(dir_nr)) == NULL) return EINVAL; if ((r = verify_dentry(parent, name, path, &ino)) != OK) @@ -59,8 +52,7 @@ int do_create(void) } /* Perform the actual create call. */ - r = sffs_table->t_open(path, O_CREAT | O_EXCL | O_RDWR, m_in.m_vfs_fs_create.mode, - &handle); + r = sffs_table->t_open(path, O_CREAT | O_EXCL | O_RDWR, mode, &handle); if (r != OK) { /* Let's not try to be too clever with error codes here. If something @@ -115,11 +107,12 @@ int do_create(void) add_dentry(parent, name, ino); - m_out.m_fs_vfs_create.inode = INODE_NR(ino); - m_out.m_fs_vfs_create.mode = get_mode(ino, attr.a_mode); - m_out.m_fs_vfs_create.file_size = attr.a_size; - m_out.m_fs_vfs_create.uid = sffs_params->p_uid; - m_out.m_fs_vfs_create.gid = sffs_params->p_gid; + node->fn_ino_nr = INODE_NR(ino); + node->fn_mode = get_mode(ino, attr.a_mode); + node->fn_size = attr.a_size; + node->fn_uid = sffs_params->p_uid; + node->fn_gid = sffs_params->p_gid; + node->fn_dev = NO_DEV; return OK; } @@ -127,11 +120,11 @@ int do_create(void) /*===========================================================================* * do_mkdir * *===========================================================================*/ -int do_mkdir(void) +int do_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid) { /* Make a new directory. */ - char path[PATH_MAX], name[NAME_MAX+1]; + char path[PATH_MAX]; struct inode *parent, *ino; int r; @@ -139,20 +132,14 @@ int do_mkdir(void) if (state.s_read_only) return EROFS; - /* Get the path string and possibly an inode for the given path. */ - if ((r = get_name(m_in.m_vfs_fs_mkdir.grant, m_in.m_vfs_fs_mkdir.path_len, name)) != OK) - return r; - - if (!strcmp(name, ".") || !strcmp(name, "..")) return EEXIST; - - if ((parent = find_inode(m_in.m_vfs_fs_mkdir.inode)) == NULL) + if ((parent = find_inode(dir_nr)) == NULL) return EINVAL; if ((r = verify_dentry(parent, name, path, &ino)) != OK) return r; /* Perform the actual mkdir call. */ - r = sffs_table->t_mkdir(path, m_in.m_vfs_fs_mkdir.mode); + r = sffs_table->t_mkdir(path, mode); if (r != OK) { if (ino != NULL) @@ -232,11 +219,11 @@ static int force_remove( /*===========================================================================* * do_unlink * *===========================================================================*/ -int do_unlink(void) +int do_unlink(ino_t dir_nr, char *name, int call) { /* Delete a file. */ - char path[PATH_MAX], name[NAME_MAX+1]; + char path[PATH_MAX]; struct inode *parent, *ino; int r; @@ -244,13 +231,7 @@ int do_unlink(void) if (state.s_read_only) return EROFS; - /* Get the path string and possibly preexisting inode for the given path. */ - if ((r = get_name(m_in.m_vfs_fs_unlink.grant, m_in.m_vfs_fs_unlink.path_len, name)) != OK) - return r; - - if (!strcmp(name, ".") || !strcmp(name, "..")) return EPERM; - - if ((parent = find_inode(m_in.m_vfs_fs_unlink.inode)) == NULL) + if ((parent = find_inode(dir_nr)) == NULL) return EINVAL; if ((r = verify_dentry(parent, name, path, &ino)) != OK) @@ -279,11 +260,11 @@ int do_unlink(void) /*===========================================================================* * do_rmdir * *===========================================================================*/ -int do_rmdir(void) +int do_rmdir(ino_t dir_nr, char *name, int call) { /* Remove an empty directory. */ - char path[PATH_MAX], name[NAME_MAX+1]; + char path[PATH_MAX]; struct inode *parent, *ino; int r; @@ -291,14 +272,7 @@ int do_rmdir(void) if (state.s_read_only) return EROFS; - /* Get the path string and possibly preexisting inode for the given path. */ - if ((r = get_name(m_in.m_vfs_fs_unlink.grant, m_in.m_vfs_fs_unlink.path_len, name)) != OK) - return r; - - if (!strcmp(name, ".")) return EINVAL; - if (!strcmp(name, "..")) return ENOTEMPTY; - - if ((parent = find_inode(m_in.m_vfs_fs_unlink.inode)) == NULL) + if ((parent = find_inode(dir_nr)) == NULL) return EINVAL; if ((r = verify_dentry(parent, name, path, &ino)) != OK) @@ -327,12 +301,12 @@ int do_rmdir(void) /*===========================================================================* * do_rename * *===========================================================================*/ -int do_rename(void) +int do_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr, + char *new_name) { /* Rename a file or directory. */ char old_path[PATH_MAX], new_path[PATH_MAX]; - char old_name[NAME_MAX+1], new_name[NAME_MAX+1]; struct inode *old_parent, *new_parent; struct inode *old_ino, *new_ino; int r; @@ -341,20 +315,9 @@ int do_rename(void) if (state.s_read_only) return EROFS; - /* Get path strings, names, directory inodes and possibly preexisting inodes - * for the old and new paths. - */ - if ((r = get_name(m_in.m_vfs_fs_rename.grant_old, m_in.m_vfs_fs_rename.len_old, - old_name)) != OK) return r; - - if ((r = get_name(m_in.m_vfs_fs_rename.grant_new, m_in.m_vfs_fs_rename.len_new, - new_name)) != OK) return r; - - if (!strcmp(old_name, ".") || !strcmp(old_name, "..") || - !strcmp(new_name, ".") || !strcmp(new_name, "..")) return EINVAL; - - if ((old_parent = find_inode(m_in.m_vfs_fs_rename.dir_old)) == NULL || - (new_parent = find_inode(m_in.m_vfs_fs_rename.dir_new)) == NULL) + /* Get possibly preexisting inodes for the old and new paths. */ + if ((old_parent = find_inode(old_dir_nr)) == NULL || + (new_parent = find_inode(new_dir_nr)) == NULL) return EINVAL; if ((r = verify_dentry(old_parent, old_name, old_path, &old_ino)) != OK) diff --git a/minix/lib/libsffs/lookup.c b/minix/lib/libsffs/lookup.c index f61c08a9e..ca5324b78 100644 --- a/minix/lib/libsffs/lookup.c +++ b/minix/lib/libsffs/lookup.c @@ -9,103 +9,6 @@ #include "inc.h" -static int get_mask(vfs_ucred_t *ucred); - -static int access_as_dir(struct inode *ino, struct sffs_attr *attr, - int uid, int mask); - -static int next_name(char **ptr, char **start, char name[NAME_MAX+1]); - -static int go_up(char path[PATH_MAX], struct inode *ino, - struct inode **res_ino, struct sffs_attr *attr); - -static int go_down(char path[PATH_MAX], struct inode *ino, char *name, - struct inode **res_ino, struct sffs_attr *attr); - -/*===========================================================================* - * get_mask * - *===========================================================================*/ -static int get_mask( - vfs_ucred_t *ucred /* credentials of the caller */ -) -{ - /* Given the caller's credentials, precompute a search access mask to test - * against directory modes. - */ - int i; - - if (ucred->vu_uid == sffs_params->p_uid) return S_IXUSR; - - if (ucred->vu_gid == sffs_params->p_gid) return S_IXGRP; - - for (i = 0; i < ucred->vu_ngroups; i++) - if (ucred->vu_sgroups[i] == sffs_params->p_gid) return S_IXGRP; - - return S_IXOTH; -} - -/*===========================================================================* - * access_as_dir * - *===========================================================================*/ -static int access_as_dir( - struct inode *ino, /* the inode to test */ - struct sffs_attr *attr, /* attributes of the inode */ - int uid, /* UID of the caller */ - int mask /* search access mask of the caller */ -) -{ -/* Check whether the given inode may be accessed as directory. - * Return OK or an appropriate error code. - */ - mode_t mode; - - assert(attr->a_mask & SFFS_ATTR_MODE); - - /* The inode must be a directory to begin with. */ - if (!IS_DIR(ino)) return ENOTDIR; - - /* The caller must have search access to the directory. Root always does. */ - if (uid == 0) return OK; - - mode = get_mode(ino, attr->a_mode); - - return (mode & mask) ? OK : EACCES; -} - -/*===========================================================================* - * next_name * - *===========================================================================*/ -static int next_name( - char **ptr, /* cursor pointer into path (in, out) */ - char **start, /* place to store start of name */ - char name[NAME_MAX+1] /* place to store name */ -) -{ -/* Get the next path component from a path. - */ - char *p; - int i; - - for (p = *ptr; *p == '/'; p++); - - *start = p; - - if (*p) { - for (i = 0; *p && *p != '/' && i <= NAME_MAX; p++, i++) - name[i] = *p; - - if (i > NAME_MAX) - return ENAMETOOLONG; - - name[i] = 0; - } else { - strcpy(name, "."); - } - - *ptr = p; - return OK; -} - /*===========================================================================* * go_up * *===========================================================================*/ @@ -199,142 +102,49 @@ static int go_down( /*===========================================================================* * do_lookup * *===========================================================================*/ -int do_lookup(void) +int do_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node, + int *is_mountpt) { /* Resolve a path string to an inode. */ - ino_t dir_ino_nr, root_ino_nr; - struct inode *cur_ino, *root_ino; - struct inode *next_ino = NULL; + struct inode *dir_ino, *ino; struct sffs_attr attr; - char buf[PATH_MAX], path[PATH_MAX]; - char name[NAME_MAX+1]; - char *ptr, *last; - vfs_ucred_t ucred; - mode_t mask; - size_t len; + char path[PATH_MAX]; int r; - dir_ino_nr = m_in.m_vfs_fs_lookup.dir_ino; - root_ino_nr = m_in.m_vfs_fs_lookup.root_ino; - len = m_in.m_vfs_fs_lookup.path_len; + dprintf(("%s: lookup: got query for %"PRIu64", '%s'\n", + sffs_name, dir_nr, name)); - /* Fetch the path name. */ - if (len < 1 || len > PATH_MAX) - return EINVAL; - - r = sys_safecopyfrom(m_in.m_source, m_in.m_vfs_fs_lookup.grant_path, 0, - (vir_bytes) buf, len); - - if (r != OK) - return r; - - if (buf[len-1] != 0) { - printf("%s: VFS did not zero-terminate path!\n", sffs_name); - - return EINVAL; - } - - /* Fetch the credentials, and generate a search access mask to test against - * directory modes. - */ - if (m_in.m_vfs_fs_lookup.flags & PATH_GET_UCRED) { - if (m_in.m_vfs_fs_lookup.ucred_size != sizeof(ucred)) { - printf("%s: bad credential structure size\n", sffs_name); - - return EINVAL; - } - - r = sys_safecopyfrom(m_in.m_source, m_in.m_vfs_fs_lookup.grant_ucred, 0, - (vir_bytes) &ucred, m_in.m_vfs_fs_lookup.ucred_size); - - if (r != OK) - return r; - } - else { - ucred.vu_uid = m_in.m_vfs_fs_lookup.uid; - ucred.vu_gid = m_in.m_vfs_fs_lookup.gid; - ucred.vu_ngroups = 0; - } - - mask = get_mask(&ucred); - - /* Start the actual lookup. */ - dprintf(("%s: lookup: got query '%s'\n", sffs_name, buf)); - - if ((cur_ino = find_inode(dir_ino_nr)) == NULL) + if ((dir_ino = find_inode(dir_nr)) == NULL) return EINVAL; attr.a_mask = SFFS_ATTR_MODE | SFFS_ATTR_SIZE; - if ((r = verify_inode(cur_ino, path, &attr)) != OK) + if ((r = verify_inode(dir_ino, path, &attr)) != OK) return r; - get_inode(cur_ino); + if (!IS_DIR(dir_ino)) + return ENOTDIR; - if (root_ino_nr > 0) - root_ino = find_inode(root_ino_nr); + r = OK; + if (!strcmp(name, ".")) + get_inode(ino = dir_ino); + else if (!strcmp(name, "..")) + r = go_up(path, dir_ino, &ino, &attr); else - root_ino = NULL; - - /* One possible optimization would be to check a path only right before the - * first ".." in a row, and at the very end (if still necessary). This would - * have consequences for inode validation, though. - */ - for (ptr = last = buf; *ptr != 0; ) { - if ((r = access_as_dir(cur_ino, &attr, ucred.vu_uid, mask)) != OK) - break; - - if ((r = next_name(&ptr, &last, name)) != OK) - break; - - dprintf(("%s: lookup: next name '%s'\n", sffs_name, name)); - - if (!strcmp(name, ".") || - (cur_ino == root_ino && !strcmp(name, ".."))) - continue; - - if (!strcmp(name, "..")) { - if (IS_ROOT(cur_ino)) - r = ELEAVEMOUNT; - else - r = go_up(path, cur_ino, &next_ino, &attr); - } else { - r = go_down(path, cur_ino, name, &next_ino, &attr); - } - - if (r != OK) - break; - - assert(next_ino != NULL); - - put_inode(cur_ino); - - cur_ino = next_ino; - } - - dprintf(("%s: lookup: result %d\n", sffs_name, r)); - - if (r != OK) { - put_inode(cur_ino); - - /* We'd need support for these here. We don't have such support. */ - assert(r != EENTERMOUNT && r != ESYMLINK); - - if (r == ELEAVEMOUNT) { - m_out.m_fs_vfs_lookup.offset = (last - buf); - m_out.m_fs_vfs_lookup.symloop = 0; - } + r = go_down(path, dir_ino, name, &ino, &attr); + if (r != OK) return r; - } - m_out.m_fs_vfs_lookup.inode = INODE_NR(cur_ino); - m_out.m_fs_vfs_lookup.mode = get_mode(cur_ino, attr.a_mode); - m_out.m_fs_vfs_lookup.file_size = attr.a_size; - m_out.m_fs_vfs_lookup.uid = sffs_params->p_uid; - m_out.m_fs_vfs_lookup.gid = sffs_params->p_gid; - m_out.m_fs_vfs_lookup.device = NO_DEV; + node->fn_ino_nr = INODE_NR(ino); + node->fn_mode = get_mode(ino, attr.a_mode); + node->fn_size = attr.a_size; + node->fn_uid = sffs_params->p_uid; + node->fn_gid = sffs_params->p_gid; + node->fn_dev = NO_DEV; + + *is_mountpt = FALSE; return OK; } diff --git a/minix/lib/libsffs/main.c b/minix/lib/libsffs/main.c index 137e520b1..dccbf54e7 100644 --- a/minix/lib/libsffs/main.c +++ b/minix/lib/libsffs/main.c @@ -26,9 +26,6 @@ int sffs_init(char *name, const struct sffs_table *table, while (i > 0 && params->p_prefix[i - 1] == '/') i--; params->p_prefix[i] = 0; - state.s_mounted = FALSE; - state.s_signaled = FALSE; - sffs_name = name; sffs_table = table; sffs_params = params; @@ -45,62 +42,9 @@ void sffs_signal(int signo) /* Only check for termination signal, ignore anything else. */ if (signo != SIGTERM) return; - /* We can now terminate if we have also been unmounted. */ - state.s_signaled = TRUE; + dprintf(("%s: got SIGTERM\n", sffs_name)); - if (state.s_mounted) { - dprintf(("%s: got SIGTERM, still mounted\n", sffs_name)); - } else { - dprintf(("%s: got SIGTERM, shutting down\n", sffs_name)); - - /* Break out of the main loop, giving the main program the chance to - * perform further cleanup. This causes sef_receive() to return with - * an EINTR error code. - */ - sef_cancel(); - } -} - -/*===========================================================================* - * get_work * - *===========================================================================*/ -static int get_work(endpoint_t *who_e) -{ -/* Receive a request message from VFS. Return TRUE if a new message is ready - * to be processed, or FALSE if sef_stop() was called from the signal handler. - */ - int r; - - if ((r = sef_receive(ANY, &m_in)) != OK) { - if (r != EINTR) - panic("receive failed: %d", r); - - return FALSE; - } - - *who_e = m_in.m_source; - return TRUE; -} - -/*===========================================================================* - * send_reply * - *===========================================================================*/ -static void send_reply( - int err, /* resulting error code */ - int transid -) -{ -/* Send a reply message to the requesting party, with the given error code. - */ - int r; - - m_out.m_type = err; - if (IS_VFS_FS_TRANSID(transid)) { - /* If a transaction ID was set, reset it */ - m_out.m_type = TRNS_ADD_ID(m_out.m_type, transid); - } - if ((r = ipc_send(m_in.m_source, &m_out)) != OK) - printf("%s: ipc_send failed (%d)\n", sffs_name, r); + fsdriver_terminate(); } /*===========================================================================* @@ -108,47 +52,8 @@ static void send_reply( *===========================================================================*/ void sffs_loop(void) { -/* The main function of this file server. After initializing, loop, receiving - * one request from VFS at a time, processing it, and sending a reply back to - * VFS. Termination occurs when we both have been unmounted and have received - * a termination signal. +/* The main function of this file server. Libfsdriver does the real work. */ - endpoint_t who_e; - int call_nr, err, transid; - while (state.s_mounted || !state.s_signaled) { - if (!get_work(&who_e)) - continue; /* Recheck running conditions */ - - transid = TRNS_GET_ID(m_in.m_type); - m_in.m_type = TRNS_DEL_ID(m_in.m_type); - if (m_in.m_type == 0) { - assert(!IS_VFS_FS_TRANSID(transid)); - m_in.m_type = transid; /* Backwards compat. */ - transid = 0; - } else - assert(IS_VFS_FS_TRANSID(transid)); - - call_nr = m_in.m_type; - if (who_e != VFS_PROC_NR) { - continue; - } - - if (state.s_mounted || call_nr == REQ_READSUPER) { - call_nr -= FS_BASE; - - dprintf(("%s: call %d\n", sffs_name, call_nr)); - - if (call_nr >= 0 && call_nr < NREQS) { - err = (*call_vec[call_nr])(); - } else { - err = ENOSYS; - } - - dprintf(("%s: call %d result %d\n", sffs_name, call_nr, err)); - } - else err = EINVAL; - - send_reply(err, transid); - } + fsdriver_task(&sffs_dtable); } diff --git a/minix/lib/libsffs/misc.c b/minix/lib/libsffs/misc.c index 59ebb0951..f7a8e3467 100644 --- a/minix/lib/libsffs/misc.c +++ b/minix/lib/libsffs/misc.c @@ -14,11 +14,10 @@ /*===========================================================================* * do_statvfs * *===========================================================================*/ -int do_statvfs(void) +int do_statvfs(struct statvfs *statvfs) { /* Retrieve file system statistics. */ - struct statvfs statvfs; struct inode *ino; char path[PATH_MAX]; u64_t free, total; @@ -38,20 +37,17 @@ int do_statvfs(void) if ((r = sffs_table->t_queryvol(path, &free, &total)) != OK) return r; - memset(&statvfs, 0, sizeof(statvfs)); - /* Returning zero for unknown values seems to be the convention. However, we * do have to use a nonzero block size, even though it is entirely arbitrary. */ - statvfs.f_flag = ST_NOTRUNC; - statvfs.f_bsize = BLOCK_SIZE; - statvfs.f_frsize = BLOCK_SIZE; - statvfs.f_iosize = BLOCK_SIZE; - statvfs.f_blocks = (unsigned long)(total / BLOCK_SIZE); - statvfs.f_bfree = (unsigned long)(free / BLOCK_SIZE); - statvfs.f_bavail = statvfs.f_bfree; - statvfs.f_namemax = NAME_MAX; + statvfs->f_flag = ST_NOTRUNC; + statvfs->f_bsize = BLOCK_SIZE; + statvfs->f_frsize = BLOCK_SIZE; + statvfs->f_iosize = BLOCK_SIZE; + statvfs->f_blocks = (fsblkcnt_t)(total / BLOCK_SIZE); + statvfs->f_bfree = (fsblkcnt_t)(free / BLOCK_SIZE); + statvfs->f_bavail = statvfs->f_bfree; + statvfs->f_namemax = NAME_MAX; - return sys_safecopyto(m_in.m_source, m_in.m_vfs_fs_statvfs.grant, 0, - (vir_bytes) &statvfs, sizeof(statvfs)); + return OK; } diff --git a/minix/lib/libsffs/mount.c b/minix/lib/libsffs/mount.c index f4cfc2b75..a8d1a41ec 100644 --- a/minix/lib/libsffs/mount.c +++ b/minix/lib/libsffs/mount.c @@ -1,7 +1,7 @@ /* This file contains mount and unmount functionality. * * The entry points into this file are: - * do_readsuper perform the READSUPER file system call + * do_mount perform the READSUPER file system call * do_unmount perform the UNMOUNT file system call * * Created: @@ -11,9 +11,10 @@ #include "inc.h" /*===========================================================================* - * do_readsuper * + * do_mount * *===========================================================================*/ -int do_readsuper(void) +int do_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node, + unsigned int *res_flags) { /* Mount the file system. */ @@ -22,17 +23,16 @@ int do_readsuper(void) struct sffs_attr attr; int r; - dprintf(("%s: readsuper (dev %x, flags %x)\n", - sffs_name, m_in.m_vfs_fs_readsuper.device, m_in.vfs_fs_readsuper.flags)); + dprintf(("%s: mount (dev %"PRIx64", flags %x)\n", sffs_name, dev, flags)); - if (m_in.m_vfs_fs_readsuper.flags & REQ_ISROOT) { + if (flags & REQ_ISROOT) { printf("%s: attempt to mount as root device\n", sffs_name); return EINVAL; } - state.s_read_only = !!(m_in.m_vfs_fs_readsuper.flags & REQ_RDONLY); - state.s_dev = m_in.m_vfs_fs_readsuper.device; + state.s_read_only = !!(flags & REQ_RDONLY); + state.s_dev = dev; init_dentry(); ino = init_inode(); @@ -55,15 +55,14 @@ int do_readsuper(void) return r; } - m_out.m_fs_vfs_readsuper.inode = INODE_NR(ino); - m_out.m_fs_vfs_readsuper.mode = get_mode(ino, attr.a_mode); - m_out.m_fs_vfs_readsuper.file_size = attr.a_size; - m_out.m_fs_vfs_readsuper.uid = sffs_params->p_uid; - m_out.m_fs_vfs_readsuper.gid = sffs_params->p_gid; - m_out.m_fs_vfs_readsuper.device = NO_DEV; - m_out.m_fs_vfs_readsuper.flags = RES_64BIT; + root_node->fn_ino_nr = INODE_NR(ino); + root_node->fn_mode = get_mode(ino, attr.a_mode); + root_node->fn_size = attr.a_size; + root_node->fn_uid = sffs_params->p_uid; + root_node->fn_gid = sffs_params->p_gid; + root_node->fn_dev = NO_DEV; - state.s_mounted = TRUE; + *res_flags = RES_64BIT; return OK; } @@ -71,25 +70,21 @@ int do_readsuper(void) /*===========================================================================* * do_unmount * *===========================================================================*/ -int do_unmount(void) +void do_unmount(void) { /* Unmount the file system. */ struct inode *ino; - dprintf(("%s: do_unmount\n", sffs_name)); + dprintf(("%s: unmount\n", sffs_name)); /* Decrease the reference count of the root inode. */ if ((ino = find_inode(ROOT_INODE_NR)) == NULL) - return EINVAL; + return; put_inode(ino); /* There should not be any referenced inodes anymore now. */ if (have_used_inode()) printf("%s: in-use inodes left at unmount time!\n", sffs_name); - - state.s_mounted = FALSE; - - return OK; } diff --git a/minix/lib/libsffs/name.c b/minix/lib/libsffs/name.c index 9627586bc..80585ea0d 100644 --- a/minix/lib/libsffs/name.c +++ b/minix/lib/libsffs/name.c @@ -28,7 +28,7 @@ void normalize_name(char dst[NAME_MAX+1], char *src) if (sffs_params->p_case_insens) { for (i = 0; i < size; i++) - *dst++ = tolower(*src++); + *dst++ = tolower((int)*src++); } else memcpy(dst, src, size); } diff --git a/minix/lib/libsffs/proto.h b/minix/lib/libsffs/proto.h index fb4131243..63c9e2ecf 100644 --- a/minix/lib/libsffs/proto.h +++ b/minix/lib/libsffs/proto.h @@ -21,27 +21,31 @@ void unlink_inode(struct inode *ino); struct inode *get_free_inode(void); int have_free_inode(void); int have_used_inode(void); -int do_putnode(void); +int do_putnode(ino_t ino_nr, unsigned int count); /* link.c */ -int do_create(void); -int do_mkdir(void); -int do_unlink(void); -int do_rmdir(void); -int do_rename(void); +int do_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid, + struct fsdriver_node *node); +int do_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid); +int do_unlink(ino_t dir_nr, char *name, int call); +int do_rmdir(ino_t dir_nr, char *name, int call); +int do_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr, + char *new_name); /* lookup.c */ -int do_lookup(void); +int do_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node, + int *is_mountpt); /* main.c */ int main(int argc, char *argv[]); /* misc.c */ -int do_statvfs(void); +int do_statvfs(struct statvfs *statvfs); /* mount.c */ -int do_readsuper(void); -int do_unmount(void); +int do_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node, + unsigned int *res_flags); +void do_unmount(void); /* name.c */ void normalize_name(char dst[NAME_MAX+1], char *src); @@ -53,19 +57,16 @@ int push_path(char path[PATH_MAX], char *name); void pop_path(char path[PATH_MAX]); /* read.c */ -int do_read(void); -int do_getdents(void); +ssize_t do_read(ino_t ino_nr, struct fsdriver_data *data, size_t count, + off_t pos, int call); +ssize_t do_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t *pos); /* stat.c */ mode_t get_mode(struct inode *ino, int mode); -int do_stat(void); -int do_chmod(void); -int do_utime(void); - -/* util.c */ -int get_name(cp_grant_id_t grant, size_t len, char name[NAME_MAX+1]); -int do_noop(void); -int no_sys(void); +int do_stat(ino_t ino_nr, struct stat *stat); +int do_chmod(ino_t ino_nr, mode_t *mode); +int do_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime); /* verify.c */ int verify_path(char *path, struct inode *ino, struct sffs_attr *attr, @@ -76,7 +77,8 @@ int verify_dentry(struct inode *parent, char name[NAME_MAX+1], char path[PATH_MAX], struct inode **res_ino); /* write.c */ -int do_write(void); -int do_ftrunc(void); +ssize_t do_write(ino_t ino_nr, struct fsdriver_data *data, size_t count, + off_t pos, int call); +int do_trunc(ino_t ino_nr, off_t start, off_t end); #endif /* _SFFS_PROTO_H */ diff --git a/minix/lib/libsffs/read.c b/minix/lib/libsffs/read.c index a4bb9b528..58586102b 100644 --- a/minix/lib/libsffs/read.c +++ b/minix/lib/libsffs/read.c @@ -12,23 +12,20 @@ #include -#define DWORD_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1)) - /*===========================================================================* * do_read * *===========================================================================*/ -int do_read(void) +ssize_t do_read(ino_t ino_nr, struct fsdriver_data *data, size_t count, + off_t pos, int call) { /* Read data from a file. */ struct inode *ino; - off_t pos; - size_t count, size; - vir_bytes off; + size_t size, off; char *ptr; int r, chunk; - if ((ino = find_inode(m_in.m_vfs_fs_readwrite.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; if (IS_DIR(ino)) return EISDIR; @@ -36,9 +33,6 @@ int do_read(void) if ((r = get_handle(ino)) != OK) return r; - pos = m_in.m_vfs_fs_readwrite.seek_pos; - count = m_in.m_vfs_fs_readwrite.nbytes; - assert(count > 0); /* Use the buffer from below to eliminate extra copying. */ @@ -53,10 +47,7 @@ int do_read(void) chunk = r; - r = sys_safecopyto(m_in.m_source, m_in.m_vfs_fs_readwrite.grant, off, - (vir_bytes) ptr, chunk); - - if (r != OK) + if ((r = fsdriver_copyout(data, off, ptr, chunk)) != OK) break; count -= chunk; @@ -67,38 +58,33 @@ int do_read(void) if (r < 0) return r; - m_out.m_fs_vfs_readwrite.seek_pos = pos; - m_out.m_fs_vfs_readwrite.nbytes = off; - - return OK; + return off; } /*===========================================================================* * do_getdents * *===========================================================================*/ -int do_getdents(void) +ssize_t do_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes, + off_t *posp) { /* Retrieve directory entries. */ + struct fsdriver_dentry fsdentry; char name[NAME_MAX+1]; struct inode *ino, *child; - struct dirent *dent; struct sffs_attr attr; - size_t len, off, user_off, user_left; off_t pos; - int r, namelen; + int r; /* must be at least sizeof(struct dirent) + NAME_MAX */ static char buf[BLOCK_SIZE]; - attr.a_mask = SFFS_ATTR_MODE; - - if ((ino = find_inode(m_in.m_vfs_fs_getdents.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; - if(m_in.m_vfs_fs_getdents.seek_pos >= ULONG_MAX) return EINVAL; - if (!IS_DIR(ino)) return ENOTDIR; + if (*posp < 0 || *posp >= ULONG_MAX) return EINVAL; + /* We are going to need at least one free inode to store children in. */ if (!have_free_inode()) return ENFILE; @@ -106,19 +92,19 @@ int do_getdents(void) if ((r = get_handle(ino)) != OK) return r; - off = 0; - user_off = 0; - user_left = m_in.m_vfs_fs_getdents.mem_size; + fsdriver_dentry_init(&fsdentry, data, bytes, buf, sizeof(buf)); /* We use the seek position as file index number. The first position is for * the "." entry, the second position is for the ".." entry, and the next * position numbers each represent a file in the directory. */ - for (pos = m_in.m_vfs_fs_getdents.seek_pos; ; pos++) { + do { /* Determine which inode and name to use for this entry. * We have no idea whether the host will give us "." and/or "..", * so generate our own and skip those from the host. */ + pos = (*posp)++; + if (pos == 0) { /* Entry for ".". */ child = ino; @@ -140,6 +126,8 @@ int do_getdents(void) } else { /* Any other entry, not being "." or "..". */ + attr.a_mask = SFFS_ATTR_MODE; + r = sffs_table->t_readdir(ino->i_dir, pos - 2, name, sizeof(name), &attr); @@ -170,66 +158,14 @@ int do_getdents(void) } } - /* record length incl. alignment. */ - namelen = strlen(name); - len = _DIRENT_RECLEN(dent, namelen); - - /* Is the user buffer too small to store another record? - * Note that we will be rerequesting the same dentry upon a subsequent - * getdents call this way, but we really need the name length for this. - */ - if (user_off + off + len > user_left) { - put_inode(child); - - /* Is the user buffer too small for even a single record? */ - if (user_off == 0 && off == 0) - return EINVAL; - - break; - } - - /* If our own buffer cannot contain the new record, copy out first. */ - if (off + len > sizeof(buf)) { - r = sys_safecopyto(m_in.m_source, m_in.m_vfs_fs_getdents.grant, - user_off, (vir_bytes) buf, off); - - if (r != OK) { - put_inode(child); - - return r; - } - - user_off += off; - user_left -= off; - off = 0; - } - - /* Fill in the actual directory entry. */ - dent = (struct dirent *) &buf[off]; - dent->d_ino = INODE_NR(child); - dent->d_reclen = len; - dent->d_namlen = namelen; - dent->d_type = IS_DIR(child) ? DT_DIR : DT_REG; - strcpy(dent->d_name, name); - - off += len; + r = fsdriver_dentry_add(&fsdentry, INODE_NR(child), name, strlen(name), + IS_DIR(child) ? DT_DIR : DT_REG); put_inode(child); - } - /* If there is anything left in our own buffer, copy that out now. */ - if (off > 0) { - r = sys_safecopyto(m_in.m_source, m_in.m_vfs_fs_getdents.grant, user_off, - (vir_bytes) buf, off); - - if (r != OK) + if (r < 0) return r; + } while (r > 0); - user_off += off; - } - - m_out.m_fs_vfs_getdents.seek_pos = pos; - m_out.m_fs_vfs_getdents.nbytes = user_off; - - return OK; + return fsdriver_dentry_finish(&fsdentry); } diff --git a/minix/lib/libsffs/stat.c b/minix/lib/libsffs/stat.c index 76f2fae89..bd9902b30 100644 --- a/minix/lib/libsffs/stat.c +++ b/minix/lib/libsffs/stat.c @@ -37,19 +37,15 @@ mode_t get_mode(struct inode *ino, int mode) /*===========================================================================* * do_stat * *===========================================================================*/ -int do_stat(void) +int do_stat(ino_t ino_nr, struct stat *stat) { /* Retrieve inode status. */ struct inode *ino; struct sffs_attr attr; - struct stat stat; char path[PATH_MAX]; - ino_t ino_nr; int r; - ino_nr = m_in.m_vfs_fs_stat.inode; - /* Don't increase the inode refcount: it's already open anyway */ if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; @@ -60,45 +56,42 @@ int do_stat(void) if ((r = verify_inode(ino, path, &attr)) != OK) return r; - memset(&stat, 0, sizeof(struct stat)); + stat->st_dev = state.s_dev; + stat->st_ino = ino_nr; + stat->st_mode = get_mode(ino, attr.a_mode); + stat->st_uid = sffs_params->p_uid; + stat->st_gid = sffs_params->p_gid; + stat->st_rdev = NO_DEV; + stat->st_size = attr.a_size; + stat->st_atimespec = attr.a_atime; + stat->st_mtimespec = attr.a_mtime; + stat->st_ctimespec = attr.a_ctime; + stat->st_birthtimespec = attr.a_crtime; - stat.st_dev = state.s_dev; - stat.st_ino = ino_nr; - stat.st_mode = get_mode(ino, attr.a_mode); - stat.st_uid = sffs_params->p_uid; - stat.st_gid = sffs_params->p_gid; - stat.st_rdev = NO_DEV; - stat.st_size = attr.a_size; - stat.st_atimespec = attr.a_atime; - stat.st_mtimespec = attr.a_mtime; - stat.st_ctimespec = attr.a_ctime; - stat.st_birthtimespec = attr.a_crtime; + stat->st_blocks = stat->st_size / S_BLKSIZE; + if (stat->st_size % S_BLKSIZE != 0) + stat->st_blocks += 1; - stat.st_blocks = stat.st_size / S_BLKSIZE; - if (stat.st_size % S_BLKSIZE != 0) - stat.st_blocks += 1; - - stat.st_blksize = BLOCK_SIZE; + stat->st_blksize = BLOCK_SIZE; /* We could make this more accurate by iterating over directory inodes' * children, counting how many of those are directories as well. * It's just not worth it. */ - stat.st_nlink = 0; - if (ino->i_parent != NULL) stat.st_nlink++; + stat->st_nlink = 0; + if (ino->i_parent != NULL) stat->st_nlink++; if (IS_DIR(ino)) { - stat.st_nlink++; - if (HAS_CHILDREN(ino)) stat.st_nlink++; + stat->st_nlink++; + if (HAS_CHILDREN(ino)) stat->st_nlink++; } - return sys_safecopyto(m_in.m_source, m_in.m_vfs_fs_stat.grant, 0, - (vir_bytes) &stat, sizeof(stat)); + return OK; } /*===========================================================================* * do_chmod * *===========================================================================*/ -int do_chmod(void) +int do_chmod(ino_t ino_nr, mode_t *mode) { /* Change file mode. */ @@ -110,7 +103,7 @@ int do_chmod(void) if (state.s_read_only) return EROFS; - if ((ino = find_inode(m_in.m_vfs_fs_chmod.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; if ((r = verify_inode(ino, path, NULL)) != OK) @@ -118,7 +111,7 @@ int do_chmod(void) /* Set the new file mode. */ attr.a_mask = SFFS_ATTR_MODE; - attr.a_mode = m_in.m_vfs_fs_chmod.mode; /* no need to convert in this direction */ + attr.a_mode = *mode; /* no need to convert in this direction */ if ((r = sffs_table->t_setattr(path, &attr)) != OK) return r; @@ -127,7 +120,7 @@ int do_chmod(void) if ((r = verify_path(path, ino, &attr, NULL)) != OK) return r; - m_out.m_fs_vfs_chmod.mode = get_mode(ino, attr.a_mode); + *mode = get_mode(ino, attr.a_mode); return OK; } @@ -135,7 +128,7 @@ int do_chmod(void) /*===========================================================================* * do_utime * *===========================================================================*/ -int do_utime(void) +int do_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime) { /* Set file times. */ @@ -147,7 +140,7 @@ int do_utime(void) if (state.s_read_only) return EROFS; - if ((ino = find_inode(m_in.m_vfs_fs_utime.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; if ((r = verify_inode(ino, path, NULL)) != OK) @@ -155,37 +148,31 @@ int do_utime(void) attr.a_mask = 0; - switch(m_in.m_vfs_fs_utime.acnsec) { + switch (atime->tv_nsec) { case UTIME_OMIT: /* do not touch */ break; case UTIME_NOW: /* XXX VFS should have time() into ACTIME, for compat; we trust it! */ - m_in.m_vfs_fs_utime.acnsec = 0; + atime->tv_nsec = 0; /*FALLTHROUGH*/ default: - /* cases m_in.m_vfs_fs_utime.acnsec < 0 || m_in.m_vfs_fs_utime.acnsec >= 1E9 - * are caught by VFS to cooperate with old instances of EXT2 - */ - attr.a_atime.tv_sec = m_in.m_vfs_fs_utime.actime; - attr.a_atime.tv_nsec = m_in.m_vfs_fs_utime.acnsec; + attr.a_atime = *atime; attr.a_mask |= SFFS_ATTR_ATIME; break; } - switch(m_in.m_vfs_fs_utime.modnsec) { + + switch (mtime->tv_nsec) { case UTIME_OMIT: /* do not touch */ break; case UTIME_NOW: /* XXX VFS should have time() into MODTIME, for compat; we trust it! */ - m_in.m_vfs_fs_utime.modnsec = 0; + mtime->tv_nsec = 0; /*FALLTHROUGH*/ default: - /* cases m_in.m_vfs_fs_utime.modnsec < 0 || m_in.m_vfs_fs_utime.modnsec >= 1E9 - * are caught by VFS to cooperate with old instances - */ - attr.a_mtime.tv_sec = m_in.m_vfs_fs_utime.modtime; - attr.a_mtime.tv_nsec = m_in.m_vfs_fs_utime.modnsec; + attr.a_mtime = *mtime; attr.a_mask |= SFFS_ATTR_MTIME; break; } + return sffs_table->t_setattr(path, &attr); } diff --git a/minix/lib/libsffs/table.c b/minix/lib/libsffs/table.c index 125b6041b..d75232ff9 100644 --- a/minix/lib/libsffs/table.c +++ b/minix/lib/libsffs/table.c @@ -7,42 +7,22 @@ #define _TABLE #include "inc.h" -int (*call_vec[])(void) = { - no_sys, /* 0 */ - no_sys, /* 1 getnode */ - do_putnode, /* 2 putnode */ - no_sys, /* 3 slink */ - do_ftrunc, /* 4 ftrunc */ - no_sys, /* 5 chown */ - do_chmod, /* 6 chmod */ - do_noop, /* 7 inhibread */ - do_stat, /* 8 stat */ - do_utime, /* 9 utime */ - do_statvfs, /* 10 statvfs */ - no_sys, /* 11 bread */ - no_sys, /* 12 bwrite */ - do_unlink, /* 13 unlink */ - do_rmdir, /* 14 rmdir */ - do_unmount, /* 15 unmount */ - do_noop, /* 16 sync */ - do_noop, /* 17 new_driver */ - do_noop, /* 18 flush */ - do_read, /* 19 read */ - do_write, /* 20 write */ - no_sys, /* 21 mknod */ - do_mkdir, /* 22 mkdir */ - do_create, /* 23 create */ - no_sys, /* 24 link */ - do_rename, /* 25 rename */ - do_lookup, /* 26 lookup */ - no_sys, /* 27 mountpoint */ - do_readsuper, /* 28 readsuper */ - no_sys, /* 29 newnode */ - no_sys, /* 30 rdlink */ - do_getdents, /* 31 getdents */ - no_sys, /* 32 peek */ - no_sys, /* 33 bpeek */ +struct fsdriver sffs_dtable = { + .fdr_mount = do_mount, + .fdr_unmount = do_unmount, + .fdr_lookup = do_lookup, + .fdr_putnode = do_putnode, + .fdr_read = do_read, + .fdr_write = do_write, + .fdr_getdents = do_getdents, + .fdr_trunc = do_trunc, + .fdr_create = do_create, + .fdr_mkdir = do_mkdir, + .fdr_unlink = do_unlink, + .fdr_rmdir = do_rmdir, + .fdr_rename = do_rename, + .fdr_stat = do_stat, + .fdr_chmod = do_chmod, + .fdr_utime = do_utime, + .fdr_statvfs = do_statvfs }; - -/* This should not fail with "array size is negative": */ -extern int dummy[sizeof(call_vec) == NREQS * sizeof(call_vec[0]) ? 1 : -1]; diff --git a/minix/lib/libsffs/type.h b/minix/lib/libsffs/type.h index c5ad74e9b..b4d705420 100644 --- a/minix/lib/libsffs/type.h +++ b/minix/lib/libsffs/type.h @@ -3,8 +3,6 @@ /* Structure with global file system state. */ struct state { - int s_mounted; /* is the file system mounted? */ - int s_signaled; /* have we received a SIGTERM? */ int s_read_only; /* is the file system mounted read-only? note, * has no relation to the shared folder mode */ dev_t s_dev; /* device the file system is mounted on */ diff --git a/minix/lib/libsffs/util.c b/minix/lib/libsffs/util.c deleted file mode 100644 index 562e97575..000000000 --- a/minix/lib/libsffs/util.c +++ /dev/null @@ -1,64 +0,0 @@ -/* This file contains various utility functions. - * - * The entry points into this file are: - * get_name retrieve a path component string from VFS - * do_noop handle file system calls that do nothing and succeed - * no_sys handle file system calls that are not implemented - * - * Created: - * April 2009 (D.C. van Moolenbroek) - */ - -#include "inc.h" - -/*===========================================================================* - * get_name * - *===========================================================================*/ -int get_name( - cp_grant_id_t grant, /* memory grant for the path component */ - size_t len, /* length of the name, including '\0' */ - char name[NAME_MAX+1] /* buffer in which store the result */ -) -{ -/* Retrieve a path component from the caller, using a given grant. - */ - int r; - - /* Copy in the name of the directory entry. */ - if (len <= 1) return EINVAL; - if (len > NAME_MAX+1) return ENAMETOOLONG; - - r = sys_safecopyfrom(m_in.m_source, grant, 0, (vir_bytes) name, len); - - if (r != OK) return r; - - if (name[len-1] != 0) { - printf("%s: VFS did not zero-terminate path component!\n", sffs_name); - - return EINVAL; - } - - return OK; -} - -/*===========================================================================* - * do_noop * - *===========================================================================*/ -int do_noop(void) -{ -/* Generic handler for no-op system calls. - */ - - return OK; -} - -/*===========================================================================* - * no_sys * - *===========================================================================*/ -int no_sys(void) -{ -/* Generic handler for unimplemented system calls. - */ - - return ENOSYS; -} diff --git a/minix/lib/libsffs/write.c b/minix/lib/libsffs/write.c index 7059a1aa7..711c26f41 100644 --- a/minix/lib/libsffs/write.c +++ b/minix/lib/libsffs/write.c @@ -2,7 +2,7 @@ * * The entry points into this file are: * do_write perform the WRITE file system call - * do_ftrunc perform the FTRUNC file system call + * do_trunc perform the TRUNC file system call * * Created: * April 2009 (D.C. van Moolenbroek) @@ -10,32 +10,27 @@ #include "inc.h" -static int write_file(struct inode *ino, u64_t *posp, size_t *countp, - cp_grant_id_t *grantp); - /*===========================================================================* * write_file * *===========================================================================*/ -static int write_file(struct inode *ino, u64_t *posp, size_t *countp, - cp_grant_id_t *grantp) +static ssize_t write_file(struct inode *ino, off_t pos, size_t count, + struct fsdriver_data *data) { /* Write data or zeroes to a file, depending on whether a valid pointer to * a data grant was provided. */ - u64_t pos; - size_t count, size; - vir_bytes off; + size_t size, off, chunk; char *ptr; - int r, chunk; + int r; + + if (pos < 0) + return EINVAL; assert(!IS_DIR(ino)); if ((r = get_handle(ino)) != OK) return r; - pos = *posp; - count = *countp; - assert(count > 0); /* Use the buffer from below to eliminate extra copying. */ @@ -45,11 +40,8 @@ static int write_file(struct inode *ino, u64_t *posp, size_t *countp, while (count > 0) { chunk = MIN(count, size); - if (grantp != NULL) { - r = sys_safecopyfrom(m_in.m_source, *grantp, - off, (vir_bytes) ptr, chunk); - - if (r != OK) + if (data != NULL) { + if ((r = fsdriver_copyin(data, off, ptr, chunk)) != OK) break; } else { /* Do this every time. We don't know what happens below. */ @@ -67,73 +59,53 @@ static int write_file(struct inode *ino, u64_t *posp, size_t *countp, if (r < 0) return r; - *posp = pos; - *countp = off; - - return OK; + return off; } /*===========================================================================* * do_write * *===========================================================================*/ -int do_write(void) +ssize_t do_write(ino_t ino_nr, struct fsdriver_data *data, size_t count, + off_t pos, int call) { /* Write data to a file. */ struct inode *ino; - off_t pos; - size_t count; - cp_grant_id_t grant; - int r; if (state.s_read_only) return EROFS; - if ((ino = find_inode(m_in.m_vfs_fs_readwrite.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; if (IS_DIR(ino)) return EISDIR; - pos = m_in.m_vfs_fs_readwrite.seek_pos; - count = m_in.m_vfs_fs_readwrite.nbytes; - grant = m_in.m_vfs_fs_readwrite.grant; + if (count == 0) return 0; - if (count == 0) return EINVAL; - - if ((r = write_file(ino, &pos, &count, &grant)) != OK) - return r; - - m_out.m_fs_vfs_readwrite.seek_pos = pos; - m_out.m_fs_vfs_readwrite.nbytes = count; - - return OK; + return write_file(ino, pos, count, data); } /*===========================================================================* - * do_ftrunc * + * do_trunc * *===========================================================================*/ -int do_ftrunc(void) +int do_trunc(ino_t ino_nr, off_t start, off_t end) { /* Change file size or create file holes. */ char path[PATH_MAX]; struct inode *ino; struct sffs_attr attr; - u64_t start, end, delta; - size_t count; - int r; + uint64_t delta; + ssize_t r; if (state.s_read_only) return EROFS; - if ((ino = find_inode(m_in.m_vfs_fs_ftrunc.inode)) == NULL) + if ((ino = find_inode(ino_nr)) == NULL) return EINVAL; if (IS_DIR(ino)) return EISDIR; - start = m_in.m_vfs_fs_ftrunc.trc_start; - end = m_in.m_vfs_fs_ftrunc.trc_end; - if (end == 0) { /* Truncate or expand the file. */ if ((r = verify_inode(ino, path, NULL)) != OK) @@ -147,13 +119,12 @@ int do_ftrunc(void) /* Write zeroes to the file. We can't create holes. */ if (end <= start) return EINVAL; - delta = end - start; + delta = (uint64_t)end - (uint64_t)start; - if (ex64hi(delta) != 0) return EINVAL; + if (delta > SSIZE_MAX) return EINVAL; - count = ex64lo(delta); - - r = write_file(ino, &start, &count, NULL); + if ((r = write_file(ino, start, (size_t)delta, NULL)) >= 0) + r = OK; } return r;