]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: Implement REQ_BPEEK. 08/408/7
authorBen Gras <ben@minix3.org>
Sat, 16 Mar 2013 04:09:36 +0000 (04:09 +0000)
committerBen Gras <ben@minix3.org>
Wed, 24 Apr 2013 10:18:16 +0000 (10:18 +0000)
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

12 files changed:
include/minix/vfsif.h
lib/libminixfs/cache.c
lib/libpuffs/table.c
lib/libsffs/table.c
lib/libvtreefs/table.c
servers/mfs/misc.c
servers/mfs/proto.h
servers/mfs/table.c
servers/vfs/mount.c
servers/vfs/proto.h
servers/vfs/request.c
servers/vfs/vmnt.h

index 35fc94e7d8509b5af845fefc3c2709ead19fac89..10a8568f41971d3072721e643deaaa53e9288d34 100644 (file)
@@ -117,8 +117,9 @@ typedef struct {
 #define REQ_GETDENTS   (VFS_BASE + 31)
 #define REQ_STATVFS    (VFS_BASE + 32)
 #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)
 
index eb55bc8089974faa48847a92ecb1ef855fedda41..579a02cfea82213519f825d2de18708b94ceed31 100644 (file)
@@ -855,3 +855,33 @@ int lmfs_rdwt_err(void)
        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;
+}
index 50f5bddb693e4cbed54b3d89bd9ba5002d5702db..b28cf6766c9c966aabafb79e20009bf39d639640 100644 (file)
@@ -43,4 +43,6 @@ int (*fs_call_vec[])(void) = {
     fs_rdlink,          /* 30  */
     fs_getdents,        /* 31  */
     fs_statvfs,                /* 32  */
+    no_sys,            /* 33 peek */
+    no_sys,            /* 34 bpeek */
 };
index 2573fb97d5caa0e5c8819b09244a6cac922c3bfb..35e778dec84155eb9b460927fab3a5470429fc30 100644 (file)
@@ -42,6 +42,7 @@ int (*call_vec[])(void) = {
        do_getdents,    /* 31 getdents          */
        do_statvfs,     /* 32 statvfs           */
        no_sys,         /* 33 peek              */
+       no_sys,         /* 33 bpeek             */
 };
 
 /* This should not fail with "array size is negative": */
index 8f73c1098bb047afa26ac05b5bde8457a0ebcd47..d3f20fac5597e2fa9c70704ff4752bbe54f07f9a 100644 (file)
@@ -38,6 +38,7 @@ int (*fs_call_vec[])(void) = {
        fs_getdents,    /* 31   getdents        */
        fs_statvfs,     /* 32   statvfs         */
        no_sys,         /* 33   peek            */
+       no_sys,         /* 34   bpeek           */
 };
 
 /* This should not fail with "array size is negative": */
index 326e86f2823041ab1c6e31ce2bd38a2d9756c1b1..036d84cda8c0ee0d451b8245ffaffbd2fc980887 100644 (file)
@@ -79,3 +79,8 @@ int fs_new_driver(void)
 
   return(OK);
 }
+
+int fs_bpeek(void)
+{
+       return lmfs_do_bpeek(&fs_m_in);
+}
index e7634f615e4f1d7bcd2078fed035a2966c155086..38e4fc5d5e9755d15cba3cfc6974ca30e7c108fb 100644 (file)
@@ -41,6 +41,7 @@ int truncate_inode(struct inode *rip, off_t len);
 int fs_flush(void);
 int fs_sync(void);
 int fs_new_driver(void);
+int fs_bpeek(void);
 
 /* mount.c */
 int fs_mountpoint(void);
index d54c91558151715f9ed2722e5eba1e600eff66ed..1fb73334e259564481d7cc571891cfc27a413377 100644 (file)
@@ -3,6 +3,8 @@
  * routines that perform them.
  */
 
+#include <minix/libminixfs.h>
+
 #define _TABLE
 
 #include "fs.h"
@@ -45,5 +47,6 @@ int (*fs_call_vec[])(void) = {
         fs_getdents,       /* 31  */
         fs_statvfs,         /* 32  */
         fs_readwrite,       /* 33  */
+       fs_bpeek,           /* 34  */
 };
 
index 51517ef46286934552d7b15dc1ee661f5d6c949f..6db6b379d561729f92d9c1e46e4b6a8a5b59c3a3 100644 (file)
@@ -282,6 +282,13 @@ char mount_label[LABEL_MAX] )
   r = req_readsuper(fs_e, label, dev, rdonly, isroot, &res, &con_reqs);
   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) {
        mark_vmnt_free(new_vmp);
        unlock_vnode(root_node);
index 5eec16aee960848a75ed947bc9ea7dedaeade7be..a2fe8728bf21225e5a2cd1e05d333f089f87f31a 100644 (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,
        endpoint_t user_e, char *user_addr, unsigned int num_of_bytes,
        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,
        char *new_name);
 int req_rmdir(endpoint_t fs_e, ino_t inode_nr, char *lastc);
index 4eab2791e13931a9e61673afe8303bb90b95c167..d1cd0b02e100540fa99343a69abafd9fa4b4b90d 100644 (file)
@@ -69,6 +69,27 @@ int req_breadwrite(
   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                                    *
@@ -762,43 +783,19 @@ u64_t *new_posp;
 unsigned int *cum_iop;
 {
   int r;
-  cp_grant_id_t grant_id = -1;
+  cp_grant_id_t grant_id;
   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)
          panic("req_readwrite: pos too large");
 
-  assert(rw_flag == READING || rw_flag == WRITING || rw_flag == PEEKING);
-
-  switch(rw_flag) {
-       case READING:
-               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");
-  }
+  grant_id = cpf_grant_magic(fs_e, user_e, (vir_bytes) user_addr, num_of_bytes,
+                            (rw_flag==READING ? CPF_WRITE:CPF_READ));
+  if (grant_id == -1)
+         panic("req_readwrite: cpf_grant_magic failed");
 
   /* 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_GRANT = grant_id;
   m.REQ_SEEK_POS_LO = ex64lo(pos);
@@ -818,6 +815,29 @@ unsigned int *cum_iop;
   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                                   *
index 2d3156e5f69ddf250facaf056cf95405056a6d6a..40c032a3ffdd254f341353230fe2cbe2095653fd 100644 (file)
@@ -15,6 +15,7 @@ EXTERN struct vmnt {
   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_dev[PATH_MAX];  /* path on which vmnt is mounted */
+  int m_haspeek;               /* supports REQ_PEEK, REQ_BPEEK */
 } vmnt[NR_MNTS];
 
 /* vmnt flags */