VFS: Implement REQ_BPEEK.
This commit introduces a new request type called REQ_BPEEK. It requests minor device blocks from the FS. Analogously to REQ_PEEK, it requests the filesystem to get the requested blocks into its cache, without actually copying the result anywhere. Change-Id: If1d06645b0e17553a64b3167091e9d12efeb3d6f
This commit is contained in:
parent
0cfff08e56
commit
44f34e53d5
12 changed files with 105 additions and 31 deletions
|
@ -117,8 +117,9 @@ typedef struct {
|
||||||
#define REQ_GETDENTS (VFS_BASE + 31)
|
#define REQ_GETDENTS (VFS_BASE + 31)
|
||||||
#define REQ_STATVFS (VFS_BASE + 32)
|
#define REQ_STATVFS (VFS_BASE + 32)
|
||||||
#define REQ_PEEK (VFS_BASE + 33)
|
#define REQ_PEEK (VFS_BASE + 33)
|
||||||
|
#define REQ_BPEEK (VFS_BASE + 34)
|
||||||
|
|
||||||
#define NREQS 34
|
#define NREQS 35
|
||||||
|
|
||||||
#define IS_VFS_RQ(type) (((type) & ~0xff) == VFS_BASE)
|
#define IS_VFS_RQ(type) (((type) & ~0xff) == VFS_BASE)
|
||||||
|
|
||||||
|
|
|
@ -855,3 +855,33 @@ int lmfs_rdwt_err(void)
|
||||||
return rdwt_err;
|
return rdwt_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int lmfs_do_bpeek(message *m)
|
||||||
|
{
|
||||||
|
block_t startblock, b, limitblock;
|
||||||
|
dev_t dev = m->REQ_DEV2;
|
||||||
|
u64_t extra, pos = make64(m->REQ_SEEK_POS_LO, m->REQ_SEEK_POS_HI);
|
||||||
|
size_t len = m->REQ_NBYTES;
|
||||||
|
struct buf *bp;
|
||||||
|
|
||||||
|
assert(m->m_type == REQ_BPEEK);
|
||||||
|
assert(fs_block_size > 0);
|
||||||
|
assert(dev != NO_DEV);
|
||||||
|
|
||||||
|
if((extra=(pos % fs_block_size))) {
|
||||||
|
pos -= extra;
|
||||||
|
len += extra;
|
||||||
|
}
|
||||||
|
|
||||||
|
len = roundup(len, fs_block_size);
|
||||||
|
|
||||||
|
startblock = pos/fs_block_size;
|
||||||
|
limitblock = startblock + len/fs_block_size;
|
||||||
|
|
||||||
|
for(b = startblock; b < limitblock; b++) {
|
||||||
|
bp = lmfs_get_block(dev, b, NORMAL);
|
||||||
|
assert(bp);
|
||||||
|
lmfs_put_block(bp, FULL_DATA_BLOCK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
|
@ -43,4 +43,6 @@ int (*fs_call_vec[])(void) = {
|
||||||
fs_rdlink, /* 30 */
|
fs_rdlink, /* 30 */
|
||||||
fs_getdents, /* 31 */
|
fs_getdents, /* 31 */
|
||||||
fs_statvfs, /* 32 */
|
fs_statvfs, /* 32 */
|
||||||
|
no_sys, /* 33 peek */
|
||||||
|
no_sys, /* 34 bpeek */
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,6 +42,7 @@ int (*call_vec[])(void) = {
|
||||||
do_getdents, /* 31 getdents */
|
do_getdents, /* 31 getdents */
|
||||||
do_statvfs, /* 32 statvfs */
|
do_statvfs, /* 32 statvfs */
|
||||||
no_sys, /* 33 peek */
|
no_sys, /* 33 peek */
|
||||||
|
no_sys, /* 33 bpeek */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This should not fail with "array size is negative": */
|
/* This should not fail with "array size is negative": */
|
||||||
|
|
|
@ -38,6 +38,7 @@ int (*fs_call_vec[])(void) = {
|
||||||
fs_getdents, /* 31 getdents */
|
fs_getdents, /* 31 getdents */
|
||||||
fs_statvfs, /* 32 statvfs */
|
fs_statvfs, /* 32 statvfs */
|
||||||
no_sys, /* 33 peek */
|
no_sys, /* 33 peek */
|
||||||
|
no_sys, /* 34 bpeek */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* This should not fail with "array size is negative": */
|
/* This should not fail with "array size is negative": */
|
||||||
|
|
|
@ -79,3 +79,8 @@ int fs_new_driver(void)
|
||||||
|
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fs_bpeek(void)
|
||||||
|
{
|
||||||
|
return lmfs_do_bpeek(&fs_m_in);
|
||||||
|
}
|
||||||
|
|
|
@ -41,6 +41,7 @@ int truncate_inode(struct inode *rip, off_t len);
|
||||||
int fs_flush(void);
|
int fs_flush(void);
|
||||||
int fs_sync(void);
|
int fs_sync(void);
|
||||||
int fs_new_driver(void);
|
int fs_new_driver(void);
|
||||||
|
int fs_bpeek(void);
|
||||||
|
|
||||||
/* mount.c */
|
/* mount.c */
|
||||||
int fs_mountpoint(void);
|
int fs_mountpoint(void);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
* routines that perform them.
|
* routines that perform them.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <minix/libminixfs.h>
|
||||||
|
|
||||||
#define _TABLE
|
#define _TABLE
|
||||||
|
|
||||||
#include "fs.h"
|
#include "fs.h"
|
||||||
|
@ -45,5 +47,6 @@ int (*fs_call_vec[])(void) = {
|
||||||
fs_getdents, /* 31 */
|
fs_getdents, /* 31 */
|
||||||
fs_statvfs, /* 32 */
|
fs_statvfs, /* 32 */
|
||||||
fs_readwrite, /* 33 */
|
fs_readwrite, /* 33 */
|
||||||
|
fs_bpeek, /* 34 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -282,6 +282,13 @@ char mount_label[LABEL_MAX] )
|
||||||
r = req_readsuper(fs_e, label, dev, rdonly, isroot, &res, &con_reqs);
|
r = req_readsuper(fs_e, label, dev, rdonly, isroot, &res, &con_reqs);
|
||||||
new_vmp->m_flags &= ~VMNT_MOUNTING;
|
new_vmp->m_flags &= ~VMNT_MOUNTING;
|
||||||
|
|
||||||
|
if(req_peek(fs_e, 1, 0, PAGE_SIZE) != OK ||
|
||||||
|
req_bpeek(fs_e, dev, 0, PAGE_SIZE) != OK) {
|
||||||
|
new_vmp->m_haspeek = 0;
|
||||||
|
} else {
|
||||||
|
new_vmp->m_haspeek = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (r != OK) {
|
if (r != OK) {
|
||||||
mark_vmnt_free(new_vmp);
|
mark_vmnt_free(new_vmp);
|
||||||
unlock_vnode(root_node);
|
unlock_vnode(root_node);
|
||||||
|
|
|
@ -254,6 +254,8 @@ int req_readsuper(endpoint_t fs_e, char *driver_name, dev_t dev, int readonly,
|
||||||
int req_readwrite(endpoint_t fs_e, ino_t inode_nr, u64_t pos, int rw_flag,
|
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,
|
endpoint_t user_e, char *user_addr, unsigned int num_of_bytes,
|
||||||
u64_t *new_posp, unsigned int *cum_iop);
|
u64_t *new_posp, unsigned int *cum_iop);
|
||||||
|
int req_bpeek(endpoint_t fs_e, dev_t dev, u64_t pos, unsigned int num_of_bytes);
|
||||||
|
int req_peek(endpoint_t fs_e, ino_t inode_nr, u64_t pos, unsigned int bytes);
|
||||||
int req_rename(endpoint_t fs_e, ino_t old_dir, char *old_name, ino_t new_dir,
|
int req_rename(endpoint_t fs_e, ino_t old_dir, char *old_name, ino_t new_dir,
|
||||||
char *new_name);
|
char *new_name);
|
||||||
int req_rmdir(endpoint_t fs_e, ino_t inode_nr, char *lastc);
|
int req_rmdir(endpoint_t fs_e, ino_t inode_nr, char *lastc);
|
||||||
|
|
|
@ -69,6 +69,27 @@ int req_breadwrite(
|
||||||
return(OK);
|
return(OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* req_bpeek *
|
||||||
|
*===========================================================================*/
|
||||||
|
int req_bpeek(endpoint_t fs_e, dev_t dev, u64_t pos, unsigned int num_of_bytes)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
memset(&m, 0, sizeof(m));
|
||||||
|
|
||||||
|
/* Fill in request message */
|
||||||
|
m.m_type = REQ_BPEEK;
|
||||||
|
m.REQ_DEV2 = dev;
|
||||||
|
m.REQ_SEEK_POS_LO = ex64lo(pos);
|
||||||
|
m.REQ_SEEK_POS_HI = ex64hi(pos);
|
||||||
|
m.REQ_NBYTES = num_of_bytes;
|
||||||
|
|
||||||
|
/* Send/rec request */
|
||||||
|
return fs_sendrec(fs_e, &m);
|
||||||
|
|
||||||
|
return(OK);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* req_chmod *
|
* req_chmod *
|
||||||
|
@ -762,43 +783,19 @@ u64_t *new_posp;
|
||||||
unsigned int *cum_iop;
|
unsigned int *cum_iop;
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
cp_grant_id_t grant_id = -1;
|
cp_grant_id_t grant_id;
|
||||||
message m;
|
message m;
|
||||||
int type = -1;
|
|
||||||
int grantflag = -1;
|
|
||||||
|
|
||||||
/* rw_flag:
|
|
||||||
* READING: do i/o from FS, copy into userspace
|
|
||||||
* WRITING: do i/o from userspace, copy into FS
|
|
||||||
* PEEKING: do i/o in FS, just get the blocks into the cache, no copy
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (ex64hi(pos) != 0)
|
if (ex64hi(pos) != 0)
|
||||||
panic("req_readwrite: pos too large");
|
panic("req_readwrite: pos too large");
|
||||||
|
|
||||||
assert(rw_flag == READING || rw_flag == WRITING || rw_flag == PEEKING);
|
grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
|
||||||
|
(rw_flag==READING ? CPF_WRITE:CPF_READ));
|
||||||
switch(rw_flag) {
|
if (grant_id == -1)
|
||||||
case READING:
|
panic("req_readwrite: cpf_grant_magic failed");
|
||||||
type = REQ_READ;
|
|
||||||
grantflag = CPF_WRITE;
|
|
||||||
/* fallthrough */
|
|
||||||
case WRITING:
|
|
||||||
if(type < 0) { type = REQ_WRITE; grantflag = CPF_READ; }
|
|
||||||
grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr,
|
|
||||||
num_of_bytes, grantflag);
|
|
||||||
if (grant_id == -1)
|
|
||||||
panic("req_readwrite: cpf_grant_magic failed");
|
|
||||||
break;
|
|
||||||
case PEEKING:
|
|
||||||
type = REQ_PEEK;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
panic("odd rw_flag");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in request message */
|
/* Fill in request message */
|
||||||
m.m_type = type;
|
m.m_type = rw_flag == READING ? REQ_READ : REQ_WRITE;
|
||||||
m.REQ_INODE_NR = inode_nr;
|
m.REQ_INODE_NR = inode_nr;
|
||||||
m.REQ_GRANT = grant_id;
|
m.REQ_GRANT = grant_id;
|
||||||
m.REQ_SEEK_POS_LO = ex64lo(pos);
|
m.REQ_SEEK_POS_LO = ex64lo(pos);
|
||||||
|
@ -818,6 +815,29 @@ unsigned int *cum_iop;
|
||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*===========================================================================*
|
||||||
|
* req_peek *
|
||||||
|
*===========================================================================*/
|
||||||
|
int req_peek(endpoint_t fs_e, ino_t inode_nr, u64_t pos, unsigned int bytes)
|
||||||
|
{
|
||||||
|
message m;
|
||||||
|
|
||||||
|
memset(&m, 0, sizeof(m));
|
||||||
|
|
||||||
|
if (ex64hi(pos) != 0)
|
||||||
|
panic("req_peek: pos too large");
|
||||||
|
|
||||||
|
/* Fill in request message */
|
||||||
|
m.m_type = REQ_PEEK;
|
||||||
|
m.REQ_INODE_NR = inode_nr;
|
||||||
|
m.REQ_GRANT = -1;
|
||||||
|
m.REQ_SEEK_POS_LO = ex64lo(pos);
|
||||||
|
m.REQ_SEEK_POS_HI = 0; /* Not used for now, so clear it. */
|
||||||
|
m.REQ_NBYTES = bytes;
|
||||||
|
|
||||||
|
/* Send/rec request */
|
||||||
|
return fs_sendrec(fs_e, &m);
|
||||||
|
}
|
||||||
|
|
||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* req_rename *
|
* req_rename *
|
||||||
|
|
|
@ -15,6 +15,7 @@ EXTERN struct vmnt {
|
||||||
char m_label[LABEL_MAX]; /* label of the file system process */
|
char m_label[LABEL_MAX]; /* label of the file system process */
|
||||||
char m_mount_path[PATH_MAX]; /* path on which vmnt is mounted */
|
char m_mount_path[PATH_MAX]; /* path on which vmnt is mounted */
|
||||||
char m_mount_dev[PATH_MAX]; /* path on which vmnt is mounted */
|
char m_mount_dev[PATH_MAX]; /* path on which vmnt is mounted */
|
||||||
|
int m_haspeek; /* supports REQ_PEEK, REQ_BPEEK */
|
||||||
} vmnt[NR_MNTS];
|
} vmnt[NR_MNTS];
|
||||||
|
|
||||||
/* vmnt flags */
|
/* vmnt flags */
|
||||||
|
|
Loading…
Reference in a new issue