[Pvfs2-cvs] commit by kunkel in pvfs2/src/kernel/linux-2.6: pvfs2-mod.c downcall.h inode.c acl.c dir.c pvfs2-cache.c pvfs2-proc.c namei.c upcall.h pvfs2-bufmap.h file.c super.c devpvfs2-req.c pvfs2-kernel.h pvfs2-bufmap.c

CVS commit program cvs at parl.clemson.edu
Wed May 23 16:48:20 EDT 2007


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

Modified Files:
      Tag: pvfs2-kunkel-tas-branch
	pvfs2-mod.c downcall.h inode.c acl.c dir.c pvfs2-cache.c 
	pvfs2-proc.c namei.c upcall.h pvfs2-bufmap.h file.c super.c 
	devpvfs2-req.c pvfs2-kernel.h pvfs2-bufmap.c 
Log Message:
Merge HEAD changes to TAS-branch.


Index: pvfs2-mod.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-mod.c,v
diff -p -u -r1.35 -r1.35.6.1
--- pvfs2-mod.c	13 Sep 2006 20:22:55 -0000	1.35
+++ pvfs2-mod.c	23 May 2007 20:48:19 -0000	1.35.6.1
@@ -31,6 +31,7 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("PVFS2 Development Team");
 MODULE_DESCRIPTION("The Linux Kernel VFS interface to PVFS2");
 MODULE_PARM_DESC(debug, "debugging level (0 for none, 1 for verbose)");
+MODULE_PARM_DESC(op_timeout_secs, "Operation timeout in seconds");
 MODULE_PARM_DESC(hash_table_size, "size of hash table for operations in progress");
 
 #ifdef PVFS2_LINUX_KERNEL_2_4

