[Pvfs2-cvs] commit by kunkel in pvfs2/src/kernel/linux-2.6: pvfs2-bufmap.h super.c file.c pvfs2-bufmap.c devpvfs2-req.c pvfs2-cache.c

CVS commit program cvs at parl.clemson.edu
Sat Jan 13 05:16:55 EST 2007


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

Modified Files:
      Tag: kunkel-hint-branch
	pvfs2-bufmap.h super.c file.c pvfs2-bufmap.c devpvfs2-req.c 
	pvfs2-cache.c 
Log Message:
Synchronization with HEAD


Index: pvfs2-bufmap.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.h,v
diff -p -u -r1.13.24.2 -r1.13.24.3
--- pvfs2-bufmap.h	2 Dec 2006 11:22:20 -0000	1.13.24.2
+++ pvfs2-bufmap.h	13 Jan 2007 10:16:54 -0000	1.13.24.3
@@ -18,8 +18,11 @@ struct pvfs_bufmap_desc
     struct list_head list_link;
 };
 
-/* this would be a function call if the buffer sizes weren't hard coded */
-#define pvfs_bufmap_size_query() PVFS2_BUFMAP_DEFAULT_DESC_SIZE
+/* pvfs_bufmap_size_query is now an inline function because buffer
+   sizes are not hardcoded */
+int pvfs_bufmap_size_query(void);
+
+int pvfs_bufmap_shift_query(void);
 
 int pvfs_bufmap_initialize(
     struct PVFS_dev_map_desc *user_desc);

Index: super.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/super.c,v
diff -p -u -r1.80.2.2 -r1.80.2.3
--- super.c	2 Dec 2006 11:22:19 -0000	1.80.2.2
+++ super.c	13 Jan 2007 10:16:54 -0000	1.80.2.3
@@ -5,6 +5,7 @@
  */
 
 #include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
 #include "pvfs2-internal.h"
 
 /* list for storing pvfs2 specific superblocks in use */
@@ -434,15 +435,16 @@ static int pvfs2_statfs(
     if (new_op->downcall.status > -1)
     {
         gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_statfs: got %ld blocks available | "
-                    "%ld blocks total\n",
+                    "%ld blocks total | %ld block size\n",
                     (long) new_op->downcall.resp.statfs.blocks_avail,
-                    (long) new_op->downcall.resp.statfs.blocks_total);
+                    (long) new_op->downcall.resp.statfs.blocks_total,
+                    (long) new_op->downcall.resp.statfs.block_size);
 
         buf->f_type = sb->s_magic;
         /* stash the fsid as well */
         memcpy(&buf->f_fsid, &(PVFS2_SB(sb)->fs_id), 
                 sizeof(PVFS2_SB(sb)->fs_id));      
-        buf->f_bsize = sb->s_blocksize;
+        buf->f_bsize = new_op->downcall.resp.statfs.block_size;
         buf->f_namelen = PVFS2_NAME_LEN;
 
         buf->f_blocks = (sector_t)
