VFS/FS: replace protocol version with flag field

The main motivation for this change is that only Loris supports
multithreading, and Loris supports dynamic thread allocation, so the
number of supported threads can be implemented as a bit flag (i.e.,
either 1 or "at least as many as VFS has"). The ABI break obviates the
need to support file system versioning at this time, and several
other aspects are better implemented as flags as well. Other changes:

- replace peek/bpeek test upon mount with FS flag as well;
- mark libsffs as 64-bit file size capable;
- remove old (3.2.1) getdents support.

Change-Id: I313eace9c50ed816656c31cd47d969033d952a03
This commit is contained in:
David van Moolenbroek
2013-08-31 21:48:15 +02:00
committed by Lionel Sambuc
parent ac65742ae4
commit cc810ee4d9
24 changed files with 47 additions and 847 deletions

View File

@@ -33,9 +33,7 @@ int fs_readsuper()
fs_m_out.RES_FILE_SIZE_LO = root_va->va_size;
fs_m_out.RES_UID = root_va->va_uid;
fs_m_out.RES_GID = root_va->va_gid;
fs_m_out.RES_PROTO = 0;
VFS_FS_PROTO_PUT_VERSION(fs_m_out.RES_PROTO, VFS_FS_CURRENT_VERSION);
VFS_FS_PROTO_PUT_CONREQS(fs_m_out.RES_PROTO, 1);
fs_m_out.RES_FLAGS = RES_NOFLAGS;
return(OK);
}

View File

@@ -62,9 +62,7 @@ int do_readsuper()
m_out.RES_UID = sffs_params->p_uid;
m_out.RES_GID = sffs_params->p_gid;
m_out.RES_DEV = NO_DEV;
m_out.RES_PROTO = 0;
VFS_FS_PROTO_PUT_VERSION(m_out.RES_PROTO, VFS_FS_CURRENT_VERSION);
VFS_FS_PROTO_PUT_CONREQS(m_out.RES_PROTO, 1);
m_out.RES_FLAGS = RES_64BIT;
state.s_mounted = TRUE;

View File

@@ -8,7 +8,6 @@
EXTERN struct fs_hooks *vtreefs_hooks;
EXTERN int proto_version;
EXTERN message fs_m_in;
EXTERN message fs_m_out;

View File

@@ -18,13 +18,6 @@ int fs_readsuper(void)
if (fs_m_in.REQ_FLAGS & REQ_ISROOT)
return EINVAL;
/* Get VFS-FS protocol version */
if (!(fs_m_in.REQ_FLAGS & REQ_HASPROTO)) {
proto_version = 0;
} else {
proto_version = VFS_FS_PROTO_VERSION(fs_m_in.REQ_PROTO);
}
/* Get the root inode and increase its reference count. */
root = get_root_inode();
ref_inode(root);
@@ -41,10 +34,7 @@ int fs_readsuper(void)
fs_m_out.RES_UID = root->i_stat.uid;
fs_m_out.RES_GID = root->i_stat.gid;
fs_m_out.RES_DEV = NO_DEV;
fs_m_out.RES_PROTO = 0;
VFS_FS_PROTO_PUT_VERSION(fs_m_out.RES_PROTO, VFS_FS_CURRENT_VERSION);
VFS_FS_PROTO_PUT_CONREQS(fs_m_out.RES_PROTO, 1);
fs_m_out.RES_FLAGS = RES_NOFLAGS;
fs_mounted = TRUE;

View File

@@ -67,153 +67,6 @@ int fs_read(void)
return r;
}
/*===========================================================================*
* fs_getdents_321 *
*===========================================================================*/
int fs_getdents_321(void)
{
/* Retrieve directory entries.
*/
struct inode *node, *child = NULL;
struct dirent_321 *dent;
char *name;
size_t len, off, user_off, user_left;
off_t pos;
int r, skip, get_next, indexed;
static char buf[GETDENTS_BUFSIZ];
if (fs_m_in.REQ_SEEK_POS_HI != 0)
return EIO;
if ((node = find_inode(fs_m_in.REQ_INODE_NR)) == NULL)
return EINVAL;
off = 0;
user_off = 0;
user_left = fs_m_in.REQ_MEM_SIZE;
indexed = node->i_indexed;
get_next = FALSE;
child = NULL;
/* Call the getdents hook, if any, to "refresh" the directory. */
if (!is_inode_deleted(node) && vtreefs_hooks->getdents_hook != NULL) {
r = vtreefs_hooks->getdents_hook(node, get_inode_cbdata(node));
if (r != OK) return r;
}
for (pos = fs_m_in.REQ_SEEK_POS_LO; ; pos++) {
/* Determine which inode and name to use for this entry. */
if (pos == 0) {
/* The "." entry. */
child = node;
name = ".";
}
else if (pos == 1) {
/* The ".." entry. */
child = get_parent_inode(node);
if (child == NULL)
child = node;
name = "..";
}
else if (pos - 2 < indexed) {
/* All indexed entries. */
child = get_inode_by_index(node, pos - 2);
/* If there is no inode with this particular index,
* continue with the next index number.
*/
if (child == NULL) continue;
name = child->i_name;
}
else {
/* All non-indexed entries. */
/* If this is the first loop iteration, first get to
* the non-indexed child identified by the current
* position.
*/
if (get_next == FALSE) {
skip = pos - indexed - 2;
child = get_first_inode(node);
/* Skip indexed children. */
while (child != NULL &&
child->i_index != NO_INDEX)
child = get_next_inode(child);
/* Skip to the right position. */
while (child != NULL && skip-- > 0)
child = get_next_inode(child);
get_next = TRUE;
}
else {
child = get_next_inode(child);
}
/* No more children? Then stop. */
if (child == NULL)
break;
assert(!is_inode_deleted(child));
name = child->i_name;
}
len = DWORD_ALIGN(sizeof(struct dirent_321) + strlen(name));
/* Is the user buffer too small to store another record? */
if (user_off + off + len > user_left) {
/* 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(fs_m_in.m_source, fs_m_in.REQ_GRANT,
user_off, (vir_bytes) buf, off);
if (r != OK) return r;
user_off += off;
user_left -= off;
off = 0;
}
/* Fill in the actual directory entry. */
dent = (struct dirent_321 *) &buf[off];
dent->d_ino = (u32_t) get_inode_number(child);
dent->d_off = (i32_t) pos;
dent->d_reclen = len;
strcpy(dent->d_name, name);
off += len;
}
/* If there is anything left in our own buffer, copy that out now. */
if (off > 0) {
r = sys_safecopyto(fs_m_in.m_source, fs_m_in.REQ_GRANT,
user_off, (vir_bytes) buf, off);
if (r != OK)
return r;
user_off += off;
}
fs_m_out.RES_SEEK_POS_HI = 0;
fs_m_out.RES_SEEK_POS_LO = pos;
fs_m_out.RES_NBYTES = user_off;
return OK;
}
/*===========================================================================*
* fs_getdents *
*===========================================================================*/
@@ -229,9 +82,6 @@ int fs_getdents(void)
int r, skip, get_next, indexed;
static char buf[GETDENTS_BUFSIZ];
if (proto_version == 0)
return fs_getdents_321();
if (fs_m_in.REQ_SEEK_POS_HI != 0)
return EIO;