Index: downcall.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/downcall.h,v
diff -p -u -r1.28 -r1.28.6.1
--- downcall.h	13 Sep 2006 20:22:55 -0000	1.28
+++ downcall.h	23 May 2007 20:48:19 -0000	1.28.6.1
@@ -78,7 +78,6 @@ struct pvfs2_dirent
 typedef struct
 {
     PVFS_ds_position token;
-    uint32_t  __pad1;
     uint64_t directory_version;
     uint32_t  __pad2;
     uint32_t pvfs_dirent_outcount;
@@ -89,7 +88,6 @@ typedef struct
 typedef struct
 {
     PVFS_ds_position token;
-    uint32_t  __pad1;
     uint64_t directory_version;
     uint32_t  __pad2;
     uint32_t pvfs_dirent_outcount;
@@ -146,10 +144,11 @@ typedef struct {
 
 typedef struct {
     int32_t  returned_count;
+    int32_t __pad1;
     PVFS_ds_position token;
     char key[PVFS_MAX_XATTR_LISTLEN*PVFS_MAX_XATTR_NAMELEN];
     int32_t  keylen;
-    int32_t  __pad1;
+    int32_t  __pad2;
     int32_t  lengths[PVFS_MAX_XATTR_LISTLEN];
 } pvfs2_listxattr_response_t;
 /* the removexattr response is a blank downcall */

Index: inode.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/inode.c,v
diff -p -u -r1.76 -r1.76.2.1
--- inode.c	20 Oct 2006 19:02:36 -0000	1.76
+++ inode.c	23 May 2007 20:48:19 -0000	1.76.2.1
@@ -167,7 +167,7 @@ void pvfs2_truncate(struct inode *inode)
     gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2: pvfs2_truncate called on inode %llu "
                 "with size %ld\n", llu(get_handle_from_ino(inode)), (long) orig_size);
 
-    /* successful truncate when size changes also requires mtime updates 
+    /* successful truncate when size changes also requires mtime updates
      * although the mtime updates are propagated lazily!
      */
     if (pvfs2_truncate_inode(inode, inode->i_size) == 0
@@ -293,9 +293,9 @@ int pvfs2_getattr_lite(
     gossip_debug(GOSSIP_INODE_DEBUG, "pvfs2_getattr_lite: called on %s\n", dentry->d_name.name);
 
     /*
-     * ->getattr_lite needs to refresh only certain fields 
+     * ->getattr_lite needs to refresh only certain fields
      * of the inode and that is indicated by the lite_mask
-     * field of kstat_lite structure. 
+     * field of kstat_lite structure.
      */
     mask = convert_to_pvfs2_mask(kstat_lite->lite_mask);
     ret = pvfs2_inode_getattr(inode, mask);
@@ -321,7 +321,7 @@ struct inode_operations pvfs2_file_inode
     setattr : pvfs2_setattr,
     revalidate : pvfs2_revalidate,
 #ifdef HAVE_XATTR
-    setxattr : pvfs2_setxattr, 
+    setxattr : pvfs2_setxattr,
     getxattr : pvfs2_getxattr,
     removexattr: pvfs2_removexattr,
     listxattr: pvfs2_listxattr,
@@ -367,15 +367,20 @@ static inline ino_t pvfs2_handle_hash(PV
 }
 
 /* the ->set callback of iget5_locked and friends. Sorta equivalent to the ->read_inode()
- * callback if we are using iget and friends 
+ * callback if we are using iget and friends
  */
-static int pvfs2_set_inode(struct inode *inode, void *data)
+int pvfs2_set_inode(struct inode *inode, void *data)
 {
     /* callbacks to set inode number handle */
     PVFS_object_ref *ref = (PVFS_object_ref *) data;
     pvfs2_inode_t *pvfs2_inode = NULL;
 
+    /* Make sure that we have sane parameters */
+    if (!data || !inode)
+        return 0;
     pvfs2_inode = PVFS2_I(inode);
+    if (!pvfs2_inode)
+        return 0;
     pvfs2_inode_initialize(pvfs2_inode);
     pvfs2_inode->refn.fs_id  = ref->fs_id;
     pvfs2_inode->refn.handle = ref->handle;
@@ -386,7 +391,7 @@ static int pvfs2_set_inode(struct inode 
 static int
 pvfs2_test_inode(struct inode *inode, void *data)
 #elif defined(HAVE_IGET4_LOCKED)
-static int 
+static int
 pvfs2_test_inode(struct inode *inode, unsigned long ino, void *data)
 #endif
 {
@@ -412,7 +417,7 @@ pvfs2_test_inode(struct inode *inode, un
  * @keep_locked : indicates whether the inode must be simply allocated and not filled
  * in with the results from a ->getattr. i.e. if keep_locked is set to 0, we do a getattr() and
  * unlock the inode and if set to 1, we do not issue a getattr() and keep it locked
- * 
+ *
  * Boy, this function is so ugly with all these macros. I wish I could find a better
  * way to reduce the macro clutter.
  */
@@ -443,6 +448,21 @@ struct inode *pvfs2_iget_common(struct s
         if (inode && (inode->i_state & I_NEW))
         {
             inode->i_ino = hash; /* needed for stat etc */
+            /* iget4_locked and iget_locked dont invoke the set_inode callback.
+             * So we work around that by stashing the pvfs object reference
+             * in the inode specific private part for 2.4 kernels and invoking
+             * the setcallback explicitly for 2.6 kernels.
+             */
+#if defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED)
+            if (PVFS2_I(inode)) {
+                pvfs2_set_inode(inode, ref);
+            }
+            else {
+#ifdef PVFS2_LINUX_KERNEL_2_4
+                inode->u.generic_ip = (void *) ref;
+#endif
+            }
+#endif
             /* issue a call to read the inode */
             sb->s_op->read_inode(inode);
             unlock_new_inode(inode);
@@ -483,6 +503,35 @@ struct inode *pvfs2_get_custom_inode(
         }
 
         inode->i_mode = mode;
+        /*
+         * Since we are using the same function to create a new on-disk object
+         * as well as to create an in-memory object, the mode of the object
+         * needs to be set carefully. If we are called from a function that is
+         * creating a new on-disk object, set its mode here since the caller is
+         * providing it. Else let it be since the getattr should fill it up
+         * properly.
+         */
+        if (from_create)
+        {
+            /* the exception is when we are creating a directory that needs
+             * to inherit the setgid bit.  That much we need to preserve from
+             * the getattr's view of the mode.
+             */
+            if(inode->i_mode & S_ISGID)
+            {
+                gossip_debug(GOSSIP_INODE_DEBUG,
+                    "pvfs2_get_custom_inode_commmon: setting SGID bit.\n");
+                inode->i_mode = mode | S_ISGID;
+            }
+            else
+            {
+                inode->i_mode = mode;
+            }
+        }
+        gossip_debug(GOSSIP_INODE_DEBUG,
+                "pvfs2_get_custom_inode_common: inode: %p, inode->i_mode %o\n",
+                inode, inode->i_mode);
+>>>>>>> 1.79
         inode->i_mapping->host = inode;
         inode->i_uid = current->fsuid;
         inode->i_gid = current->fsgid;
@@ -534,7 +583,7 @@ struct inode *pvfs2_get_custom_inode(
             goto error;
 	}
 #if !defined(PVFS2_LINUX_KERNEL_2_4) && defined(HAVE_GENERIC_GETXATTR) && defined(CONFIG_FS_POSIX_ACL)
-        gossip_debug(GOSSIP_ACL_DEBUG, "Initializing ACL's for inode %llu\n", 
+        gossip_debug(GOSSIP_ACL_DEBUG, "Initializing ACL's for inode %llu\n",
                 llu(get_handle_from_ino(inode)));
         /* Initialize the ACLs of the new inode */
         pvfs2_init_acl(inode, dir);

Index: acl.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/acl.c,v
diff -p -u -r1.24 -r1.24.4.1
--- acl.c	20 Sep 2006 22:59:53 -0000	1.24
+++ acl.c	23 May 2007 20:48:19 -0000	1.24.4.1
@@ -612,10 +612,15 @@ int pvfs2_acl_chmod(struct inode *inode)
         goto out;
     }
     acl = pvfs2_get_acl(inode, ACL_TYPE_ACCESS);
-    if (IS_ERR(acl) || !acl)
+    if (IS_ERR(acl))
     {
         error = PTR_ERR(acl);
         gossip_err("pvfs2_acl_chmod: get acl (access) failed with %d\n", error);
+        goto out;
+    }
+    if(!acl)
+    {
+        error = 0;
         goto out;
     }
     clone = posix_acl_clone(acl, GFP_KERNEL);

Index: dir.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/dir.c,v
diff -p -u -r1.46 -r1.46.2.1
--- dir.c	10 Oct 2006 16:36:56 -0000	1.46
+++ dir.c	23 May 2007 20:48:19 -0000	1.46.2.1
@@ -15,7 +15,7 @@
 #include "pvfs2-sysint.h"
 #include "pvfs2-internal.h"
 
-typedef struct 
+typedef struct
 {
     int buffer_index;
     pvfs2_readdir_response_t readdir_response;
@@ -23,7 +23,7 @@ typedef struct 
 } readdir_handle_t;
 
 /* decode routine needed by kmod to make sense of the shared page for readdirs */
-static long decode_dirents(char *ptr, pvfs2_readdir_response_t *readdir) 
+static long decode_dirents(char *ptr, pvfs2_readdir_response_t *readdir)
 {
     int i;
     pvfs2_readdir_response_t *rd = (pvfs2_readdir_response_t *) ptr;
@@ -33,7 +33,7 @@ static long decode_dirents(char *ptr, pv
     readdir->token = rd->token;
     readdir->directory_version = rd->directory_version;
     readdir->pvfs_dirent_outcount = rd->pvfs_dirent_outcount;
-    readdir->dirent_array = (struct pvfs2_dirent *) 
+    readdir->dirent_array = (struct pvfs2_dirent *)
             kmalloc(readdir->pvfs_dirent_outcount * sizeof(struct pvfs2_dirent), GFP_KERNEL);
     if (readdir->dirent_array == NULL)
     {
@@ -130,7 +130,7 @@ static int pvfs2_readdir(
     /* are we done? */
     if (pos == PVFS_READDIR_END)
     {
-        gossip_debug(GOSSIP_DIR_DEBUG, 
+        gossip_debug(GOSSIP_DIR_DEBUG,
                      "Skipping to graceful termination "
                      "path since we are done\n");
         pvfs2_inode->directory_version = 0;
@@ -150,9 +150,13 @@ static int pvfs2_readdir(
     case 0:
         token_set = 1;
         if (pvfs2_inode->directory_version == 0)
+            ino = get_ino_from_handle(dentry->d_inode);
+        gossip_debug(GOSSIP_DIR_DEBUG,
+                     "calling filldir of . with pos = %llu\n", llu(pos));
+        if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
         {
             ino = get_ino_from_handle(dentry->d_inode);
-            gossip_debug(GOSSIP_DIR_DEBUG, 
+            gossip_debug(GOSSIP_DIR_DEBUG,
                          "calling filldir of . with pos = %d\n", pos);
             if (filldir(dirent, ".", 1, pos, ino, DT_DIR) < 0)
             {
@@ -165,9 +169,13 @@ static int pvfs2_readdir(
     case 1:
         token_set = 1;
         if (pvfs2_inode->directory_version == 0)
+            ino = get_parent_ino_from_dentry(dentry);
+        gossip_debug(GOSSIP_DIR_DEBUG,
+                     "calling filldir of .. with pos = %llu\n", llu(pos));
+        if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
         {
             ino = get_parent_ino_from_dentry(dentry);
-            gossip_debug(GOSSIP_DIR_DEBUG, 
+            gossip_debug(GOSSIP_DIR_DEBUG,
                          "calling filldir of .. with pos = %d\n", pos);
             if (filldir(dirent, "..", 2, pos, ino, DT_DIR) < 0)
             {
@@ -230,7 +238,7 @@ static int pvfs2_readdir(
         new_op->upcall.req.readdir.buf_index = buffer_index;
 
         ret = service_operation(
-            new_op, "pvfs2_readdir", 
+            new_op, "pvfs2_readdir",
             get_interruptible_flag(dentry->d_inode));
 
 	gossip_debug(GOSSIP_DIR_DEBUG, "Readdir downcall status is %d\n",
@@ -243,7 +251,7 @@ static int pvfs2_readdir(
             char *current_entry = NULL;
             long bytes_decoded;
 
-            if ((bytes_decoded = readdir_handle_ctor(&rhandle, 
+            if ((bytes_decoded = readdir_handle_ctor(&rhandle,
                                                      new_op->downcall.trailer_buf,
                                                      buffer_index)) < 0)
             {
@@ -281,7 +289,7 @@ static int pvfs2_readdir(
                 current_ino = pvfs2_handle_to_ino(
                     rhandle.readdir_response.dirent_array[i].handle);
 
-                gossip_debug(GOSSIP_DIR_DEBUG, 
+                gossip_debug(GOSSIP_DIR_DEBUG,
                              "calling filldir for %s with len %d, pos %ld\n",
                              current_entry, len, (unsigned long) pos);
                 if (filldir(dirent, current_entry, len, pos,
@@ -295,23 +303,24 @@ graceful_termination_path:
                 file->f_pos++;
                 pos++;
             }
-            /* For the first time around, use the token 
+            /* For the first time around, use the token
              * returned by the readdir response */
-            if (token_set == 1) 
+            if (token_set == 1)
             {
                 if (i == rhandle.readdir_response.pvfs_dirent_outcount)
                     file->f_pos = rhandle.readdir_response.token;
-                else 
+                else
                     file->f_pos = i;
             }
-            gossip_debug(GOSSIP_DIR_DEBUG, 
-                         "pos = %d, file->f_pos should have been %ld\n", pos, 
+            gossip_debug(GOSSIP_DIR_DEBUG,
+                         "pos = %llu, file->f_pos should have been %ld\n",
+                         llu(pos),
                          (unsigned long) file->f_pos);
         }
         else
         {
             readdir_index_put(buffer_index);
-            gossip_debug(GOSSIP_DIR_DEBUG, 
+            gossip_debug(GOSSIP_DIR_DEBUG,
                          "Failed to readdir (downcall status %d)\n",
                          new_op->downcall.status);
         }
@@ -324,8 +333,8 @@ err:
 
     if (ret == 0)
     {
-        gossip_debug(GOSSIP_DIR_DEBUG, 
-                     "pvfs2_readdir about to update_atime %p\n", 
+        gossip_debug(GOSSIP_DIR_DEBUG,
+                     "pvfs2_readdir about to update_atime %p\n",
                      dentry->d_inode);
 
         SetAtimeFlag(pvfs2_inode);
@@ -356,20 +365,20 @@ typedef struct
     } u;
 } readdirplus_info_t;
 
-typedef struct 
+typedef struct
 {
     int buffer_index;
     pvfs2_readdirplus_response_t readdirplus_response;
     void *dentsplus_buf;
 } readdirplus_handle_t;
 
-static long decode_sys_attr(char *ptr, pvfs2_readdirplus_response_t *readdirplus) 
+static long decode_sys_attr(char *ptr, pvfs2_readdirplus_response_t *readdirplus)
 {
     int i;
     char *buf = (char *) ptr;
     char **pptr = &buf;
 
-    readdirplus->stat_err_array = (PVFS_error *) 
+    readdirplus->stat_err_array = (PVFS_error *)
         kmalloc(readdirplus->pvfs_dirent_outcount * sizeof(PVFS_error), GFP_KERNEL);
     if (readdirplus->stat_err_array == NULL)
     {
@@ -377,11 +386,11 @@ static long decode_sys_attr(char *ptr, p
     }
     memcpy(readdirplus->stat_err_array, buf, readdirplus->pvfs_dirent_outcount * sizeof(PVFS_error));
     *pptr += readdirplus->pvfs_dirent_outcount * sizeof(PVFS_error);
-    if (readdirplus->pvfs_dirent_outcount % 2) 
+    if (readdirplus->pvfs_dirent_outcount % 2)
     {
         *pptr += 4;
     }
-    readdirplus->attr_array = (PVFS_sys_attr *) 
+    readdirplus->attr_array = (PVFS_sys_attr *)
         kmalloc(readdirplus->pvfs_dirent_outcount * sizeof(PVFS_sys_attr), GFP_KERNEL);
     if (readdirplus->attr_array == NULL)
     {
@@ -556,7 +565,7 @@ static int pvfs2_readdirplus_common(
                             break;
                         }
                     }
-                    else 
+                    else
                     {
                         if (filldirplus_lite(direntplus, ".", 1, pos, ino, DT_DIR, &info->u.plus_lite.ks) < 0)
                         {
@@ -579,7 +588,7 @@ static int pvfs2_readdirplus_common(
                 ref.fs_id = get_fsid_from_ino(dentry->d_parent->d_inode);
                 ref.handle = get_handle_from_ino(dentry->d_parent->d_inode);
                 inode = pvfs2_iget(dentry->d_inode->i_sb, &ref);
-                if (inode) 
+                if (inode)
                 {
                     if (info->lite == 0)
                     {
@@ -664,7 +673,7 @@ static int pvfs2_readdirplus_common(
             new_op->upcall.req.readdirplus.buf_index = buffer_index;
 
             ret = service_operation(
-                new_op, "pvfs2_readdirplus", 
+                new_op, "pvfs2_readdirplus",
                 get_interruptible_flag(dentry->d_inode));
 
             gossip_debug(GOSSIP_DIR_DEBUG, "Readdirplus downcall status is %d\n",
@@ -784,19 +793,19 @@ static int pvfs2_readdirplus_common(
                         {
                             ptr = &info->u.plus_lite.ks;
                         }
-                        if (attrs->objtype == PVFS_TYPE_METAFILE) 
+                        if (attrs->objtype == PVFS_TYPE_METAFILE)
                         {
                             dt_type = DT_REG;
                         }
-                        else if (attrs->objtype == PVFS_TYPE_DIRECTORY) 
+                        else if (attrs->objtype == PVFS_TYPE_DIRECTORY)
                         {
                             dt_type = DT_DIR;
                         }
-                        else if (attrs->objtype == PVFS_TYPE_SYMLINK) 
+                        else if (attrs->objtype == PVFS_TYPE_SYMLINK)
                         {
                             dt_type = DT_LNK;
                         }
-                        else 
+                        else
                         {
                             dt_type = DT_UNKNOWN;
                         }
@@ -807,16 +816,16 @@ static int pvfs2_readdirplus_common(
                         dt_type = DT_UNKNOWN;
                     }
                     gossip_debug(GOSSIP_DIR_DEBUG, "calling filldirplus for %s "
-                            " (%lu) with len %d, pos %ld kstat %p\n", 
+                            " (%lu) with len %d, pos %ld kstat %p\n",
                             current_entry, (unsigned long) handle,
                             len, (unsigned long) pos, ptr);
-                    
+
                     if (info->lite == 0)
                     {
                         ret = filldirplus(direntplus, current_entry, len, pos,
                                 current_ino, dt_type, ptr);
                     }
-                    else 
+                    else
                     {
                         ret = filldirplus_lite(direntplus, current_entry, len, pos,
                                 current_ino, dt_type, ptr);
@@ -840,7 +849,7 @@ graceful_termination_path:
                     else
                         file->f_pos = i;
                 }
-                gossip_debug(GOSSIP_DIR_DEBUG, "pos = %d, file->f_pos is %ld\n", pos, 
+                gossip_debug(GOSSIP_DIR_DEBUG, "pos = %d, file->f_pos is %ld\n", pos,
                         (unsigned long) file->f_pos);
             }
             else
@@ -867,7 +876,7 @@ err:
     return ret;
 }
 
-/** Read directory entries from an instance of an open directory 
+/** Read directory entries from an instance of an open directory
  *  and the associated attributes for every entry in one-shot.
  *
  * \param filldirplus callback function called for each entry read.
@@ -893,7 +902,7 @@ static int pvfs2_readdirplus(
     return pvfs2_readdirplus_common(file, &info);
 }
 
-/** Read directory entries from an instance of an open directory 
+/** Read directory entries from an instance of an open directory
  *  and the associated attributes for every entry in one-shot.
  *
  * \param filldirplus_lite callback function called for each entry read.

Index: pvfs2-cache.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-cache.c,v
diff -p -u -r1.36 -r1.36.4.1
--- pvfs2-cache.c	20 Sep 2006 22:59:53 -0000	1.36
+++ pvfs2-cache.c	23 May 2007 20:48:19 -0000	1.36.4.1
@@ -16,15 +16,32 @@ static spinlock_t next_tag_value_lock = 
 
 /* the pvfs2 memory caches */
 
+#ifdef HAVE_STRUCT_KMEM_CACHE
+typedef struct kmem_cache pvfs2_kmem_cache_t;
+#else
+typedef kmem_cache_t pvfs2_kmem_cache_t;
+#endif
+
 /* a cache for pvfs2 upcall/downcall operations */
-static kmem_cache_t *op_cache = NULL;
+static pvfs2_kmem_cache_t *op_cache = NULL;
 /* a cache for device (/dev/pvfs2-req) communication */
-static kmem_cache_t *dev_req_cache = NULL;
+static pvfs2_kmem_cache_t *dev_req_cache = NULL;
 /* a cache for pvfs2-inode objects (i.e. pvfs2 inode private data) */
-static kmem_cache_t *pvfs2_inode_cache = NULL;
+static pvfs2_kmem_cache_t *pvfs2_inode_cache = NULL;
 #ifdef HAVE_AIO_VFS_SUPPORT
 /* a cache for pvfs2_kiocb objects (i.e pvfs2 iocb structures ) */
-static kmem_cache_t *pvfs2_kiocb_cache = NULL;
+static pvfs2_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)
@@ -48,7 +65,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;
@@ -183,7 +200,7 @@ void op_release(pvfs2_kernel_op_t *pvfs2
 
 static void dev_req_cache_ctor(
     void *req,
-    kmem_cache_t * cachep,
+    pvfs2_kmem_cache_t * cachep,
     unsigned long flags)
 {
     if (flags & SLAB_CTOR_CONSTRUCTOR)
@@ -212,7 +229,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;
@@ -247,7 +264,7 @@ void dev_req_release(void *buffer)
 
 static void pvfs2_inode_cache_ctor(
     void *new_pvfs2_inode,
-    kmem_cache_t * cachep,
+    pvfs2_kmem_cache_t * cachep,
     unsigned long flags)
 {
     pvfs2_inode_t *pvfs2_inode = (pvfs2_inode_t *)new_pvfs2_inode;
@@ -281,7 +298,7 @@ static void pvfs2_inode_cache_ctor(
 
 static void pvfs2_inode_cache_dtor(
     void *old_pvfs2_inode,
-    kmem_cache_t * cachep,
+    pvfs2_kmem_cache_t * cachep,
     unsigned long flags)
 {
     pvfs2_inode_t *pvfs2_inode = (pvfs2_inode_t *)old_pvfs2_inode;
@@ -336,7 +353,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;
@@ -383,7 +400,7 @@ void pvfs2_inode_release(pvfs2_inode_t *
 
 static void kiocb_ctor(
     void *req,
-    kmem_cache_t * cachep,
+    pvfs2_kmem_cache_t * cachep,
     unsigned long flags)
 {
     if (flags & SLAB_CTOR_CONSTRUCTOR)
@@ -413,7 +430,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;

Index: pvfs2-proc.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-proc.c,v
diff -p -u -r1.6 -r1.6.16.1
--- pvfs2-proc.c	10 Aug 2006 19:02:24 -0000	1.6
+++ pvfs2-proc.c	23 May 2007 20:48:20 -0000	1.6.16.1
@@ -260,74 +260,190 @@ static struct pvfs2_param_extra perf_res
 };
 static int min_debug[] = {0}, max_debug[] = {GOSSIP_MAX_DEBUG};
 static int min_op_timeout_secs[] = {0}, max_op_timeout_secs[] = {INT_MAX};
+
 static ctl_table pvfs2_acache_table[] = {
     /* controls acache timeout */
-    {1, "timeout-msecs", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &acache_timeout_extra, NULL},
+    {
+        .ctl_name = 1,
+        .procname = "timeout-msecs",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &acache_timeout_extra
+    },
     /* controls acache hard limit */
-    {2, "hard-limit", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &acache_hard_extra, NULL},
+    {
+        .ctl_name = 2,
+        .procname = "hard-limit",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &acache_hard_extra
+    },
     /* controls acache soft limit */
-    {3, "soft-limit", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &acache_soft_extra, NULL},
+    {
+        .ctl_name = 3,
+        .procname = "soft-limit",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &acache_soft_extra
+    },
     /* controls acache reclaim percentage */
-    {4, "reclaim-percentage", NULL, sizeof(int), 
-        0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &acache_rec_extra, NULL},
+    {
+        .ctl_name = 4,
+        .procname = "reclaim-percentage",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &acache_rec_extra,
+    },
     {0}
 };
 static ctl_table pvfs2_ncache_table[] = {
     /* controls ncache timeout */
-    {1, "timeout-msecs", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &ncache_timeout_extra, NULL},
+    {
+        .ctl_name = 1,
+        .procname = "timeout-msecs",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &ncache_timeout_extra
+    },
     /* controls ncache hard limit */
-    {2, "hard-limit", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &ncache_hard_extra, NULL},
+    {
+        .ctl_name = 2,
+        .procname = "hard-limit",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &ncache_hard_extra
+    },
     /* controls ncache soft limit */
-    {3, "soft-limit", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &ncache_soft_extra, NULL},
+    {
+        .ctl_name = 3,
+        .procname = "soft-limit",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &ncache_soft_extra
+    },
     /* controls ncache reclaim percentage */
-    {4, "reclaim-percentage", NULL, sizeof(int), 
-        0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &ncache_rec_extra, NULL},
+    {
+        .ctl_name = 4,
+        .procname = "reclaim-percentage",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &ncache_rec_extra
+    },
     {0}
 };
 static int acache_perf_count = PVFS2_PERF_COUNT_REQUEST_ACACHE;
 static int ncache_perf_count = PVFS2_PERF_COUNT_REQUEST_NCACHE;
 static ctl_table pvfs2_pc_table[] = {
-    {1, "acache", NULL, 4096, 0444, NULL,
-        pvfs2_pc_proc_handler, NULL, NULL, &acache_perf_count, NULL},
-    {2, "ncache", NULL, 4096, 0444, NULL,
-        pvfs2_pc_proc_handler, NULL, NULL, &ncache_perf_count, NULL},
+    {
+        .ctl_name = 1,
+        .procname = "acache",
+        .maxlen = 4096,
+        .mode = 0444,
+        .proc_handler = pvfs2_pc_proc_handler,
+        .extra1 = &acache_perf_count,
+    },
+    {
+        .ctl_name = 2,
+        .procname = "ncache",
+        .maxlen = 4096,
+        .mode = 0444,
+        .proc_handler = pvfs2_pc_proc_handler,
+        .extra1 = &ncache_perf_count
+    },
     {0}
 };
 static ctl_table pvfs2_table[] = {
     /* controls debugging level */
-    {1, "debug", &gossip_debug_mask, sizeof(int), 0644, NULL,
-        &proc_dointvec_minmax, &sysctl_intvec,
-        NULL, &min_debug, &max_debug},
+    {
+        .ctl_name = 1,
+        .procname = "debug",
+        .data = &gossip_debug_mask,
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &proc_dointvec_minmax, 
+        .strategy = &sysctl_intvec,
+        .extra1 = &min_debug,
+        .extra2 = &max_debug
+    },
     /* operation timeout */
-    {2, "op-timeout-secs", &op_timeout_secs, sizeof(int), 0644, NULL,
-        &proc_dointvec_minmax, &sysctl_intvec,
-        NULL, &min_op_timeout_secs, &max_op_timeout_secs},
+    {
+        .ctl_name = 2,
+        .procname = "op-timeout-secs",
+        .data = &op_timeout_secs,
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &proc_dointvec_minmax,
+        .strategy = &sysctl_intvec,
+        .extra1 = &min_op_timeout_secs,
+        .extra2 = &max_op_timeout_secs
+    },
     /* time interval for client side performance counters */
-    {3, "perf-time-interval-secs", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &perf_time_interval_extra, NULL},
+    {
+        .ctl_name = 3,
+        .procname = "perf-time-interval-secs",
+        .maxlen = sizeof(int), 
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &perf_time_interval_extra
+    },
     /* time interval for client side performance counters */
-    {4, "perf-history-size", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &perf_history_size_extra, NULL},
+    {
+        .ctl_name = 4,
+        .procname = "perf-history-size",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &perf_history_size_extra
+    },
     /* reset performance counters */
-    {5, "perf-counter-reset", NULL, sizeof(int), 0644, NULL,
-        &pvfs2_param_proc_handler, NULL, NULL, &perf_reset_extra, NULL},
+    {
+        .ctl_name = 5,
+        .procname = "perf-counter-reset",
+        .maxlen = sizeof(int),
+        .mode = 0644,
+        .proc_handler = &pvfs2_param_proc_handler,
+        .extra1 = &perf_reset_extra,
+    },
     /* subdir for acache control */
-    {6, "acache", NULL, 0, 0555, pvfs2_acache_table},
-    {7, "perf-counters", NULL, 0, 0555, pvfs2_pc_table},
+    {
+        .ctl_name = 6,
+        .procname = "acache",
+        .maxlen = 0,
+        .mode = 0555,
+        .child = pvfs2_acache_table
+    },
+    {
+        .ctl_name = 7,
+        .procname = "perf-counters",
+        .maxlen = 0,
+        .mode = 0555,
+        .child = pvfs2_pc_table
+    },
     /* subdir for ncache control */
-    {8, "ncache", NULL, 0, 0555, pvfs2_ncache_table},
+    {
+        .ctl_name = 8,
+        .procname = "ncache",
+        .maxlen = 0,
+        .mode = 0555,
+        .child = pvfs2_ncache_table
+    },
     {0}
 };
 static ctl_table fs_table[] = {
-    {1, "pvfs2", NULL, 0, 0555, pvfs2_table},
+    {
+        .ctl_name = 1,
+        .procname = "pvfs2",
+        .mode = 0555,
+        .child = pvfs2_table
+    },
     {0}
 };
 #endif
@@ -337,7 +453,11 @@ void pvfs2_proc_initialize(void)
 #ifdef CONFIG_SYSCTL
     if (!fs_table_header)
     {
+#ifdef HAVE_TWO_ARG_REGISTER_SYSCTL_TABLE
         fs_table_header = register_sysctl_table(fs_table, 0);
+#else
+        fs_table_header = register_sysctl_table(fs_table);
+#endif
     }
 #endif
 

Index: namei.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/namei.c,v
diff -p -u -r1.81 -r1.81.4.1
--- namei.c	20 Sep 2006 22:59:53 -0000	1.81
+++ namei.c	23 May 2007 20:48:20 -0000	1.81.4.1
@@ -158,76 +158,86 @@ static struct dentry *pvfs2_lookup(
                 llu(new_op->downcall.resp.lookup.refn.handle),
                 new_op->downcall.resp.lookup.refn.fs_id, ret);
 
-    /* lookup inode matching name (or add if not there) */
-    if (ret > -1)
+    if(ret < 0)
     {
-	inode = pvfs2_iget(sb, &new_op->downcall.resp.lookup.refn);
-	if (inode && !is_bad_inode(inode))
-	{
-            struct dentry *res;
-
-	    /* update dentry/inode pair into dcache */
-	    dentry->d_op = &pvfs2_dentry_operations;
-
-            res = pvfs2_d_splice_alias(dentry, inode);
-
-            gossip_debug(GOSSIP_NAME_DEBUG, "Lookup success (inode ct = %d)\n",
-                        (int)atomic_read(&inode->i_count));
-            op_release(new_op);
-            if (res) 
-                res->d_op = &pvfs2_dentry_operations;
-            return res;
-	}
-        else if (inode && is_bad_inode(inode))
+        if(ret == -ENOENT)
         {
-            ret = -EACCES;
-	    found_pvfs2_inode = PVFS2_I(inode);
-            /* look for an error code, possibly set by pvfs2_read_inode(),
-             * otherwise we have to guess EACCES 
+            /*
+             * if no inode was found, add a negative dentry to dcache anyway;
+             * if we don't, we don't hold expected lookup semantics and we most
+             * noticeably break during directory renames.
+             *
+             * however, if the operation failed or exited, do not add the
+             * dentry (e.g. in the case that a touch is issued on a file that
+             * already exists that was interrupted during this lookup -- no
+             * need to add another negative dentry for an existing file)
              */
-            if(found_pvfs2_inode->error_code)
-            {
-                ret = found_pvfs2_inode->error_code;
-            }
-            iput(inode);
+
+            gossip_debug(GOSSIP_NAME_DEBUG, 
+                         "pvfs2_lookup: Adding *negative* dentry %p\n for %s\n",
+                         dentry, dentry->d_name.name);
+
+            /*
+             * make sure to set the pvfs2 specific dentry operations for
+             * the negative dentry that we're adding now so that a
+             * potential future lookup of this cached negative dentry can
+             * be properly revalidated.
+             */
+            dentry->d_op = &pvfs2_dentry_operations;
+            d_add(dentry, inode);
+
             op_release(new_op);
-            return ERR_PTR(ret);
+            return NULL;
         }
-	else
-	{
-            op_release(new_op);
-            gossip_debug(GOSSIP_NAME_DEBUG, "Returning -EACCES\n");
-            return ERR_PTR(-EACCES);
-	}
+
+        /* must be a non-recoverable error */
+        return ERR_PTR(ret);
     }
 
-    /*
-      if no inode was found, add a negative dentry to dcache anyway;
-      if we don't, we don't hold expected lookup semantics and we most
-      noticeably break during directory renames.
-
-      however, if the operation failed or exited, do not add the
-      dentry (e.g. in the case that a touch is issued on a file that
-      already exists that was interrupted during this lookup -- no
-      need to add another negative dentry for an existing file)
-    */
-    if (!inode && op_state_serviced(new_op))
+    inode = pvfs2_iget(sb, &new_op->downcall.resp.lookup.refn);
+    if (inode && !is_bad_inode(inode))
     {
-        /*
-          make sure to set the pvfs2 specific dentry operations for
-          the negative dentry that we're adding now so that a
-          potential future lookup of this cached negative dentry can
-          be properly revalidated.
-        */
-        gossip_debug(GOSSIP_NAME_DEBUG, "pvfs2_lookup: Adding *negative* dentry %p\n  "
-                    "for %s\n", dentry, dentry->d_name.name);
+        struct dentry *res;
 
+        /* update dentry/inode pair into dcache */
         dentry->d_op = &pvfs2_dentry_operations;
-        d_add(dentry, inode);
+
+        res = pvfs2_d_splice_alias(dentry, inode);
+
+        gossip_debug(GOSSIP_NAME_DEBUG, "Lookup success (inode ct = %d)\n",
+                     (int)atomic_read(&inode->i_count));
+        if (res)
+            res->d_op = &pvfs2_dentry_operations;
+
+        op_release(new_op);
+#ifdef PVFS2_LINUX_KERNEL_2_4
+        return NULL;
+#else
+        return res;
+#endif
+    }
+    else if (inode && is_bad_inode(inode))
+    {
+        ret = -EACCES;
+        found_pvfs2_inode = PVFS2_I(inode);
+        /* look for an error code, possibly set by pvfs2_read_inode(),
+         * otherwise we have to guess EACCES 
+         */
+        if(found_pvfs2_inode->error_code)
+        {
+            ret = found_pvfs2_inode->error_code;
+        }
+        iput(inode);
+        op_release(new_op);
+        return ERR_PTR(ret);
     }
 
+    /* no error was returned from service_operation, but the inode
+     * from pvfs2_iget was null...just return EACCESS
+     */
     op_release(new_op);
-    return NULL;
+    gossip_debug(GOSSIP_NAME_DEBUG, "Returning -EACCES\n");
+    return ERR_PTR(-EACCES);
 }
 
 /* return 0 on success; non-zero otherwise */

Index: upcall.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/upcall.h,v
diff -p -u -r1.35 -r1.35.6.1
--- upcall.h	13 Sep 2006 20:22:56 -0000	1.35
+++ upcall.h	23 May 2007 20:48:20 -0000	1.35.6.1
@@ -89,7 +89,6 @@ typedef struct
     PVFS_ds_position token;
     int32_t max_dirent_count;
     int32_t buf_index;
-    uint32_t __pad1;
 } pvfs2_readdir_request_t;
 
 typedef struct
@@ -99,6 +98,7 @@ typedef struct
     int32_t max_dirent_count;
     uint32_t mask;
     int32_t  buf_index;
+    int32_t  __pad1;
 } pvfs2_readdirplus_request_t;
 
 typedef struct
@@ -158,6 +158,7 @@ typedef struct 
 {
     PVFS_object_ref refn;
     int32_t  requested_count;
+    int32_t  __pad1;
     PVFS_ds_position token;
 } pvfs2_listxattr_request_t;
 

Index: pvfs2-bufmap.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.h,v
diff -p -u -r1.16 -r1.16.4.1
--- pvfs2-bufmap.h	28 Sep 2006 05:13:41 -0000	1.16
+++ pvfs2-bufmap.h	23 May 2007 20:48:20 -0000	1.16.4.1
@@ -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: file.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/file.c,v
diff -p -u -r1.129 -r1.129.4.1
--- file.c	29 Sep 2006 16:48:13 -0000	1.129
+++ file.c	23 May 2007 20:48:20 -0000	1.129.4.1
@@ -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 {
@@ -151,7 +155,7 @@ struct rw_options {
  * @total_size - total expected size of the I/O operation
  */
 static ssize_t wait_for_io(struct rw_options *rw, struct iovec *vec,
-        int nr_segs, size_t total_size)
+        unsigned long nr_segs, size_t total_size)
 {
     pvfs2_kernel_op_t *new_op = NULL;
     int buffer_index = -1;
@@ -160,7 +164,7 @@ static ssize_t wait_for_io(struct rw_opt
     if (!rw || !vec || nr_segs < 0 || total_size <= 0 
             || !rw->pvfs2_inode || !rw->inode || !rw->fnstr)
     {
-        gossip_lerr("invalid parameters (rw: %p, vec: %p, nr_segs: %d, "
+        gossip_lerr("invalid parameters (rw: %p, vec: %p, nr_segs: %lu, "
                 "total_size: %zd)\n", rw, vec, nr_segs, total_size);
         ret = -EINVAL;
         goto out;
@@ -191,7 +195,7 @@ static ssize_t wait_for_io(struct rw_opt
     new_op->upcall.req.io.count = total_size;
     new_op->upcall.req.io.offset = *(rw->off.io.offset);
 
-    gossip_debug(GOSSIP_FILE_DEBUG, "%s: copy_to_user %d nr_segs %u, "
+    gossip_debug(GOSSIP_FILE_DEBUG, "%s: copy_to_user %d nr_segs %lu, "
             "offset: %llu total_size: %zd\n", rw->fnstr, rw->copy_to_user, 
             nr_segs, llu(*(rw->off.io.offset)), total_size);
     if (rw->type == IO_WRITEV)
@@ -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,19 +321,22 @@ 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).
  */
-static int split_iovecs(unsigned long max_new_nr_segs,  /* IN */
+static int split_iovecs(
+	unsigned long max_new_nr_segs,      /* IN */
         unsigned long nr_segs,              /* IN */
         const struct iovec *original_iovec, /* IN */
-        unsigned long *new_nr_segs, struct iovec **new_vec,  /* OUT */
-        unsigned int *seg_count, unsigned int **seg_array)   /* OUT */
+        unsigned long *new_nr_segs, 	    /* OUT */
+	struct iovec **new_vec,  	    /* OUT */
+        unsigned long *seg_count,           /* OUT */
+	unsigned long **seg_array)   	    /* OUT */
 {
-    int seg, count = 0, begin_seg, tmpnew_nr_segs = 0;
+    unsigned long seg, count = 0, begin_seg, tmpnew_nr_segs = 0;
     struct iovec *new_iovec = NULL, *orig_iovec;
-    unsigned int *sizes = NULL, sizes_count = 0;
+    unsigned long *sizes = NULL, sizes_count = 0;
 
     if (nr_segs <= 0 || original_iovec == NULL 
             || new_nr_segs == NULL || new_vec == NULL
@@ -341,37 +350,33 @@ static int split_iovecs(unsigned long ma
     *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 = kmalloc(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 = (int *) kmalloc(max_new_nr_segs * sizeof(int), 
-            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(*sizes)));
         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++)
@@ -381,7 +386,7 @@ repeat:
             kfree(sizes);
             kfree(orig_iovec);
             kfree(new_iovec);
-            gossip_err("split_iovecs: exceeded the index limit (%d)\n", 
+            gossip_err("split_iovecs: exceeded the index limit (%lu)\n", 
                     tmpnew_nr_segs);
             return -EINVAL;
         }
@@ -426,11 +431,11 @@ repeat:
     return 0;
 }
 
-static long estimate_max_iovecs(const struct iovec *curr, unsigned long nr_segs, ssize_t *total_count)
+static long estimate_max_iovecs(const struct iovec *curr, unsigned long nr_segs, size_t *total_count)
 {
     unsigned long i;
     long max_nr_iovecs;
-    ssize_t total, count;
+    size_t total, count;
 
     total = 0;
     count = 0;
@@ -467,10 +472,11 @@ 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;
-    long max_new_nr_segs = 0;
-    unsigned int  seg_count = 0, *seg_array = NULL;
+    unsigned long max_new_nr_segs = 0;
+    unsigned long  seg_count = 0;
+    unsigned long *seg_array = NULL;
     struct iovec *iovecptr = NULL, *ptr = NULL;
     loff_t *offset;
 
@@ -508,14 +514,14 @@ static ssize_t do_direct_readv_writev(st
     nr_segs = rw->dest.address.nr_segs;
     if (iov == NULL || nr_segs < 0)
     {
-        gossip_err("%s: Invalid iovec %p or nr_segs %ld\n",
+        gossip_err("%s: Invalid iovec %p or nr_segs %lu\n",
                 rw->fnstr, iov, nr_segs);
         goto out;
     }
     /* Compute total and max number of segments after split */
     if ((max_new_nr_segs = estimate_max_iovecs(iov, nr_segs, &count)) < 0)
     {
-        gossip_lerr("%s: could not estimate iovec %ld\n", rw->fnstr, max_new_nr_segs);
+        gossip_lerr("%s: could not estimate iovec %lu\n", rw->fnstr, max_new_nr_segs);
         goto out;
     }
     if (rw->type == IO_WRITEV)
@@ -565,9 +571,14 @@ static ssize_t do_direct_readv_writev(st
          * entries that will store the number of segments that straddle the
          * block-size boundaries.
          */
-        if ((ret = split_iovecs(max_new_nr_segs, nr_segs, iov, /* IN */
-                        &new_nr_segs, &iovecptr, /* OUT */
-                        &seg_count, &seg_array)  /* OUT */ ) < 0)
+        ret = split_iovecs(max_new_nr_segs, /* IN */
+			   nr_segs,         /* IN */
+			   iov,             /* IN */
+			   &new_nr_segs,    /* OUT */
+			   &iovecptr,       /* OUT */
+			   &seg_count,      /* OUT */
+			   &seg_array);     /* OUT */ 
+	if(ret < 0)
         {
             gossip_err("%s: Failed to split iovecs to satisfy larger "
                     " than blocksize readv/writev request %zd\n", rw->fnstr, ret);
@@ -586,7 +597,7 @@ static ssize_t do_direct_readv_writev(st
         /* There is only 1 element in the seg_array */
         seg_count = 1;
         /* and its value is the number of segments passed in */
-        seg_array = (unsigned int *) &nr_segs;
+        seg_array = &nr_segs;
         /* We dont have to free up anything */
         to_free = 0;
     }
@@ -594,7 +605,7 @@ static ssize_t do_direct_readv_writev(st
 
     gossip_debug(GOSSIP_FILE_DEBUG, "%s %zd@%llu\n", 
             rw->fnstr, count, llu(*offset));
-    gossip_debug(GOSSIP_FILE_DEBUG, "%s: new_nr_segs: %lu, seg_count: %u\n", 
+    gossip_debug(GOSSIP_FILE_DEBUG, "%s: new_nr_segs: %lu, seg_count: %lu\n", 
             rw->fnstr, new_nr_segs, seg_count);
 #ifdef PVFS2_KERNEL_DEBUG
     for (seg = 0; seg < new_nr_segs; seg++)
@@ -607,7 +618,7 @@ static ssize_t do_direct_readv_writev(st
     }
     for (seg = 0; seg < seg_count; seg++)
     {
-        gossip_debug(GOSSIP_FILE_DEBUG, "%s: %d) %u\n",
+        gossip_debug(GOSSIP_FILE_DEBUG, "%s: %d) %lu\n",
                 rw->fnstr, seg + 1, seg_array[seg]);
     }
 #endif
@@ -728,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 
     {
@@ -767,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.
  */
@@ -822,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
@@ -854,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
@@ -862,19 +878,22 @@ 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).
  */
-static int split_xtvecs(unsigned long max_new_nr_segs,  /* IN */
-        unsigned long nr_segs,              /* IN */
-        const struct xtvec *original_xtvec, /* IN */
-        unsigned long *new_nr_segs, struct xtvec **new_vec,  /* OUT */
-        unsigned int *seg_count, unsigned int **seg_array)   /* OUT */
+static int split_xtvecs(
+		unsigned long max_new_nr_segs,      /* IN */
+		unsigned long nr_segs,              /* IN */
+		const struct xtvec *original_xtvec, /* IN */
+		unsigned long *new_nr_segs,         /* OUT */
+		struct xtvec **new_vec,  	    /* OUT */
+		unsigned long *seg_count,           /* OUT */
+		unsigned long **seg_array)          /* OUT */
 {
-    int seg, count, begin_seg, tmpnew_nr_segs;
+    unsigned long seg, count, begin_seg, tmpnew_nr_segs;
     struct xtvec *new_xtvec = NULL, *orig_xtvec;
-    unsigned int *sizes = NULL, sizes_count = 0;
+    unsigned long *sizes = NULL, sizes_count = 0;
 
     if (nr_segs <= 0 || original_xtvec == NULL 
             || new_nr_segs == NULL || new_vec == NULL
@@ -888,37 +907,33 @@ static int split_xtvecs(unsigned long ma
     *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 int *) kmalloc(max_new_nr_segs * sizeof(unsigned int), 
-            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;
@@ -930,8 +945,8 @@ repeat:
             kfree(sizes);
             kfree(orig_xtvec);
             kfree(new_xtvec);
-            gossip_err("split_xtvecs: exceeded the index limit (%d)\n", 
-                    tmpnew_nr_segs);
+            gossip_err("split_xtvecs: exceeded the index limit (%lu)\n", 
+			    tmpnew_nr_segs);
             return -EINVAL;
         }
         if (count + orig_xtvec[seg].xtv_len < pvfs_bufmap_size_query())
@@ -976,11 +991,11 @@ repeat:
 }
 
 static long 
-estimate_max_xtvecs(const struct xtvec *curr, unsigned long nr_segs, ssize_t *total_count)
+estimate_max_xtvecs(const struct xtvec *curr, unsigned long nr_segs, size_t *total_count)
 {
     unsigned long i;
     long max_nr_xtvecs;
-    ssize_t total, count;
+    size_t total, count;
 
     total = 0;
     count = 0;
@@ -1014,8 +1029,12 @@ estimate_max_xtvecs(const struct xtvec *
  * @xtvec - contains the file regions
  * @xtnr_segs - number of file vector regions
  */
-static ssize_t wait_for_iox(struct rw_options *rw, struct iovec *vec, int nr_segs,
-        struct xtvec *xtvec, int xtnr_segs, size_t total_size)
+static ssize_t wait_for_iox(struct rw_options *rw, 
+			    struct iovec *vec, 
+			    unsigned long nr_segs,
+			    struct xtvec *xtvec, 
+		            unsigned long xtnr_segs, 
+                            size_t total_size)
 {
     pvfs2_kernel_op_t *new_op = NULL;
     int buffer_index = -1;
@@ -1024,8 +1043,8 @@ static ssize_t wait_for_iox(struct rw_op
     if (!rw || !vec || nr_segs < 0 || total_size <= 0
             || !xtvec || xtnr_segs < 0)
     {
-        gossip_lerr("invalid parameters (rw: %p, vec: %p, nr_segs: %d, "
-                "xtvec %p, xtnr_segs %d, total_size: %zd\n", rw, vec, nr_segs,
+        gossip_lerr("invalid parameters (rw: %p, vec: %p, nr_segs: %lu, "
+                "xtvec %p, xtnr_segs %lu, total_size: %zd\n", rw, vec, nr_segs,
                 xtvec, xtnr_segs, total_size);
         ret = -EINVAL;
         goto out;
@@ -1065,8 +1084,8 @@ static ssize_t wait_for_iox(struct rw_op
                 "failure (%ld)\n", rw->fnstr, (long) ret);
         goto out;
     }
-    gossip_debug(GOSSIP_FILE_DEBUG, "%s: copy_to_user %d nr_segs %d, "
-            "xtnr_segs: %d "
+    gossip_debug(GOSSIP_FILE_DEBUG, "%s: copy_to_user %d nr_segs %lu, "
+            "xtnr_segs: %lu "
             "total_size: %zd\n",
             rw->fnstr, rw->copy_to_user, 
             nr_segs, xtnr_segs,
@@ -1186,17 +1205,18 @@ out:
 
 static ssize_t do_direct_readx_writex(struct rw_options *rw)
 {
-    ssize_t ret, total_count, count_mem, count_stream;
+    ssize_t ret, total_count;
+    size_t count_mem, count_stream;
     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; 
-    long max_new_nr_segs_mem, max_new_nr_segs_stream;
+    unsigned long max_new_nr_segs_mem, max_new_nr_segs_stream;
     unsigned long new_nr_segs_mem = 0, new_nr_segs_stream = 0;
-    unsigned int seg_count_mem, *seg_array_mem = NULL;
-    unsigned int seg_count_stream, *seg_array_stream = NULL;
+    unsigned long seg_count_mem, *seg_array_mem = NULL;
+    unsigned long seg_count_stream, *seg_array_stream = NULL;
     struct iovec *iovecptr = NULL, *ptr = NULL;
     struct xtvec *xtvecptr = NULL, *xptr = NULL;
 
@@ -1230,28 +1250,28 @@ static ssize_t do_direct_readx_writex(st
     nr_segs = rw->dest.address.nr_segs;
     if (iov == NULL || nr_segs < 0)
     {
-        gossip_err("%s: Invalid iovec %p or nr_segs %ld\n",
+        gossip_err("%s: Invalid iovec %p or nr_segs %lu\n",
                 rw->fnstr, iov, nr_segs);
         goto out;
     }
     /* Compute total and max number of segments after split of the memory vector */
     if ((max_new_nr_segs_mem = estimate_max_iovecs(iov, nr_segs, &count_mem)) < 0)
     {
-        gossip_lerr("%s: could not estimate iovec %ld\n", rw->fnstr, max_new_nr_segs_mem);
+        gossip_lerr("%s: could not estimate iovec %lu\n", rw->fnstr, max_new_nr_segs_mem);
         goto out;
     }
     xtvec = rw->off.iox.xtvec;
     xtnr_segs = rw->off.iox.xtnr_segs;
     if (xtvec == NULL || xtnr_segs < 0)
     {
-        gossip_err("%s: Invalid xtvec %p or xtnr_segs %ld\n",
+        gossip_err("%s: Invalid xtvec %p or xtnr_segs %lu\n",
                 rw->fnstr, xtvec, xtnr_segs);
         goto out;
     }
     /* Calculate the total stream length amd max segments after split of the stream vector */
     if ((max_new_nr_segs_stream = estimate_max_xtvecs(xtvec, xtnr_segs, &count_stream)) < 0)
     {
-        gossip_lerr("%s: could not estimate xtvec %ld\n", rw->fnstr, max_new_nr_segs_stream);
+        gossip_lerr("%s: could not estimate xtvec %lu\n", rw->fnstr, max_new_nr_segs_stream);
         goto out;
     }
     if (count_mem == 0)
@@ -1279,9 +1299,14 @@ static ssize_t do_direct_readx_writex(st
          * entries that will store the number of segments that straddle the
          * block-size boundaries.
          */
-        if ((ret = split_iovecs(max_new_nr_segs_mem, nr_segs, iov, /* IN */
-                        &new_nr_segs_mem, &iovecptr, /* OUT */
-                        &seg_count_mem, &seg_array_mem)  /* OUT */ ) < 0)
+        ret = split_iovecs(max_new_nr_segs_mem, /* IN */
+			   nr_segs, 		/* IN */
+			   iov, 		/* IN */
+			   &new_nr_segs_mem,    /* OUT */
+			   &iovecptr, 		/* OUT */
+			   &seg_count_mem, 	/* OUT */
+			   &seg_array_mem);     /* OUT */
+        if(ret < 0)
         {
             gossip_err("%s: Failed to split iovecs to satisfy larger "
                     " than blocksize readx request %ld\n", rw->fnstr, (long) ret);
@@ -1295,9 +1320,14 @@ static ssize_t do_direct_readx_writex(st
          * Split up the given xtvec description such that
          * no xtvec descriptor straddles over the block-size limitation.
          */
-        if ((ret = split_xtvecs(max_new_nr_segs_stream, xtnr_segs, xtvec, /* IN */
-                        &new_nr_segs_stream, &xtvecptr, /* OUT */
-                        &seg_count_stream, &seg_array_stream) /* OUT */) < 0)
+        ret = split_xtvecs(max_new_nr_segs_stream, /* IN */
+			   xtnr_segs,              /* IN */
+			   xtvec,  		   /* IN */
+                           &new_nr_segs_stream,    /* OUT */
+			   &xtvecptr, 		   /* OUT */
+                           &seg_count_stream,      /* OUT */
+			   &seg_array_stream);     /* OUT */
+        if(ret < 0)
         {
             gossip_err("Failed to split iovecs to satisfy larger "
                     " than blocksize readx request %ld\n", (long) ret);
@@ -1314,7 +1344,7 @@ static ssize_t do_direct_readx_writex(st
         /* There is only 1 element in the seg_array_mem */
         seg_count_mem = 1;
         /* and its value is the number of segments passed in */
-        seg_array_mem = (unsigned int *) &nr_segs;
+        seg_array_mem = &nr_segs;
         
         new_nr_segs_stream = xtnr_segs;
         /* use the given file description */
@@ -1322,7 +1352,7 @@ static ssize_t do_direct_readx_writex(st
         /* There is only 1 element in the seg_array_stream */
         seg_count_stream = 1;
         /* and its value is the number of segments passed in */
-        seg_array_stream = (unsigned int *) &xtnr_segs;
+        seg_array_stream = &xtnr_segs;
         /* We dont have to free up anything */
         to_free = 0;
     }
@@ -1850,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;
@@ -2064,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;
@@ -2078,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)
     {
@@ -2087,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 
     {
@@ -2102,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);
@@ -2118,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)
     {
@@ -2127,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.
  */
@@ -2459,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: super.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/super.c,v
diff -p -u -r1.86 -r1.86.4.1
--- super.c	26 Sep 2006 03:44:17 -0000	1.86
+++ super.c	23 May 2007 20:48:20 -0000	1.86.4.1
@@ -5,6 +5,7 @@
  */
 
 #include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
 #include "pvfs2-internal.h"
 
 /* list for storing pvfs2 specific superblocks in use */
@@ -250,13 +251,18 @@ static void pvfs2_read_inode(
     struct inode *inode)
 {
     pvfs2_inode_t *pvfs2_inode = NULL;
+    void *ptr = NULL;
 
+#if !defined(HAVE_IGET4_LOCKED) && !defined(HAVE_IGET_LOCKED)
     if (inode->u.generic_ip)
     {
         gossip_err("ERROR! Found an initialized inode in pvfs2_read_inode! "
                     "Should not have been initialized?\n");
         return;
     }
+#else
+    ptr = inode->u.generic_ip;
+#endif
 
     /* Here we allocate the PVFS2 specific inode structure */
     pvfs2_inode = pvfs2_inode_alloc();
@@ -266,7 +272,15 @@ static void pvfs2_read_inode(
         inode->u.generic_ip = pvfs2_inode;
         pvfs2_inode->vfs_inode = inode;
         inode->i_flags &= ~(S_APPEND|S_IMMUTABLE|S_NOATIME);
-
+        /* Initialize the handle id to be looked up in the case of iget4_locked
+         * and iget_locked functions, since they are not done elsewhere 
+         */
+#if defined(HAVE_IGET4_LOCKED) || defined(HAVE_IGET_LOCKED)
+        if (ptr == NULL) {
+            gossip_err("Warning! We don't have the reference to the pvfs2 object handle.. using iget4/iget(locked) interface\n");
+        }
+        pvfs2_set_inode(inode, ptr);
+#endif
         if (pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT) != 0)
         {
             pvfs2_make_bad_inode(inode);
@@ -421,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)
@@ -936,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;
@@ -1057,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: devpvfs2-req.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/devpvfs2-req.c,v
diff -p -u -r1.66 -r1.66.6.1
--- devpvfs2-req.c	13 Sep 2006 20:22:55 -0000	1.66
+++ devpvfs2-req.c	23 May 2007 20:48:20 -0000	1.66.6.1
@@ -232,11 +232,12 @@ static ssize_t pvfs2_devreq_read(
     return len;
 }
 
+/* Common function for writev() and aio_write() callers into the device */
 static ssize_t pvfs2_devreq_writev(
     struct file *file,
     const struct iovec *iov,
     unsigned long count,
-    loff_t * offset)
+    loff_t *offset)
 {
     pvfs2_kernel_op_t *op = NULL;
     struct qhash_head *hash_link = NULL;
@@ -250,6 +251,7 @@ static ssize_t pvfs2_devreq_writev(
     int32_t magic = 0;
     int32_t proto_ver = 0;
     uint64_t tag = 0;
+    ssize_t total_returned_size = 0;
 
     /* Either there is a trailer or there isn't */
     if (count != notrailer_count && count != (notrailer_count + 1))
@@ -284,6 +286,7 @@ static ssize_t pvfs2_devreq_writev(
 	ptr += iov[i].iov_len;
 	payload_size += iov[i].iov_len;
     }
+    total_returned_size = payload_size;
 
     /* these elements are currently 8 byte aligned (8 bytes for (version +  
      * magic) 8 bytes for tag).  If you add another element, either make it 8
@@ -541,9 +544,22 @@ static ssize_t pvfs2_devreq_writev(
     }
     dev_req_release(buffer);
 
-    return count;
+    /* if we are called from aio context, just mark that the iocb is completed */
+    return total_returned_size;
 }
 
+#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 +791,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 +812,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 +829,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 +1031,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-kernel.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-kernel.h,v
diff -p -u -r1.136 -r1.136.2.1
--- pvfs2-kernel.h	23 Oct 2006 22:25:42 -0000	1.136
+++ pvfs2-kernel.h	23 May 2007 20:48:20 -0000	1.136.2.1
@@ -237,7 +237,11 @@ enum PVFS_async_io_type 
 #define PVFS2_CACHE_CREATE_FLAGS 0
 #endif /* ((defined PVFS2_KERNEL_DEBUG) && (defined CONFIG_DEBUG_SLAB)) */
 
-#define PVFS2_CACHE_ALLOC_FLAGS (SLAB_KERNEL)
+#ifdef HAVE_SLAB_KERNEL_FLAG
+# define PVFS2_CACHE_ALLOC_FLAGS (SLAB_KERNEL)
+#else
+# define PVFS2_CACHE_ALLOC_FLAGS (GFP_KERNEL)
+#endif
 #define PVFS2_GFP_FLAGS (GFP_KERNEL)
 #define PVFS2_BUFMAP_GFP_FLAGS (GFP_KERNEL)
 
@@ -735,6 +739,7 @@ void fsid_key_table_finalize(void);
 /****************************
  * defined in inode.c
  ****************************/
+int pvfs2_set_inode(struct inode *inode, void *data);
 uint32_t convert_to_pvfs2_mask(unsigned long lite_mask);
 struct inode *pvfs2_get_custom_inode(
     struct super_block *sb,
@@ -1249,6 +1254,21 @@ static inline unsigned int diff(struct t
     end->tv_usec -= begin->tv_usec;
     return ((end->tv_sec * 1000000) + end->tv_usec);
 }
+
+#ifndef HAVE_KZALLOC
+static inline void *kzalloc(size_t size, int flags)
+{
+	void * ptr;
+
+	ptr = kmalloc(size, flags);
+	if(!ptr)
+	{
+		return ptr;
+	}
+	memset(ptr, 0, size);
+	return ptr;
+}
+#endif
 
 #endif /* __PVFS2KERNEL_H */
 

Index: pvfs2-bufmap.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.c,v
diff -p -u -r1.46 -r1.46.4.1
--- pvfs2-bufmap.c	28 Sep 2006 05:13:41 -0000	1.46
+++ pvfs2-bufmap.c	23 May 2007 20:48:20 -0000	1.46.4.1
@@ -7,23 +7,90 @@
 #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 = kzalloc(ndescs * sizeof(*buffer_index_array), 
+                                 PVFS2_BUFMAP_GFP_FLAGS);
+    if (buffer_index_array == NULL) 
+    {
+        gossip_err("pvfs2: could not allocate %d bytes\n",
+                (int) (ndescs * sizeof(*buffer_index_array)));
+        goto out;
+    }
+
+    desc_array = kmalloc(ndescs * sizeof(*desc_array), 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 +103,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 +120,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 +175,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 +189,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 +214,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 +274,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 +283,7 @@ void pvfs_bufmap_finalize(void)
 
     bufmap_init = 0;
 
+    finalize_bufmap_descriptors();
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: exiting normally\n");
 }
 
@@ -239,6 +331,7 @@ static int wait_for_a_slot(struct slot_a
             if (!schedule_timeout(timeout))
             {
                 gossip_debug(GOSSIP_BUFMAP_DEBUG, "*** wait_for_a_slot timed out\n");
+                ret = -ETIMEDOUT;
                 break;
             }
             continue;
@@ -281,7 +374,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 +391,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 +413,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 +424,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;
@@ -548,21 +641,21 @@ int pvfs_bufmap_copy_iovec_from_user(
 
         if (iv->iov_len < (PAGE_SIZE - page_offset)) 
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_addr = iv->iov_base;
             inc_index = 0;
         }
         else if (iv->iov_len == (PAGE_SIZE - page_offset))
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_addr = iv->iov_base;
             inc_index = 1;
         }
         else 
         {
-            cur_copy_size = (PAGE_SIZE - page_offset);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
             from_addr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len -= cur_copy_size;
@@ -671,21 +764,21 @@ int pvfs_bufmap_copy_iovec_from_kernel(
 
         if (iv->iov_len < (PAGE_SIZE - page_offset)) 
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_kaddr = iv->iov_base;
             inc_index = 0;
         }
         else if (iv->iov_len == (PAGE_SIZE - page_offset))
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_kaddr = iv->iov_base;
             inc_index = 1;
         }
         else 
         {
-            cur_copy_size = (PAGE_SIZE - page_offset);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
             from_kaddr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len -= cur_copy_size;
@@ -784,21 +877,21 @@ int pvfs_bufmap_copy_to_user_iovec(
 
         if (iv->iov_len < (PAGE_SIZE - page_offset))
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_addr = iv->iov_base;
             inc_index = 0;
         }
         else if (iv->iov_len == (PAGE_SIZE - page_offset))
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_addr = iv->iov_base;
             inc_index = 1;
         }
         else 
         {
-            cur_copy_size = (PAGE_SIZE - page_offset);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
             to_addr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len  -= cur_copy_size;
@@ -904,21 +997,21 @@ int pvfs_bufmap_copy_to_kernel_iovec(
 
         if (iv->iov_len < (PAGE_SIZE - page_offset))
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_kaddr = iv->iov_base;
             inc_index = 0;
         }
         else if (iv->iov_len == (PAGE_SIZE - page_offset))
         {
-            cur_copy_size = iv->iov_len;
+            cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_kaddr = iv->iov_base;
             inc_index = 1;
         }
         else 
         {
-            cur_copy_size = (PAGE_SIZE - page_offset);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
             to_kaddr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len  -= cur_copy_size;



More information about the Pvfs2-cvs mailing list