#define REQ_TRC_START_LO m9_l3
#define REQ_UCRED_SIZE m9_s4
#define REQ_UID m9_s4
+#define REQ_PROTO m9_s4 /* For definition see RES_PROTO */
/* VFS/FS reply fields */
#define RES_SEEK_POS_LO m9_l4
#define RES_SYMLOOP m9_s3
#define RES_UID m9_s4
-#define RES_CONREQS m9_s3
+
+#define RES_PROTO m9_s3
+/* RES_PROTO is defined as follows:
+ * |----------------|
+ * 7V 4CR 0
+ * 15 0
+ * mentioned bits are inclusive
+ * CR: bits 4-0 encode no. concurrent requests are supported by FS
+ * V: bits 7-5 encode version of protocol
+ */
+#define RES_PROTO_CR_SHIFT 0
+#define RES_PROTO_CR_MASK 0x1F
+#define VFS_FS_PROTO_CONREQS(b) (((b) & RES_PROTO_CR_MASK)>>RES_PROTO_CR_SHIFT)
+#define VFS_FS_PROTO_PUT_CONREQS(b,v) \
+ ((b) |= (((v) << RES_PROTO_CR_SHIFT) & RES_PROTO_CR_MASK))
+#define RES_PROTO_V_SHIFT 5
+#define RES_PROTO_V_MASK 0x70
+#define VFS_FS_PROTO_VERSION(b) (((b) & RES_PROTO_V_MASK) >> RES_PROTO_V_SHIFT)
+#define VFS_FS_PROTO_PUT_VERSION(b,v) \
+ ((b) |= (((v) << RES_PROTO_V_SHIFT) & RES_PROTO_V_MASK))
+#define VFS_FS_CURRENT_VERSION 0 /* Current version */
/* VFS/FS flags */
#define REQ_RDONLY 001
#define REQ_ISROOT 002
+#define REQ_HASPROTO 004
#define PATH_NOFLAGS 000
#define PATH_RET_SYMLINK 010 /* Return a symlink object (i.e.
* do not continue with the contents
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_CONREQS = 1;
+ 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);
return(OK);
}
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_CONREQS = 1; /* We can handle only 1 request at a time */
+ 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);
state.s_mounted = TRUE;
fs_m_out.RES_GID = root->i_stat.gid;
fs_m_out.RES_DEV = NO_DEV;
- fs_m_out.RES_CONREQS = 1;/* We can handle only 1 request at a time */
+ 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_mounted = TRUE;
fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
fs_m_out.RES_UID = root_ip->i_uid;
fs_m_out.RES_GID = root_ip->i_gid;
-
- fs_m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */
+ 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);
return(r);
}
fs_m_out.RES_FILE_SIZE_LO = v_pri.dir_rec_root->d_file_size;
fs_m_out.RES_UID = SYS_UID; /* Always root */
fs_m_out.RES_GID = SYS_GID; /* operator */
-
- fs_m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */
+ 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);
return(r);
}
fs_m_out.RES_FILE_SIZE_LO = root_ip->i_size;
fs_m_out.RES_UID = root_ip->i_uid;
fs_m_out.RES_GID = root_ip->i_gid;
-
- fs_m_out.RES_CONREQS = 1; /* We can handle only 1 request at a time */
+ 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);
/* Mark it dirty */
if(!superblock.s_rd_only) {
int rdonly,
char mount_label[LABEL_MAX] )
{
- int i, r = OK, found, isroot, mount_root, con_reqs, slot;
+ int i, r = OK, found, isroot, mount_root, slot;
struct fproc *tfp, *rfp;
struct dmap *dp;
struct vnode *root_node, *vp = NULL;
/* Tell FS which device to mount */
new_vmp->m_flags |= VMNT_MOUNTING;
- r = req_readsuper(fs_e, label, dev, rdonly, isroot, &res, &con_reqs);
+ r = req_readsuper(new_vmp, label, dev, rdonly, isroot, &res);
new_vmp->m_flags &= ~VMNT_MOUNTING;
if(req_peek(fs_e, 1, 0, PAGE_SIZE) != OK ||
/* Root node is indeed on the partition */
root_node->v_vmnt = new_vmp;
root_node->v_dev = new_vmp->m_dev;
- if (con_reqs == 0)
+ if (VFS_FS_PROTO_CONREQS(new_vmp->m_proto) == 0)
new_vmp->m_comm.c_max_reqs = 1; /* Default if FS doesn't tell us */
else
- new_vmp->m_comm.c_max_reqs = con_reqs;
+ new_vmp->m_comm.c_max_reqs = VFS_FS_PROTO_CONREQS(new_vmp->m_proto);
new_vmp->m_comm.c_cur_reqs = 0;
if (mount_root) {
vmp->m_dev = dev;
vmp->m_fs_e = PFS_PROC_NR;
+ vmp->m_proto = 0;
+ VFS_FS_PROTO_PUT_CONREQS(vmp->m_proto, 1);
+ VFS_FS_PROTO_PUT_VERSION(vmp->m_proto, VFS_FS_CURRENT_VERSION);
strlcpy(vmp->m_label, "pfs", LABEL_MAX);
strlcpy(vmp->m_mount_path, "pipe", PATH_MAX);
strlcpy(vmp->m_mount_dev, "none", PATH_MAX);
int req_breadwrite(endpoint_t fs_e, endpoint_t user_e, dev_t dev, u64_t pos,
unsigned int num_of_bytes, char *user_addr, int rw_flag,
u64_t *new_posp, unsigned int *cum_iop);
-int req_chmod(int fs_e, ino_t inode_nr, mode_t rmode, mode_t *new_modep);
+int req_chmod(endpoint_t fs_e, ino_t inode_nr, mode_t rmode,
+ mode_t *new_modep);
int req_chown(endpoint_t fs_e, ino_t inode_nr, uid_t newuid, gid_t newgid,
mode_t *new_modep);
-int req_create(int fs_e, ino_t inode_nr, int omode, uid_t uid, gid_t gid,
- char *path, node_details_t *res);
+int req_create(endpoint_t fs_e, ino_t inode_nr, int omode, uid_t uid,
+ gid_t gid, char *path, node_details_t *res);
int req_flush(endpoint_t fs_e, dev_t dev);
int req_fstatfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf);
int req_statvfs(endpoint_t fs_e, endpoint_t proc_e, vir_bytes buf);
int req_mknod(endpoint_t fs_e, ino_t inode_nr, char *lastc, uid_t uid,
gid_t gid, mode_t dmode, dev_t dev);
int req_mountpoint(endpoint_t fs_e, ino_t inode_nr);
-int req_newnode(endpoint_t fs_e, uid_t uid, gid_t gid, mode_t dmode, dev_t dev,
- struct node_details *res);
+int req_newnode(endpoint_t fs_e, uid_t uid, gid_t gid, mode_t dmode,
+ dev_t dev, struct node_details *res);
int req_putnode(int fs_e, ino_t inode_nr, int count);
int req_rdlink(endpoint_t fs_e, ino_t inode_nr, endpoint_t proc_e,
vir_bytes buf, size_t len, int direct);
-int req_readsuper(endpoint_t fs_e, char *driver_name, dev_t dev, int readonly,
- int isroot, struct node_details *res_nodep, int *con_reqs);
+int req_readsuper(struct vmnt *vmp, char *driver_name, dev_t dev, int readonly,
+ int isroot, struct node_details *res_nodep);
int req_readwrite(endpoint_t fs_e, ino_t inode_nr, u64_t pos, int rw_flag,
endpoint_t user_e, char *user_addr, unsigned int num_of_bytes,
u64_t *new_posp, unsigned int *cum_iop);
*/
#include "fs.h"
-#include <fcntl.h>
-#include <unistd.h>
+#include <minix/callnr.h>
#include <minix/com.h>
#include <minix/u64.h>
+#include <minix/vfsif.h>
+#include <assert.h>
+#include <dirent.h>
+#include <fcntl.h>
+#include <unistd.h>
#include "file.h"
#include "fproc.h"
-#include "scratchpad.h"
#include "param.h"
-#include <dirent.h>
-#include <assert.h>
-#include <minix/vfsif.h>
+#include "scratchpad.h"
#include "vnode.h"
#include "vmnt.h"
* req_chmod *
*===========================================================================*/
int req_chmod(
- int fs_e,
+ endpoint_t fs_e,
ino_t inode_nr,
mode_t rmode,
mode_t *new_modep
* req_create *
*===========================================================================*/
int req_create(
- int fs_e,
+ endpoint_t fs_e,
ino_t inode_nr,
int omode,
uid_t uid,
/* Fill in request message */
m.m_type = REQ_CREATE;
m.REQ_INODE_NR = inode_nr;
- m.REQ_MODE = omode;
+ m.REQ_MODE = omode;
m.REQ_UID = uid;
m.REQ_GID = gid;
m.REQ_GRANT = grant_id;
/* Fill in response structure */
res->fs_e = m.m_source;
res->inode_nr = m.RES_INODE_NR;
- res->fmode = m.RES_MODE;
+ res->fmode = m.RES_MODE;
res->fsize = m.RES_FILE_SIZE_LO;
res->uid = m.RES_UID;
res->gid = m.RES_GID;
switch (r) {
case OK:
- res->inode_nr = m.RES_INODE_NR;
- res->fmode = m.RES_MODE;
- res->fsize = m.RES_FILE_SIZE_LO;
- res->dev = m.RES_DEV;
- res->uid= m.RES_UID;
- res->gid= m.RES_GID;
- break;
+ res->inode_nr = m.RES_INODE_NR;
+ res->fmode = m.RES_MODE;
+ res->fsize = m.RES_FILE_SIZE_LO;
+ res->dev = m.RES_DEV;
+ res->uid= m.RES_UID;
+ res->gid= m.RES_GID;
+ break;
case EENTERMOUNT:
- res->inode_nr = m.RES_INODE_NR;
- res->char_processed = m.RES_OFFSET;
- res->symloop = m.RES_SYMLOOP;
- break;
+ res->inode_nr = m.RES_INODE_NR;
+ res->char_processed = m.RES_OFFSET;
+ res->symloop = m.RES_SYMLOOP;
+ break;
case ELEAVEMOUNT:
- res->char_processed = m.RES_OFFSET;
- res->symloop = m.RES_SYMLOOP;
- break;
+ res->char_processed = m.RES_OFFSET;
+ res->symloop = m.RES_SYMLOOP;
+ break;
case ESYMLINK:
- res->char_processed = m.RES_OFFSET;
- res->symloop = m.RES_SYMLOOP;
- break;
+ res->char_processed = m.RES_OFFSET;
+ res->symloop = m.RES_SYMLOOP;
+ break;
default:
- break;
+ break;
}
return(r);
res->fs_e = m.m_source;
res->inode_nr = m.RES_INODE_NR;
- res->fmode = m.RES_MODE;
+ res->fmode = m.RES_MODE;
res->fsize = m.RES_FILE_SIZE_LO;
res->dev = m.RES_DEV;
res->uid = m.RES_UID;
* req_readsuper *
*===========================================================================*/
int req_readsuper(
- endpoint_t fs_e,
+ struct vmnt *vmp,
char *label,
dev_t dev,
int readonly,
int isroot,
- struct node_details *res_nodep,
- int *con_reqs
+ struct node_details *res_nodep
)
{
int r;
cp_grant_id_t grant_id;
size_t len;
message m;
+ endpoint_t fs_e;
+
+ fs_e = vmp->m_fs_e;
len = strlen(label)+1;
grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
/* Fill in request message */
m.m_type = REQ_READSUPER;
m.REQ_FLAGS = 0;
+ m.REQ_PROTO = 0;
+ VFS_FS_PROTO_PUT_VERSION(m.REQ_PROTO, VFS_FS_CURRENT_VERSION);
+ m.REQ_FLAGS |= REQ_HASPROTO;
if(readonly) m.REQ_FLAGS |= REQ_RDONLY;
if(isroot) m.REQ_FLAGS |= REQ_ISROOT;
m.REQ_GRANT = grant_id;
/* Fill in response structure */
res_nodep->fs_e = m.m_source;
res_nodep->inode_nr = m.RES_INODE_NR;
+ vmp->m_proto = m.RES_PROTO;
+ printf("%d: proto = 0x%x, version=%d conreqs=%d\n", fs_e, vmp->m_proto,
+ VFS_FS_PROTO_VERSION(vmp->m_proto), VFS_FS_PROTO_CONREQS(vmp->m_proto));
res_nodep->fmode = m.RES_MODE;
res_nodep->fsize = m.RES_FILE_SIZE_LO;
res_nodep->uid = m.RES_UID;
res_nodep->gid = m.RES_GID;
- *con_reqs = m.RES_CONREQS;
}
return(r);
comm_t m_comm;
dev_t m_dev; /* device number */
unsigned int m_flags; /* mount flags */
+ unsigned int m_proto; /* vfs-fs protocol info */
struct vnode *m_mounted_on; /* vnode on which the partition is mounted */
struct vnode *m_root_node; /* root vnode */
char m_label[LABEL_MAX]; /* label of the file system process */