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

CVS commit program cvs at parl.clemson.edu
Thu Jul 10 17:43:59 EDT 2008


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

Modified Files:
      Tag: he-branch
	dcache.c devpvfs2-req.c file.c inode.c pvfs2-bufmap.c 
	pvfs2-bufmap.h pvfs2-kernel.h super.c 
Log Message:
reverse merge of trunk changes since branch.


Index: dcache.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/dcache.c,v
diff -p -u -r1.40.4.1 -r1.40.4.2
--- dcache.c	21 May 2008 18:55:27 -0000	1.40.4.1
+++ dcache.c	10 Jul 2008 21:43:58 -0000	1.40.4.2
@@ -109,9 +109,7 @@ static int pvfs2_d_revalidate_common(str
     gossip_debug(GOSSIP_DCACHE_DEBUG,
                  "%s: doing getattr: inode: %p, handle: %llu)\n",
                  __func__, inode, llu(get_handle_from_ino(inode)));
-    pvfs2_inode_lock(inode);
     ret = pvfs2_inode_getattr(inode, PVFS_ATTR_SYS_ALL_NOHINT);
-    pvfs2_inode_unlock(inode);
     gossip_debug(GOSSIP_DCACHE_DEBUG,
                  "%s: getattr %s (ret = %d), returning %s for dentry\n",
                  __func__,

Index: devpvfs2-req.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/devpvfs2-req.c,v
diff -p -u -r1.73 -r1.73.6.1
--- devpvfs2-req.c	11 Jan 2008 14:40:47 -0000	1.73
+++ devpvfs2-req.c	10 Jul 2008 21:43:58 -0000	1.73.6.1
@@ -468,7 +468,7 @@ static ssize_t pvfs2_devreq_writev(
                     && op->upcall.req.io.async_vfs_io == PVFS_VFS_ASYNC_IO)
             {
                 pvfs2_kiocb *x = (pvfs2_kiocb *) op->priv;
-                if (x == NULL || x->buffer == NULL 
+                if (x == NULL || x->iov == NULL 
                         || x->op != op 
                         || x->bytes_to_be_copied <= 0)
                 {
@@ -476,7 +476,7 @@ static ssize_t pvfs2_devreq_writev(
                     {
                         gossip_debug(GOSSIP_DEV_DEBUG, "WARNING: pvfs2_iocb from op"
                                 "has invalid fields! %p, %p(%p), %d\n",
-                                x->buffer, x->op, op, (int) x->bytes_to_be_copied);
+                                x->iov, x->op, op, (int) x->bytes_to_be_copied);
                     }
                     else
                     {
@@ -503,9 +503,9 @@ static ssize_t pvfs2_devreq_writev(
                             && bytes_copied > 0)
                     {
                         /* try and copy it out to user-space */
-                        bytes_copied = pvfs_bufmap_copy_to_user_task(
+                        bytes_copied = pvfs_bufmap_copy_to_user_task_iovec(
                                 x->tsk,
-                                x->buffer,
+                                x->iov, x->nr_segs,
                                 x->buffer_index,
                                 bytes_copied);
                     }

Index: file.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/file.c,v
diff -p -u -r1.146.4.1 -r1.146.4.2
--- file.c	21 May 2008 18:55:27 -0000	1.146.4.1
+++ file.c	10 Jul 2008 21:43:58 -0000	1.146.4.2
@@ -328,7 +328,7 @@ static int copy_from_pagecache(struct rw
         gossip_err("copy_from_pagecache: failed allocating memory\n");
         return -ENOMEM;
     }
-    memcpy(copied_iovec, vec, nr_segs * sizeof(struct iovec));
+    memcpy(copied_iovec, vec, nr_segs * sizeof(*copied_iovec));
     /*
      * Go through each segment in the iovec and make sure that
      * the summation of iov_len is greater than the given size.
@@ -635,7 +635,7 @@ repeat:
             count += orig_iovec[seg].iov_len;
             
             memcpy(&new_iovec[tmpnew_nr_segs], &orig_iovec[seg], 
-                    sizeof(struct iovec));
+                    sizeof(*new_iovec));
             tmpnew_nr_segs++;
             sizes[sizes_count]++;
         }
@@ -671,7 +671,7 @@ repeat:
     return 0;
 }
 
-static long estimate_max_iovecs(const struct iovec *curr, unsigned long nr_segs, ssize_t *total_count)
+static long bound_max_iovecs(const struct iovec *curr, unsigned long nr_segs, ssize_t *total_count)
 {
     unsigned long i;
     long max_nr_iovecs;
@@ -1134,7 +1134,7 @@ static ssize_t wait_for_cached_io(struct
     struct rw_options rw;
     loff_t isize, offset;
 
-    memcpy(&rw, old_rw, sizeof(struct rw_options));
+    memcpy(&rw, old_rw, sizeof(rw));
     if (rw.type != IO_READV) {
         gossip_err("writes are not handled yet!\n");
         return -EOPNOTSUPP;
@@ -1232,9 +1232,9 @@ static ssize_t do_readv_writev(struct rw
         goto out;
     }
     /* Compute total and max number of segments after split */
-    if ((max_new_nr_segs = estimate_max_iovecs(iov, nr_segs, &count)) < 0)
+    if ((max_new_nr_segs = bound_max_iovecs(iov, nr_segs, &count)) < 0)
     {
-        gossip_lerr("%s: could not estimate iovec %lu\n", rw->fnstr, max_new_nr_segs);
+        gossip_lerr("%s: could not bound iovec %lu\n", rw->fnstr, max_new_nr_segs);
         goto out;
     }
     if (rw->type == IO_WRITEV)
@@ -1574,7 +1574,7 @@ static int construct_file_offset_trailer
     int i;
     struct read_write_x *rwx;
 
-    *trailer_size = seg_count * sizeof(struct read_write_x);
+    *trailer_size = seg_count * sizeof(*rwx);
     *trailer = (char *) vmalloc(*trailer_size);
     if (*trailer == NULL)
     {
@@ -1679,7 +1679,7 @@ repeat:
             count += orig_xtvec[seg].xtv_len;
             
             memcpy(&new_xtvec[tmpnew_nr_segs], &orig_xtvec[seg], 
-                    sizeof(struct xtvec));
+                    sizeof(*new_xtvec));
             tmpnew_nr_segs++;
             sizes[sizes_count]++;
         }
@@ -1716,7 +1716,7 @@ repeat:
 }
 
 static long 
-estimate_max_xtvecs(const struct xtvec *curr, unsigned long nr_segs, size_t *total_count)
+bound_max_xtvecs(const struct xtvec *curr, unsigned long nr_segs, size_t *total_count)
 {
     unsigned long i;
     long max_nr_xtvecs;
@@ -1943,9 +1943,9 @@ static ssize_t do_readx_writex(struct rw
         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)
+    if ((max_new_nr_segs_mem = bound_max_iovecs(iov, nr_segs, &count_mem)) < 0)
     {
-        gossip_lerr("%s: could not estimate iovec %lu\n", rw->fnstr, max_new_nr_segs_mem);
+        gossip_lerr("%s: could not bound iovec %lu\n", rw->fnstr, max_new_nr_segs_mem);
         goto out;
     }
     xtvec = rw->off.iox.xtvec;
@@ -1957,9 +1957,9 @@ static ssize_t do_readx_writex(struct rw
         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)
+    if ((max_new_nr_segs_stream = bound_max_xtvecs(xtvec, xtnr_segs, &count_stream)) < 0)
     {
-        gossip_lerr("%s: could not estimate xtvec %lu\n", rw->fnstr, max_new_nr_segs_stream);
+        gossip_lerr("%s: could not bound xtvec %lu\n", rw->fnstr, max_new_nr_segs_stream);
         goto out;
     }
     if (count_mem == 0)
@@ -2280,9 +2280,9 @@ static ssize_t pvfs2_aio_retry(struct ki
         error = x->bytes_copied;
         op->priv = NULL;
         spin_unlock(&op->lock);
-        gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_aio_retry: buffer %p,"
+        gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_aio_retry: iov %p,"
                 " size %d return %d bytes\n",
-                    x->buffer, (int) x->bytes_to_be_copied, (int) error);
+                    x->iov, (int) x->bytes_to_be_copied, (int) error);
         if (error > 0)
         {
             struct inode *inode = iocb->ki_filp->f_mapping->host;
@@ -2514,6 +2514,11 @@ static void pvfs2_aio_dtor(struct kiocb 
             x->op->priv = NULL;
             put_op(x->op);
         }
+        if (x->iov) 
+        {
+            kfree(x->iov);
+            x->iov = NULL;
+        }
         x->needs_cleanup = 0;
     }
     gossip_debug(GOSSIP_FILE_DEBUG, "pvfs2_aio_dtor: kiocb_release %p\n", x);
@@ -2522,12 +2527,12 @@ static void pvfs2_aio_dtor(struct kiocb 
     return;
 }
 
-static inline void 
+static inline int 
 fill_default_kiocb(pvfs2_kiocb *x,
         struct task_struct *tsk,
         struct kiocb *iocb, int rw,
         int buffer_index, pvfs2_kernel_op_t *op, 
-        void __user *buffer,
+        const struct iovec *iovec, unsigned long nr_segs,
         loff_t offset, size_t count,
         int (*aio_cancel)(struct kiocb *, struct io_event *))
 {
@@ -2536,13 +2541,23 @@ fill_default_kiocb(pvfs2_kiocb *x,
     x->buffer_index = buffer_index;
     x->op = op;
     x->rw = rw;
-    x->buffer = buffer;
     x->bytes_to_be_copied = count;
     x->offset = offset;
     x->bytes_copied = 0;
     x->needs_cleanup = 1;
     iocb->ki_cancel = aio_cancel;
-    return;
+    /* Allocate a private pointer to store the
+     * iovector since the caller could pass in a
+     * local variable for the iovector.
+     */
+    x->iov = kmalloc(nr_segs * sizeof(*x->iov), PVFS2_BUFMAP_GFP_FLAGS);
+    if (x->iov == NULL) 
+    {
+        return -ENOMEM;
+    }
+    memcpy(x->iov, iovec, nr_segs * sizeof(*x->iov));
+    x->nr_segs = nr_segs;
+    return 0;
 }
 
 /*
@@ -2560,7 +2575,10 @@ fill_default_kiocb(pvfs2_kiocb *x,
  * that get completion notification from interrupt
  * context, we get completion notification from a process
  * context (i.e. the client daemon).
- * TODO: We do not handle vectored aio requests yet
+ * TODO: We handle vectored aio requests now but we do
+ * not handle the case where the total size of IO is
+ * larger than our FS transfer block size (4 MB
+ * default).
  */
 static ssize_t do_aio_read_write(struct rw_options *rw)
 {
@@ -2605,17 +2623,11 @@ static ssize_t do_aio_read_write(struct 
                 iov, nr_segs);
         goto out_error;
     }
-    if (nr_segs > 1)
-    {
-        gossip_lerr("%s: not implemented yet (aio with %ld segments)\n",
-                rw->fnstr, nr_segs);
-        goto out_error;
-    }
     count = 0;
     /* Compute total and max number of segments after split */
-    if ((max_new_nr_segs = estimate_max_iovecs(iov, nr_segs, &count)) < 0)
+    if ((max_new_nr_segs = bound_max_iovecs(iov, nr_segs, &count)) < 0)
     {
-        gossip_lerr("%s: could not estimate iovecs %ld\n", rw->fnstr, max_new_nr_segs);
+        gossip_lerr("%s: could not bound iovecs %ld\n", rw->fnstr, max_new_nr_segs);
         goto out_error;
     }
     if (unlikely(((ssize_t)count)) < 0)
@@ -2667,7 +2679,6 @@ static ssize_t do_aio_read_write(struct 
     {
         int buffer_index = -1;
         pvfs2_kernel_op_t *new_op = NULL;
-        char __user *current_buf = (char *) rw->dest.address.iov[0].iov_base;
         pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
         
         new_op = op_alloc(PVFS2_VFS_OP_FILE_IO);
@@ -2700,14 +2711,30 @@ static ssize_t do_aio_read_write(struct 
         if (rw->type == IO_WRITE)
         {
             /* 
-             * copy the data from the application for writes 
-             * Should this be done here even for async I/O? 
+             * copy the data from the application for writes.
              * We could return -EIOCBRETRY here and have 
              * the data copied in the pvfs2_aio_retry routine,
-             * I think. But I dont see the point in doing that...
+             * I dont see too much point in doing that
+             * since the app would have touched the
+             * memory pages prior to the write and
+             * hence accesses to the page won't block.
              */
-            error = pvfs_bufmap_copy_from_user(
-                    buffer_index, current_buf, count);
+            if (rw->copy_to_user_addresses) 
+            {
+                error = pvfs_bufmap_copy_iovec_from_user(
+                        buffer_index,
+                        iov,
+                        nr_segs,
+                        count);
+            } 
+            else 
+            {
+                error = pvfs_bufmap_copy_iovec_from_kernel(
+                        buffer_index,
+                        iov,
+                        nr_segs,
+                        count);
+            }
             if (error < 0)
             {
                 gossip_err("%s: Failed to copy user buffer %ld. Make sure that pvfs2-client-core"
@@ -2735,21 +2762,33 @@ static ssize_t do_aio_read_write(struct 
         }
         gossip_debug(GOSSIP_FILE_DEBUG, "kiocb_alloc: %p\n", x);
         /* 
-         * destructor function to make sure that we free
-         * up this allocated piece of memory 
-         */
-        iocb->ki_dtor = pvfs2_aio_dtor;
-        /* 
          * We need to set the cancellation callbacks + 
          * other state information
          * here if the asynchronous request is going to
          * be successfully submitted 
          */
-        fill_default_kiocb(x, current, iocb, 
-                (rw->type == IO_READ) ? PVFS_IO_READ : PVFS_IO_WRITE,
-                buffer_index, new_op, current_buf,
-                *offset, count,
-                &pvfs2_aio_cancel);
+        error = fill_default_kiocb(x, current, iocb, 
+                                   (rw->type == IO_READ) ? PVFS_IO_READ : PVFS_IO_WRITE,
+                                   buffer_index,
+                                   new_op, iov, nr_segs,
+                                   *offset, count,
+                                   &pvfs2_aio_cancel);
+        if (error != 0) 
+        {
+            kiocb_release(x);
+            /* drop the buffer index */
+            pvfs_bufmap_put(buffer_index);
+            gossip_debug(GOSSIP_FILE_DEBUG, "%s: pvfs_bufmap_put %d\n",
+                    rw->fnstr, buffer_index);
+            /* drop the reference count and deallocate */
+            put_op(new_op);
+            goto out_error;
+        }
+        /* 
+         * destructor function to make sure that we free
+         * up this allocated piece of memory 
+         */
+        iocb->ki_dtor = pvfs2_aio_dtor;
         /*
          * We need to be able to retrieve this structure from
          * the op structure as well, since the client-daemon
@@ -3259,8 +3298,10 @@ struct file_operations pvfs2_file_operat
     .write = pvfs2_file_write,
 #ifdef HAVE_COMBINED_AIO_AND_VECTOR
     /* for >= 2.6.19 */
+#ifdef HAVE_AIO_VFS_SUPPORT
     .aio_read = pvfs2_file_aio_read_iovec,
     .aio_write = pvfs2_file_aio_write_iovec,
+#endif
     .lock = pvfs2_lock,
 #else
     .readv = pvfs2_file_readv,

Index: inode.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/inode.c,v
diff -p -u -r1.81.4.1 -r1.81.4.2
--- inode.c	21 May 2008 18:55:27 -0000	1.81.4.1
+++ inode.c	10 Jul 2008 21:43:59 -0000	1.81.4.2
@@ -251,14 +251,18 @@ int pvfs2_getattr(
      * parsed by the VFS layer.  Propigate them to our internal sb structure so
      * that we can handle lazy time updates properly.
      */
+#ifdef HAVE_MNT_NOATIME
     if(mnt->mnt_flags && MNT_NOATIME) 
     { 
         inode->i_sb->s_flags |= MS_NOATIME; 
     } 
+#endif
+#ifdef HAVE_MNT_NODIRATIME
     if(mnt->mnt_flags && MNT_NODIRATIME) 
     { 
         inode->i_sb->s_flags |= MS_NODIRATIME; 
     } 
+#endif
 
     /*
      * Similar to the above comment, a getattr also expects that all fields/attributes
@@ -483,6 +487,8 @@ struct inode *pvfs2_iget_common(struct s
         }
 #endif
     }
+    gossip_debug(GOSSIP_INODE_DEBUG, "iget handle %llu, fsid %d hash %ld i_ino %lu\n",
+                 ref->handle, ref->fs_id, hash, inode->i_ino);
     return inode;
 }
 

Index: pvfs2-bufmap.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.c,v
diff -p -u -r1.56 -r1.56.4.1
--- pvfs2-bufmap.c	20 Mar 2008 03:21:26 -0000	1.56
+++ pvfs2-bufmap.c	10 Jul 2008 21:43:59 -0000	1.56.4.1
@@ -65,7 +65,7 @@ static int initialize_bufmap_descriptors
     if (desc_array == NULL)
     {
         gossip_err("pvfs2: could not allocate %d bytes\n",
-		(int) (ndescs * sizeof(struct pvfs_bufmap_desc)));
+		(int) (ndescs * sizeof(*desc_array)));
         goto out1;
     }
     err = 0;
@@ -105,7 +105,7 @@ int pvfs_bufmap_initialize(struct PVFS_d
     int i = 0;
     int offset = 0;
 
-    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: called "
+    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_initialize: called "
                  "(ptr (%p) sz (%d) cnt(%d).\n",
                  user_desc->ptr, user_desc->size, user_desc->count);
 
@@ -249,7 +249,7 @@ int pvfs_bufmap_initialize(struct PVFS_d
     bufmap_init = 1;
     up_write(&bufmap_init_sem);
 
-    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: exiting normally\n");
+    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_initialize: exiting normally\n");
     return 0;
 
 init_failure:
@@ -502,9 +502,9 @@ void readdir_index_put(int buffer_index)
 int pvfs_bufmap_copy_to_user(void __user *to, int buffer_index, size_t size)
 {
     size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
-    int index = 0;
-    void __user *offset = to;
+    int from_page_index = 0;
     void *from_kaddr = NULL;
+    void __user *to_kaddr = to;
     struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
 
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_user: to %p, from %p, index %d, "
@@ -526,9 +526,9 @@ int pvfs_bufmap_copy_to_user(void __user
         cur_copy_size =
             ((amt_remaining > PAGE_SIZE) ? PAGE_SIZE : amt_remaining);
 
-        from_kaddr = pvfs2_kmap(from->page_array[index]);
-        ret = copy_to_user(offset, from_kaddr, cur_copy_size);
-        pvfs2_kunmap(from->page_array[index]);
+        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
+        ret = copy_to_user(to_kaddr, from_kaddr, cur_copy_size);
+        pvfs2_kunmap(from->page_array[from_page_index]);
 
         if (ret)
         {
@@ -537,20 +537,25 @@ int pvfs_bufmap_copy_to_user(void __user
             return -EFAULT;
         }
 
-        offset += cur_copy_size;
+        to_kaddr += cur_copy_size;
         amt_copied += cur_copy_size;
-        index++;
+        from_page_index++;
     }
     up_read(&bufmap_init_sem);
     return 0;
 }
 
-int pvfs_bufmap_copy_to_kernel(
-    void *to, int buffer_index, size_t size)
+/* pvfs_bufmap_copy_to_kernel()
+ *
+ * copies data out of a mapped buffer to a kernel space address
+ *
+ * returns 0 on success, -errno on failure
+ */
+int pvfs_bufmap_copy_to_kernel(void *to, int buffer_index, size_t size)
 {
     size_t amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
-    int index = 0;
-    void *offset = to, *from_kaddr = NULL;
+    int from_page_index = 0;
+    void *to_kaddr = to, *from_kaddr = NULL;
     struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
 
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_kernel: to %p, index %d, size %zd\n",
@@ -572,13 +577,13 @@ int pvfs_bufmap_copy_to_kernel(
         cur_copy_size =
             ((amt_remaining > PAGE_SIZE) ? PAGE_SIZE : amt_remaining);
 
-        from_kaddr = pvfs2_kmap(from->page_array[index]);
-        memcpy(offset, from_kaddr, cur_copy_size);
-        pvfs2_kunmap(from->page_array[index]);
+        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
+        memcpy(to_kaddr, from_kaddr, cur_copy_size);
+        pvfs2_kunmap(from->page_array[from_page_index]);
 
-        offset += cur_copy_size;
+        to_kaddr += cur_copy_size;
         amt_copied += cur_copy_size;
-        index++;
+        from_page_index++;
     }
     up_read(&bufmap_init_sem);
     return 0;
@@ -590,13 +595,12 @@ int pvfs_bufmap_copy_to_kernel(
  *
  * returns 0 on success, -errno on failure
  */
-int pvfs_bufmap_copy_from_user(
-    int buffer_index, void __user *from, size_t size)
+int pvfs_bufmap_copy_from_user(int buffer_index, void __user *from, size_t size)
 {
     size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
-    int index = 0;
-    void __user *offset = from;
+    void __user *from_kaddr = from;
     void *to_kaddr = NULL;
+    int to_page_index = 0;
     struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
     char* tmp_printer = NULL;
     int tmp_int = 0;
@@ -620,16 +624,16 @@ int pvfs_bufmap_copy_from_user(
         cur_copy_size =
             ((amt_remaining > PAGE_SIZE) ? PAGE_SIZE : amt_remaining);
 
-        to_kaddr = pvfs2_kmap(to->page_array[index]);
-        ret = copy_from_user(to_kaddr, offset, cur_copy_size);
-        if(!tmp_printer)
+        to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
+        ret = copy_from_user(to_kaddr, from_kaddr, cur_copy_size);
+        if (!tmp_printer)
         {
             tmp_printer = (char*)(to_kaddr);
             tmp_int += tmp_printer[0];
             gossip_debug(GOSSIP_BUFMAP_DEBUG, "First character (integer value) in pvfs_bufmap_copy_from_user: %d\n", tmp_int);
         }
 
-        pvfs2_kunmap(to->page_array[index]);
+        pvfs2_kunmap(to->page_array[to_page_index]);
 
         if (ret)
         {
@@ -638,9 +642,9 @@ int pvfs_bufmap_copy_from_user(
             return -EFAULT;
         }
 
-        offset += cur_copy_size;
+        from_kaddr += cur_copy_size;
         amt_copied += cur_copy_size;
-        index++;
+        to_page_index++;
     }
     up_read(&bufmap_init_sem);
     return 0;
@@ -649,10 +653,12 @@ int pvfs_bufmap_copy_from_user(
 /*
  * pvfs_bufmap_copy_to_pages() 
  *
- * Copies data from client-core's address space to the specified 
- * pages (typically page-cache pages) for a specified size and 
+ * Copies data from the mapped buffer to the specified set of
+ * kernel pages (typically page-cache pages) for a specified size and 
  * number of pages.
  * NOTE: iovec is expected to store pointers to struct page
+ *
+ * Returns 0 on success, -errno on failure.
  */
 int pvfs_bufmap_copy_to_pages(int buffer_index,
                               const struct iovec *vec, 
@@ -660,7 +666,7 @@ int pvfs_bufmap_copy_to_pages(int buffer
                               size_t size)
 {
     size_t amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
-    int index = 0;
+    int from_page_index = 0;
     void *from_kaddr = NULL, *to_kaddr = NULL;
     struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
     struct page *page;
@@ -680,17 +686,17 @@ int pvfs_bufmap_copy_to_pages(int buffer
 
     while (amt_copied < size)
     {
-        if (index >= nr_segs) 
+        if (from_page_index >= nr_segs) 
         {
             gossip_err("pvfs_bufmap_copy_to_pages: count cannot exceed "
                        "number of pages(%lu)\n", nr_segs);
             up_read(&bufmap_init_sem);
             return -EIO;
         }
-        page = (struct page *) vec[index].iov_base;
+        page = (struct page *) vec[from_page_index].iov_base;
         if (page == NULL) {
             gossip_err("pvfs_bufmap_copy_to_pages: invalid page pointer %d\n",
-                        index);
+                        from_page_index);
             up_read(&bufmap_init_sem);
             return -EIO;
         }
@@ -699,9 +705,9 @@ int pvfs_bufmap_copy_to_pages(int buffer
                           PAGE_SIZE : amt_remaining);
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_pages:"
                                           "from_page: %p, to_page: %p\n",
-                                          from->page_array[index], page);
+                                          from->page_array[from_page_index], page);
 
-        from_kaddr = pvfs2_kmap(from->page_array[index]);
+        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
         to_kaddr = pvfs2_kmap(page);
 #if 0
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_pages -> "
@@ -714,10 +720,10 @@ int pvfs_bufmap_copy_to_pages(int buffer
             memset(to_kaddr + cur_copy_size, 0, PAGE_SIZE - cur_copy_size);
         }
         pvfs2_kunmap(page);
-        pvfs2_kunmap(from->page_array[index]);
+        pvfs2_kunmap(from->page_array[from_page_index]);
 
         amt_copied += cur_copy_size;
-        index++;
+        from_page_index++;
     }
     up_read(&bufmap_init_sem);
     return 0;
@@ -726,10 +732,12 @@ int pvfs_bufmap_copy_to_pages(int buffer
 /*
  * pvfs_bufmap_copy_from_pages() 
  *
- * Copies data to client-core's address space from the specified target 
+ * Copies data to the mapped buffer from the specified set of target 
  * pages (typically the kernel's page-cache)
  * for a given size and number of pages.
- * NOTE: iovec is expected to store pointers to struct page
+ * NOTE: iovec is expected to store pointers to struct page.
+ *
+ * Returns 0 on success and -errno on failure.
  */
 int pvfs_bufmap_copy_from_pages(int buffer_index, 
                                 const struct iovec *vec,
@@ -737,7 +745,7 @@ int pvfs_bufmap_copy_from_pages(int buff
                                 size_t size)
 {
     size_t amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
-    int index = 0;
+    int to_page_index = 0;
     void *from_kaddr = NULL, *to_kaddr = NULL;
     struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
     struct page *page;
@@ -757,13 +765,13 @@ int pvfs_bufmap_copy_from_pages(int buff
 
     while (amt_copied < size)
     {
-        if (index >= nr_segs) {
+        if (to_page_index >= nr_segs) {
             gossip_err("pvfs_bufmap_copy_from_pages: count cannot exceed number of"
                        "pages(%lu)\n", nr_segs);
             up_read(&bufmap_init_sem);
             return -EIO;
         }
-        page = (struct page *) vec[index].iov_base;
+        page = (struct page *) vec[to_page_index].iov_base;
         if (page == NULL) {
             gossip_err("pvfs_bufmap_copy_from_pages: invalid page pointer\n");
             up_read(&bufmap_init_sem);
@@ -773,8 +781,8 @@ int pvfs_bufmap_copy_from_pages(int buff
         cur_copy_size = ((amt_remaining > PAGE_SIZE) ?
                           PAGE_SIZE : amt_remaining);
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_pages:"
-                "from_page: %p, to_page: %p\n", page, to->page_array[index]);
-        to_kaddr = pvfs2_kmap(to->page_array[index]);
+                "from_page: %p, to_page: %p\n", page, to->page_array[to_page_index]);
+        to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
         from_kaddr = pvfs2_kmap(page);
 #if 0
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_from_pages -> "
@@ -783,9 +791,9 @@ int pvfs_bufmap_copy_from_pages(int buff
 #endif
         memcpy(to_kaddr, from_kaddr, cur_copy_size);
         pvfs2_kunmap(page);
-        pvfs2_kunmap(to->page_array[index]);
+        pvfs2_kunmap(to->page_array[to_page_index]);
         amt_copied += cur_copy_size;
-        index++;
+        to_page_index++;
     }
     up_read(&bufmap_init_sem);
     return 0;
@@ -811,12 +819,12 @@ int pvfs_bufmap_copy_iovec_from_user(
     size_t size)
 {
     size_t ret = 0, amt_copied = 0, cur_copy_size = 0;
-    int index = 0;
+    unsigned int to_page_offset = 0, to_page_index = 0;
     void *to_kaddr = NULL;
     void __user *from_addr = NULL;
     struct iovec *copied_iovec = NULL;
     struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
-    unsigned int seg, page_offset = 0;
+    unsigned int seg;
     char* tmp_printer = NULL;
     int tmp_int = 0;
 
@@ -842,7 +850,7 @@ int pvfs_bufmap_copy_iovec_from_user(
         up_read(&bufmap_init_sem);
         return -ENOMEM;
     }
-    memcpy(copied_iovec, iov, nr_segs * sizeof(struct iovec));
+    memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
     /*
      * Go through each segment in the iovec and make sure that
      * the summation of iov_len matches the given size.
@@ -860,54 +868,54 @@ int pvfs_bufmap_copy_iovec_from_user(
         return -EINVAL;
     }
 
-    index = 0;
+    to_page_index = 0;
+    to_page_offset = 0;
     amt_copied = 0;
     seg = 0;
-    page_offset = 0;
     /* Go through each segment in the iovec and copy its
      * buffer into the mapped buffer one page at a time though
      */
     while (amt_copied < size)
     {
 	struct iovec *iv = &copied_iovec[seg];
-        int inc_index = 0;
+        int inc_to_page_index;
 
-        if (iv->iov_len < (PAGE_SIZE - page_offset)) 
+        if (iv->iov_len < (PAGE_SIZE - to_page_offset)) 
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_addr = iv->iov_base;
-            inc_index = 0;
+            inc_to_page_index = 0;
         }
-        else if (iv->iov_len == (PAGE_SIZE - page_offset))
+        else if (iv->iov_len == (PAGE_SIZE - to_page_offset))
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_addr = iv->iov_base;
-            inc_index = 1;
+            inc_to_page_index = 1;
         }
         else 
         {
-            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - to_page_offset, size - amt_copied);
             from_addr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len -= cur_copy_size;
-            inc_index = 1;
+            inc_to_page_index = 1;
         }
-        to_kaddr = pvfs2_kmap(to->page_array[index]);
-        ret = copy_from_user(to_kaddr + page_offset, from_addr, cur_copy_size);
-        if(!tmp_printer)
+        to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
+        ret = copy_from_user(to_kaddr + to_page_offset, from_addr, cur_copy_size);
+        if (!tmp_printer)
         {
-            tmp_printer = (char*)(to_kaddr+page_offset);
+            tmp_printer = (char*)(to_kaddr + to_page_offset);
             tmp_int += tmp_printer[0];
             gossip_debug(GOSSIP_BUFMAP_DEBUG, "First character (integer value) in pvfs_bufmap_copy_from_user: %d\n", tmp_int);
         }
 
 
-        pvfs2_kunmap(to->page_array[index]);
+        pvfs2_kunmap(to->page_array[to_page_index]);
 #if 0
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_iovec_from_user: copying from user %p to kernel %p %zd bytes (to_kddr: %p,page_offset: %d)\n",
-                from_addr, to_kaddr + page_offset, cur_copy_size, to_kaddr, page_offset); 
+                from_addr, to_kaddr + to_page_offset, cur_copy_size, to_kaddr, to_page_offset); 
 #endif
         if (ret)
         {
@@ -918,12 +926,14 @@ int pvfs_bufmap_copy_iovec_from_user(
         }
 
         amt_copied += cur_copy_size;
-        if (inc_index) {
-            page_offset = 0;
-            index++;
+        if (inc_to_page_index) 
+        {
+            to_page_offset = 0;
+            to_page_index++;
         }
-        else {
-            page_offset += cur_copy_size;
+        else 
+        {
+            to_page_offset += cur_copy_size;
         }
     }
     kfree(copied_iovec);
@@ -950,12 +960,12 @@ int pvfs_bufmap_copy_iovec_from_kernel(
     size_t size)
 {
     size_t amt_copied = 0, cur_copy_size = 0;
-    int index = 0;
+    int to_page_index = 0;
     void *to_kaddr = NULL;
     void *from_kaddr = NULL;
     struct iovec *copied_iovec = NULL;
     struct pvfs_bufmap_desc *to = &desc_array[buffer_index];
-    unsigned int seg, page_offset = 0;
+    unsigned int seg, to_page_offset = 0;
 
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_iovec_from_kernel: index %d, "
                 "size %zd\n", buffer_index, size);
@@ -979,7 +989,7 @@ int pvfs_bufmap_copy_iovec_from_kernel(
         up_read(&bufmap_init_sem);
         return -ENOMEM;
     }
-    memcpy(copied_iovec, iov, nr_segs * sizeof(struct iovec));
+    memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
     /*
      * Go through each segment in the iovec and make sure that
      * the summation of iov_len matches the given size.
@@ -997,54 +1007,56 @@ int pvfs_bufmap_copy_iovec_from_kernel(
         return -EINVAL;
     }
 
-    index = 0;
+    to_page_index = 0;
     amt_copied = 0;
     seg = 0;
-    page_offset = 0;
+    to_page_offset = 0;
     /* Go through each segment in the iovec and copy its
      * buffer into the mapped buffer one page at a time though
      */
     while (amt_copied < size)
     {
 	struct iovec *iv = &copied_iovec[seg];
-        int inc_index = 0;
+        int inc_to_page_index;
 
-        if (iv->iov_len < (PAGE_SIZE - page_offset)) 
+        if (iv->iov_len < (PAGE_SIZE - to_page_offset)) 
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_kaddr = iv->iov_base;
-            inc_index = 0;
+            inc_to_page_index = 0;
         }
-        else if (iv->iov_len == (PAGE_SIZE - page_offset))
+        else if (iv->iov_len == (PAGE_SIZE - to_page_offset))
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             from_kaddr = iv->iov_base;
-            inc_index = 1;
+            inc_to_page_index = 1;
         }
         else 
         {
-            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - to_page_offset, size - amt_copied);
             from_kaddr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len -= cur_copy_size;
-            inc_index = 1;
+            inc_to_page_index = 1;
         }
-        to_kaddr = pvfs2_kmap(to->page_array[index]);
-        memcpy(to_kaddr + page_offset, from_kaddr, cur_copy_size);
-        pvfs2_kunmap(to->page_array[index]);
+        to_kaddr = pvfs2_kmap(to->page_array[to_page_index]);
+        memcpy(to_kaddr + to_page_offset, from_kaddr, cur_copy_size);
+        pvfs2_kunmap(to->page_array[to_page_index]);
 #if 0
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_iovec_from_kernel: copying from kernel %p to kernel %p %zd bytes (to_kddr: %p,page_offset: %d)\n",
                 from_kaddr, to_kaddr + page_offset, cur_copy_size, to_kaddr, page_offset); 
 #endif
         amt_copied += cur_copy_size;
-        if (inc_index) {
-            page_offset = 0;
-            index++;
+        if (inc_to_page_index) 
+        {
+            to_page_offset = 0;
+            to_page_index++;
         }
-        else {
-            page_offset += cur_copy_size;
+        else 
+        {
+            to_page_offset += cur_copy_size;
         }
     }
     kfree(copied_iovec);
@@ -1067,12 +1079,12 @@ int pvfs_bufmap_copy_to_user_iovec(
 {
     size_t ret = 0, amt_copied = 0;
     size_t cur_copy_size = 0;
-    int index = 0;
+    int from_page_index = 0;
     void *from_kaddr = NULL;
     void __user *to_addr = NULL;
     struct iovec *copied_iovec = NULL;
     struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
-    unsigned int seg, page_offset = 0;
+    unsigned int seg, from_page_offset = 0;
     char* tmp_printer = NULL;
     int tmp_int = 0;
 
@@ -1098,7 +1110,7 @@ int pvfs_bufmap_copy_to_user_iovec(
         up_read(&bufmap_init_sem);
         return -ENOMEM;
     }
-    memcpy(copied_iovec, iov, nr_segs * sizeof(struct iovec));
+    memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
     /*
      * Go through each segment in the iovec and make sure that
      * the summation of iov_len is greater than the given size.
@@ -1116,10 +1128,10 @@ int pvfs_bufmap_copy_to_user_iovec(
         return -EINVAL;
     }
 
-    index = 0;
+    from_page_index = 0;
     amt_copied = 0;
     seg = 0;
-    page_offset = 0;
+    from_page_offset = 0;
     /* 
      * Go through each segment in the iovec and copy from the mapper buffer,
      * but make sure that we do so one page at a time.
@@ -1127,42 +1139,42 @@ int pvfs_bufmap_copy_to_user_iovec(
     while (amt_copied < size)
     {
 	struct iovec *iv = &copied_iovec[seg];
-        int inc_index = 0;
+        int inc_from_page_index;
 
-        if (iv->iov_len < (PAGE_SIZE - page_offset))
+        if (iv->iov_len < (PAGE_SIZE - from_page_offset))
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_addr = iv->iov_base;
-            inc_index = 0;
+            inc_from_page_index = 0;
         }
-        else if (iv->iov_len == (PAGE_SIZE - page_offset))
+        else if (iv->iov_len == (PAGE_SIZE - from_page_offset))
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_addr = iv->iov_base;
-            inc_index = 1;
+            inc_from_page_index = 1;
         }
         else 
         {
-            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - from_page_offset, size - amt_copied);
             to_addr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len  -= cur_copy_size;
-            inc_index = 1;
+            inc_from_page_index = 1;
         }
-        from_kaddr = pvfs2_kmap(from->page_array[index]);
-        if(!tmp_printer)
+        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
+        if (!tmp_printer)
         {
-            tmp_printer = (char*)(from_kaddr + page_offset);
+            tmp_printer = (char*)(from_kaddr + from_page_offset);
             tmp_int += tmp_printer[0];
             gossip_debug(GOSSIP_BUFMAP_DEBUG, "First character (integer value) in pvfs_bufmap_copy_to_user_iovec: %d\n", tmp_int);
         }
-        ret = copy_to_user(to_addr, from_kaddr + page_offset, cur_copy_size);
-        pvfs2_kunmap(from->page_array[index]);
+        ret = copy_to_user(to_addr, from_kaddr + from_page_offset, cur_copy_size);
+        pvfs2_kunmap(from->page_array[from_page_index]);
 #if 0
         gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_to_user_iovec: copying to user %p from kernel %p %d bytes (from_kaddr:%p, page_offset:%d)\n",
-                to_addr, from_kaddr + page_offset, cur_copy_size, from_kaddr, page_offset); 
+                to_addr, from_kaddr + from_page_offset, cur_copy_size, from_kaddr, from_page_offset); 
 #endif
         if (ret)
         {
@@ -1173,12 +1185,14 @@ int pvfs_bufmap_copy_to_user_iovec(
         }
 
         amt_copied += cur_copy_size;
-        if (inc_index) {
-            page_offset = 0;
-            index++;
+        if (inc_from_page_index) 
+        {
+            from_page_offset = 0;
+            from_page_index++;
         }
-        else {
-            page_offset += cur_copy_size;
+        else 
+        {
+            from_page_offset += cur_copy_size;
         }
     }
     kfree(copied_iovec);
@@ -1201,12 +1215,12 @@ int pvfs_bufmap_copy_to_kernel_iovec(
 {
     size_t amt_copied = 0;
     size_t cur_copy_size = 0;
-    int index = 0;
+    int from_page_index = 0;
     void *from_kaddr = NULL;
     void *to_kaddr = NULL;
     struct iovec *copied_iovec = NULL;
     struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
-    unsigned int seg, page_offset = 0;
+    unsigned int seg, from_page_offset = 0;
 
     gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_kernel_iovec: index %d, "
                 "size %zd\n", buffer_index, size);
@@ -1230,7 +1244,7 @@ int pvfs_bufmap_copy_to_kernel_iovec(
         up_read(&bufmap_init_sem);
         return -ENOMEM;
     }
-    memcpy(copied_iovec, iov, nr_segs * sizeof(struct iovec));
+    memcpy(copied_iovec, iov, nr_segs * sizeof(*copied_iovec));
     /*
      * Go through each segment in the iovec and make sure that
      * the summation of iov_len is greater than the given size.
@@ -1248,10 +1262,10 @@ int pvfs_bufmap_copy_to_kernel_iovec(
         return -EINVAL;
     }
 
-    index = 0;
+    from_page_index = 0;
     amt_copied = 0;
     seg = 0;
-    page_offset = 0;
+    from_page_offset = 0;
     /* 
      * Go through each segment in the iovec and copy from the mapper buffer,
      * but make sure that we do so one page at a time.
@@ -1259,44 +1273,46 @@ int pvfs_bufmap_copy_to_kernel_iovec(
     while (amt_copied < size)
     {
 	struct iovec *iv = &copied_iovec[seg];
-        int inc_index = 0;
+        int inc_from_page_index;
 
-        if (iv->iov_len < (PAGE_SIZE - page_offset))
+        if (iv->iov_len < (PAGE_SIZE - from_page_offset))
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_kaddr = iv->iov_base;
-            inc_index = 0;
+            inc_from_page_index = 0;
         }
-        else if (iv->iov_len == (PAGE_SIZE - page_offset))
+        else if (iv->iov_len == (PAGE_SIZE - from_page_offset))
         {
             cur_copy_size = PVFS_util_min(iv->iov_len, size - amt_copied);
             seg++;
             to_kaddr = iv->iov_base;
-            inc_index = 1;
+            inc_from_page_index = 1;
         }
         else 
         {
-            cur_copy_size = PVFS_util_min(PAGE_SIZE - page_offset, size - amt_copied);
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - from_page_offset, size - amt_copied);
             to_kaddr = iv->iov_base;
             iv->iov_base += cur_copy_size;
             iv->iov_len  -= cur_copy_size;
-            inc_index = 1;
+            inc_from_page_index = 1;
         }
-        from_kaddr = pvfs2_kmap(from->page_array[index]);
-        memcpy(to_kaddr, from_kaddr + page_offset, cur_copy_size);
-        pvfs2_kunmap(from->page_array[index]);
+        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
+        memcpy(to_kaddr, from_kaddr + from_page_offset, cur_copy_size);
+        pvfs2_kunmap(from->page_array[from_page_index]);
 #if 0
-        gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_copy_to_kernel_iovec: copying to kernel %p from kernel %p %d bytes (from_kaddr:%p, page_offset:%d)\n",
+        gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_kernel_iovec: copying to kernel %p from kernel %p %d bytes (from_kaddr:%p, page_offset:%d)\n",
                 to_kaddr, from_kaddr + page_offset, cur_copy_size, from_kaddr, page_offset); 
 #endif
         amt_copied += cur_copy_size;
-        if (inc_index) {
-            page_offset = 0;
-            index++;
+        if (inc_from_page_index) 
+        {
+            from_page_offset = 0;
+            from_page_index++;
         }
-        else {
-            page_offset += cur_copy_size;
+        else 
+        {
+            from_page_offset += cur_copy_size;
         }
     }
     kfree(copied_iovec);
@@ -1306,40 +1322,45 @@ int pvfs_bufmap_copy_to_kernel_iovec(
 
 #ifdef HAVE_AIO_VFS_SUPPORT
 
-/* pvfs_bufmap_copy_to_user_task()
+/* pvfs_bufmap_copy_to_user_task_iovec()
  *
- * copies data out of a mapped buffer to a user space address
+ * copies data out of a mapped buffer to a vector of user space address
  * of a given task specified by the task structure argument (tsk)
  * This is used by the client-daemon for completing an aio
  * operation that was issued by an arbitrary user program.
  * Unfortunately, we cannot use a copy_to_user
  * in that case and need to map in the user pages before
  * attempting the copy!
- * returns number of bytes copied on success,
- * -errno on failure
+ *
+ * NOTE: There is no need for an analogous copy from user task since
+ * the data buffers get copied in the context of the process initiating
+ * the write system call!
+ *
+ * Returns number of bytes copied on success, -errno on failure.
  */
-size_t pvfs_bufmap_copy_to_user_task(
+size_t pvfs_bufmap_copy_to_user_task_iovec(
         struct task_struct *tsk,
-        void __user *to, 
+        struct iovec *iovec, unsigned long nr_segs,
         int buffer_index,
-        size_t size)
+        size_t size_to_be_copied)
 {
-    size_t ret = 0, amt_copied = 0, amt_remaining = 0, cur_copy_size = 0;
-    int index = 0;
+    size_t ret = 0, amt_copied = 0, cur_copy_size = 0;
+    int from_page_index = 0;
     void *from_kaddr = NULL;
+    struct iovec *copied_iovec = NULL;
     struct pvfs_bufmap_desc *from = &desc_array[buffer_index];
 
     struct mm_struct *mm = NULL;
     struct vm_area_struct *vma = NULL;
     struct page *page = NULL;
-    unsigned long to_addr = (unsigned long) to;
+    unsigned long to_addr = 0;
     void *maddr = NULL;
-    int to_offset = 0, from_offset = 0;
-    int inc_index = 0;
+    unsigned int to_offset = 0;
+    unsigned int seg, from_page_offset = 0;
 
-    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_user_task: "
-            " PID: %d, to %p, from %p, index %d, "
-            " size %zd\n", tsk->pid, to, from, buffer_index, size);
+    gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs_bufmap_copy_to_user_task_iovec: "
+            " PID: %d, iovec %p, from %p, index %d, "
+            " size %zd\n", tsk->pid, iovec, from, buffer_index, size_to_be_copied);
 
     down_read(&bufmap_init_sem);
     if (bufmap_init == 0)
@@ -1351,22 +1372,78 @@ size_t pvfs_bufmap_copy_to_user_task(
         up_read(&bufmap_init_sem);
         return -EIO;
     }
+    /*
+     * copy the passed in iovec so that we can change some of its fields
+     */
+    copied_iovec = kmalloc(nr_segs * sizeof(*copied_iovec),
+                           PVFS2_BUFMAP_GFP_FLAGS);
+    if (copied_iovec == NULL)
+    {
+        gossip_err("pvfs_bufmap_copy_to_user_iovec: failed allocating memory\n");
+        up_read(&bufmap_init_sem);
+        return -ENOMEM;
+    }
+    memcpy(copied_iovec, iovec, nr_segs * sizeof(*copied_iovec));
+    /*
+     * Go through each segment in the iovec and make sure that
+     * the summation of iov_len is greater than the given size.
+     */
+    for (seg = 0, amt_copied = 0; seg < nr_segs; seg++)
+    {
+        amt_copied += copied_iovec[seg].iov_len;
+    }
+    if (amt_copied < size_to_be_copied)
+    {
+        gossip_err("pvfs_bufmap_copy_to_user_task_iovec: computed total (%zd) "
+                "is less than (%zd)\n", amt_copied, size_to_be_copied);
+        kfree(copied_iovec);
+        up_read(&bufmap_init_sem);
+        return -EINVAL;
+    }
     mm = get_task_mm(tsk);
     if (!mm) 
     {
+        kfree(copied_iovec);
         up_read(&bufmap_init_sem);
         return -EIO;
     }
+    from_page_index = 0;
+    amt_copied = 0;
+    seg = 0;
+    from_page_offset = 0;
     /* 
      * Go through each of the page in the specified process
      * address space and copy from the mapped
      * buffer, and make sure to do this one page at a time!
      */
     down_read(&mm->mmap_sem);
-    while(amt_copied < size)
+    while (amt_copied < size_to_be_copied)
     {
-        int bytes = 0;
+        int inc_from_page_index = 0;
+	struct iovec *iv = &copied_iovec[seg];
 
+        if (iv->iov_len < (PAGE_SIZE - from_page_offset))
+        {
+            cur_copy_size = PVFS_util_min(iv->iov_len, size_to_be_copied - amt_copied);
+            seg++;
+            to_addr = (unsigned long) iv->iov_base;
+            inc_from_page_index = 0;
+        }
+        else if (iv->iov_len == (PAGE_SIZE - from_page_offset))
+        {
+            cur_copy_size = PVFS_util_min(iv->iov_len, size_to_be_copied - amt_copied);
+            seg++;
+            to_addr = (unsigned long) iv->iov_base;
+            inc_from_page_index = 1;
+        }
+        else 
+        {
+            cur_copy_size = PVFS_util_min(PAGE_SIZE - from_page_offset, size_to_be_copied - amt_copied);
+            to_addr = (unsigned long) iv->iov_base;
+            iv->iov_base += cur_copy_size;
+            iv->iov_len  -= cur_copy_size;
+            inc_from_page_index = 1;
+        }
         ret = get_user_pages(tsk, mm, to_addr, 
                 1,/* count */
                 1,/* write */
@@ -1375,52 +1452,33 @@ size_t pvfs_bufmap_copy_to_user_task(
         if (ret <= 0)
             break;
         to_offset = to_addr & (PAGE_SIZE - 1);
-        amt_remaining = (size - amt_copied);
-        if ((PAGE_SIZE - to_offset) < (PAGE_SIZE - from_offset))
-        {
-            bytes = PAGE_SIZE - to_offset;
-            inc_index = 0;
-        }
-        else if ((PAGE_SIZE - to_offset) == (PAGE_SIZE - from_offset))
-        {
-            bytes = (PAGE_SIZE - to_offset);
-            inc_index = 1;
-        }
-        else 
-        {
-            bytes = (PAGE_SIZE - from_offset);
-            inc_index = 1;
-        }
-        cur_copy_size =
-            amt_remaining > bytes 
-                  ? bytes : amt_remaining;
         maddr = pvfs2_kmap(page);
-        from_kaddr = pvfs2_kmap(from->page_array[index]);
+        from_kaddr = pvfs2_kmap(from->page_array[from_page_index]);
         copy_to_user_page(vma, page, to_addr,
              maddr + to_offset /* dst */, 
-             from_kaddr + from_offset, /* src */
+             from_kaddr + from_page_offset, /* src */
              cur_copy_size /* len */);
         set_page_dirty_lock(page);
-        pvfs2_kunmap(from->page_array[index]);
+        pvfs2_kunmap(from->page_array[from_page_index]);
         pvfs2_kunmap(page);
         page_cache_release(page);
 
         amt_copied += cur_copy_size;
-        to_addr += cur_copy_size;
-        if (inc_index)
+        if (inc_from_page_index)
         {
-            from_offset = 0;
-            index++;
+            from_page_offset = 0;
+            from_page_index++;
         }
         else 
         {
-            from_offset += cur_copy_size;
+            from_page_offset += cur_copy_size;
         }
     }
     up_read(&mm->mmap_sem);
     mmput(mm);
     up_read(&bufmap_init_sem);
-    return (amt_copied < size) ? -EFAULT: amt_copied;
+    kfree(copied_iovec);
+    return (amt_copied < size_to_be_copied) ? -EFAULT: amt_copied;
 }
 
 #endif

Index: pvfs2-bufmap.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.h,v
diff -p -u -r1.18 -r1.18.10.1
--- pvfs2-bufmap.h	19 Aug 2007 18:20:28 -0000	1.18
+++ pvfs2-bufmap.h	10 Jul 2008 21:43:59 -0000	1.18.10.1
@@ -96,8 +96,15 @@ int pvfs_bufmap_copy_from_pages(
 size_t pvfs_bufmap_copy_to_user_task(
         struct task_struct *tsk,
         void __user *to,
-        int buffer_index, 
-        size_t size);
+        size_t size,
+        int buffer_index,
+        int *buffer_index_offset);
+size_t pvfs_bufmap_copy_to_user_task_iovec(
+        struct task_struct *tsk,
+        struct iovec *iovec,
+        unsigned long nr_segs,
+        int buffer_index,
+        size_t bytes_to_be_copied);
 #endif
 
 #endif /* __PVFS2_BUFMAP_H */

Index: pvfs2-kernel.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-kernel.h,v
diff -p -u -r1.150.4.1 -r1.150.4.2
--- pvfs2-kernel.h	21 May 2008 18:55:27 -0000	1.150.4.1
+++ pvfs2-kernel.h	10 Jul 2008 21:43:59 -0000	1.150.4.2
@@ -570,7 +570,8 @@ typedef struct
     struct kiocb *kiocb; /* pointer to the kiocb that kicked this operation */
     int buffer_index; /* buffer index that was used for the I/O */
     pvfs2_kernel_op_t *op; /* pvfs2 kernel operation type */
-    char __user *buffer; /* The user space buffer to which I/O is being staged */
+    struct iovec *iov; /* The user space buffers from/to which I/O is being staged */
+    unsigned long nr_segs; /* number of elements in the iovector */
     int   rw; /* set to indicate the type of the operation */
     loff_t offset; /* file offset */
     size_t bytes_to_be_copied; /* and the count in bytes */

Index: super.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/super.c,v
diff -p -u -r1.97.4.1 -r1.97.4.2
--- super.c	21 May 2008 18:55:27 -0000	1.97.4.1
+++ super.c	10 Jul 2008 21:43:59 -0000	1.97.4.2
@@ -967,6 +967,8 @@ struct super_block* pvfs2_get_sb(
     root_object.handle = PVFS2_SB(sb)->root_handle;
     root_object.fs_id  = PVFS2_SB(sb)->fs_id;
 
+    gossip_debug(GOSSIP_SUPER_DEBUG, "get inode %llu, fsid %d\n",
+                 root_object.handle, root_object.fs_id);
     /* alloc and initialize our root directory inode by explicitly requesting
      * the sticky bit to be set */
     root = pvfs2_get_custom_core_inode(
@@ -1027,7 +1029,109 @@ struct super_block* pvfs2_get_sb(
 
 #else /* !PVFS2_LINUX_KERNEL_2_4 */
 
-static struct export_operations pvfs2_export_ops = {};
+#ifdef HAVE_FHTODENTRY_EXPORT_OPERATIONS
+struct dentry *
+pvfs2_fh_to_dentry(struct super_block *sb, struct fid *fid,
+                   int fh_len, int fh_type)
+{
+   PVFS_object_ref refn;
+   struct inode *inode;
+   struct dentry *dentry;
+
+   if (fh_len < 3 || fh_type > 2) 
+   {
+      return NULL;
+   }
+
+   refn.handle = (u64) (fid->raw[0]) << 32;
+   refn.handle |= (u32) fid->raw[1];
+   refn.fs_id  = (u32) fid->raw[2];
+   gossip_debug(GOSSIP_SUPER_DEBUG, "fh_to_dentry: handle %llu, fs_id %d\n",
+                refn.handle, refn.fs_id);
+
+   inode = pvfs2_iget(sb, &refn);
+   if (inode == NULL)
+   {
+      return ERR_PTR(-ESTALE);
+   }
+   if (IS_ERR(inode))
+   {
+      return (void *) inode;
+   }
+   dentry = d_alloc_anon(inode);
+
+   if (dentry == NULL)
+   {
+      iput(inode);
+      return ERR_PTR(-ENOMEM);
+   }
+   dentry->d_op = &pvfs2_dentry_operations;
+   return dentry;
+}
+#endif /* HAVE_FHTODENTRY_EXPORT_OPERATIONS */
+
+#ifdef HAVE_ENCODEFH_EXPORT_OPERATIONS
+int pvfs2_encode_fh(struct dentry *dentry, __u32 *fh, int *max_len, int connectable)
+{
+   struct inode *inode = dentry->d_inode;
+   int len = *max_len;
+   int type = 1;
+   PVFS_object_ref handle;
+   u32 generation;
+
+   /*
+    * if connectable is specified, parent handle identity has to be stashed
+    * as well.
+    */
+   if (len < 3 || (connectable && len < 6)) {
+      gossip_lerr("fh buffer is too small for encoding\n");
+      type = 255;
+      goto out;
+   }
+
+   handle = PVFS2_I(inode)->refn;
+   generation = inode->i_generation;
+   gossip_debug(GOSSIP_SUPER_DEBUG, "Encoding fh: handle %llu, gen %u, fsid %u\n",
+                handle.handle, generation, handle.fs_id);
+
+   len = 3;
+   fh[0] = handle.handle >> 32;
+   fh[1] = handle.handle & 0xffffffff;
+   fh[2] = handle.fs_id;
+
+   if (connectable && !S_ISDIR(inode->i_mode)) {
+      struct inode *parent;
+
+      spin_lock(&dentry->d_lock);
+
+      parent = dentry->d_parent->d_inode;
+      handle = PVFS2_I(parent)->refn;
+      generation = parent->i_generation;
+      fh[3] = handle.handle >> 32;
+      fh[4] = handle.handle & 0xffffffff;
+      fh[5] = handle.fs_id;
+
+      spin_unlock(&dentry->d_lock);
+      len = 6;
+      type = 2;
+      gossip_debug(GOSSIP_SUPER_DEBUG, "Encoding parent: handle %llu, gen %u, fsid %u\n",
+                  handle.handle, generation, handle.fs_id);
+   }
+   *max_len = len;
+
+out:
+   return type;
+}
+#endif /* HAVE_ENCODEFH_EXPORT_OPERATIONS */
+
+static struct export_operations pvfs2_export_ops = {
+#ifdef HAVE_ENCODEFH_EXPORT_OPERATIONS
+   .encode_fh    = pvfs2_encode_fh,
+#endif
+#ifdef HAVE_FHTODENTRY_EXPORT_OPERATIONS
+   .fh_to_dentry = pvfs2_fh_to_dentry,
+#endif
+};
 
 int pvfs2_fill_sb(
     struct super_block *sb,
@@ -1087,6 +1191,8 @@ int pvfs2_fill_sb(
 
     root_object.handle = PVFS2_SB(sb)->root_handle;
     root_object.fs_id  = PVFS2_SB(sb)->fs_id;
+    gossip_debug(GOSSIP_SUPER_DEBUG, "get inode %llu, fsid %d\n",
+                 root_object.handle, root_object.fs_id);
     /* alloc and initialize our root directory inode. be explicit about sticky
      * bit */
     root = pvfs2_get_custom_core_inode(sb, NULL, (S_IFDIR | 0755 | S_ISVTX),



More information about the Pvfs2-cvs mailing list