[Pvfs2-cvs] commit by kunkel in pvfs2/src/apps/kernel/linux: module.mk.in pvfs2-client-core.c pvfs2-client.c

CVS commit program cvs at parl.clemson.edu
Sat Feb 17 06:16:10 EST 2007


Update of /projects/cvsroot/pvfs2/src/apps/kernel/linux
In directory parlweb1:/tmp/cvs-serv2872/src/apps/kernel/linux

Modified Files:
      Tag: kunkel-migration-branch
	module.mk.in pvfs2-client-core.c pvfs2-client.c 
Log Message:
Update migration branch to current CVS version


Index: module.mk.in
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/apps/kernel/linux/module.mk.in,v
diff -p -u -r1.3 -r1.3.28.1
--- module.mk.in	22 Jul 2005 20:20:35 -0000	1.3
+++ module.mk.in	17 Feb 2007 11:16:09 -0000	1.3.28.1
@@ -4,6 +4,9 @@ KERNAPPSRC += \
 	$(DIR)/pvfs2-client-core.c \
 	$(DIR)/pvfs2-client.c 
 
+KERNAPPSTHRSRC += \
+	$(DIR)/pvfs2-client-core.c
+
 ifneq (,$(LINUX24_KERNEL_SRC))
 KERNAPPSRC += $(DIR)/mount.pvfs2.c
 endif

Index: pvfs2-client-core.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/apps/kernel/linux/pvfs2-client-core.c,v
diff -p -u -r1.73 -r1.73.4.1
--- pvfs2-client-core.c	18 Aug 2006 22:54:31 -0000	1.73
+++ pvfs2-client-core.c	17 Feb 2007 11:16:09 -0000	1.73.4.1
@@ -28,6 +28,7 @@
 #include "server-config-mgr.h"
 #include "client-state-machine.h"
 #include "pint-perf-counter.h"
+#include "pvfs2-encode-stubs.h"
 
 #ifdef USE_MMAP_RA_CACHE
 #include "mmap-ra-cache.h"
@@ -43,32 +44,18 @@
 */
 #define MAX_NUM_OPS                 64
 #define MAX_LIST_SIZE      MAX_NUM_OPS
+#define IOX_HINDEXED_COUNT          64
 
 #define REMOUNT_PENDING     0xFFEEFF33
 #define OP_IN_PROGRESS      0xFFEEFF34
 
 /*
-  the block size to report in statfs as the blocksize (i.e. the
-  optimal i/o transfer size); regardless of this value, the fragment
-  size (underlying fs block size) in the kernel is fixed at 1024
-*/
-#define STATFS_DEFAULT_BLOCKSIZE PVFS2_BUFMAP_DEFAULT_DESC_SIZE
-
-/*
   default timeout value to wait for completion of in progress
   operations
 */
 #define PVFS2_CLIENT_DEFAULT_TEST_TIMEOUT_MS 10
 
 /*
-  uncomment if you want to run this application stand-alone
-  (i.e. without the pvfs2-client wrapper).  this is only useful as a
-  developer and allows clean shutdown for valgrind debugging or
-  getting core dumps.  this is NOT a supported run mode
-*/
-/* #define STANDALONE_RUN_MODE */
-
-/*
   uncomment for timing of individual operation information to be
   emitted to the pvfs2-client logging output
 */
@@ -104,6 +91,12 @@ typedef struct
     char* gossip_mask;
     int logstamp_type;
     int logstamp_type_set;
+    int standalone;
+    /* kernel module buffer size settings */
+    unsigned int dev_buffer_count;
+    int dev_buffer_count_set;
+    unsigned int dev_buffer_size;
+    int dev_buffer_size_set;
 } options_t;
 
 /*
@@ -130,7 +123,10 @@ typedef struct
     job_status_s jstat;
     struct PINT_dev_unexp_info info;
 
+    /* iox requests may post multiple operations at one shot */
+    int num_ops, num_incomplete_ops;
     PVFS_sys_op_id op_id;
+    PVFS_sys_op_id *op_ids;
 
 #ifdef USE_MMAP_RA_CACHE
     void *io_tmp_buf;
@@ -142,6 +138,12 @@ typedef struct
     PVFS_ds_keyval  key;/* used only by geteattr, seteattr */
     PVFS_ds_keyval  val;
     void *io_kernel_mapped_buf;
+    /* The next few fields are used only by readx, writex */
+    int32_t  iox_count;
+    int32_t  *iox_sizes;
+    PVFS_size *iox_offsets;
+    PVFS_Request *file_req_a;
+    PVFS_Request *mem_req_a;
 
     struct PVFS_sys_mntent* mntent; /* used only by mount */
 
@@ -162,6 +164,8 @@ typedef struct
         PVFS_sysresp_io io;
         PVFS_sysresp_geteattr geteattr;
         PVFS_sysresp_listeattr listeattr;
+        PVFS_sysresp_readdirplus readdirplus;
+        PVFS_sysresp_io *iox;
     } response;
 
 #ifdef CLIENT_CORE_OP_TIMING
@@ -175,7 +179,12 @@ static options_t s_opts;
 
 static job_context_id s_client_dev_context;
 static int s_client_is_processing = 1;
-static struct PVFS_dev_map_desc s_io_desc;
+
+/* We have 2 sets of description buffers, one used for staging I/O 
+ * and one for readdir/readdirplus */
+#define NUM_MAP_DESC 2
+static struct PVFS_dev_map_desc s_io_desc[NUM_MAP_DESC];
+static struct PINT_dev_params s_desc_params[NUM_MAP_DESC];
 
 static struct PINT_perf_counter* acache_pc = NULL;
 static struct PINT_perf_counter* ncache_pc = NULL;
@@ -192,8 +201,11 @@ static struct qhash_table *s_ops_in_prog
 static void parse_args(int argc, char **argv, options_t *opts);
 static void print_help(char *progname);
 static void reset_acache_timeout(void);
+#ifndef GOSSIP_DISABLE_DEBUG
 static char *get_vfs_op_name_str(int op_type);
+#endif
 static int set_acache_parameters(options_t* s_opts);
+static void set_device_parameters(options_t *s_opts);
 static void reset_ncache_timeout(void);
 static int set_ncache_parameters(options_t* s_opts);
 
@@ -242,12 +254,10 @@ static void client_segfault_handler(int 
     abort();
 }
 
-#ifdef STANDALONE_RUN_MODE
 static void client_core_sig_handler(int signum)
 {
     s_client_is_processing = 0;
 }