@@ -949,8 +951,8 @@ struct super_block* pvfs2_get_sb(
     sb->s_op = &pvfs2_s_ops;
     sb->s_type = &pvfs2_fs_type;
 
-    sb->s_blocksize = PVFS2_BUFMAP_DEFAULT_DESC_SIZE;
-    sb->s_blocksize_bits = PVFS2_BUFMAP_DEFAULT_DESC_SHIFT;
+    sb->s_blocksize = pvfs_bufmap_size_query();
+    sb->s_blocksize_bits = pvfs_bufmap_shift_query();
     sb->s_maxbytes = MAX_LFS_FILESIZE;
 
     root_object.handle = PVFS2_SB(sb)->root_handle;
@@ -1070,8 +1072,8 @@ int pvfs2_fill_sb(
     sb->s_op = &pvfs2_s_ops;
     sb->s_type = &pvfs2_fs_type;
 
-    sb->s_blocksize = PVFS2_BUFMAP_DEFAULT_DESC_SIZE;
-    sb->s_blocksize_bits = PVFS2_BUFMAP_DEFAULT_DESC_SHIFT;
+    sb->s_blocksize = pvfs_bufmap_size_query();
+    sb->s_blocksize_bits = pvfs_bufmap_shift_query();
     sb->s_maxbytes = MAX_LFS_FILESIZE;
 
     root_object.handle = PVFS2_SB(sb)->root_handle;

Index: file.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/file.c,v
diff -p -u -r1.122.2.2 -r1.122.2.3
--- file.c	2 Dec 2006 11:22:19 -0000	1.122.2.2
+++ file.c	13 Jan 2007 10:16:54 -0000	1.122.2.3
@@ -39,6 +39,10 @@ do {                                    
   wake_up_interruptible(&op->io_completion_waitq);\
 } while(0)
 
+#ifndef HAVE_COMBINED_AIO_AND_VECTOR
+/* <2.6.19 called it this instead */
+#define do_sync_read generic_file_read
+#endif
 
 /** Called when a process requests to open a file.
  */
@@ -124,7 +128,7 @@ struct rw_options {
     struct kiocb *iocb;
     union {
         struct {
-            struct iovec *iov;
+            const struct iovec *iov;
             unsigned long nr_segs;
         } address;
         struct {
@@ -307,7 +311,9 @@ out:
 /*
  * The reason we need to do this is to be able to support 
  * readv and writev that are
- * larger than PVFS_DEFAULT_DESC_SIZE (4 MB). What that means is that
+ * larger than (pvfs_bufmap_size_query())
+ * Default is PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB.
+ * What that means is that
  * we will create a new io vec descriptor for those memory addresses that 
  * go beyond the limit
  * Return value for this routine is -ve in case of errors
@@ -315,7 +321,7 @@ out:
  * Further, the new_nr_segs pointer is updated to hold the new value
  * of number of iovecs, the new_vec pointer is updated to hold the pointer
  * to the new split iovec, and the size array is an array of integers holding
- * the number of iovecs that straddle PVFS_DEFAULT_DESC_SIZE.
+ * the number of iovecs that straddle pvfs_bufmap_size_query().
  * The max_new_nr_segs value is computed by the caller and returned.
  * (It will be (count of all iov_len/ block_size) + 1).
  */
@@ -344,37 +350,33 @@ static int split_iovecs(
     *seg_count = 0;
     *seg_array = NULL;
     /* copy the passed in iovec descriptor to a temp structure */
-    orig_iovec = (struct iovec *) kmalloc(nr_segs * sizeof(struct iovec),
-            PVFS2_BUFMAP_GFP_FLAGS);
+    orig_iovec = kzalloc(nr_segs * sizeof(*orig_iovec), PVFS2_BUFMAP_GFP_FLAGS);
     if (orig_iovec == NULL)
     {
         gossip_err("split_iovecs: Could not allocate memory for %lu bytes!\n", 
-                (unsigned long)(nr_segs * sizeof(struct iovec)));
+                (unsigned long)(nr_segs * sizeof(*orig_iovec)));
         return -ENOMEM;
     }
-    new_iovec = (struct iovec *) kmalloc(max_new_nr_segs * sizeof(struct iovec), 
+    new_iovec = kzalloc(max_new_nr_segs * sizeof(*new_iovec), 
             PVFS2_BUFMAP_GFP_FLAGS);
     if (new_iovec == NULL)
     {
         kfree(orig_iovec);
         gossip_err("split_iovecs: Could not allocate memory for %lu bytes!\n", 
-                (unsigned long)(max_new_nr_segs * sizeof(struct iovec)));
+                (unsigned long)(max_new_nr_segs * sizeof(*new_iovec)));
         return -ENOMEM;
     }
-    sizes = (unsigned long *) kmalloc(max_new_nr_segs * sizeof(unsigned long), 
-		    PVFS2_BUFMAP_GFP_FLAGS);
+    sizes = kzalloc(max_new_nr_segs * sizeof(*sizes), PVFS2_BUFMAP_GFP_FLAGS);
     if (sizes == NULL)
     {
         kfree(new_iovec);
         kfree(orig_iovec);
         gossip_err("split_iovecs: Could not allocate memory for %lu bytes!\n", 
-                (unsigned long)(max_new_nr_segs * sizeof(int)));
+                (unsigned long)(max_new_nr_segs * sizeof(unsigned long)));
         return -ENOMEM;
     }
     /* copy the passed in iovec to a temp structure */
-    memcpy(orig_iovec, original_iovec, nr_segs * sizeof(struct iovec));
-    memset(new_iovec, 0, max_new_nr_segs * sizeof(struct iovec));
-    memset(sizes, 0, max_new_nr_segs * sizeof(int));
+    memcpy(orig_iovec, original_iovec, nr_segs * sizeof(*orig_iovec));
     begin_seg = 0;
 repeat:
     for (seg = begin_seg; seg < nr_segs; seg++)
@@ -470,7 +472,7 @@ static ssize_t do_direct_readv_writev(st
     struct file *file;
     unsigned int to_free;
     size_t count;
-    struct iovec *iov;
+    const struct iovec *iov;
     unsigned long nr_segs, seg, new_nr_segs = 0;
     unsigned long max_new_nr_segs = 0;
     unsigned long  seg_count = 0;
@@ -737,7 +739,7 @@ ssize_t pvfs2_file_read(
     if (IS_IMMUTABLE(rw.inode)) 
     {
         rw.readahead_size = (rw.inode)->i_size;
-        return generic_file_read(file, buf, count, offset);
+        return do_sync_read(file, buf, count, offset);
     }
     else 
     {
@@ -776,6 +778,8 @@ static ssize_t pvfs2_file_write(
     return do_direct_readv_writev(&rw);
 }
 
+/* compat code, < 2.6.19 */
+#ifndef HAVE_COMBINED_AIO_AND_VECTOR
 /** Reads data to several contiguous user buffers (an iovec) from a file at a
  * specified offset.
  */
@@ -831,6 +835,7 @@ static ssize_t pvfs2_file_writev(
 
     return do_direct_readv_writev(&rw);
 }
+#endif
 
 
 /* Construct a trailer of <file offsets, length pairs> in a buffer that we
@@ -863,7 +868,9 @@ static int construct_file_offset_trailer
 
 /*
  * The reason we need to do this is to be able to support readx() and writex()
- * of larger than PVFS_DEFAULT_DESC_SIZE (4 MB). What that means is that
+ * of larger than (pvfs_bufmap_size_query()) 
+ * (default is PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB).
+ * What that means is that
  * we will create a new xtvec descriptor for those file offsets that 
  * go beyond the limit
  * Return value for this routine is -ve in case of errors
@@ -871,7 +878,7 @@ static int construct_file_offset_trailer
  * Further, the new_nr_segs pointer is updated to hold the new value
  * of number of xtvecs, the new_xtvec pointer is updated to hold the pointer
  * to the new split xtvec, and the size array is an array of integers holding
- * the number of xtvecs that straddle PVFS_DEFAULT_DESC_SIZE.
+ * the number of xtvecs that straddle (pvfs_bufmap_size_query()).
  * The max_new_nr_segs value is computed by the caller and passed in.
  * (It will be (count of all xtv_len/ block_size) + 1).
  */
@@ -900,37 +907,33 @@ static int split_xtvecs(
     *seg_count = 0;
     *seg_array = NULL;
     /* copy the passed in xtvec descriptor to a temp structure */
-    orig_xtvec = (struct xtvec *) kmalloc(nr_segs * sizeof(struct xtvec),
-            PVFS2_BUFMAP_GFP_FLAGS);
+    orig_xtvec = kmalloc(nr_segs * sizeof(*orig_xtvec), PVFS2_BUFMAP_GFP_FLAGS);
     if (orig_xtvec == NULL)
     {
         gossip_err("split_xtvecs: Could not allocate memory for %lu bytes!\n", 
-                (unsigned long)(nr_segs * sizeof(struct xtvec)));
+                (unsigned long)(nr_segs * sizeof(*orig_xtvec)));
         return -ENOMEM;
     }
-    new_xtvec = (struct xtvec *) kmalloc(max_new_nr_segs * sizeof(struct xtvec), 
+    new_xtvec = kzalloc(max_new_nr_segs * sizeof(*new_xtvec), 
             PVFS2_BUFMAP_GFP_FLAGS);
     if (new_xtvec == NULL)
     {
         kfree(orig_xtvec);
         gossip_err("split_xtvecs: Could not allocate memory for %lu bytes!\n", 
-                (unsigned long)(max_new_nr_segs * sizeof(struct xtvec)));
+                (unsigned long)(max_new_nr_segs * sizeof(*new_xtvec)));
         return -ENOMEM;
     }
-    sizes = (unsigned long *) kmalloc(max_new_nr_segs * sizeof(unsigned long), 
-            PVFS2_BUFMAP_GFP_FLAGS);
+    sizes = kzalloc(max_new_nr_segs * sizeof(*sizes), PVFS2_BUFMAP_GFP_FLAGS);
     if (sizes == NULL)
     {
         kfree(new_xtvec);
         kfree(orig_xtvec);
         gossip_err("split_xtvecs: Could not allocate memory for %lu bytes!\n", 
-                (unsigned long)(max_new_nr_segs * sizeof(int)));
+                (unsigned long)(max_new_nr_segs * sizeof(*sizes)));
         return -ENOMEM;
     }
     /* copy the passed in xtvec to a temp structure */
-    memcpy(orig_xtvec, original_xtvec, nr_segs * sizeof(struct xtvec));
-    memset(new_xtvec, 0, max_new_nr_segs * sizeof(struct xtvec));
-    memset(sizes, 0, max_new_nr_segs * sizeof(int));
+    memcpy(orig_xtvec, original_xtvec, nr_segs * sizeof(*orig_xtvec));
     begin_seg = 0;
     count = 0;
     tmpnew_nr_segs = 0;
@@ -1207,7 +1210,7 @@ static ssize_t do_direct_readx_writex(st
     struct inode *inode = NULL;
     pvfs2_inode_t *pvfs2_inode = NULL;
     unsigned int to_free;
-    struct iovec *iov; 
+    const struct iovec *iov; 
     unsigned long seg, nr_segs, xtnr_segs;
     struct xtvec *xtvec; 
     unsigned long max_new_nr_segs_mem, max_new_nr_segs_stream;
@@ -1877,7 +1880,7 @@ static ssize_t do_direct_aio_read_write(
     struct inode *inode;
     ssize_t error;
     pvfs2_inode_t *pvfs2_inode;
-    struct iovec *iov;
+    const struct iovec *iov;
     unsigned long nr_segs, max_new_nr_segs;
     size_t count;
     struct kiocb *iocb;
@@ -2091,12 +2094,12 @@ out_error:
     return error;
 }
 
-static ssize_t 
-pvfs2_file_aio_read(struct kiocb *iocb, char __user *buffer,
-        size_t count, loff_t offset)
+static ssize_t pvfs2_file_aio_read_iovec(struct kiocb *iocb,
+                                         const struct iovec *iov,
+                                         unsigned long nr_segs, loff_t offset)
 {
     struct rw_options rw;
-    struct iovec vec;
+
     memset(&rw, 0, sizeof(rw));
     rw.async = !is_sync_kiocb(iocb);
     rw.type = IO_READ;
@@ -2105,8 +2108,6 @@ pvfs2_file_aio_read(struct kiocb *iocb, 
     rw.copy_to_user = 1;
     rw.fnstr = __FUNCTION__;
     rw.iocb = iocb;
-    vec.iov_base = (char __user *) buffer;
-    vec.iov_len  = count;
     rw.file = iocb->ki_filp;
     if (!rw.file || !(rw.file)->f_mapping)
     {
@@ -2114,13 +2115,19 @@ pvfs2_file_aio_read(struct kiocb *iocb, 
     }
     rw.inode = (rw.file)->f_mapping->host;
     rw.pvfs2_inode = PVFS2_I(rw.inode);
-    rw.dest.address.iov = &vec;
-    rw.dest.address.nr_segs = 1;
+    rw.dest.address.iov = iov;
+    rw.dest.address.nr_segs = nr_segs;
 
     if (IS_IMMUTABLE(rw.inode)) 
     {
         rw.readahead_size = (rw.inode)->i_size;
-        return generic_file_aio_read(iocb, buffer, count, offset);
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+        return generic_file_aio_read(iocb, iov, nr_segs, offset);
+#else
+        /* compatibility code; know nr_segs == 1 as only caller is the
+         * compat function below */
+        return generic_file_aio_read(iocb, iov->iov_base, iov->iov_len, offset);
+#endif
     }
     else 
     {
@@ -2129,12 +2136,11 @@ pvfs2_file_aio_read(struct kiocb *iocb, 
     }
 }
 
-static ssize_t 
-pvfs2_file_aio_write(struct kiocb *iocb, const char __user *buffer,
-        size_t count, loff_t offset)
+static ssize_t pvfs2_file_aio_write_iovec(struct kiocb *iocb,
+                                          const struct iovec *iov,
+                                          unsigned long nr_segs, loff_t offset)
 {
     struct rw_options rw;
-    struct iovec vec;
 
     memset(&rw, 0, sizeof(rw));
     rw.async = !is_sync_kiocb(iocb);
@@ -2145,8 +2151,6 @@ pvfs2_file_aio_write(struct kiocb *iocb,
     rw.copy_to_user = 1;
     rw.fnstr = __FUNCTION__;
     rw.iocb = iocb;
-    vec.iov_base = (char __user *) buffer;
-    vec.iov_len  = count;
     rw.file = iocb->ki_filp;
     if (!rw.file || !(rw.file)->f_mapping)
     {
@@ -2154,12 +2158,37 @@ pvfs2_file_aio_write(struct kiocb *iocb,
     }
     rw.inode = (rw.file)->f_mapping->host;
     rw.pvfs2_inode = PVFS2_I(rw.inode);
-    rw.dest.address.iov = &vec;
-    rw.dest.address.nr_segs = 1;
+    rw.dest.address.iov = iov;
+    rw.dest.address.nr_segs = nr_segs;
     return do_direct_aio_read_write(&rw);
 }
 
+/* compat functions for < 2.6.19 */
+#ifndef HAVE_COMBINED_AIO_AND_VECTOR
+static ssize_t 
+pvfs2_file_aio_read(struct kiocb *iocb, char __user *buffer,
+        size_t count, loff_t offset)
+
+{
+    struct iovec iov = {
+        .iov_base = buffer,
+        .iov_len = count,
+    };
+    return pvfs2_file_aio_read_iovec(iocb, &iov, 1, offset);
+}
+
+static ssize_t 
+pvfs2_file_aio_write(struct kiocb *iocb, const char __user *buffer,
+        size_t count, loff_t offset)
+{
+    struct iovec iov = {
+        .iov_base = (void __user *) buffer,  /* discard const so it fits */
+        .iov_len = count,
+    };
+    return pvfs2_file_aio_write_iovec(iocb, &iov, 1, offset);
+}
 #endif
+#endif  /* HAVE_AIO_VFS_SUPPORT */
 
 /** Perform a miscellaneous operation on a file.
  */
@@ -2486,11 +2515,17 @@ struct file_operations pvfs2_file_operat
     .llseek = pvfs2_file_llseek,
     .read = pvfs2_file_read,
     .write = pvfs2_file_write,
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+    /* for >= 2.6.19 */
+    .aio_read = pvfs2_file_aio_read_iovec,
+    .aio_write = pvfs2_file_aio_write_iovec,
+#else
     .readv = pvfs2_file_readv,
     .writev = pvfs2_file_writev,
-#ifdef HAVE_AIO_VFS_SUPPORT
+#  ifdef HAVE_AIO_VFS_SUPPORT
     .aio_read = pvfs2_file_aio_read,
     .aio_write = pvfs2_file_aio_write,
+#  endif
 #endif
     .ioctl = pvfs2_ioctl,
     .mmap = pvfs2_file_mmap,

Index: pvfs2-bufmap.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.c,v
diff -p -u -r1.42.2.2 -r1.42.2.3
--- pvfs2-bufmap.c	2 Dec 2006 11:22:19 -0000	1.42.2.2
+++ pvfs2-bufmap.c	13 Jan 2007 10:16:55 -0000	1.42.2.3
@@ -7,23 +7,93 @@
 #include "pvfs2-bufmap.h"
 #include "pint-dev-shared.h"
 
-#define BUFMAP_PAGE_COUNT (PVFS2_BUFMAP_TOTAL_SIZE/PAGE_SIZE)
-#define PAGES_PER_DESC (PVFS2_BUFMAP_DEFAULT_DESC_SIZE/PAGE_SIZE)
+
+static int bufmap_page_count, pages_per_desc;
+
+static int32_t pvfs2_bufmap_desc_size, pvfs2_bufmap_desc_shift,
+               pvfs2_bufmap_desc_count, pvfs2_bufmap_total_size;
+
+inline int pvfs_bufmap_size_query(void)
+{
+    return pvfs2_bufmap_desc_size;
+}
+
+inline int pvfs_bufmap_shift_query(void)
+{
+    return pvfs2_bufmap_desc_shift;
+}
 
 static int bufmap_init = 0;
 static struct page **bufmap_page_array = NULL;
+
 /* array to track usage of buffer descriptors */
-static int buffer_index_array[PVFS2_BUFMAP_DESC_COUNT] = {0};
+static int *buffer_index_array = NULL;
 static spinlock_t buffer_index_lock = SPIN_LOCK_UNLOCKED;
 
 /* array to track usage of buffer descriptors for readdir/readdirplus */
-int readdir_index_array[PVFS2_READDIR_DESC_COUNT] = {0};
+static int readdir_index_array[PVFS2_READDIR_DEFAULT_DESC_COUNT] = {0};
 static spinlock_t readdir_index_lock = SPIN_LOCK_UNLOCKED;
 
-static struct pvfs_bufmap_desc desc_array[PVFS2_BUFMAP_DESC_COUNT];
+static struct pvfs_bufmap_desc *desc_array = NULL;
+
 static DECLARE_WAIT_QUEUE_HEAD(bufmap_waitq);
 static DECLARE_WAIT_QUEUE_HEAD(readdir_waitq);
 
+static int initialize_bufmap_descriptors(int ndescs)
+{
+    int err;
+
+    err = -EINVAL;
+    if (ndescs < 0)
+    {
+        gossip_err("pvfs2: ndescs (%d) cannot be < 0.\n", ndescs);
+        goto out;
+    }
+    err = -ENOMEM;
+    buffer_index_array = (int *) kmalloc(ndescs * sizeof(int), 
+                                         PVFS2_BUFMAP_GFP_FLAGS);
+    if (buffer_index_array == NULL) 
+    {
+        gossip_err("pvfs2: could not allocate %d bytes\n",
+                (int) (ndescs * sizeof(int)));
+        goto out;
+    }
+    memset(buffer_index_array, 0, ndescs * sizeof(int));
+
+    desc_array = (struct pvfs_bufmap_desc *) 
+                 kmalloc(ndescs * sizeof(struct pvfs_bufmap_desc),
+                         PVFS2_BUFMAP_GFP_FLAGS);
+    if (desc_array == NULL)
+    {
+        gossip_err("pvfs2: could not allocate %d bytes\n",
+                (int) (ndescs * sizeof(struct pvfs_bufmap_desc)));
+        goto out1;
+    }
+    err = 0;
+    goto out;
+
+out1:
+    kfree(buffer_index_array);
+    buffer_index_array = NULL;
+out:
+    return err;
+}
+
+static void finalize_bufmap_descriptors(void)
+{
+    if (buffer_index_array != NULL) 
+    {
+        kfree(buffer_index_array);
+        buffer_index_array = NULL;
+    }
+    if (desc_array != NULL)
+    {
+        kfree(desc_array);
+        desc_array = NULL;
+    }
+    return;
+}
+
 /* pvfs_bufmap_initialize()
  *
  * initializes the mapped buffer interface
@@ -36,7 +106,9 @@ int pvfs_bufmap_initialize(struct PVFS_d
     int i = 0;
     int offset = 0;
 
-    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: called\n");
+    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: called "
+                 "(ptr (%p) sz (%d) cnt(%d).\n",
+                 user_desc->ptr, user_desc->size, user_desc->count);
 
     if (bufmap_init == 1)
     {
@@ -51,34 +123,50 @@ int pvfs_bufmap_initialize(struct PVFS_d
     if (PAGE_ALIGN((unsigned long)user_desc->ptr) != 
         (unsigned long)user_desc->ptr)
     {
-        gossip_err("pvfs2 error: memory alignment (front).\n");
+        gossip_err("pvfs2 error: memory alignment (front). %p\n",
+                user_desc->ptr);
         goto init_failure;
     }
 
-    if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->size)) != 
-        (unsigned long)(user_desc->ptr + user_desc->size))
+    if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->total_size)) != 
+        (unsigned long)(user_desc->ptr + user_desc->total_size))
     {
-        gossip_err("pvfs2 error: memory alignment (back).\n");
+        gossip_err("pvfs2 error: memory alignment (back).(%p + %d)\n",
+                user_desc->ptr, user_desc->total_size);
         goto init_failure;
     }
 
-    if (user_desc->size != PVFS2_BUFMAP_TOTAL_SIZE)
+    if (user_desc->total_size != (user_desc->size * user_desc->count))
     {
         gossip_err("pvfs2 error: user provided an oddly "
-                    "sized buffer...\n");
+                    "sized buffer...(%d, %d, %d)\n",
+                    user_desc->total_size, user_desc->size, user_desc->count);
         goto init_failure;
     }
 
-    if ((PVFS2_BUFMAP_DEFAULT_DESC_SIZE % PAGE_SIZE) != 0)
+    if ((user_desc->size % PAGE_SIZE) != 0)
     {
         gossip_err("pvfs2 error: bufmap size not page size "
-                    "divisible.\n");
+                    "divisible (%d).\n", user_desc->size);
+        goto init_failure;
+    }
+    /* Initialize critical variables */
+    pvfs2_bufmap_total_size = user_desc->total_size;
+    pvfs2_bufmap_desc_count = user_desc->count;
+    pvfs2_bufmap_desc_size  = user_desc->size;
+    pvfs2_bufmap_desc_shift = LOG2(pvfs2_bufmap_desc_size);
+    bufmap_page_count = pvfs2_bufmap_total_size / PAGE_SIZE;
+    pages_per_desc    = pvfs2_bufmap_desc_size / PAGE_SIZE;
+    /* Initialize descriptor arrays */
+    if ((ret = initialize_bufmap_descriptors(pvfs2_bufmap_desc_count)) < 0)
+    {
         goto init_failure;
     }
 
     /* allocate storage to track our page mappings */
-    bufmap_page_array = (struct page **)kmalloc(
-        BUFMAP_PAGE_COUNT*sizeof(struct page *), PVFS2_BUFMAP_GFP_FLAGS);
+    bufmap_page_array = (struct page **)
+                         kmalloc(bufmap_page_count * sizeof(struct page *),
+                                 PVFS2_BUFMAP_GFP_FLAGS);
     if (!bufmap_page_array)
     {
         ret = -ENOMEM;
@@ -90,7 +178,7 @@ int pvfs_bufmap_initialize(struct PVFS_d
 
     ret = get_user_pages(
         current, current->mm, (unsigned long)user_desc->ptr,
-        BUFMAP_PAGE_COUNT, 1, 0, bufmap_page_array, NULL);
+        bufmap_page_count, 1, 0, bufmap_page_array, NULL);
 
     up_read(&current->mm->mmap_sem);
 
@@ -104,10 +192,10 @@ int pvfs_bufmap_initialize(struct PVFS_d
       in theory we could run with what we got, but I will just treat
       it as an error for simplicity's sake right now
     */
-    if (ret != BUFMAP_PAGE_COUNT)
+    if (ret != bufmap_page_count)
     {
         gossip_err("pvfs2 error: asked for %d pages, only got %d.\n",
-                    (int)BUFMAP_PAGE_COUNT, ret);
+                    (int) bufmap_page_count, ret);
 
         for(i = 0; i < ret; i++)
         {
@@ -129,37 +217,43 @@ int pvfs_bufmap_initialize(struct PVFS_d
       it's worth.  in 2.4.x, marking the pages does what's expected
       and doesn't try to swap out our pages
     */
-    for(i = 0; i < BUFMAP_PAGE_COUNT; i++)
+    for(i = 0; i < bufmap_page_count; i++)
     {
         flush_dcache_page(bufmap_page_array[i]);
         pvfs2_set_page_reserved(bufmap_page_array[i]);
     }
 
     /* build a list of available descriptors */
-    for(offset = 0, i = 0; i < PVFS2_BUFMAP_DESC_COUNT; i++)
+    for(offset = 0, i = 0; i < pvfs2_bufmap_desc_count; i++)
     {
         desc_array[i].page_array = &bufmap_page_array[offset];
-        desc_array[i].array_count = PAGES_PER_DESC;
+        desc_array[i].array_count = pages_per_desc;
         desc_array[i].uaddr =
-            (user_desc->ptr + (i * PAGES_PER_DESC * PAGE_SIZE));
-        offset += PAGES_PER_DESC;
+            (user_desc->ptr + (i * pages_per_desc * PAGE_SIZE));
+        offset += pages_per_desc;
     }
 
     /* clear any previously used buffer indices */
     spin_lock(&buffer_index_lock);
-    for(i = 0; i < PVFS2_BUFMAP_DESC_COUNT; i++)
+    for(i = 0; i < pvfs2_bufmap_desc_count; i++)
     {
         buffer_index_array[i] = 0;
     }
     spin_unlock(&buffer_index_lock);
+    spin_lock(&readdir_index_lock);
+    for (i = 0; i < PVFS2_READDIR_DEFAULT_DESC_COUNT; i++)
+    {
+        readdir_index_array[i] = 0;
+    }
+    spin_unlock(&readdir_index_lock);
 
     bufmap_init = 1;
 
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: exiting normally\n");
     return 0;
 
-  init_failure:
-
+init_failure:
+    finalize_bufmap_descriptors();
     return ret;
 }
 
@@ -183,7 +277,7 @@ void pvfs_bufmap_finalize(void)
         return;
     }
 
-    for(i = 0; i < BUFMAP_PAGE_COUNT; i++)
+    for(i = 0; i < bufmap_page_count; i++)
     {
         pvfs2_clear_page_reserved(bufmap_page_array[i]);
         page_cache_release(bufmap_page_array[i]);
@@ -192,6 +286,7 @@ void pvfs_bufmap_finalize(void)
 
     bufmap_init = 0;
 
+    finalize_bufmap_descriptors();
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: exiting normally\n");
 }
 
@@ -281,7 +376,7 @@ int pvfs_bufmap_get(int *buffer_index)
 {
     struct slot_args slargs;
 
-    slargs.slot_count = PVFS2_BUFMAP_DESC_COUNT;
+    slargs.slot_count = pvfs2_bufmap_desc_count;
     slargs.slot_array = buffer_index_array;
     slargs.slot_lock  = &buffer_index_lock;
     slargs.slot_wq    = &bufmap_waitq;
@@ -298,7 +393,7 @@ void pvfs_bufmap_put(int buffer_index)
 {
     struct slot_args slargs;
 
-    slargs.slot_count = PVFS2_BUFMAP_DESC_COUNT;
+    slargs.slot_count = pvfs2_bufmap_desc_count;
     slargs.slot_array = buffer_index_array;
     slargs.slot_lock  = &buffer_index_lock;
     slargs.slot_wq    = &bufmap_waitq;
@@ -320,7 +415,7 @@ int readdir_index_get(int *buffer_index)
 {
     struct slot_args slargs;
 
-    slargs.slot_count = PVFS2_READDIR_DESC_COUNT;
+    slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
     slargs.slot_array = readdir_index_array;
     slargs.slot_lock  = &readdir_index_lock;
     slargs.slot_wq    = &readdir_waitq;
@@ -331,7 +426,7 @@ void readdir_index_put(int buffer_index)
 {
     struct slot_args slargs;
 
-    slargs.slot_count = PVFS2_READDIR_DESC_COUNT;
+    slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
     slargs.slot_array = readdir_index_array;
     slargs.slot_lock  = &readdir_index_lock;
     slargs.slot_wq    = &readdir_waitq;

Index: devpvfs2-req.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/devpvfs2-req.c,v
diff -p -u -r1.65.2.1 -r1.65.2.2
--- devpvfs2-req.c	25 Sep 2006 12:39:57 -0000	1.65.2.1
+++ devpvfs2-req.c	13 Jan 2007 10:16:55 -0000	1.65.2.2
@@ -544,6 +544,18 @@ static ssize_t pvfs2_devreq_writev(
     return count;
 }
 
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+/*
+ * Kernels >= 2.6.19 have no writev, use this instead with SYNC_KEY.
+ */
+static ssize_t pvfs2_devreq_aio_write(struct kiocb *kiocb,
+                                      const struct iovec *iov,
+                                      unsigned long count, loff_t offset)
+{
+    return pvfs2_devreq_writev(kiocb->ki_filp, iov, count, &kiocb->ki_pos);
+}
+#endif
+
 /* Returns whether any FS are still pending remounted */
 static int mark_all_pending_mounts(void)
 {
@@ -775,7 +787,9 @@ static int pvfs2_devreq_ioctl(
 struct PVFS_dev_map_desc32 
 {
     compat_uptr_t ptr;
+    int32_t      total_size;
     int32_t      size;
+    int32_t      count;
 };
 
 #ifndef PVFS2_LINUX_KERNEL_2_4
@@ -794,9 +808,13 @@ static unsigned long translate_dev_map26
     /* try to put that into a 64-bit layout */
     if (put_user(compat_ptr(addr), &p->ptr))
         goto err;
-    /* copy the remaining field */
+    /* copy the remaining fields */
+    if (copy_in_user(&p->total_size, &p32->total_size, sizeof(int32_t)))
+        goto err;
     if (copy_in_user(&p->size, &p32->size, sizeof(int32_t)))
         goto err;
+    if (copy_in_user(&p->count, &p32->count, sizeof(int32_t)))
+        goto err;
     return (unsigned long) p;
 err:
     *error = -EFAULT;
@@ -807,17 +825,23 @@ static unsigned long translate_dev_map24
         unsigned long args, struct PVFS_dev_map_desc *p, long *error)
 {
     struct PVFS_dev_map_desc32  __user *p32 = (void __user *) args;
-    u32 addr, size;
+    u32 addr, size, total_size, count;
 
     *error = 0;
     /* get the ptr from the 32 bit user-space */
     if (get_user(addr, &p32->ptr))
         goto err;
     p->ptr = compat_ptr(addr);
-    /* copy the size */
+    /* copy the remaining fields */
+    if (get_user(total_size, &p32->total_size))
+        goto err;
     if (get_user(size, &p32->size))
         goto err;
+    if (get_user(count, &p32->count))
+        goto err;
+    p->total_size = total_size;
     p->size = size;
+    p->count = count;
     return 0;
 err:
     *error = -EFAULT;
@@ -1003,7 +1027,11 @@ struct file_operations pvfs2_devreq_file
     poll : pvfs2_devreq_poll
 #else
     .read = pvfs2_devreq_read,
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+    .aio_write = pvfs2_devreq_aio_write,
+#else
     .writev = pvfs2_devreq_writev,
+#endif
     .open = pvfs2_devreq_open,
     .release = pvfs2_devreq_release,
     .ioctl = pvfs2_devreq_ioctl,

Index: pvfs2-cache.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-cache.c,v
diff -p -u -r1.33.2.1 -r1.33.2.2
--- pvfs2-cache.c	25 Sep 2006 12:39:58 -0000	1.33.2.1
+++ pvfs2-cache.c	13 Jan 2007 10:16:55 -0000	1.33.2.2
@@ -27,6 +27,17 @@ static kmem_cache_t *pvfs2_inode_cache =
 static kmem_cache_t *pvfs2_kiocb_cache = NULL;
 #endif
 
+#ifdef HAVE_KMEM_CACHE_DESTROY_INT_RETURN
+#define pvfs_kmem_cache_destroy kmem_cache_destroy
+#else
+/* recent kernels do not return a value */
+static int pvfs_kmem_cache_destroy(void *x)
+{
+    kmem_cache_destroy(x);
+    return 0;
+}
+#endif
+
 int op_cache_initialize(void)
 {
     op_cache = kmem_cache_create(
@@ -48,7 +59,7 @@ int op_cache_initialize(void)
 
 int op_cache_finalize(void)
 {
-    if (kmem_cache_destroy(op_cache) != 0)
+    if (pvfs_kmem_cache_destroy(op_cache) != 0)
     {
         gossip_err("Failed to destroy pvfs2_op_cache\n");
         return -EINVAL;
@@ -212,7 +223,7 @@ int dev_req_cache_initialize(void)
 
 int dev_req_cache_finalize(void)
 {
-    if (kmem_cache_destroy(dev_req_cache) != 0)
+    if (pvfs_kmem_cache_destroy(dev_req_cache) != 0)
     {
         gossip_err("Failed to destroy pvfs2_devreqcache\n");
         return -EINVAL;
@@ -336,7 +347,7 @@ int pvfs2_inode_cache_finalize(void)
             kmem_cache_free(pvfs2_inode_cache, pinode);
         }
     }
-    if (kmem_cache_destroy(pvfs2_inode_cache) != 0)
+    if (pvfs_kmem_cache_destroy(pvfs2_inode_cache) != 0)
     {
         gossip_err("Failed to destroy pvfs2_inode_cache\n");
         return -EINVAL;
@@ -413,7 +424,7 @@ int kiocb_cache_initialize(void)
 
 int kiocb_cache_finalize(void)
 {
-    if (kmem_cache_destroy(pvfs2_kiocb_cache) != 0)
+    if (pvfs_kmem_cache_destroy(pvfs2_kiocb_cache) != 0)
     {
         gossip_err("Failed to destroy pvfs2_devreqcache\n");
         return -EINVAL;



More information about the Pvfs2-cvs mailing list