[Pvfs2-cvs] commit by kunkel in pvfs2/src/kernel/linux-2.6:
pvfs2-bufmap.h super.c file.c pvfs2-bufmap.c devpvfs2-req.c
pvfs2-cache.c
CVS commit program
cvs at parl.clemson.edu
Sat Jan 13 05:16:55 EST 2007
Update of /projects/cvsroot/pvfs2/src/kernel/linux-2.6
In directory parlweb1:/tmp/cvs-serv19417/src/kernel/linux-2.6
Modified Files:
Tag: kunkel-hint-branch
pvfs2-bufmap.h super.c file.c pvfs2-bufmap.c devpvfs2-req.c
pvfs2-cache.c
Log Message:
Synchronization with HEAD
Index: pvfs2-bufmap.h
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.h,v
diff -p -u -r1.13.24.2 -r1.13.24.3
--- pvfs2-bufmap.h 2 Dec 2006 11:22:20 -0000 1.13.24.2
+++ pvfs2-bufmap.h 13 Jan 2007 10:16:54 -0000 1.13.24.3
@@ -18,8 +18,11 @@ struct pvfs_bufmap_desc
struct list_head list_link;
};
-/* this would be a function call if the buffer sizes weren't hard coded */
-#define pvfs_bufmap_size_query() PVFS2_BUFMAP_DEFAULT_DESC_SIZE
+/* pvfs_bufmap_size_query is now an inline function because buffer
+ sizes are not hardcoded */
+int pvfs_bufmap_size_query(void);
+
+int pvfs_bufmap_shift_query(void);
int pvfs_bufmap_initialize(
struct PVFS_dev_map_desc *user_desc);
Index: super.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/super.c,v
diff -p -u -r1.80.2.2 -r1.80.2.3
--- super.c 2 Dec 2006 11:22:19 -0000 1.80.2.2
+++ super.c 13 Jan 2007 10:16:54 -0000 1.80.2.3
@@ -5,6 +5,7 @@
*/
#include "pvfs2-kernel.h"
+#include "pvfs2-bufmap.h"
#include "pvfs2-internal.h"
/* list for storing pvfs2 specific superblocks in use */
@@ -434,15 +435,16 @@ static int pvfs2_statfs(
if (new_op->downcall.status > -1)
{
gossip_debug(GOSSIP_SUPER_DEBUG, "pvfs2_statfs: got %ld blocks available | "
- "%ld blocks total\n",
+ "%ld blocks total | %ld block size\n",
(long) new_op->downcall.resp.statfs.blocks_avail,
- (long) new_op->downcall.resp.statfs.blocks_total);
+ (long) new_op->downcall.resp.statfs.blocks_total,
+ (long) new_op->downcall.resp.statfs.block_size);
buf->f_type = sb->s_magic;
/* stash the fsid as well */
memcpy(&buf->f_fsid, &(PVFS2_SB(sb)->fs_id),
sizeof(PVFS2_SB(sb)->fs_id));
- buf->f_bsize = sb->s_blocksize;
+ buf->f_bsize = new_op->downcall.resp.statfs.block_size;
buf->f_namelen = PVFS2_NAME_LEN;
buf->f_blocks = (sector_t)
@@ -949,8 +951,8 @@ struct super_block* pvfs2_get_sb(
sb->s_op = &pvfs2_s_ops;
sb->s_type = &pvfs2_fs_type;
- sb->s_blocksize = PVFS2_BUFMAP_DEFAULT_DESC_SIZE;
- sb->s_blocksize_bits = PVFS2_BUFMAP_DEFAULT_DESC_SHIFT;
+ sb->s_blocksize = pvfs_bufmap_size_query();
+ sb->s_blocksize_bits = pvfs_bufmap_shift_query();
sb->s_maxbytes = MAX_LFS_FILESIZE;
root_object.handle = PVFS2_SB(sb)->root_handle;
@@ -1070,8 +1072,8 @@ int pvfs2_fill_sb(
sb->s_op = &pvfs2_s_ops;
sb->s_type = &pvfs2_fs_type;
- sb->s_blocksize = PVFS2_BUFMAP_DEFAULT_DESC_SIZE;
- sb->s_blocksize_bits = PVFS2_BUFMAP_DEFAULT_DESC_SHIFT;
+ sb->s_blocksize = pvfs_bufmap_size_query();
+ sb->s_blocksize_bits = pvfs_bufmap_shift_query();
sb->s_maxbytes = MAX_LFS_FILESIZE;
root_object.handle = PVFS2_SB(sb)->root_handle;
Index: file.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/file.c,v
diff -p -u -r1.122.2.2 -r1.122.2.3
--- file.c 2 Dec 2006 11:22:19 -0000 1.122.2.2
+++ file.c 13 Jan 2007 10:16:54 -0000 1.122.2.3
@@ -39,6 +39,10 @@ do {
wake_up_interruptible(&op->io_completion_waitq);\
} while(0)
+#ifndef HAVE_COMBINED_AIO_AND_VECTOR
+/* <2.6.19 called it this instead */
+#define do_sync_read generic_file_read
+#endif
/** Called when a process requests to open a file.
*/
@@ -124,7 +128,7 @@ struct rw_options {
struct kiocb *iocb;
union {
struct {
- struct iovec *iov;
+ const struct iovec *iov;
unsigned long nr_segs;
} address;
struct {
@@ -307,7 +311,9 @@ out:
/*
* The reason we need to do this is to be able to support
* readv and writev that are
- * larger than PVFS_DEFAULT_DESC_SIZE (4 MB). What that means is that
+ * larger than (pvfs_bufmap_size_query())
+ * Default is PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB.
+ * What that means is that
* we will create a new io vec descriptor for those memory addresses that
* go beyond the limit
* Return value for this routine is -ve in case of errors
@@ -315,7 +321,7 @@ out:
* Further, the new_nr_segs pointer is updated to hold the new value
* of number of iovecs, the new_vec pointer is updated to hold the pointer
* to the new split iovec, and the size array is an array of integers holding
- * the number of iovecs that straddle PVFS_DEFAULT_DESC_SIZE.
+ * the number of iovecs that straddle pvfs_bufmap_size_query().
* The max_new_nr_segs value is computed by the caller and returned.
* (It will be (count of all iov_len/ block_size) + 1).
*/
@@ -344,37 +350,33 @@ static int split_iovecs(
*seg_count = 0;
*seg_array = NULL;
/* copy the passed in iovec descriptor to a temp structure */
- orig_iovec = (struct iovec *) kmalloc(nr_segs * sizeof(struct iovec),
- PVFS2_BUFMAP_GFP_FLAGS);
+ orig_iovec = kzalloc(nr_segs * sizeof(*orig_iovec), PVFS2_BUFMAP_GFP_FLAGS);
if (orig_iovec == NULL)
{
gossip_err("split_iovecs: Could not allocate memory for %lu bytes!\n",
- (unsigned long)(nr_segs * sizeof(struct iovec)));
+ (unsigned long)(nr_segs * sizeof(*orig_iovec)));
return -ENOMEM;
}
- new_iovec = (struct iovec *) kmalloc(max_new_nr_segs * sizeof(struct iovec),
+ new_iovec = kzalloc(max_new_nr_segs * sizeof(*new_iovec),
PVFS2_BUFMAP_GFP_FLAGS);
if (new_iovec == NULL)
{
kfree(orig_iovec);
gossip_err("split_iovecs: Could not allocate memory for %lu bytes!\n",
- (unsigned long)(max_new_nr_segs * sizeof(struct iovec)));
+ (unsigned long)(max_new_nr_segs * sizeof(*new_iovec)));
return -ENOMEM;
}
- sizes = (unsigned long *) kmalloc(max_new_nr_segs * sizeof(unsigned long),
- PVFS2_BUFMAP_GFP_FLAGS);
+ sizes = kzalloc(max_new_nr_segs * sizeof(*sizes), PVFS2_BUFMAP_GFP_FLAGS);
if (sizes == NULL)
{
kfree(new_iovec);
kfree(orig_iovec);
gossip_err("split_iovecs: Could not allocate memory for %lu bytes!\n",
- (unsigned long)(max_new_nr_segs * sizeof(int)));
+ (unsigned long)(max_new_nr_segs * sizeof(unsigned long)));
return -ENOMEM;
}
/* copy the passed in iovec to a temp structure */
- memcpy(orig_iovec, original_iovec, nr_segs * sizeof(struct iovec));
- memset(new_iovec, 0, max_new_nr_segs * sizeof(struct iovec));
- memset(sizes, 0, max_new_nr_segs * sizeof(int));
+ memcpy(orig_iovec, original_iovec, nr_segs * sizeof(*orig_iovec));
begin_seg = 0;
repeat:
for (seg = begin_seg; seg < nr_segs; seg++)
@@ -470,7 +472,7 @@ static ssize_t do_direct_readv_writev(st
struct file *file;
unsigned int to_free;
size_t count;
- struct iovec *iov;
+ const struct iovec *iov;
unsigned long nr_segs, seg, new_nr_segs = 0;
unsigned long max_new_nr_segs = 0;
unsigned long seg_count = 0;
@@ -737,7 +739,7 @@ ssize_t pvfs2_file_read(
if (IS_IMMUTABLE(rw.inode))
{
rw.readahead_size = (rw.inode)->i_size;
- return generic_file_read(file, buf, count, offset);
+ return do_sync_read(file, buf, count, offset);
}
else
{
@@ -776,6 +778,8 @@ static ssize_t pvfs2_file_write(
return do_direct_readv_writev(&rw);
}
+/* compat code, < 2.6.19 */
+#ifndef HAVE_COMBINED_AIO_AND_VECTOR
/** Reads data to several contiguous user buffers (an iovec) from a file at a
* specified offset.
*/
@@ -831,6 +835,7 @@ static ssize_t pvfs2_file_writev(
return do_direct_readv_writev(&rw);
}
+#endif
/* Construct a trailer of <file offsets, length pairs> in a buffer that we
@@ -863,7 +868,9 @@ static int construct_file_offset_trailer
/*
* The reason we need to do this is to be able to support readx() and writex()
- * of larger than PVFS_DEFAULT_DESC_SIZE (4 MB). What that means is that
+ * of larger than (pvfs_bufmap_size_query())
+ * (default is PVFS2_BUFMAP_DEFAULT_DESC_SIZE MB).
+ * What that means is that
* we will create a new xtvec descriptor for those file offsets that
* go beyond the limit
* Return value for this routine is -ve in case of errors
@@ -871,7 +878,7 @@ static int construct_file_offset_trailer
* Further, the new_nr_segs pointer is updated to hold the new value
* of number of xtvecs, the new_xtvec pointer is updated to hold the pointer
* to the new split xtvec, and the size array is an array of integers holding
- * the number of xtvecs that straddle PVFS_DEFAULT_DESC_SIZE.
+ * the number of xtvecs that straddle (pvfs_bufmap_size_query()).
* The max_new_nr_segs value is computed by the caller and passed in.
* (It will be (count of all xtv_len/ block_size) + 1).
*/
@@ -900,37 +907,33 @@ static int split_xtvecs(
*seg_count = 0;
*seg_array = NULL;
/* copy the passed in xtvec descriptor to a temp structure */
- orig_xtvec = (struct xtvec *) kmalloc(nr_segs * sizeof(struct xtvec),
- PVFS2_BUFMAP_GFP_FLAGS);
+ orig_xtvec = kmalloc(nr_segs * sizeof(*orig_xtvec), PVFS2_BUFMAP_GFP_FLAGS);
if (orig_xtvec == NULL)
{
gossip_err("split_xtvecs: Could not allocate memory for %lu bytes!\n",
- (unsigned long)(nr_segs * sizeof(struct xtvec)));
+ (unsigned long)(nr_segs * sizeof(*orig_xtvec)));
return -ENOMEM;
}
- new_xtvec = (struct xtvec *) kmalloc(max_new_nr_segs * sizeof(struct xtvec),
+ new_xtvec = kzalloc(max_new_nr_segs * sizeof(*new_xtvec),
PVFS2_BUFMAP_GFP_FLAGS);
if (new_xtvec == NULL)
{
kfree(orig_xtvec);
gossip_err("split_xtvecs: Could not allocate memory for %lu bytes!\n",
- (unsigned long)(max_new_nr_segs * sizeof(struct xtvec)));
+ (unsigned long)(max_new_nr_segs * sizeof(*new_xtvec)));
return -ENOMEM;
}
- sizes = (unsigned long *) kmalloc(max_new_nr_segs * sizeof(unsigned long),
- PVFS2_BUFMAP_GFP_FLAGS);
+ sizes = kzalloc(max_new_nr_segs * sizeof(*sizes), PVFS2_BUFMAP_GFP_FLAGS);
if (sizes == NULL)
{
kfree(new_xtvec);
kfree(orig_xtvec);
gossip_err("split_xtvecs: Could not allocate memory for %lu bytes!\n",
- (unsigned long)(max_new_nr_segs * sizeof(int)));
+ (unsigned long)(max_new_nr_segs * sizeof(*sizes)));
return -ENOMEM;
}
/* copy the passed in xtvec to a temp structure */
- memcpy(orig_xtvec, original_xtvec, nr_segs * sizeof(struct xtvec));
- memset(new_xtvec, 0, max_new_nr_segs * sizeof(struct xtvec));
- memset(sizes, 0, max_new_nr_segs * sizeof(int));
+ memcpy(orig_xtvec, original_xtvec, nr_segs * sizeof(*orig_xtvec));
begin_seg = 0;
count = 0;
tmpnew_nr_segs = 0;
@@ -1207,7 +1210,7 @@ static ssize_t do_direct_readx_writex(st
struct inode *inode = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
unsigned int to_free;
- struct iovec *iov;
+ const struct iovec *iov;
unsigned long seg, nr_segs, xtnr_segs;
struct xtvec *xtvec;
unsigned long max_new_nr_segs_mem, max_new_nr_segs_stream;
@@ -1877,7 +1880,7 @@ static ssize_t do_direct_aio_read_write(
struct inode *inode;
ssize_t error;
pvfs2_inode_t *pvfs2_inode;
- struct iovec *iov;
+ const struct iovec *iov;
unsigned long nr_segs, max_new_nr_segs;
size_t count;
struct kiocb *iocb;
@@ -2091,12 +2094,12 @@ out_error:
return error;
}
-static ssize_t
-pvfs2_file_aio_read(struct kiocb *iocb, char __user *buffer,
- size_t count, loff_t offset)
+static ssize_t pvfs2_file_aio_read_iovec(struct kiocb *iocb,
+ const struct iovec *iov,
+ unsigned long nr_segs, loff_t offset)
{
struct rw_options rw;
- struct iovec vec;
+
memset(&rw, 0, sizeof(rw));
rw.async = !is_sync_kiocb(iocb);
rw.type = IO_READ;
@@ -2105,8 +2108,6 @@ pvfs2_file_aio_read(struct kiocb *iocb,
rw.copy_to_user = 1;
rw.fnstr = __FUNCTION__;
rw.iocb = iocb;
- vec.iov_base = (char __user *) buffer;
- vec.iov_len = count;
rw.file = iocb->ki_filp;
if (!rw.file || !(rw.file)->f_mapping)
{
@@ -2114,13 +2115,19 @@ pvfs2_file_aio_read(struct kiocb *iocb,
}
rw.inode = (rw.file)->f_mapping->host;
rw.pvfs2_inode = PVFS2_I(rw.inode);
- rw.dest.address.iov = &vec;
- rw.dest.address.nr_segs = 1;
+ rw.dest.address.iov = iov;
+ rw.dest.address.nr_segs = nr_segs;
if (IS_IMMUTABLE(rw.inode))
{
rw.readahead_size = (rw.inode)->i_size;
- return generic_file_aio_read(iocb, buffer, count, offset);
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+ return generic_file_aio_read(iocb, iov, nr_segs, offset);
+#else
+ /* compatibility code; know nr_segs == 1 as only caller is the
+ * compat function below */
+ return generic_file_aio_read(iocb, iov->iov_base, iov->iov_len, offset);
+#endif
}
else
{
@@ -2129,12 +2136,11 @@ pvfs2_file_aio_read(struct kiocb *iocb,
}
}
-static ssize_t
-pvfs2_file_aio_write(struct kiocb *iocb, const char __user *buffer,
- size_t count, loff_t offset)
+static ssize_t pvfs2_file_aio_write_iovec(struct kiocb *iocb,
+ const struct iovec *iov,
+ unsigned long nr_segs, loff_t offset)
{
struct rw_options rw;
- struct iovec vec;
memset(&rw, 0, sizeof(rw));
rw.async = !is_sync_kiocb(iocb);
@@ -2145,8 +2151,6 @@ pvfs2_file_aio_write(struct kiocb *iocb,
rw.copy_to_user = 1;
rw.fnstr = __FUNCTION__;
rw.iocb = iocb;
- vec.iov_base = (char __user *) buffer;
- vec.iov_len = count;
rw.file = iocb->ki_filp;
if (!rw.file || !(rw.file)->f_mapping)
{
@@ -2154,12 +2158,37 @@ pvfs2_file_aio_write(struct kiocb *iocb,
}
rw.inode = (rw.file)->f_mapping->host;
rw.pvfs2_inode = PVFS2_I(rw.inode);
- rw.dest.address.iov = &vec;
- rw.dest.address.nr_segs = 1;
+ rw.dest.address.iov = iov;
+ rw.dest.address.nr_segs = nr_segs;
return do_direct_aio_read_write(&rw);
}
+/* compat functions for < 2.6.19 */
+#ifndef HAVE_COMBINED_AIO_AND_VECTOR
+static ssize_t
+pvfs2_file_aio_read(struct kiocb *iocb, char __user *buffer,
+ size_t count, loff_t offset)
+
+{
+ struct iovec iov = {
+ .iov_base = buffer,
+ .iov_len = count,
+ };
+ return pvfs2_file_aio_read_iovec(iocb, &iov, 1, offset);
+}
+
+static ssize_t
+pvfs2_file_aio_write(struct kiocb *iocb, const char __user *buffer,
+ size_t count, loff_t offset)
+{
+ struct iovec iov = {
+ .iov_base = (void __user *) buffer, /* discard const so it fits */
+ .iov_len = count,
+ };
+ return pvfs2_file_aio_write_iovec(iocb, &iov, 1, offset);
+}
#endif
+#endif /* HAVE_AIO_VFS_SUPPORT */
/** Perform a miscellaneous operation on a file.
*/
@@ -2486,11 +2515,17 @@ struct file_operations pvfs2_file_operat
.llseek = pvfs2_file_llseek,
.read = pvfs2_file_read,
.write = pvfs2_file_write,
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+ /* for >= 2.6.19 */
+ .aio_read = pvfs2_file_aio_read_iovec,
+ .aio_write = pvfs2_file_aio_write_iovec,
+#else
.readv = pvfs2_file_readv,
.writev = pvfs2_file_writev,
-#ifdef HAVE_AIO_VFS_SUPPORT
+# ifdef HAVE_AIO_VFS_SUPPORT
.aio_read = pvfs2_file_aio_read,
.aio_write = pvfs2_file_aio_write,
+# endif
#endif
.ioctl = pvfs2_ioctl,
.mmap = pvfs2_file_mmap,
Index: pvfs2-bufmap.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-bufmap.c,v
diff -p -u -r1.42.2.2 -r1.42.2.3
--- pvfs2-bufmap.c 2 Dec 2006 11:22:19 -0000 1.42.2.2
+++ pvfs2-bufmap.c 13 Jan 2007 10:16:55 -0000 1.42.2.3
@@ -7,23 +7,93 @@
#include "pvfs2-bufmap.h"
#include "pint-dev-shared.h"
-#define BUFMAP_PAGE_COUNT (PVFS2_BUFMAP_TOTAL_SIZE/PAGE_SIZE)
-#define PAGES_PER_DESC (PVFS2_BUFMAP_DEFAULT_DESC_SIZE/PAGE_SIZE)
+
+static int bufmap_page_count, pages_per_desc;
+
+static int32_t pvfs2_bufmap_desc_size, pvfs2_bufmap_desc_shift,
+ pvfs2_bufmap_desc_count, pvfs2_bufmap_total_size;
+
+inline int pvfs_bufmap_size_query(void)
+{
+ return pvfs2_bufmap_desc_size;
+}
+
+inline int pvfs_bufmap_shift_query(void)
+{
+ return pvfs2_bufmap_desc_shift;
+}
static int bufmap_init = 0;
static struct page **bufmap_page_array = NULL;
+
/* array to track usage of buffer descriptors */
-static int buffer_index_array[PVFS2_BUFMAP_DESC_COUNT] = {0};
+static int *buffer_index_array = NULL;
static spinlock_t buffer_index_lock = SPIN_LOCK_UNLOCKED;
/* array to track usage of buffer descriptors for readdir/readdirplus */
-int readdir_index_array[PVFS2_READDIR_DESC_COUNT] = {0};
+static int readdir_index_array[PVFS2_READDIR_DEFAULT_DESC_COUNT] = {0};
static spinlock_t readdir_index_lock = SPIN_LOCK_UNLOCKED;
-static struct pvfs_bufmap_desc desc_array[PVFS2_BUFMAP_DESC_COUNT];
+static struct pvfs_bufmap_desc *desc_array = NULL;
+
static DECLARE_WAIT_QUEUE_HEAD(bufmap_waitq);
static DECLARE_WAIT_QUEUE_HEAD(readdir_waitq);
+static int initialize_bufmap_descriptors(int ndescs)
+{
+ int err;
+
+ err = -EINVAL;
+ if (ndescs < 0)
+ {
+ gossip_err("pvfs2: ndescs (%d) cannot be < 0.\n", ndescs);
+ goto out;
+ }
+ err = -ENOMEM;
+ buffer_index_array = (int *) kmalloc(ndescs * sizeof(int),
+ PVFS2_BUFMAP_GFP_FLAGS);
+ if (buffer_index_array == NULL)
+ {
+ gossip_err("pvfs2: could not allocate %d bytes\n",
+ (int) (ndescs * sizeof(int)));
+ goto out;
+ }
+ memset(buffer_index_array, 0, ndescs * sizeof(int));
+
+ desc_array = (struct pvfs_bufmap_desc *)
+ kmalloc(ndescs * sizeof(struct pvfs_bufmap_desc),
+ PVFS2_BUFMAP_GFP_FLAGS);
+ if (desc_array == NULL)
+ {
+ gossip_err("pvfs2: could not allocate %d bytes\n",
+ (int) (ndescs * sizeof(struct pvfs_bufmap_desc)));
+ goto out1;
+ }
+ err = 0;
+ goto out;
+
+out1:
+ kfree(buffer_index_array);
+ buffer_index_array = NULL;
+out:
+ return err;
+}
+
+static void finalize_bufmap_descriptors(void)
+{
+ if (buffer_index_array != NULL)
+ {
+ kfree(buffer_index_array);
+ buffer_index_array = NULL;
+ }
+ if (desc_array != NULL)
+ {
+ kfree(desc_array);
+ desc_array = NULL;
+ }
+ return;
+}
+
/* pvfs_bufmap_initialize()
*
* initializes the mapped buffer interface
@@ -36,7 +106,9 @@ int pvfs_bufmap_initialize(struct PVFS_d
int i = 0;
int offset = 0;
- gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: called\n");
+ gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: called "
+ "(ptr (%p) sz (%d) cnt(%d).\n",
+ user_desc->ptr, user_desc->size, user_desc->count);
if (bufmap_init == 1)
{
@@ -51,34 +123,50 @@ int pvfs_bufmap_initialize(struct PVFS_d
if (PAGE_ALIGN((unsigned long)user_desc->ptr) !=
(unsigned long)user_desc->ptr)
{
- gossip_err("pvfs2 error: memory alignment (front).\n");
+ gossip_err("pvfs2 error: memory alignment (front). %p\n",
+ user_desc->ptr);
goto init_failure;
}
- if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->size)) !=
- (unsigned long)(user_desc->ptr + user_desc->size))
+ if (PAGE_ALIGN(((unsigned long)user_desc->ptr + user_desc->total_size)) !=
+ (unsigned long)(user_desc->ptr + user_desc->total_size))
{
- gossip_err("pvfs2 error: memory alignment (back).\n");
+ gossip_err("pvfs2 error: memory alignment (back).(%p + %d)\n",
+ user_desc->ptr, user_desc->total_size);
goto init_failure;
}
- if (user_desc->size != PVFS2_BUFMAP_TOTAL_SIZE)
+ if (user_desc->total_size != (user_desc->size * user_desc->count))
{
gossip_err("pvfs2 error: user provided an oddly "
- "sized buffer...\n");
+ "sized buffer...(%d, %d, %d)\n",
+ user_desc->total_size, user_desc->size, user_desc->count);
goto init_failure;
}
- if ((PVFS2_BUFMAP_DEFAULT_DESC_SIZE % PAGE_SIZE) != 0)
+ if ((user_desc->size % PAGE_SIZE) != 0)
{
gossip_err("pvfs2 error: bufmap size not page size "
- "divisible.\n");
+ "divisible (%d).\n", user_desc->size);
+ goto init_failure;
+ }
+ /* Initialize critical variables */
+ pvfs2_bufmap_total_size = user_desc->total_size;
+ pvfs2_bufmap_desc_count = user_desc->count;
+ pvfs2_bufmap_desc_size = user_desc->size;
+ pvfs2_bufmap_desc_shift = LOG2(pvfs2_bufmap_desc_size);
+ bufmap_page_count = pvfs2_bufmap_total_size / PAGE_SIZE;
+ pages_per_desc = pvfs2_bufmap_desc_size / PAGE_SIZE;
+ /* Initialize descriptor arrays */
+ if ((ret = initialize_bufmap_descriptors(pvfs2_bufmap_desc_count)) < 0)
+ {
goto init_failure;
}
/* allocate storage to track our page mappings */
- bufmap_page_array = (struct page **)kmalloc(
- BUFMAP_PAGE_COUNT*sizeof(struct page *), PVFS2_BUFMAP_GFP_FLAGS);
+ bufmap_page_array = (struct page **)
+ kmalloc(bufmap_page_count * sizeof(struct page *),
+ PVFS2_BUFMAP_GFP_FLAGS);
if (!bufmap_page_array)
{
ret = -ENOMEM;
@@ -90,7 +178,7 @@ int pvfs_bufmap_initialize(struct PVFS_d
ret = get_user_pages(
current, current->mm, (unsigned long)user_desc->ptr,
- BUFMAP_PAGE_COUNT, 1, 0, bufmap_page_array, NULL);
+ bufmap_page_count, 1, 0, bufmap_page_array, NULL);
up_read(¤t->mm->mmap_sem);
@@ -104,10 +192,10 @@ int pvfs_bufmap_initialize(struct PVFS_d
in theory we could run with what we got, but I will just treat
it as an error for simplicity's sake right now
*/
- if (ret != BUFMAP_PAGE_COUNT)
+ if (ret != bufmap_page_count)
{
gossip_err("pvfs2 error: asked for %d pages, only got %d.\n",
- (int)BUFMAP_PAGE_COUNT, ret);
+ (int) bufmap_page_count, ret);
for(i = 0; i < ret; i++)
{
@@ -129,37 +217,43 @@ int pvfs_bufmap_initialize(struct PVFS_d
it's worth. in 2.4.x, marking the pages does what's expected
and doesn't try to swap out our pages
*/
- for(i = 0; i < BUFMAP_PAGE_COUNT; i++)
+ for(i = 0; i < bufmap_page_count; i++)
{
flush_dcache_page(bufmap_page_array[i]);
pvfs2_set_page_reserved(bufmap_page_array[i]);
}
/* build a list of available descriptors */
- for(offset = 0, i = 0; i < PVFS2_BUFMAP_DESC_COUNT; i++)
+ for(offset = 0, i = 0; i < pvfs2_bufmap_desc_count; i++)
{
desc_array[i].page_array = &bufmap_page_array[offset];
- desc_array[i].array_count = PAGES_PER_DESC;
+ desc_array[i].array_count = pages_per_desc;
desc_array[i].uaddr =
- (user_desc->ptr + (i * PAGES_PER_DESC * PAGE_SIZE));
- offset += PAGES_PER_DESC;
+ (user_desc->ptr + (i * pages_per_desc * PAGE_SIZE));
+ offset += pages_per_desc;
}
/* clear any previously used buffer indices */
spin_lock(&buffer_index_lock);
- for(i = 0; i < PVFS2_BUFMAP_DESC_COUNT; i++)
+ for(i = 0; i < pvfs2_bufmap_desc_count; i++)
{
buffer_index_array[i] = 0;
}
spin_unlock(&buffer_index_lock);
+ spin_lock(&readdir_index_lock);
+ for (i = 0; i < PVFS2_READDIR_DEFAULT_DESC_COUNT; i++)
+ {
+ readdir_index_array[i] = 0;
+ }
+ spin_unlock(&readdir_index_lock);
bufmap_init = 1;
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_initialize: exiting normally\n");
return 0;
- init_failure:
-
+init_failure:
+ finalize_bufmap_descriptors();
return ret;
}
@@ -183,7 +277,7 @@ void pvfs_bufmap_finalize(void)
return;
}
- for(i = 0; i < BUFMAP_PAGE_COUNT; i++)
+ for(i = 0; i < bufmap_page_count; i++)
{
pvfs2_clear_page_reserved(bufmap_page_array[i]);
page_cache_release(bufmap_page_array[i]);
@@ -192,6 +286,7 @@ void pvfs_bufmap_finalize(void)
bufmap_init = 0;
+ finalize_bufmap_descriptors();
gossip_debug(GOSSIP_BUFMAP_DEBUG, "pvfs2_bufmap_finalize: exiting normally\n");
}
@@ -281,7 +376,7 @@ int pvfs_bufmap_get(int *buffer_index)
{
struct slot_args slargs;
- slargs.slot_count = PVFS2_BUFMAP_DESC_COUNT;
+ slargs.slot_count = pvfs2_bufmap_desc_count;
slargs.slot_array = buffer_index_array;
slargs.slot_lock = &buffer_index_lock;
slargs.slot_wq = &bufmap_waitq;
@@ -298,7 +393,7 @@ void pvfs_bufmap_put(int buffer_index)
{
struct slot_args slargs;
- slargs.slot_count = PVFS2_BUFMAP_DESC_COUNT;
+ slargs.slot_count = pvfs2_bufmap_desc_count;
slargs.slot_array = buffer_index_array;
slargs.slot_lock = &buffer_index_lock;
slargs.slot_wq = &bufmap_waitq;
@@ -320,7 +415,7 @@ int readdir_index_get(int *buffer_index)
{
struct slot_args slargs;
- slargs.slot_count = PVFS2_READDIR_DESC_COUNT;
+ slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
slargs.slot_array = readdir_index_array;
slargs.slot_lock = &readdir_index_lock;
slargs.slot_wq = &readdir_waitq;
@@ -331,7 +426,7 @@ void readdir_index_put(int buffer_index)
{
struct slot_args slargs;
- slargs.slot_count = PVFS2_READDIR_DESC_COUNT;
+ slargs.slot_count = PVFS2_READDIR_DEFAULT_DESC_COUNT;
slargs.slot_array = readdir_index_array;
slargs.slot_lock = &readdir_index_lock;
slargs.slot_wq = &readdir_waitq;
Index: devpvfs2-req.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/devpvfs2-req.c,v
diff -p -u -r1.65.2.1 -r1.65.2.2
--- devpvfs2-req.c 25 Sep 2006 12:39:57 -0000 1.65.2.1
+++ devpvfs2-req.c 13 Jan 2007 10:16:55 -0000 1.65.2.2
@@ -544,6 +544,18 @@ static ssize_t pvfs2_devreq_writev(
return count;
}
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+/*
+ * Kernels >= 2.6.19 have no writev, use this instead with SYNC_KEY.
+ */
+static ssize_t pvfs2_devreq_aio_write(struct kiocb *kiocb,
+ const struct iovec *iov,
+ unsigned long count, loff_t offset)
+{
+ return pvfs2_devreq_writev(kiocb->ki_filp, iov, count, &kiocb->ki_pos);
+}
+#endif
+
/* Returns whether any FS are still pending remounted */
static int mark_all_pending_mounts(void)
{
@@ -775,7 +787,9 @@ static int pvfs2_devreq_ioctl(
struct PVFS_dev_map_desc32
{
compat_uptr_t ptr;
+ int32_t total_size;
int32_t size;
+ int32_t count;
};
#ifndef PVFS2_LINUX_KERNEL_2_4
@@ -794,9 +808,13 @@ static unsigned long translate_dev_map26
/* try to put that into a 64-bit layout */
if (put_user(compat_ptr(addr), &p->ptr))
goto err;
- /* copy the remaining field */
+ /* copy the remaining fields */
+ if (copy_in_user(&p->total_size, &p32->total_size, sizeof(int32_t)))
+ goto err;
if (copy_in_user(&p->size, &p32->size, sizeof(int32_t)))
goto err;
+ if (copy_in_user(&p->count, &p32->count, sizeof(int32_t)))
+ goto err;
return (unsigned long) p;
err:
*error = -EFAULT;
@@ -807,17 +825,23 @@ static unsigned long translate_dev_map24
unsigned long args, struct PVFS_dev_map_desc *p, long *error)
{
struct PVFS_dev_map_desc32 __user *p32 = (void __user *) args;
- u32 addr, size;
+ u32 addr, size, total_size, count;
*error = 0;
/* get the ptr from the 32 bit user-space */
if (get_user(addr, &p32->ptr))
goto err;
p->ptr = compat_ptr(addr);
- /* copy the size */
+ /* copy the remaining fields */
+ if (get_user(total_size, &p32->total_size))
+ goto err;
if (get_user(size, &p32->size))
goto err;
+ if (get_user(count, &p32->count))
+ goto err;
+ p->total_size = total_size;
p->size = size;
+ p->count = count;
return 0;
err:
*error = -EFAULT;
@@ -1003,7 +1027,11 @@ struct file_operations pvfs2_devreq_file
poll : pvfs2_devreq_poll
#else
.read = pvfs2_devreq_read,
+#ifdef HAVE_COMBINED_AIO_AND_VECTOR
+ .aio_write = pvfs2_devreq_aio_write,
+#else
.writev = pvfs2_devreq_writev,
+#endif
.open = pvfs2_devreq_open,
.release = pvfs2_devreq_release,
.ioctl = pvfs2_devreq_ioctl,
Index: pvfs2-cache.c
===================================================================
RCS file: /projects/cvsroot/pvfs2/src/kernel/linux-2.6/pvfs2-cache.c,v
diff -p -u -r1.33.2.1 -r1.33.2.2
--- pvfs2-cache.c 25 Sep 2006 12:39:58 -0000 1.33.2.1
+++ pvfs2-cache.c 13 Jan 2007 10:16:55 -0000 1.33.2.2
@@ -27,6 +27,17 @@ static kmem_cache_t *pvfs2_inode_cache =
static kmem_cache_t *pvfs2_kiocb_cache = NULL;
#endif
+#ifdef HAVE_KMEM_CACHE_DESTROY_INT_RETURN
+#define pvfs_kmem_cache_destroy kmem_cache_destroy
+#else
+/* recent kernels do not return a value */
+static int pvfs_kmem_cache_destroy(void *x)
+{
+ kmem_cache_destroy(x);
+ return 0;
+}
+#endif
+
int op_cache_initialize(void)
{
op_cache = kmem_cache_create(
@@ -48,7 +59,7 @@ int op_cache_initialize(void)
int op_cache_finalize(void)
{
- if (kmem_cache_destroy(op_cache) != 0)
+ if (pvfs_kmem_cache_destroy(op_cache) != 0)
{
gossip_err("Failed to destroy pvfs2_op_cache\n");
return -EINVAL;
@@ -212,7 +223,7 @@ int dev_req_cache_initialize(void)
int dev_req_cache_finalize(void)
{
- if (kmem_cache_destroy(dev_req_cache) != 0)
+ if (pvfs_kmem_cache_destroy(dev_req_cache) != 0)
{
gossip_err("Failed to destroy pvfs2_devreqcache\n");
return -EINVAL;
@@ -336,7 +347,7 @@ int pvfs2_inode_cache_finalize(void)
kmem_cache_free(pvfs2_inode_cache, pinode);
}
}
- if (kmem_cache_destroy(pvfs2_inode_cache) != 0)
+ if (pvfs_kmem_cache_destroy(pvfs2_inode_cache) != 0)
{
gossip_err("Failed to destroy pvfs2_inode_cache\n");
return -EINVAL;
@@ -413,7 +424,7 @@ int kiocb_cache_initialize(void)
int kiocb_cache_finalize(void)
{
- if (kmem_cache_destroy(pvfs2_kiocb_cache) != 0)
+ if (pvfs_kmem_cache_destroy(pvfs2_kiocb_cache) != 0)
{
gossip_err("Failed to destroy pvfs2_devreqcache\n");
return -EINVAL;
More information about the Pvfs2-cvs
mailing list