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:
Ben Gras 2013-03-16 04:09:36 +00:00
parent 0cfff08e56
commit 44f34e53d5
12 changed files with 105 additions and 31 deletions

View file

@ -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)

View file

@ -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;
}

View file

@ -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 */
}; };

View file

@ -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": */

View file

@ -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": */

View file

@ -79,3 +79,8 @@ int fs_new_driver(void)
return(OK); return(OK);
} }
int fs_bpeek(void)
{
return lmfs_do_bpeek(&fs_m_in);
}

View file

@ -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);

View file

@ -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 */
}; };

View file

@ -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);

View file

@ -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);

View file

@ -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 *

View file

@ -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 */