-#endif
 
 static int hash_key(void *key, int table_size)
 {
@@ -656,6 +666,32 @@ static PVFS_error post_readdir_request(v
     return ret;
 }
 
+static PVFS_error post_readdirplus_request(vfs_request_t *vfs_request)
+{
+    PVFS_error ret = -PVFS_EINVAL;
+
+    gossip_debug(GOSSIP_CLIENTCORE_DEBUG, "Got a readdirplus request "
+                 "for %llu,%d (token %d)\n",
+                 llu(vfs_request->in_upcall.req.readdirplus.refn.handle),
+                 vfs_request->in_upcall.req.readdirplus.refn.fs_id,
+                 vfs_request->in_upcall.req.readdirplus.token);
+
+    ret = PVFS_isys_readdirplus(
+        vfs_request->in_upcall.req.readdirplus.refn,
+        vfs_request->in_upcall.req.readdirplus.token,
+        vfs_request->in_upcall.req.readdirplus.max_dirent_count,
+        &vfs_request->in_upcall.credentials,
+        vfs_request->in_upcall.req.readdirplus.mask,
+        &vfs_request->response.readdirplus,
+        &vfs_request->op_id, (void *)vfs_request);
+
+    if (ret < 0)
+    {
+        PVFS_perror_gossip("Posting readdirplus failed", ret);
+    }
+    return ret;
+}
+
 static PVFS_error post_rename_request(vfs_request_t *vfs_request)
 {
     PVFS_error ret = -PVFS_EINVAL;
@@ -993,6 +1029,8 @@ static inline int generate_upcall_mntent
     if (!mount)                                           
         mntent->fs_id = in_upcall->req.fs_umount.fs_id;     
     
+    /* By default, the VFS does not wish to perform integrity checks */
+    mntent->integrity_check = 0;
     return 0;
 }
 
@@ -1315,6 +1353,57 @@ static PVFS_error post_statfs_request(vf
     return ret;
 }
 
+static PVFS_error service_fs_key_request(vfs_request_t *vfs_request)
+{
+    PVFS_error ret = 0;
+    int  key_len;
+    char *key;
+    struct server_configuration_s *sconfig;
+
+    gossip_debug(
+            GOSSIP_CLIENTCORE_DEBUG,
+            "service_fs_key_request called for fsid %d\n",
+            vfs_request->in_upcall.req.fs_key.fsid);
+    /* get a pointer to the server configuration */
+    sconfig = PINT_get_server_config_struct(
+            vfs_request->in_upcall.req.fs_key.fsid);
+    if (sconfig == NULL)
+    {
+        gossip_err("PINT_get_server_config_struct failed:\n");
+        ret = -PVFS_ENOENT;
+        goto out;
+    }
+    /* get a secure shared key for this file system */
+    PINT_config_get_fs_key(
+            sconfig,
+            vfs_request->in_upcall.req.fs_key.fsid, 
+            &key, &key_len);
+    /* drop reference to the server configuration */
+    PINT_put_server_config_struct(sconfig);
+    if (key_len == 0)
+    {
+        ret = 0;
+        goto out;
+    }
+    if (key_len < 0 || key == NULL)
+    {
+        gossip_err("PINT_config_get_fs_key failed:\n");
+        ret = -PVFS_EINVAL;
+        goto out;
+    }
+    /* Copy the key length of the FS */
+    vfs_request->out_downcall.resp.fs_key.fs_keylen = 
+        key_len > FS_KEY_BUF_SIZE ? FS_KEY_BUF_SIZE : key_len;
+    /* Copy the secret key of the FS */
+    memcpy(vfs_request->out_downcall.resp.fs_key.fs_key, key,
+            vfs_request->out_downcall.resp.fs_key.fs_keylen); 
+out:
+    vfs_request->out_downcall.status = ret;
+    vfs_request->out_downcall.type = vfs_request->in_upcall.type;
+    write_inlined_device_response(vfs_request);
+    return 0;
+}
+
 #ifdef USE_MMAP_RA_CACHE
 static PVFS_error post_io_readahead_request(vfs_request_t *vfs_request)
 {
@@ -1327,7 +1416,7 @@ static PVFS_error post_io_readahead_requ
 
     assert((vfs_request->in_upcall.req.io.buf_index > -1) &&
            (vfs_request->in_upcall.req.io.buf_index <
-            PVFS2_BUFMAP_DESC_COUNT));
+            s_desc_params[BM_IO].dev_buffer_count));
 
     vfs_request->io_tmp_buf = malloc(
         vfs_request->in_upcall.req.io.readahead_size);
@@ -1474,11 +1563,12 @@ static PVFS_error post_io_request(vfs_re
 
     assert((vfs_request->in_upcall.req.io.buf_index > -1) &&
            (vfs_request->in_upcall.req.io.buf_index <
-            PVFS2_BUFMAP_DESC_COUNT));
+            s_desc_params[BM_IO].dev_buffer_count));
 
     /* get a shared kernel/userspace buffer for the I/O transfer */
