[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(¤t->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