-    vfs_request->io_kernel_mapped_buf = PINT_dev_get_mapped_buffer(
-        &s_io_desc, vfs_request->in_upcall.req.io.buf_index);
+    vfs_request->io_kernel_mapped_buf = 
+        PINT_dev_get_mapped_buffer(BM_IO, s_io_desc, 
+            vfs_request->in_upcall.req.io.buf_index);
     assert(vfs_request->io_kernel_mapped_buf);
 
     ret = PVFS_Request_contiguous(
@@ -1510,8 +1600,8 @@ static PVFS_error post_io_request(vfs_re
     vfs_request->out_downcall.resp.io.amt_complete = amt_returned;
 
     /* get a shared kernel/userspace buffer for the I/O transfer */
-    buf = PINT_dev_get_mapped_buffer(
-        &s_io_desc, vfs_request->in_upcall.req.io.buf_index);
+    buf = PINT_dev_get_mapped_buffer(BM_IO, s_io_desc,
+            vfs_request->in_upcall.req.io.buf_index);
     assert(buf);
 
     /* copy cached data into the shared user/kernel space */
@@ -1531,6 +1621,191 @@ static PVFS_error post_io_request(vfs_re
 #endif /* USE_MMAP_RA_CACHE */
 }
 
+static PVFS_error post_iox_request(vfs_request_t *vfs_request)
+{
+    int32_t i, num_ops_posted, iox_count, iox_index;
+    int32_t *mem_sizes = NULL;
+    PVFS_error ret = -PVFS_EINVAL;
+    struct read_write_x *rwx = (struct read_write_x *) vfs_request->in_upcall.trailer_buf;
+
+    if (vfs_request->in_upcall.trailer_size <= 0 || rwx == NULL)
+    {
+        gossip_err("post_iox_request: did not receive any offset-length trailers\n");
+        goto out;
+    }
+    gossip_debug(GOSSIP_CLIENTCORE_DEBUG, "%s: size %ld\n",
+            vfs_request->in_upcall.req.iox.io_type == PVFS_IO_READ ? "readx" : "writex",
+            (unsigned long) vfs_request->in_upcall.req.iox.count);
+
+    if ((vfs_request->in_upcall.req.iox.buf_index < 0) ||
+           (vfs_request->in_upcall.req.iox.buf_index >= 
+            s_desc_params[BM_IO].dev_buffer_count))
+    {
+        gossip_err("post_iox_request: invalid buffer index %d\n",
+                vfs_request->in_upcall.req.iox.buf_index);
+        goto out;
+    }
+
+    /* get a shared kernel/userspace buffer for the I/O transfer */
+    vfs_request->io_kernel_mapped_buf = 
+        PINT_dev_get_mapped_buffer(BM_IO, s_io_desc, 
+            vfs_request->in_upcall.req.iox.buf_index);
+    if (vfs_request->io_kernel_mapped_buf == NULL)
+    {
+        gossip_err("post_iox_request: PINT_dev_get_mapped_buffer failed\n");
+        goto out;
+    }
+
+    /* trailer is interpreted as struct read_write_x */
+    if (vfs_request->in_upcall.trailer_size % sizeof(struct read_write_x) != 0)
+    {
+        gossip_err("post_iox_request: trailer size (%Ld) is not a multiple of read_write_x structure (%ld)\n",
+            lld(vfs_request->in_upcall.trailer_size),
+            (long) sizeof(struct read_write_x));
+        goto out;
+    }
+    vfs_request->iox_count = vfs_request->in_upcall.trailer_size / sizeof(struct read_write_x);
+    /* We will split this in units of IOX_HINDEXED_COUNT */
+    num_ops_posted = (vfs_request->iox_count / IOX_HINDEXED_COUNT);
+    if (vfs_request->iox_count % IOX_HINDEXED_COUNT != 0)
+        num_ops_posted++;
+    gossip_debug(GOSSIP_CLIENTCORE_DEBUG, "iox: iox_count %d, num_ops_posted %d\n",
+            vfs_request->iox_count, num_ops_posted);
+    vfs_request->num_ops = vfs_request->num_incomplete_ops = num_ops_posted;
+    ret = -PVFS_ENOMEM;
+    mem_sizes = (int32_t *) calloc(num_ops_posted, sizeof(int32_t));
+    if (mem_sizes == NULL)
+    {
+        gossip_err("post_iox_request: mem_sizes allocation failed\n");
+        goto out;
+    }
+    vfs_request->iox_sizes = (int32_t *) calloc(vfs_request->iox_count, sizeof(int32_t));
+    if (vfs_request->iox_sizes == NULL)
+    {
+        gossip_err("post_iox_request: iox_sizes allocation failed\n");
+        goto out;
+    }
+    vfs_request->iox_offsets = (PVFS_size *) calloc(vfs_request->iox_count, sizeof(PVFS_size));
+    if (vfs_request->iox_offsets == NULL)
+    {
+        gossip_err("post_iox_request: iox_offsets allocation failed\n");
+        goto err_sizes;
+    }
+    for (i = 0; i < vfs_request->iox_count; i++)
+    {
+        vfs_request->iox_sizes[i] = (int32_t) rwx->len;
+        vfs_request->iox_offsets[i] = rwx->off;
+        mem_sizes[i/IOX_HINDEXED_COUNT] += (int32_t) rwx->len;
+        rwx++;
+    }
+    vfs_request->op_ids = (PVFS_sys_op_id *) malloc(num_ops_posted * sizeof(PVFS_sys_op_id));
+    if (vfs_request->op_ids == NULL)
+    {
+        gossip_err("post_iox_request: op_ids allocation failed\n");
+        goto err_offsets;
+    }
+    vfs_request->file_req_a = (PVFS_Request *) malloc(num_ops_posted * sizeof(PVFS_Request));
+    if (vfs_request->file_req_a == NULL)
+    {
+        gossip_err("post_iox_request: file_req_a allocation failed\n");
+        goto err_opids;
+    }
+    vfs_request->mem_req_a  = (PVFS_Request *) malloc(num_ops_posted * sizeof(PVFS_Request));
+    if (vfs_request->mem_req_a == NULL)
+    {
+        gossip_err("post_iox_request: mem_req_a allocation failed\n");
+        goto err_filereq;
+    }
+    vfs_request->response.iox = (PVFS_sysresp_io *) malloc(num_ops_posted * sizeof(PVFS_sysresp_io)); 
+    if (vfs_request->response.iox == NULL)
+    {
+        gossip_err("post_iox_request: iox response allocation failed\n");
+        goto err_memreq;
+    }
+    iox_index = 0;
+    iox_count = vfs_request->iox_count;
+    ret = 0;
+    for (i = 0; i < num_ops_posted; i++)
+    {
+        int32_t iox_stage;
+
+        assert(iox_count >= 0);
+        assert(iox_index >= 0 && iox_index < vfs_request->iox_count);
+        iox_stage = PVFS_util_min(IOX_HINDEXED_COUNT, iox_count);
+        /* Construct a mem request type for this portion */
+        ret = PVFS_Request_contiguous(mem_sizes[i], PVFS_BYTE,
+                &vfs_request->mem_req_a[i]);
+        if (ret != 0)
+        {
+            gossip_err("post_iox_request: request_contiguous failed mem_sizes[%d] = %d\n",
+                    i, mem_sizes[i]);
+            break;
+        }
+        /* file request is now a hindexed request type */
+        ret = PVFS_Request_hindexed(iox_stage, 
+                &vfs_request->iox_sizes[iox_index],
+                &vfs_request->iox_offsets[iox_index],
+                PVFS_BYTE, 
+                &vfs_request->file_req_a[i]);
+        if (ret != 0)
+        {
+            gossip_err("post_iox_request: request_hindexed failed\n");
+            break;
+        }
+        /* post the I/O */
+        ret = PVFS_isys_io(
+            vfs_request->in_upcall.req.iox.refn, vfs_request->file_req_a[i],
+            0, 
+            vfs_request->io_kernel_mapped_buf, vfs_request->mem_req_a[i],
+            &vfs_request->in_upcall.credentials,
+            &vfs_request->response.iox[i],
+            vfs_request->in_upcall.req.iox.io_type,
+            &vfs_request->op_ids[i],
+            (void *)vfs_request);
+
+        if (ret < 0)
+        {
+            PVFS_perror_gossip("Posting file I/O failed", ret);
+            break;
+        }
+        iox_count -= iox_stage;
+        iox_index += iox_stage;
+    }
+    if (i != num_ops_posted)
+    {
+        int j;
+        for (j = 0; j < i; j++)
+        {
+            /* cancel previously posted I/O's */
+            PINT_client_io_cancel(vfs_request->op_ids[j]);
+            PVFS_Request_free(&vfs_request->mem_req_a[j]);
+            PVFS_Request_free(&vfs_request->file_req_a[j]);
+        }
+        free(vfs_request->in_upcall.trailer_buf);
+        vfs_request->in_upcall.trailer_buf = NULL;
+        goto err_iox;
+    }
+    vfs_request->op_id = vfs_request->op_ids[0];
+    ret = 0;
+out:
+    free(mem_sizes);
+    return ret;
+err_iox:
+    free(vfs_request->response.iox);
+err_memreq:
+    free(vfs_request->mem_req_a);
+err_filereq:
+    free(vfs_request->file_req_a);
+err_opids:
+    free(vfs_request->op_ids);
+err_offsets:
+    free(vfs_request->iox_offsets);
+err_sizes:
+    free(vfs_request->iox_sizes);
+    goto out;
+}
+
+
 #ifdef USE_MMAP_RA_CACHE
 static PVFS_error service_mmap_ra_flush_request(
     vfs_request_t *vfs_request)
@@ -1672,44 +1947,138 @@ PVFS_error write_device_response(
     return ret;
 }
 
-static inline void copy_dirents_to_downcall(vfs_request_t *vfs_request)
+/* encoding needed by client-core to copy readdir entries to the shared page */
+static long encode_dirents(pvfs2_readdir_response_t *ptr, PVFS_sysresp_readdir *readdir)
 {
-    int i = 0, len = 0;
+    int i; 
+    char *buf = (char *) ptr;
+    char **pptr = &buf;
 
-    vfs_request->out_downcall.resp.readdir.token =
-        vfs_request->response.readdir.token;
-    vfs_request->out_downcall.resp.readdir.directory_version =
-        vfs_request->response.readdir.directory_version;
+    ptr->token = readdir->token;
+    ptr->directory_version = readdir->directory_version;
+    ptr->pvfs_dirent_outcount = readdir->pvfs_dirent_outcount;
+    *pptr += offsetof(pvfs2_readdir_response_t, dirent_array);
+    for (i = 0; i < readdir->pvfs_dirent_outcount; i++) 
+    {
+        enc_string(pptr, &readdir->dirent_array[i].d_name);
+        *(int64_t *) *pptr = readdir->dirent_array[i].handle;
+        *pptr += 8;
+    }
+    return ((unsigned long) *pptr - (unsigned long) ptr);
+}
 
-    for(; i < vfs_request->response.readdir.pvfs_dirent_outcount; i++)
+static int copy_dirents_to_downcall(vfs_request_t *vfs_request)
+{
+    int ret = 0;
+    /* get a buffer for xfer of dirents */
+    vfs_request->out_downcall.trailer_buf = 
+        PINT_dev_get_mapped_buffer(BM_READDIR, s_io_desc, 
+            vfs_request->in_upcall.req.readdir.buf_index);
+    if (vfs_request->out_downcall.trailer_buf == NULL)
     {
-        vfs_request->out_downcall.resp.readdir.refn[i].handle =
-            vfs_request->response.readdir.dirent_array[i].handle;
-        vfs_request->out_downcall.resp.readdir.refn[i].fs_id =
-            vfs_request->in_upcall.req.readdir.refn.fs_id;
+        ret = -PVFS_EINVAL;
+        goto err;
+    }
 
-        len = strlen(
-            vfs_request->response.readdir.dirent_array[i].d_name);
-        vfs_request->out_downcall.resp.readdir.d_name_len[i] = len;
+    /* Simply encode the readdir system response into the shared buffer */
+    vfs_request->out_downcall.trailer_size = 
+        encode_dirents((pvfs2_readdir_response_t *) vfs_request->out_downcall.trailer_buf,
+                &vfs_request->response.readdir);
 
-        strncpy(
-            &vfs_request->out_downcall.resp.readdir.d_name[i][0],
-            vfs_request->response.readdir.dirent_array[i].d_name, len);
+    if (vfs_request->out_downcall.trailer_size <= 0) 
+    {
+        gossip_err("copy_dirents_to_downcall: invalid trailer size %ld\n",
+                (long) vfs_request->out_downcall.trailer_size);
+        ret = -PVFS_EINVAL;
+    }
+err:
+    /* free sysresp dirent array */
+    free(vfs_request->response.readdir.dirent_array);
+    vfs_request->response.readdir.dirent_array = NULL;
+    return ret;
+}
 
-        vfs_request->out_downcall.resp.readdir.dirent_count++;
+static long encode_sys_attr(char *ptr, PVFS_sysresp_readdirplus *readdirplus) 
+{
+    char *buf = ptr;
+    char **pptr = &buf;
+    int i;
+
+    memcpy(buf, readdirplus->stat_err_array, sizeof(PVFS_error) * readdirplus->pvfs_dirent_outcount);
+    *pptr += sizeof(PVFS_error) * readdirplus->pvfs_dirent_outcount;
+    if (readdirplus->pvfs_dirent_outcount % 2) 
+    {
+        *pptr += 4;
+    }
+    for (i = 0; i < readdirplus->pvfs_dirent_outcount; i++)
+    {
+        memcpy(*pptr, &readdirplus->attr_array[i], sizeof(PVFS_sys_attr));
+        *pptr += sizeof(PVFS_sys_attr);
+        if (readdirplus->attr_array[i].link_target)
+        {
+            enc_string(pptr, &readdirplus->attr_array[i].link_target);
+        }
     }
+    return ((unsigned long) *pptr - (unsigned long) ptr);
+}
+
+static long encode_readdirplus_to_buffer(char *ptr, PVFS_sysresp_readdirplus *readdirplus)
+{
+    long amt;
+    char *buf = (char *) ptr;
+
+   /* encode the dirent part of the response */
+    amt = encode_dirents((pvfs2_readdir_response_t *) buf, (PVFS_sysresp_readdir *) readdirplus);
+    if (amt < 0)
+        return amt;
+    buf += amt;
+    /* and then we encode the stat part of the response */
+    amt = encode_sys_attr(buf, readdirplus);
+    if (amt < 0)
+        return amt;
+    buf += amt;
+
+    return ((unsigned long) buf - (unsigned long) ptr);
+}
 
-    if (vfs_request->out_downcall.resp.readdir.dirent_count !=
-        vfs_request->response.readdir.pvfs_dirent_outcount)
+static int copy_direntplus_to_downcall(vfs_request_t *vfs_request)
+{
+    int i, ret = 0;
+    /* get a buffer for xfer of direntplus */
+    vfs_request->out_downcall.trailer_buf = 
+        PINT_dev_get_mapped_buffer(BM_READDIR, s_io_desc, 
+        vfs_request->in_upcall.req.readdirplus.buf_index);
+    if (vfs_request->out_downcall.trailer_buf == NULL)
     {
-        gossip_err("Error! readdir counts don't match! (%d != %d)\n",
-                   vfs_request->out_downcall.resp.readdir.dirent_count,
-                   vfs_request->response.readdir.pvfs_dirent_outcount);
+        ret = -PVFS_EINVAL;
+        goto err;
     }
 
+    /* Simply encode the readdirplus system response into the shared buffer */
+    vfs_request->out_downcall.trailer_size = 
+        encode_readdirplus_to_buffer(vfs_request->out_downcall.trailer_buf,
+                &vfs_request->response.readdirplus);
+    if (vfs_request->out_downcall.trailer_size <= 0)
+    {
+        gossip_err("copy_direntplus_to_downcall: invalid trailer size %ld\n",
+                (long) vfs_request->out_downcall.trailer_size);
+        ret = -PVFS_EINVAL;
+    }
+err:
     /* free sysresp dirent array */
-    free(vfs_request->response.readdir.dirent_array);
-    vfs_request->response.readdir.dirent_array = NULL;
+    free(vfs_request->response.readdirplus.dirent_array);
+    vfs_request->response.readdirplus.dirent_array = NULL;
+    /* free sysresp stat error array */
+    free(vfs_request->response.readdirplus.stat_err_array);
+    vfs_request->response.readdirplus.stat_err_array = NULL;
+    /* free sysresp attribute array */
+    for (i = 0; i < vfs_request->response.readdirplus.pvfs_dirent_outcount; i++) 
+    {
+        PVFS_util_release_sys_attr(&vfs_request->response.readdirplus.attr_array[i]);
+    }
+    free(vfs_request->response.readdirplus.attr_array);
+    vfs_request->response.readdirplus.attr_array = NULL;
+    return ret;
 }
 
 /* 
@@ -1872,12 +2241,22 @@ static inline void package_downcall_memb
             }
             else
             {
-                copy_dirents_to_downcall(vfs_request);
+                *error_code = copy_dirents_to_downcall(vfs_request);
+            }
+            break;
+        case PVFS2_VFS_OP_READDIRPLUS:
+            if (*error_code)
+            {
+                vfs_request->out_downcall.status = *error_code;
+            }
+            else
+            {
+                *error_code = copy_direntplus_to_downcall(vfs_request);
             }
             break;
         case PVFS2_VFS_OP_STATFS:
             vfs_request->out_downcall.resp.statfs.block_size =
-                STATFS_DEFAULT_BLOCKSIZE;
+                s_desc_params[BM_IO].dev_buffer_size;
             vfs_request->out_downcall.resp.statfs.blocks_total = (int64_t)
                 (vfs_request->response.statfs.statfs_buf.bytes_total /
                  vfs_request->out_downcall.resp.statfs.block_size);
@@ -1989,12 +2368,12 @@ static inline void package_downcall_memb
                       get a shared kernel/userspace buffer for the I/O
                       transfer
                     */
-                    buf = PINT_dev_get_mapped_buffer(
-                        &s_io_desc, vfs_request->in_upcall.req.io.buf_index);
+                    buf = PINT_dev_get_mapped_buffer(BM_IO, s_io_desc, 
+                        vfs_request->in_upcall.req.io.buf_index);
                     assert(buf);
 
                     /* copy cached data into the shared user/kernel space */
-                    memcpy(buf, (vfs_request->io_tmp_buf +
+                    memcpy(buf, ((char *) vfs_request->io_tmp_buf +
                                  vfs_request->in_upcall.req.io.offset),
                            vfs_request->in_upcall.req.io.count);
 
@@ -2058,6 +2437,37 @@ static inline void package_downcall_memb
                 *error_code = -PVFS_EINTR;
             }
             break;
+        case PVFS2_VFS_OP_FILE_IOX:
+        {
+            int j;
+
+            vfs_request->out_downcall.resp.iox.amt_complete = 0;
+            for (j = 0; j < vfs_request->num_ops; j++)
+            {
+                vfs_request->out_downcall.resp.iox.amt_complete +=
+                    vfs_request->response.iox[j].total_completed;
+            }
+            free(vfs_request->response.iox);
+            for (j = 0; j < vfs_request->num_ops; j++)
+            {
+                PVFS_Request_free(&vfs_request->mem_req_a[j]);
+                PVFS_Request_free(&vfs_request->file_req_a[j]);
+            }
+            free(vfs_request->mem_req_a);
+            free(vfs_request->file_req_a);
+            free(vfs_request->op_ids);
+            free(vfs_request->iox_offsets);
+            free(vfs_request->iox_sizes);
+            free(vfs_request->in_upcall.trailer_buf);
+            vfs_request->in_upcall.trailer_buf = NULL;
+            
+            /* replace non-errno error code to avoid passing to kernel */
+            if (*error_code == -PVFS_ECANCEL)
+            {
+                *error_code = -PVFS_EINTR;
+            }
+            break;
+        }
         case PVFS2_VFS_OP_GETXATTR:
             if (*error_code == 0)
             {
@@ -2256,6 +2666,9 @@ static inline PVFS_error handle_unexp_vf
     PINT_time_mark(&vfs_request->start);
 #endif
 
+    vfs_request->num_ops = 1;
+    vfs_request->num_incomplete_ops = 1;
+    vfs_request->op_ids  = NULL;
     switch(vfs_request->in_upcall.type)
     {
         case PVFS2_VFS_OP_LOOKUP:
@@ -2290,6 +2703,10 @@ static inline PVFS_error handle_unexp_vf
             posted_op = 1;
             ret = post_readdir_request(vfs_request);
             break;
+        case PVFS2_VFS_OP_READDIRPLUS:
+            posted_op = 1;
+            ret = post_readdirplus_request(vfs_request);
+            break;
         case PVFS2_VFS_OP_RENAME:
             posted_op = 1;
             ret = post_rename_request(vfs_request);
@@ -2335,6 +2752,9 @@ static inline PVFS_error handle_unexp_vf
         case PVFS2_VFS_OP_PARAM:
             ret = service_param_request(vfs_request);
             break;
+        case PVFS2_VFS_OP_FSKEY:
+            ret = service_fs_key_request(vfs_request);
+            break;
             /*
               if the mmap-readahead-cache is enabled and we
               get a cache hit for data, the io call is
@@ -2344,6 +2764,10 @@ static inline PVFS_error handle_unexp_vf
             posted_op = 1;
             ret = post_io_request(vfs_request);
             break;
+        case PVFS2_VFS_OP_FILE_IOX:
+            posted_op = 1;
+            ret = post_iox_request(vfs_request);
+            break;
 #ifdef USE_MMAP_RA_CACHE
             /*
               if the mmap-readahead-cache is enabled, cache
@@ -2480,7 +2904,7 @@ static PVFS_error process_vfs_requests(v
                (MAX_NUM_OPS * sizeof(vfs_request_t *)));
 
         ret = PVFS_sys_testsome(
-            op_id_array, &op_count, (void **)vfs_request_array,
+            op_id_array, &op_count, (void *)vfs_request_array,
             error_code_array, PVFS2_CLIENT_DEFAULT_TEST_TIMEOUT_MS);
 
         for(i = 0; i < op_count; i++)
@@ -2488,10 +2912,28 @@ static PVFS_error process_vfs_requests(v
             vfs_request = vfs_request_array[i];
             assert(vfs_request);
 /*             assert(vfs_request->op_id == op_id_array[i]); */
-            if (vfs_request->op_id != op_id_array[i])
+            if (vfs_request->num_ops == 1 &&
+                    vfs_request->op_id != op_id_array[i])
             {
+                gossip_err("op_id %Ld != completed op id %Ld\n",
+                        lld(vfs_request->op_id), lld(op_id_array[i]));
                 continue;
             }
+            else if (vfs_request->num_ops > 1)
+            {
+                int j;
+                /* assert that completed op is one that we posted earlier */
+                for (j = 0; j < vfs_request->num_ops; j++) {
+                    if (op_id_array[i] == vfs_request->op_ids[j])
+                        break;
+                }
+                if (j == vfs_request->num_ops)
+                {
+                    gossip_err("completed op id (%Ld) is weird\n",
+                            lld(op_id_array[i]));
+                    continue;
+                }
+            }
 
             /* check if this is a new dev unexp request */
             if (vfs_request->is_dev_unexp)
@@ -2509,6 +2951,10 @@ static PVFS_error process_vfs_requests(v
             }
             else
             {
+                vfs_request->num_incomplete_ops--;
+                /* if operation is not complete, we gotta continue */
+                if (vfs_request->num_incomplete_ops != 0)
+                    continue;
                 log_operation_timing(vfs_request);
 
                 gossip_debug(GOSSIP_CLIENTCORE_DEBUG, "PINT_sys_testsome"
@@ -2548,9 +2994,14 @@ static PVFS_error process_vfs_requests(v
                 {
                     buffer_list[0] = &vfs_request->out_downcall;
                     size_list[0] = sizeof(pvfs2_downcall_t);
-                    total_size = sizeof(pvfs2_downcall_t);
                     list_size = 1;
-
+                    total_size = sizeof(pvfs2_downcall_t);
+                    if (vfs_request->out_downcall.trailer_size > 0) {
+                        buffer_list[1] = vfs_request->out_downcall.trailer_buf;
+                        size_list[1] = vfs_request->out_downcall.trailer_size;
+                        list_size++;
+                        total_size += vfs_request->out_downcall.trailer_size;
+                    }
                     ret = write_device_response(
                         buffer_list,size_list,list_size, total_size,
                         vfs_request->info.tag,
@@ -2603,20 +3054,6 @@ int main(int argc, char **argv)
     PINT_client_sm *acache_timer_sm_p = NULL;
     PINT_client_sm *ncache_timer_sm_p = NULL;
 
-#ifndef STANDALONE_RUN_MODE
-    struct rlimit lim = {0,0};
-
-    /* set rlimit to prevent core files */
-    ret = setrlimit(RLIMIT_CORE, &lim);
-    if (ret < 0)
-    {
-	fprintf(stderr, "setrlimit system call failed (%d); "
-                "continuing", ret);
-    }
-#else
-    signal(SIGINT, client_core_sig_handler);
-#endif
-
     /* if pvfs2-client-core segfaults, at least log the occurence so
      * pvfs2-client won't repeatedly respawn pvfs2-client-core */
     signal(SIGSEGV, client_segfault_handler);
@@ -2624,6 +3061,25 @@ int main(int argc, char **argv)
     memset(&s_opts, 0, sizeof(options_t));
     parse_args(argc, argv, &s_opts);
 
+    if(!s_opts.standalone)
+    {
+        struct rlimit lim = {0,0};
+
+        /* set rlimit to prevent core files */
+        ret = setrlimit(RLIMIT_CORE, &lim);
+        if (ret < 0)
+        {
+            fprintf(stderr, "setrlimit system call failed (%d); "
+                    "continuing", ret);
+        }
+    }
+    else
+    {
+        signal(SIGINT,  client_core_sig_handler);
+        signal(SIGHUP,  client_core_sig_handler);
+        signal(SIGQUIT, client_core_sig_handler);
+    }
+
     /* convert gossip mask if provided on command line */
     if (s_opts.gossip_mask)
     {
@@ -2694,19 +3150,20 @@ int main(int argc, char **argv)
         PVFS_perror("set_ncache_parameters", ret);
         return(ret);
     }
+    set_device_parameters(&s_opts);
 
     /* start performance counters for acache */
     acache_pc = PINT_perf_initialize(acache_keys);
     if(!acache_pc)
     {
-        fprintf(stderr, "Error: PINT_perf_initialize failure.\n");
+        gossip_err("Error: PINT_perf_initialize failure.\n");
         return(-PVFS_ENOMEM);
     }
     ret = PINT_perf_set_info(acache_pc, PINT_PERF_HISTORY_SIZE,
         s_opts.perf_history_size);
     if(ret < 0)
     {
-        fprintf(stderr, "Error: PINT_perf_set_info (history_size).\n");
+        gossip_err("Error: PINT_perf_set_info (history_size).\n");
         return(ret);
     }
     PINT_acache_enable_perf_counter(acache_pc);
@@ -2715,19 +3172,18 @@ int main(int argc, char **argv)
     ncache_pc = PINT_perf_initialize(ncache_keys);
     if(!ncache_pc)
     {
-        fprintf(stderr, "Error: PINT_perf_initialize failure.\n");
+        gossip_err("Error: PINT_perf_initialize failure.\n");
         return(-PVFS_ENOMEM);
     }
     ret = PINT_perf_set_info(ncache_pc, PINT_PERF_HISTORY_SIZE,
         s_opts.perf_history_size);
     if(ret < 0)
     {
-        fprintf(stderr, "Error: PINT_perf_set_info (history_size).\n");
+        gossip_err("Error: PINT_perf_set_info (history_size).\n");
         return(ret);
     }
     PINT_ncache_enable_perf_counter(ncache_pc);
 
-    /* start a timer to roll over performance counters (acache) */
     acache_timer_sm_p = (PINT_client_sm *)malloc(sizeof(PINT_client_sm));
     if(!acache_timer_sm_p)
     {
@@ -2776,8 +3232,8 @@ int main(int argc, char **argv)
     }
 
     /* setup a mapped region for I/O transfers */
-    memset(&s_io_desc, 0 , sizeof(struct PVFS_dev_map_desc));
-    ret = PINT_dev_get_mapped_region(&s_io_desc, PVFS2_BUFMAP_TOTAL_SIZE);
+    memset(s_io_desc, 0 , NUM_MAP_DESC * sizeof(struct PVFS_dev_map_desc));
+    ret = PINT_dev_get_mapped_regions(NUM_MAP_DESC, s_io_desc, s_desc_params);
     if (ret < 0)
     {
 	PVFS_perror("PINT_dev_get_mapped_region", ret);
@@ -2836,7 +3292,7 @@ int main(int argc, char **argv)
 #endif
 
     PINT_dev_finalize();
-    PINT_dev_put_mapped_region(&s_io_desc);
+    PINT_dev_put_mapped_regions(NUM_MAP_DESC, s_io_desc);
 
     gossip_debug(GOSSIP_CLIENTCORE_DEBUG,
                  "calling PVFS_sys_finalize()\n");
@@ -2871,7 +3327,9 @@ static void print_help(char *progname)
     printf("--logfile=VALUE               override the default log file\n");
     printf("--logstamp=none|usec|datetime overrides the default log message's time stamp\n");
     printf("--gossip-mask=MASK_LIST       gossip logging mask\n");
- }
+    printf("--desc-count=VALUE            overrides the default # of kernel buffer descriptors\n");
+    printf("--desc-size=VALUE             overrides the default size of each kernel buffer descriptor\n");
+}
 
 static void parse_args(int argc, char **argv, options_t *opts)
 {
@@ -2891,8 +3349,11 @@ static void parse_args(int argc, char **
         {"acache-soft-limit",1,0,0},
         {"ncache-hard-limit",1,0,0},
         {"ncache-soft-limit",1,0,0},
+        {"desc-count",1,0,0},
+        {"desc-size",1,0,0},
         {"logfile",1,0,0},
         {"logstamp",1,0,0},
+        {"standalone",0,0,0},
         {0,0,0,0}
     };
 
@@ -2920,6 +3381,28 @@ static void parse_args(int argc, char **
                 {
                     goto do_ncache;
                 }
+                else if (strcmp("desc-count", cur_option) == 0) 
+                {
+                    ret = sscanf(optarg, "%u", &opts->dev_buffer_count);
+                    if(ret != 1)
+                    {
+                        gossip_err(
+                            "Error: invalid descriptor count value.\n");
+                        exit(EXIT_FAILURE);
+                    }
+                    opts->dev_buffer_count_set = 1;
+                }
+                else if (strcmp("desc-size", cur_option) == 0)
+                {
+                    ret = sscanf(optarg, "%u", &opts->dev_buffer_size);
+                    if(ret != 1)
+                    {
+                        gossip_err(
+                            "Error: invalid descriptor size value.\n");
+                        exit(EXIT_FAILURE);
+                    }
+                    opts->dev_buffer_size_set = 1;
+                }
                 else if (strcmp("logfile", cur_option) == 0)
                 {
                     goto do_logfile;
@@ -2940,7 +3423,9 @@ static void parse_args(int argc, char **
                     }
                     else
                     {
-                        fprintf(stderr, "Error: invalid logstamp value. See usage below\n\n");
+                        gossip_err(
+                            "Error: invalid logstamp value. "
+                            "See usage below\n\n");
                         print_help(argv[0]);
                         exit(EXIT_FAILURE);
                     }
@@ -2951,7 +3436,8 @@ static void parse_args(int argc, char **
                     ret = sscanf(optarg, "%u", &opts->acache_hard_limit);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid acache-hard-limit value.\n");
+                        gossip_err(
+                            "Error: invalid acache-hard-limit value.\n");
                         exit(EXIT_FAILURE);
                     }
                     opts->acache_hard_limit_set = 1;
@@ -2961,7 +3447,8 @@ static void parse_args(int argc, char **
                     ret = sscanf(optarg, "%u", &opts->acache_soft_limit);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid acache-soft-limit value.\n");
+                        gossip_err(
+                            "Error: invalid acache-soft-limit value.\n");
                         exit(EXIT_FAILURE);
                     }
                     opts->acache_soft_limit_set = 1;
@@ -2971,7 +3458,9 @@ static void parse_args(int argc, char **
                     ret = sscanf(optarg, "%u", &opts->acache_reclaim_percentage);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid acache-reclaim-percentage value.\n");
+                        gossip_err(
+                            "Error: invalid "
+                            "acache-reclaim-percentage value.\n");
                         exit(EXIT_FAILURE);
                     }
                     opts->acache_reclaim_percentage_set = 1;
@@ -2981,7 +3470,8 @@ static void parse_args(int argc, char **
                     ret = sscanf(optarg, "%u", &opts->ncache_hard_limit);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid ncache-hard-limit value.\n");
+                        gossip_err(
+                            "Error: invalid ncache-hard-limit value.\n");
                         exit(EXIT_FAILURE);
                     }
                     opts->ncache_hard_limit_set = 1;
@@ -2991,7 +3481,8 @@ static void parse_args(int argc, char **
                     ret = sscanf(optarg, "%u", &opts->ncache_soft_limit);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid ncache-soft-limit value.\n");
+                        gossip_err(
+                            "Error: invalid ncache-soft-limit value.\n");
                         exit(EXIT_FAILURE);
                     }
                     opts->ncache_soft_limit_set = 1;
@@ -3001,7 +3492,8 @@ static void parse_args(int argc, char **
                     ret = sscanf(optarg, "%u", &opts->ncache_reclaim_percentage);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid ncache-reclaim-percentage value.\n");
+                        gossip_err(
+                            "Error: invalid ncache-reclaim-percentage value.\n");
                         exit(EXIT_FAILURE);
                     }
                     opts->ncache_reclaim_percentage_set = 1;
@@ -3012,7 +3504,8 @@ static void parse_args(int argc, char **
                         &opts->perf_time_interval_secs);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid perf-time-interval-secs value.\n");
+                        gossip_err(
+                            "Error: invalid perf-time-interval-secs value.\n");
                         exit(EXIT_FAILURE);
                     }
                 }
@@ -3022,7 +3515,8 @@ static void parse_args(int argc, char **
                         &opts->perf_history_size);
                     if(ret != 1)
                     {
-                        fprintf(stderr, "Error: invalid perf-history-size value.\n");
+                        gossip_err(
+                            "Error: invalid perf-history-size value.\n");
                         exit(EXIT_FAILURE);
                     }
                 }
@@ -3030,6 +3524,10 @@ static void parse_args(int argc, char **
                 {
                     opts->gossip_mask = optarg;
                 }
+                else if (strcmp("standalone", cur_option) == 0)
+                {
+                    opts->standalone = 1;
+                }
                 break;
             case 'h':
           do_help:
@@ -3044,7 +3542,7 @@ static void parse_args(int argc, char **
                 opts->acache_timeout = atoi(optarg);
                 if (opts->acache_timeout < 0)
                 {
-                    fprintf(stderr, "Invalid acache timeout value of %d ms,"
+                    gossip_err("Invalid acache timeout value of %d ms,"
                                "disabling the acache.\n",
                                opts->acache_timeout);
                     opts->acache_timeout = 0;
@@ -3055,14 +3553,14 @@ static void parse_args(int argc, char **
                 opts->ncache_timeout = atoi(optarg);
                 if (opts->ncache_timeout < 0)
                 {
-                    fprintf(stderr, "Invalid ncache timeout value of %d ms,"
+                    gossip_err("Invalid ncache timeout value of %d ms,"
                                "disabling the ncache.\n",
                                opts->ncache_timeout);
                     opts->ncache_timeout = 0;
                 }
                 break;
             default:
-                fprintf(stderr, "Unrecognized option.  "
+                gossip_err("Unrecognized option.  "
                         "Try --help for information.\n");
                 exit(1);
         }
@@ -3159,6 +3657,7 @@ static void reset_ncache_timeout(void)
     }
 }
 
+#ifndef GOSSIP_DISABLE_DEBUG
 static char *get_vfs_op_name_str(int op_type)
 {
     typedef struct
@@ -3177,6 +3676,7 @@ static char *get_vfs_op_name_str(int op_
         { PVFS2_VFS_OP_REMOVE, "PVFS2_VFS_OP_REMOVE" },
         { PVFS2_VFS_OP_MKDIR, "PVFS2_VFS_OP_MKDIR" },
         { PVFS2_VFS_OP_READDIR, "PVFS2_VFS_OP_READDIR" },
+        { PVFS2_VFS_OP_READDIRPLUS, "PVFS2_VFS_OP_READDIRPLUS" },
         { PVFS2_VFS_OP_SETATTR, "PVFS2_VFS_OP_SETATTR" },
         { PVFS2_VFS_OP_SYMLINK, "PVFS2_VFS_OP_SYMLINK" },
         { PVFS2_VFS_OP_RENAME, "PVFS2_VFS_OP_RENAME" },
@@ -3192,6 +3692,9 @@ static char *get_vfs_op_name_str(int op_
         { PVFS2_VFS_OP_CANCEL, "PVFS2_VFS_OP_CANCEL" },
         { PVFS2_VFS_OP_FSYNC,  "PVFS2_VFS_OP_FSYNC" },
         { PVFS2_VFS_OP_PARAM,  "PVFS2_VFS_OP_PARAM" },
+        { PVFS2_VFS_OP_PERF_COUNT, "PVFS2_VFS_OP_PERF_COUNT" },
+        { PVFS2_VFS_OP_FSKEY,  "PVFS2_VFS_OP_FSKEY" },
+        { PVFS2_VFS_OP_FILE_IOX, "PVFS2_VFS_OP_FILE_IOX" },
         { 0, "UNKNOWN" }
     };
 
@@ -3206,6 +3709,7 @@ static char *get_vfs_op_name_str(int op_
     }
     return vfs_op_info[limit-1].type_str;
 }
+#endif
 
 static int set_acache_parameters(options_t* s_opts)
 {
@@ -3299,6 +3803,30 @@ static int set_ncache_parameters(options
     }
 
     return(0);
+}
+
+static void set_device_parameters(options_t *s_opts)
+{
+    if (s_opts->dev_buffer_count_set)
+    {
+        s_desc_params[BM_IO].dev_buffer_count = s_opts->dev_buffer_count;
+    }
+    else
+    {
+        s_desc_params[BM_IO].dev_buffer_count = PVFS2_BUFMAP_DEFAULT_DESC_COUNT;
+    }
+    if (s_opts->dev_buffer_size_set)
+    {
+        s_desc_params[BM_IO].dev_buffer_size  = s_opts->dev_buffer_size;
+    }
+    else
+    {
+        s_desc_params[BM_IO].dev_buffer_size = PVFS2_BUFMAP_DEFAULT_DESC_SIZE;
+    }
+    /* No command line options accepted for the readdir buffers */
+    s_desc_params[BM_READDIR].dev_buffer_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
+    s_desc_params[BM_READDIR].dev_buffer_size  = PVFS2_READDIR_DEFAULT_DESC_SIZE;
+    return;
 }
 
 /*

Index: pvfs2-client.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/apps/kernel/linux/pvfs2-client.c,v
diff -p -u -r1.19 -r1.19.4.1
--- pvfs2-client.c	28 Aug 2006 18:42:10 -0000	1.19
+++ pvfs2-client.c	17 Feb 2007 11:16:09 -0000	1.19.4.1
@@ -26,7 +26,11 @@
 #define PVFS2_VERSION "Unknown"
 #endif
 
-#define PVFS2_CLIENT_CORE_NAME  "pvfs2-client-core"
+#define PVFS2_CLIENT_CORE_SUFFIX  "-core"
+#define PVFS2_CLIENT_CORE_NAME "pvfs2-client" PVFS2_CLIENT_CORE_SUFFIX
+#define PVFS2_CLIENT_CORE_THR_SUFFIX "-threaded"
+
+static char s_client_core_path[PATH_MAX];
 
 #define MAX_DEV_INIT_FAILURES 10
 
@@ -53,6 +57,9 @@ typedef struct
     char *path;
     char *logfile;
     char *logstamp;
+    char *dev_buffer_count;
+    char *dev_buffer_size;
+    int threaded;
 } options_t;
 
 static void client_sig_handler(int signum);
@@ -263,19 +270,22 @@ static int monitor_pvfs2_client(options_
         {
             sleep(1);
 
-            if (opts->verbose)
+            if(opts->threaded)
+            {
+                arg_list[0] = PVFS2_CLIENT_CORE_NAME PVFS2_CLIENT_CORE_THR_SUFFIX;
+            }
+            else
             {
-                printf("About to exec %s\n",opts->path);
+                arg_list[0] = PVFS2_CLIENT_CORE_NAME;
             }
 
-            arg_list[0] = PVFS2_CLIENT_CORE_NAME;
-            arg_list[1] = "-a";
-            arg_list[2] = opts->acache_timeout;
-            arg_list[3] = "-n";
-            arg_list[4] = opts->ncache_timeout;
-            arg_list[5] = "-L";
-            arg_list[6] = opts->logfile;
-            arg_index = 7;
+            arg_index = 1;
+            arg_list[arg_index++] = "-a";
+            arg_list[arg_index++] = opts->acache_timeout;
+            arg_list[arg_index++] = "-n";
+            arg_list[arg_index++] = opts->ncache_timeout;
+            arg_list[arg_index++] = "-L";
+            arg_list[arg_index++] = opts->logfile;
             if(opts->acache_hard_limit)
             {
                 arg_list[arg_index] = "--acache-hard-limit";
@@ -336,7 +346,29 @@ static int monitor_pvfs2_client(options_
                 arg_list[arg_index+1] = opts->logstamp;
                 arg_index+=2;
             }
+            if(opts->dev_buffer_count)
+            {
+                arg_list[arg_index] = "--desc-count";
+                arg_list[arg_index+1] = opts->dev_buffer_count;
+                arg_index+=2;
+            }
+            if(opts->dev_buffer_size)
+            {
+                arg_list[arg_index] = "--desc-size";
+                arg_list[arg_index+1] = opts->dev_buffer_size;
+                arg_index+=2;
+            }
 
+            if(opts->verbose)
+            {
+                int i;
+                printf("About to exec: %s, with args: ", opts->path);
+                for(i = 0; i < arg_index; ++i)
+                {
+                    printf("%s ", arg_list[i]);
+                }
+                printf("\n");
+            }
             ret = execvp(opts->path, arg_list);
 
             fprintf(stderr, "Could not exec %s, errno is %d\n",
@@ -374,6 +406,8 @@ static void print_help(char *progname)
     printf("--gossip-mask=MASK_LIST       gossip logging mask\n");
     printf("-p PATH, --path PATH          execute pvfs2-client at "
            "PATH\n");
+    printf("--logstamp=none|usec|datetime override default log message time stamp format\n");
+    printf("--threaded                    use threaded client\n");
 }
 
 static void parse_args(int argc, char **argv, options_t *opts)
@@ -395,12 +429,15 @@ static void parse_args(int argc, char **
         {"ncache-timeout",1,0,0},
         {"ncache-soft-limit",1,0,0},
         {"ncache-hard-limit",1,0,0},
+        {"desc-count",1,0,0},
+        {"desc-size",1,0,0},
         {"ncache-reclaim-percentage",1,0,0},
         {"perf-time-interval-secs",1,0,0},
         {"perf-history-size",1,0,0},
         {"gossip-mask",1,0,0},
         {"path",1,0,0},
         {"logstamp",1,0,0},
+        {"threaded",0,0,0},
         {0,0,0,0}
     };
 
@@ -480,6 +517,16 @@ static void parse_args(int argc, char **
                     opts->ncache_reclaim_percentage = optarg;
                     break;
                 }
+                else if (strcmp("desc-count", cur_option) == 0) 
+                {
+                    opts->dev_buffer_count = optarg;
+                    break;
+                }
+                else if (strcmp("desc-size", cur_option) == 0)
+                {
+                    opts->dev_buffer_size = optarg;
+                    break;
+                }
                 else if (strcmp("perf-time-interval-secs", cur_option) == 0)
                 {
                     opts->perf_time_interval_secs = optarg;
@@ -495,6 +542,11 @@ static void parse_args(int argc, char **
                     opts->gossip_mask = optarg;
                     break;
                 }
+                else if (strcmp("threaded", cur_option) == 0)
+                {
+                    opts->threaded = 1;
+                    break;
+                }
                 break;
             case 'h':
           do_help:
@@ -558,11 +610,18 @@ static void parse_args(int argc, char **
 
     if (!opts->path)
     {
-        /*
-          since they didn't specify a specific path, we're going to
-          let execlp() sort things out later
-        */
-        opts->path = PVFS2_CLIENT_CORE_NAME;
+        if(opts->threaded)
+        {
+            sprintf(s_client_core_path, 
+                    "%s" PVFS2_CLIENT_CORE_SUFFIX PVFS2_CLIENT_CORE_THR_SUFFIX, 
+                    argv[0]);
+        }
+        else
+        {
+            sprintf(s_client_core_path, "%s" PVFS2_CLIENT_CORE_SUFFIX,
+                    argv[0]);
+        }
+        opts->path = s_client_core_path;
     }
 
     if (!opts->acache_timeout)



More information about the Pvfs2-cvs mailing list