[PVFS2-CVS]
commit by robl in pvfs2-1/src/kernel/linux-2.6: dcache.c
devpvfs2-req.c dir.c file.c namei.c pvfs2-kernel.h pvfs2-proc.c
pvfs2-utils.c super.c waitqueue.c
CVS commit program
cvs at parl.clemson.edu
Wed Jan 18 12:41:29 EST 2006
Update of /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6
In directory parlweb:/tmp/cvs-serv28540/src/kernel/linux-2.6
Modified Files:
dcache.c devpvfs2-req.c dir.c file.c namei.c pvfs2-kernel.h
pvfs2-proc.c pvfs2-utils.c super.c waitqueue.c
Log Message:
[pcarns]:
This patch replaces the following macros:
------------------------
service_operation()
service_cancellation_operation()
service_priority_operation()
service_operation_with_timeout_retry()
service_error_exit_op_with_timeout_retry()
translate_error_if_wait_failed()
pvfs2_kernel_error_code_convert()
With one function that uses flags to modify its behavior as needed:
------------------------
service_operation()
Aside from code simplification, this patch includes many cleanups / bug
fixes:
------------------------
- eliminate jumping to gotos that are defined outside of macro scope
(this led to at least 2 confirmed bugs due to labels not being defined
in the correct function)
- check return code of down_interruptible()
- eliminate duplicatation of error code variables
- normalize all error codes to errno before leaving service_operation()
so that caller does not have to perform extra conversion steps, some
of which were previously buggy
- eliminate implicit modification of "ret" variable by macros
- eliminate PVFS2_WAIT_SUCCESS, PVFS2_WAIT_TIMEOUT_REACHED,
PVFS2_SIGNAL_RECEIVED error codes and replace with 0, ETIMEDOUT, and
EINTR respectively.
Index: dcache.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/dcache.c,v
diff -u -w -p -u -r1.26 -r1.27
--- dcache.c 11 Nov 2005 21:31:08 -0000 1.26
+++ dcache.c 18 Jan 2006 17:41:28 -0000 1.27
@@ -27,7 +27,6 @@ static int pvfs2_d_revalidate_common(str
struct inode *parent_inode = NULL;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *parent = NULL;
- int retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
pvfs2_print("pvfs2_d_revalidate: called on dentry %p.\n", dentry);
@@ -73,9 +72,9 @@ static int pvfs2_d_revalidate_common(str
strncpy(new_op->upcall.req.lookup.d_name,
dentry->d_name.name, PVFS2_NAME_LEN);
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_lookup", retries, error_exit,
- PVFS2_SB(parent_inode->i_sb)->mnt_options.intr);
+ ret = service_operation(
+ new_op, "pvfs2_lookup", PVFS2_OP_RETRY_COUNT,
+ get_interruptible_flag(parent_inode));
if((new_op->downcall.status != 0) ||
(new_op->downcall.resp.lookup.refn.handle !=
@@ -104,11 +103,6 @@ static int pvfs2_d_revalidate_common(str
pvfs2_print("\n");
}
return ret;
-
-error_exit:
- pvfs2_print("pvfs2_d_revalidate: error_exit path.\n");
- op_release(new_op);
- return 0;
}
/* should return 1 if dentry can still be trusted, else 0 */
Index: devpvfs2-req.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/devpvfs2-req.c,v
diff -u -w -p -u -r1.56 -r1.57
--- devpvfs2-req.c 20 Dec 2005 15:33:57 -0000 1.56
+++ devpvfs2-req.c 18 Jan 2006 17:41:28 -0000 1.57
@@ -404,11 +404,9 @@ static ssize_t pvfs2_devreq_writev(
if (op->downcall.status != 0)
{
- ret = pvfs2_kernel_error_code_convert(
+ ret = pvfs2_normalize_to_errno(
op->downcall.status);
- bytes_copied =
- (ret == PVFS2_WAIT_TIMEOUT_REACHED) ? -EIO :
- (ret == PVFS2_WAIT_SIGNAL_RECVD) ? -EINTR: ret;
+ bytes_copied = ret;
}
else {
bytes_copied = op->downcall.resp.io.amt_complete;
@@ -481,7 +479,7 @@ static int pvfs2_devreq_release(
pvfs2_print("pvfs2_devreq_release: trying to finalize\n");
- down_interruptible(&devreq_semaphore);
+ down(&devreq_semaphore);
pvfs_bufmap_finalize();
open_access_count--;
@@ -560,7 +558,11 @@ static int pvfs2_devreq_ioctl(
all of the remounts are serviced (to avoid ops between
mounts to fail)
*/
- down_interruptible(&request_semaphore);
+ ret = down_interruptible(&request_semaphore);
+ if(ret < 0)
+ {
+ return(ret);
+ }
pvfs2_print("pvfs2_devreq_ioctl: priority remount "
"in progress\n");
list_for_each(tmp, &pvfs2_superblocks) {
Index: dir.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/dir.c,v
diff -u -w -p -u -r1.36 -r1.37
--- dir.c 11 Nov 2005 21:31:08 -0000 1.36
+++ dir.c 18 Jan 2006 17:41:28 -0000 1.37
@@ -43,7 +43,7 @@ static int pvfs2_readdir(
void *dirent,
filldir_t filldir)
{
- int ret = 0, retries = PVFS2_OP_RETRY_COUNT;
+ int ret = 0;
PVFS_ds_position pos = 0;
ino_t ino = 0;
struct dentry *dentry = file->f_dentry;
@@ -147,8 +147,8 @@ static int pvfs2_readdir(
}
}
- service_operation_with_timeout_retry(
- new_op, "pvfs2_readdir", retries,
+ ret = service_operation(
+ new_op, "pvfs2_readdir", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(dentry->d_inode));
pvfs2_print("Readdir downcall status is %d (dirent_count "
@@ -260,11 +260,8 @@ static int pvfs2_readdir(
{
pvfs2_print("Failed to readdir (downcall status %d)\n",
new_op->downcall.status);
- ret = -EIO;
}
- error_exit:
- translate_error_if_wait_failed(ret, -EIO, 0);
op_release(new_op);
break;
}
Index: file.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/file.c,v
diff -u -w -p -u -r1.111 -r1.112
--- file.c 13 Jan 2006 22:44:18 -0000 1.111
+++ file.c 18 Jan 2006 17:41:29 -0000 1.112
@@ -112,16 +112,14 @@ ssize_t pvfs2_inode_read(
int copy_to_user,
loff_t readahead_size)
{
- int ret = -1, error_exit = 0;
+ int ret = -1;
size_t each_count = 0, amt_complete = 0;
size_t total_count = 0;
pvfs2_kernel_op_t *new_op = NULL;
int buffer_index = -1;
char *current_buf = buf;
loff_t original_offset = *offset;
- int retries = PVFS2_OP_RETRY_COUNT;
pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
- int dc_status;
if (copy_to_user && (!access_ok(VERIFY_WRITE, buf, count)))
return -EFAULT;
@@ -158,16 +156,12 @@ ssize_t pvfs2_inode_read(
new_op->upcall.req.io.count = each_count;
new_op->upcall.req.io.offset = *offset;
- dc_status = 0; /* macro may jump to error_exit below */
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_read", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_inode_read", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- if (new_op->downcall.status != 0)
+ if (ret < 0)
{
- dc_status = new_op->downcall.status;
-
- error_exit:
/* this macro is defined in pvfs2-kernel.h */
handle_io_error();
@@ -176,19 +170,16 @@ ssize_t pvfs2_inode_read(
termination unless we've got debugging turned on, as
this can happen regularly (i.e. ctrl-c)
*/
- if ((error_exit != 0) && (ret == -EINTR))
+ if(ret == -EINTR)
{
- pvfs2_print("pvfs2_inode_read: returning error %d "
- "(error_exit=%d)\n", ret, error_exit);
+ pvfs2_print("pvfs2_inode_read: returning error %d\n", ret);
}
else
{
pvfs2_error(
"pvfs2_inode_read: error reading from handle %llu, "
- "\n -- downcall status is %d, returning %d "
- "(error_exit=%d)\n",
- llu(pvfs2_ino_to_handle(inode->i_ino)),
- dc_status, ret, error_exit);
+ "\n -- returning %d \n",
+ llu(pvfs2_ino_to_handle(inode->i_ino)), ret);
}
return ret;
}
@@ -215,8 +206,9 @@ ssize_t pvfs2_inode_read(
/* put error code in downcall so that handle_io_error()
* preserves properly
*/
- new_op->downcall.status = -PVFS_EFAULT;
- goto error_exit;
+ new_op->downcall.status = ret;
+ handle_io_error();
+ return(ret);
}
}
@@ -276,16 +268,15 @@ static ssize_t pvfs2_file_write(
size_t count,
loff_t *offset)
{
- int ret = -1, retries = PVFS2_OP_RETRY_COUNT;
+ int ret = -1;
pvfs2_kernel_op_t *new_op = NULL;
char __user *current_buf = (char __user *)buf;
loff_t original_offset = *offset;
- int buffer_index = -1, error_exit = 0;
+ int buffer_index = -1;
size_t each_count = 0, total_count = 0;
struct inode *inode = file->f_dentry->d_inode;
pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
size_t amt_complete = 0;
- int dc_status;
pvfs2_print("pvfs2_file_write: called on %s [f_pos %ld off %ld size %ld]\n",
(file && file->f_dentry && file->f_dentry->d_name.name ?
@@ -364,16 +355,12 @@ static ssize_t pvfs2_file_write(
return ret;
}
- dc_status = 0;
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_file_write", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_file_write", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- if (new_op->downcall.status != 0)
+ if (ret < 0)
{
- dc_status = new_op->downcall.status;
-
- error_exit:
/* this macro is defined in pvfs2-kernel.h */
handle_io_error();
@@ -382,21 +369,19 @@ static ssize_t pvfs2_file_write(
termination unless we've got debugging turned on, as
this can happen regularly (i.e. ctrl-c)
*/
- if ((error_exit != 0) && (ret == -EINTR))
+ if (ret == -EINTR)
{
- pvfs2_print("pvfs2_file_write: returning error %d "
- "(error_exit=%d)\n", ret, error_exit);
+ pvfs2_print("pvfs2_file_write: returning error %d\n", ret);
}
else
{
pvfs2_error(
"pvfs2_file_write: error writing to handle %llu, "
- "FILE: %s\n -- downcall status is %d, returning %d "
- "(error_exit=%d)\n",
+ "FILE: %s\n -- returning %d\n",
llu(pvfs2_ino_to_handle(inode->i_ino)),
(file && file->f_dentry && file->f_dentry->d_name.name ?
(char *)file->f_dentry->d_name.name : "UNKNOWN"),
- dc_status, ret, error_exit);
+ ret);
}
*offset = original_offset;
return ret;
@@ -583,11 +568,11 @@ static ssize_t pvfs2_file_readv(
unsigned long nr_segs,
loff_t *offset)
{
- int ret = -1, retries = PVFS2_OP_RETRY_COUNT;
+ int ret = -1;
pvfs2_kernel_op_t *new_op = NULL;
struct iovec *iovecptr = NULL, *ptr = NULL;
loff_t original_offset = *offset;
- int buffer_index = -1, error_exit = 0;
+ int buffer_index = -1;
struct inode *inode = file->f_dentry->d_inode;
pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
size_t amt_complete = 0;
@@ -674,7 +659,6 @@ static ssize_t pvfs2_file_readv(
seg = 0;
while (total_count < count)
{
- int dc_status = 0;
new_op = op_alloc();
if (!new_op)
{
@@ -715,18 +699,12 @@ static ssize_t pvfs2_file_readv(
new_op->upcall.req.io.count = each_count;
new_op->upcall.req.io.offset = *offset;
-
- dc_status = 0;
-
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_file_readv", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_file_readv", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- if (new_op->downcall.status != 0)
+ if (ret < 0)
{
- dc_status = new_op->downcall.status;
-
- error_exit:
/* this macro is defined in pvfs2-kernel.h */
handle_io_error();
@@ -735,21 +713,19 @@ static ssize_t pvfs2_file_readv(
termination unless we've got debugging turned on, as
this can happen regularly (i.e. ctrl-c)
*/
- if ((error_exit != 0) && (ret == -EINTR))
+ if (ret == -EINTR)
{
- pvfs2_print("pvfs2_file_readv: returning error %d "
- "(error_exit=%d)\n", ret, error_exit);
+ pvfs2_print("pvfs2_file_readv: returning error %d\n", ret);
}
else
{
pvfs2_error(
"pvfs2_file_readv: error writing to handle %llu, "
- "FILE: %s\n -- downcall status is %d, returning %d "
- "(error_exit=%d)\n",
+ "FILE: %s\n -- returning %d\n",
llu(pvfs2_ino_to_handle(inode->i_ino)),
(file && file->f_dentry && file->f_dentry->d_name.name ?
(char *)file->f_dentry->d_name.name : "UNKNOWN"),
- dc_status, ret, error_exit);
+ ret);
}
*offset = original_offset;
if (to_free) {
@@ -780,8 +756,9 @@ static ssize_t pvfs2_file_readv(
"that the pvfs2-client is running.\n");
/* put error codes in downcall so that handle_io_error()
* preserves it properly */
- new_op->downcall.status = -PVFS_EFAULT;
- goto error_exit;
+ new_op->downcall.status = ret;
+ handle_io_error();
+ return(ret);
}
}
/* advance the iovec pointer */
@@ -826,11 +803,11 @@ static ssize_t pvfs2_file_writev(
unsigned long nr_segs,
loff_t *offset)
{
- int ret = -1, retries = PVFS2_OP_RETRY_COUNT;
+ int ret = -1;
pvfs2_kernel_op_t *new_op = NULL;
struct iovec *iovecptr = NULL, *ptr = NULL;
loff_t original_offset = *offset;
- int buffer_index = -1, error_exit = 0;
+ int buffer_index = -1;
struct inode *inode = file->f_dentry->d_inode;
pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
size_t amt_complete = 0;
@@ -931,7 +908,6 @@ static ssize_t pvfs2_file_writev(
seg = 0;
while (total_count < count)
{
- int dc_status = 0;
new_op = op_alloc();
if (!new_op)
{
@@ -995,16 +971,12 @@ static ssize_t pvfs2_file_writev(
return ret;
}
- dc_status = 0;
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_file_writev", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_file_writev", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- if (new_op->downcall.status != 0)
+ if (ret < 0)
{
- dc_status = new_op->downcall.status;
-
- error_exit:
/* this macro is defined in pvfs2-kernel.h */
handle_io_error();
@@ -1013,21 +985,19 @@ static ssize_t pvfs2_file_writev(
termination unless we've got debugging turned on, as
this can happen regularly (i.e. ctrl-c)
*/
- if ((error_exit != 0) && (ret == -EINTR))
+ if (ret == -EINTR)
{
- pvfs2_print("pvfs2_file_writev: returning error %d "
- "(error_exit=%d)\n", ret, error_exit);
+ pvfs2_print("pvfs2_file_writev: returning error %d\n", ret);
}
else
{
pvfs2_error(
"pvfs2_file_writev: error writing to handle %llu, "
- "FILE: %s\n -- downcall status is %d, returning %d "
- "(error_exit=%d)\n",
+ "FILE: %s\n -- returning %d\n",
llu(pvfs2_ino_to_handle(inode->i_ino)),
(file && file->f_dentry && file->f_dentry->d_name.name ?
(char *)file->f_dentry->d_name.name : "UNKNOWN"),
- dc_status, ret, error_exit);
+ ret);
}
*offset = original_offset;
if (to_free) {
@@ -1469,15 +1439,13 @@ pvfs2_file_aio_read(struct kiocb *iocb,
if (filp && filp->f_mapping
&& (inode = filp->f_mapping->host))
{
- int dc_status = 0;
ssize_t ret = 0;
pvfs2_kiocb *x = NULL;
/* First time submission */
if ((x = (pvfs2_kiocb *) iocb->private) == NULL)
{
- int buffer_index = -1, error_exit = 0;
- int retries = PVFS2_OP_RETRY_COUNT;
+ int buffer_index = -1;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_kiocb pvfs_kiocb;
char __user *current_buf = buffer;
@@ -1513,7 +1481,6 @@ pvfs2_file_aio_read(struct kiocb *iocb,
new_op->upcall.req.io.buf_index = buffer_index;
new_op->upcall.req.io.count = count;
new_op->upcall.req.io.offset = offset;
- dc_status = 0;
/*
* if it is a synchronous operation, we
* don't allocate anything here
@@ -1548,35 +1515,31 @@ pvfs2_file_aio_read(struct kiocb *iocb,
{
/*
* Stage the operation!
- * On an error, macro jumps to error_exit
*/
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_file_aio_read", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_file_aio_read", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- if (new_op->downcall.status != 0)
+ if (ret < 0)
{
- dc_status = new_op->downcall.status;
- error_exit:
handle_sync_aio_error();
/*
don't write an error to syslog on signaled operation
termination unless we've got debugging turned on, as
this can happen regularly (i.e. ctrl-c)
*/
- if ((error_exit != 0) && (ret == -EINTR))
+ if (ret == -EINTR)
{
- pvfs2_print("pvfs2_file_aio_read: returning error %d "
- "(error_exit=%d)\n", (int) ret, error_exit);
+ pvfs2_print("pvfs2_file_aio_read: returning error %d\n"
+ , (int) ret);
}
else
{
pvfs2_error(
"pvfs2_file_aio_read: error reading from "
" handle %llu, "
- "\n -- downcall status is %d, returning %d "
- "(error_exit=%d)\n",
+ "\n -- returning %d\n",
llu(pvfs2_ino_to_handle(inode->i_ino)),
- dc_status, (int) ret, error_exit);
+ (int) ret);
}
error = ret;
goto out_error;
@@ -1591,9 +1554,10 @@ pvfs2_file_aio_read(struct kiocb *iocb,
if (ret)
{
pvfs2_print("Failed to copy user buffer %d\n", (int) ret);
- new_op->downcall.status = -PVFS_EFAULT;
- /* error is set in the goto target */
- goto error_exit;
+ new_op->downcall.status = ret;
+ handle_sync_aio_error();
+ error = ret;
+ goto out_error;
}
error = new_op->downcall.resp.io.amt_complete;
wake_up_device_for_return(new_op);
@@ -1723,7 +1687,6 @@ pvfs2_file_aio_write(struct kiocb *iocb,
error = -EINVAL;
if (filp && inode)
{
- int dc_status = 0;
ssize_t ret = 0;
pvfs2_kiocb *x = NULL;
@@ -1731,7 +1694,6 @@ pvfs2_file_aio_write(struct kiocb *iocb,
if ((x = (pvfs2_kiocb *) iocb->private) == NULL)
{
int buffer_index = -1;
- int retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_kiocb pvfs_kiocb;
char __user *current_buf = (char *) buffer;
@@ -1787,7 +1749,6 @@ pvfs2_file_aio_write(struct kiocb *iocb,
goto out_error;
}
- dc_status = 0;
/*
* if it is a synchronous operation, we
* don't allocate anything here
@@ -1822,25 +1783,22 @@ pvfs2_file_aio_write(struct kiocb *iocb,
{
/*
* Stage the operation!
- * On an error, macro jumps to error_exit
*/
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_file_aio_write", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_file_aio_write", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- if (new_op->downcall.status != 0)
+ if (ret < 0)
{
- dc_status = new_op->downcall.status;
- error_exit:
handle_sync_aio_error();
/*
don't write an error to syslog on signaled operation
termination unless we've got debugging turned on, as
this can happen regularly (i.e. ctrl-c)
*/
- if ((error_exit != 0) && (ret == -EINTR))
+ if (ret == -EINTR)
{
- pvfs2_print("pvfs2_file_aio_write: returning error %d "
- "(error_exit=%d)\n", (int) ret, error_exit);
+ pvfs2_print("pvfs2_file_aio_write: returning error %d\n",
+ (int) ret);
}
else
{
@@ -1848,13 +1806,12 @@ pvfs2_file_aio_write(struct kiocb *iocb,
"pvfs2_file_aio_write: error writing to "
" handle %llu, "
"FILE: %s\n -- "
- "downcall status is %d, returning %d "
- "(error_exit=%d)\n",
+ "returning %d\n",
llu(pvfs2_ino_to_handle(inode->i_ino)),
(filp && filp->f_dentry
&& filp->f_dentry->d_name.name ?
(char *)filp->f_dentry->d_name.name : "UNKNOWN"),
- dc_status, (int) ret, error_exit);
+ (int) ret);
}
error = ret;
goto out_error;
@@ -2022,17 +1979,12 @@ int pvfs2_fsync(
new_op->upcall.type = PVFS2_VFS_OP_FSYNC;
new_op->upcall.req.fsync.refn = pvfs2_inode->refn;
- service_operation(new_op, "pvfs2_fsync",
+ ret = service_operation(new_op, "pvfs2_fsync", 0,
get_interruptible_flag(file->f_dentry->d_inode));
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
-
pvfs2_print("pvfs2_fsync got return value of %d\n",ret);
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
-
return ret;
}
Index: namei.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/namei.c,v
diff -u -w -p -u -r1.74 -r1.75
--- namei.c 7 Jan 2006 02:47:27 -0000 1.74
+++ namei.c 18 Jan 2006 17:41:29 -0000 1.75
@@ -67,7 +67,7 @@ struct dentry *pvfs2_lookup(
struct nameidata *nd)
#endif
{
- int ret = -EINVAL, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -EINVAL;
struct inode *inode = NULL;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *parent = NULL, *found_pvfs2_inode = NULL;
@@ -147,11 +147,9 @@ struct dentry *pvfs2_lookup(
((new_op->upcall.req.lookup.sym_follow ==
PVFS2_LOOKUP_LINK_FOLLOW) ? "yes" : "no"));
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_lookup", retries, error_exit,
- PVFS2_SB(dir->i_sb)->mnt_options.intr);
-
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
+ ret = service_operation(
+ new_op, "pvfs2_lookup", PVFS2_OP_RETRY_COUNT,
+ get_interruptible_flag(dir));
pvfs2_print("Lookup Got %llu, fsid %d (ret=%d)\n",
llu(new_op->downcall.resp.lookup.refn.handle),
@@ -200,9 +198,6 @@ struct dentry *pvfs2_lookup(
}
}
- error_exit:
- op_release(new_op);
-
/*
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
@@ -213,8 +208,7 @@ struct dentry *pvfs2_lookup(
already exists that was interrupted during this lookup -- no
need to add another negative dentry for an existing file)
*/
- pvfs2_print("error_exit = %d\n", error_exit);
- if (!inode && !error_exit)
+ if (!inode && (new_op->op_state == PVFS2_VFS_STATE_SERVICED))
{
/*
make sure to set the pvfs2 specific dentry operations for
@@ -228,6 +222,8 @@ struct dentry *pvfs2_lookup(
dentry->d_op = &pvfs2_dentry_operations;
d_add(dentry, inode);
}
+
+ op_release(new_op);
return NULL;
}
@@ -358,7 +354,7 @@ static int pvfs2_rename(
struct inode *new_dir,
struct dentry *new_dentry)
{
- int ret = -EINVAL, retries = 5, are_directories = 0;
+ int ret = -EINVAL, are_directories = 0;
pvfs2_inode_t *pvfs2_old_parent_inode = PVFS2_I(old_dir);
pvfs2_inode_t *pvfs2_new_parent_inode = PVFS2_I(new_dir);
pvfs2_kernel_op_t *new_op = NULL;
@@ -430,12 +426,10 @@ static int pvfs2_rename(
strncpy(new_op->upcall.req.rename.d_new_name,
new_dentry->d_name.name, PVFS2_NAME_LEN);
- service_operation_with_timeout_retry(
- new_op, "pvfs2_rename", retries,
+ ret = service_operation(
+ new_op, "pvfs2_rename", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(old_dentry->d_inode));
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
-
pvfs2_print("pvfs2_rename: got downcall status %d\n", ret);
if (new_dentry->d_inode)
@@ -462,8 +456,6 @@ static int pvfs2_rename(
}
#endif
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
#ifdef PVFS2_LINUX_KERNEL_2_4
Index: pvfs2-kernel.h
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-kernel.h,v
diff -u -w -p -u -r1.109 -r1.110
--- pvfs2-kernel.h 13 Jan 2006 22:16:04 -0000 1.109
+++ pvfs2-kernel.h 18 Jan 2006 17:41:29 -0000 1.110
@@ -195,12 +195,6 @@ sizeof(uint64_t) + sizeof(pvfs2_downcall
#define PVFS2_VFS_STATE_INPROGR 0x00FF0002
#define PVFS2_VFS_STATE_SERVICED 0x00FF0003
-/* defines used for wait_for_matching_downcall return values */
-#define PVFS2_WAIT_ERROR 0xFFFFFFFF
-#define PVFS2_WAIT_SUCCESS 0x00000000
-#define PVFS2_WAIT_TIMEOUT_REACHED 0x00EC0001
-#define PVFS2_WAIT_SIGNAL_RECVD 0x00EC0002
-
/* Defines for incrementing aio_ref_count */
#ifndef HAVE_AIO_VFS_SUPPORT
#define get_op(op)
@@ -581,9 +575,6 @@ int pvfs2_truncate_inode(
struct inode *inode,
loff_t size);
-PVFS_error pvfs2_kernel_error_code_convert(
- PVFS_error pvfs2_error_code);
-
void pvfs2_inode_initialize(
pvfs2_inode_t *pvfs2_inode);
@@ -616,6 +607,8 @@ int pvfs2_cancel_op_in_progress(
PVFS_time pvfs2_convert_time_field(
void *time_ptr);
+int pvfs2_normalize_to_errno(PVFS_error error_code);
+
/************************************
* misc convenience macros
************************************/
@@ -669,151 +662,13 @@ do {
&(op->tag)); \
} while(0)
-#define translate_error_if_wait_failed(ret, etime, esig) \
-do { \
- if (ret == PVFS2_WAIT_TIMEOUT_REACHED) \
- { \
- ret = (etime ? etime : -EINVAL); \
- pvfs2_print("OP timed out. Returning %d\n", (int)ret); \
- } \
- else if (ret == PVFS2_WAIT_SIGNAL_RECVD) \
- { \
- ret = (esig ? esig : -EINTR); \
- pvfs2_print("OP interrupted. Returning %d\n", (int)ret); \
- } \
-} while(0)
-
-#define service_operation(op, method, intr) \
-do { \
- sigset_t orig_sigset; \
- if (!intr) mask_blocked_signals(&orig_sigset); \
- down_interruptible(&request_semaphore); \
- add_op_to_request_list(op); \
- up(&request_semaphore); \
- ret = wait_for_matching_downcall(op); \
- if (!intr) unmask_blocked_signals(&orig_sigset); \
- if (ret != PVFS2_WAIT_SUCCESS) \
- { \
- if (ret == PVFS2_WAIT_TIMEOUT_REACHED) \
- { \
- pvfs2_error("%s -- wait timed out (%x). " \
- "aborting attempt.\n", method, (int)ret); \
- } \
- goto error_exit; \
- } \
-} while(0)
-
-#define service_cancellation_operation(op) \
-do { \
- down_interruptible(&request_semaphore); \
- add_op_to_request_list(op); \
- up(&request_semaphore); \
- ret = wait_for_cancellation_downcall(op); \
- if (ret != PVFS2_WAIT_SUCCESS) \
- { \
- if (ret == PVFS2_WAIT_TIMEOUT_REACHED) \
- { \
- pvfs2_error("pvfs2_op_cancel: wait timed out " \
- "(%x). aborting attempt.\n", (int)ret); \
- } \
- goto error_exit; \
- } \
-} while(0)
+#define PVFS2_OP_INTERRUPTIBLE 1 /**< service_operation() is interruptible */
+#define PVFS2_OP_PRIORITY 2 /**< service_operation() is high priority */
+#define PVFS2_OP_CANCELLATION 4 /**< this is a cancellation */
+#define PVFS2_OP_NO_SEMAPHORE 8 /**< don't acquire semaphore */
-#define service_priority_operation(op, method, intr) \
-do { \
- sigset_t orig_sigset; \
- if (!intr) mask_blocked_signals(&orig_sigset); \
- add_priority_op_to_request_list(op); \
- ret = wait_for_matching_downcall(op); \
- if (!intr) unmask_blocked_signals(&orig_sigset); \
- if (ret != PVFS2_WAIT_SUCCESS) \
- { \
- if (ret == PVFS2_WAIT_TIMEOUT_REACHED) \
- { \
- pvfs2_error("%s -- wait timed out (%x). " \
- "aborting attempt.\n", method,(int)ret); \
- } \
- goto error_exit; \
- } \
-} while(0)
-
-/** tries to service the operation and will retry on timeout
- * failure up to num times (num MUST be a numeric lvalue).
- */
-#define service_operation_with_timeout_retry(op, method, num, intr)\
-do { \
- sigset_t orig_sigset; \
- wait_for_op: \
- if (!intr) mask_blocked_signals(&orig_sigset); \
- down_interruptible(&request_semaphore); \
- add_op_to_request_list(op); \
- up(&request_semaphore); \
- ret = wait_for_matching_downcall(op); \
- if (!intr) unmask_blocked_signals(&orig_sigset); \
- if (ret != PVFS2_WAIT_SUCCESS) \
- { \
- if ((ret == PVFS2_WAIT_TIMEOUT_REACHED) && (--num)) \
- { \
- pvfs2_print("%s -- timeout; requeing op\n", method); \
- goto wait_for_op; \
- } \
- else \
- { \
- if (ret == PVFS2_WAIT_TIMEOUT_REACHED) \
- { \
- pvfs2_error("%s -- wait timed out (%x). aborting "\
- "retry attempts.\n", method, (int) ret); \
- } \
- goto error_exit; \
- } \
- } \
-} while(0)
-
-/** tries to service the operation and will retry on timeout
- * failure up to num times (num MUST be a numeric lvalue).
- *
- * this allows us to know if we've reached the error_exit code path
- * from here or elsewhere
- *
- * \note used in namei.c:lookup(), file.c:pvfs2_inode_read[v](), and
- * file.c:pvfs2_file_write[v]()
- *
- * POSSIBLE OPTIMIZATION:
- * if we realize that on a timeout after several attempts, we still
- * have not been picked off the queue, we will attempt to not send in
- * the cancellation upcall since there is no point.
- * See the NOTES above handle_error() macro as well.
- */
-#define service_error_exit_op_with_timeout_retry(op,meth,num,e,intr)\
-do { \
- sigset_t orig_sigset; \
- wait_for_op: \
- if (!intr) mask_blocked_signals(&orig_sigset); \
- down_interruptible(&request_semaphore); \
- add_op_to_request_list(op); \
- up(&request_semaphore); \
- ret = wait_for_matching_downcall(op); \
- if (!intr) unmask_blocked_signals(&orig_sigset); \
- if (ret != PVFS2_WAIT_SUCCESS) \
- { \
- if ((ret == PVFS2_WAIT_TIMEOUT_REACHED) && (--num)) \
- { \
- pvfs2_print("%s -- timeout; requeing op\n", meth); \
- goto wait_for_op; \
- } \
- else \
- { \
- if (ret == PVFS2_WAIT_TIMEOUT_REACHED) \
- { \
- pvfs2_error("%s -- wait timed out (%x). aborting " \
- " retry attempts.\n", meth, (int)ret); \
- } \
- e = 1; \
- goto error_exit; \
- } \
- } \
-} while(0)
+int service_operation(pvfs2_kernel_op_t* op, const char* op_name,
+ int num_retries, int flags);
/** handles two possible error cases, depending on context.
*
@@ -844,16 +699,13 @@ do {
*/
#define handle_io_error() \
do { \
- if (error_exit) \
+ if(new_op->op_state != PVFS2_VFS_STATE_SERVICED) \
{ \
- ret = pvfs2_cancel_op_in_progress(new_op->tag); \
+ pvfs2_cancel_op_in_progress(new_op->tag); \
op_release(new_op); \
} \
else \
{ \
- ret = pvfs2_kernel_error_code_convert( \
- new_op->downcall.status); \
- translate_error_if_wait_failed(ret, -EIO, 0); \
wake_up_device_for_return(new_op); \
} \
pvfs_bufmap_put(buffer_index); \
@@ -867,16 +719,13 @@ do {
*/
#define handle_sync_aio_error() \
do { \
- if (error_exit) \
+ if(new_op->op_state != PVFS2_VFS_STATE_SERVICED) \
{ \
- ret = pvfs2_cancel_op_in_progress(new_op->tag); \
+ pvfs2_cancel_op_in_progress(new_op->tag); \
op_release(new_op); \
} \
else \
{ \
- ret = pvfs2_kernel_error_code_convert( \
- new_op->downcall.status); \
- translate_error_if_wait_failed(ret, -EIO, 0); \
wake_up_device_for_return(new_op); \
} \
pvfs_bufmap_put(buffer_index); \
@@ -890,16 +739,15 @@ do {
*/
#define service_async_vfs_op(op) \
do { \
- down_interruptible(&request_semaphore); \
+ down(&request_semaphore); \
add_op_to_request_list(op); \
up(&request_semaphore); \
} while(0)
#endif
-
#define get_interruptible_flag(inode) \
-(PVFS2_SB(inode->i_sb)->mnt_options.intr)
+((PVFS2_SB(inode->i_sb)->mnt_options.intr ? PVFS2_OP_INTERRUPTIBLE : 0))
#define get_acl_flag(inode) \
(PVFS2_SB(inode->i_sb)->mnt_options.acl)
Index: pvfs2-proc.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-proc.c,v
diff -u -w -p -u -r1.1 -r1.2
--- pvfs2-proc.c 20 Dec 2005 00:08:29 -0000 1.1
+++ pvfs2-proc.c 18 Jan 2006 17:41:29 -0000 1.2
@@ -58,7 +58,6 @@ static int pvfs2_param_proc_handler(
struct pvfs2_param_extra* extra = ctl->extra1;
int val = 0;
int ret = 0;
- int intr_flag = 0;
ctl_table tmp_ctl = *ctl;
/* override fields in control structure for call to generic proc handler */
@@ -89,7 +88,6 @@ static int pvfs2_param_proc_handler(
pvfs2_print("pvfs2: proc write %d\n", val);
new_op->upcall.req.param.value = val;
new_op->upcall.req.param.type = PVFS2_PARAM_REQUEST_SET;
- intr_flag = 1;
}
else
{
@@ -101,11 +99,8 @@ static int pvfs2_param_proc_handler(
new_op->upcall.req.param.op = extra->op;
/* perform operation (get or set) */
- /* TODO: change logic to use retry fn */
- service_operation(new_op, "pvfs2_param", intr_flag);
-
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
- pvfs2_print("pvfs2_param got return value of %d\n", ret);
+ ret = service_operation(new_op, "pvfs2_param", PVFS2_OP_RETRY_COUNT,
+ PVFS2_OP_INTERRUPTIBLE);
if(ret == 0 && !write)
{
@@ -119,10 +114,7 @@ static int pvfs2_param_proc_handler(
#endif
}
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
-
return(ret);
}
@@ -146,8 +138,6 @@ static int pvfs2_acache_pc_proc_handler(
pvfs2_kernel_op_t *new_op = NULL;
int ret;
int pos = 0;
- int error_exit = 0;
- int retries = PVFS2_OP_RETRY_COUNT;
int to_copy = 0;
int* pc_type = ctl->extra1;
#ifdef HAVE_PROC_HANDLER_SIX_ARG
@@ -173,14 +163,8 @@ static int pvfs2_acache_pc_proc_handler(
new_op->upcall.type = PVFS2_VFS_OP_PERF_COUNT;
/* retrieve performance counters */
- service_error_exit_op_with_timeout_retry(new_op, "pvfs2_perf_count",
- retries, error_exit, 1);
-
- error_exit:
- ret = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(new_op->downcall.status));
-
- pvfs2_print("pvfs2 perf count: returned %d\n", ret);
+ ret = service_operation(new_op, "pvfs2_perf_count",
+ PVFS2_OP_RETRY_COUNT, PVFS2_OP_INTERRUPTIBLE);
if(ret == 0)
{
Index: pvfs2-utils.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/pvfs2-utils.c,v
diff -u -w -p -u -r1.113 -r1.114
--- pvfs2-utils.c 2 Dec 2005 22:15:46 -0000 1.113
+++ pvfs2-utils.c 18 Jan 2006 17:41:29 -0000 1.114
@@ -334,7 +334,7 @@ static inline int copy_attributes_from_i
*/
int pvfs2_inode_getattr(struct inode *inode, uint32_t getattr_mask)
{
- int ret = -EINVAL, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -EINVAL;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -384,12 +384,12 @@ int pvfs2_inode_getattr(struct inode *in
new_op->upcall.req.getattr.refn = pvfs2_inode->refn;
new_op->upcall.req.getattr.mask = getattr_mask;
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_getattr", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_inode_getattr", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
/* check what kind of goodies we got */
- if (new_op->downcall.status > -1)
+ if (ret == 0)
{
if (copy_attributes_to_inode
(inode, &new_op->downcall.resp.getattr.attributes,
@@ -402,15 +402,11 @@ int pvfs2_inode_getattr(struct inode *in
}
}
- error_exit:
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
- translate_error_if_wait_failed(ret, 0, 0);
-
copy_attr_failure:
pvfs2_print("Getattr on handle %llu, fsid %d\n (inode ct = %d) "
- "returned %d (error_exit = %d)\n",
+ "returned %d\n",
llu(pvfs2_inode->refn.handle), pvfs2_inode->refn.fs_id,
- (int)atomic_read(&inode->i_count), ret, error_exit);
+ (int)atomic_read(&inode->i_count), ret);
/* store error code in the inode so that we can retrieve it later if
* needed
*/
@@ -432,7 +428,7 @@ int pvfs2_inode_setattr(
struct inode *inode,
struct iattr *iattr)
{
- int ret = -ENOMEM, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -ENOMEM;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -465,14 +461,10 @@ int pvfs2_inode_setattr(
return(ret);
}
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_setattr", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_inode_setattr", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- error_exit:
- ret = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(new_op->downcall.status));
-
pvfs2_print("pvfs2_inode_setattr: returning %d\n", ret);
/* when request is serviced properly, free req op struct */
@@ -517,7 +509,6 @@ ssize_t pvfs2_inode_getxattr(struct inod
void *buffer, size_t size)
{
ssize_t ret = -ENOMEM;
- int retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
ssize_t length = 0;
@@ -559,13 +550,10 @@ ssize_t pvfs2_inode_getxattr(struct inod
pvfs2_print("pvfs2_inode_getxattr: key %s, key_sz %d\n",
name, (int) new_op->upcall.req.getxattr.key_sz);
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_getxattr", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_inode_getxattr", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- error_exit:
- ret = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(new_op->downcall.status));
/* Upon success, we need to get the value length
* from downcall and return that.
* and also copy the value out to the requester
@@ -635,7 +623,7 @@ ssize_t pvfs2_inode_getxattr(struct inod
int pvfs2_inode_setxattr(struct inode *inode, const char *name,
const void *value, size_t size, int flags)
{
- int ret = -ENOMEM, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -ENOMEM;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -694,14 +682,10 @@ int pvfs2_inode_setxattr(struct inode *i
/* For some reason, val_sz should include the \0 at the end as well */
new_op->upcall.req.setxattr.keyval.val_sz = size + 1;
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_setxattr", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_inode_setxattr", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- error_exit:
- ret = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(new_op->downcall.status));
-
pvfs2_print("pvfs2_inode_setxattr: returning %d\n", ret);
/* when request is serviced properly, free req op struct */
@@ -713,7 +697,7 @@ int pvfs2_inode_setxattr(struct inode *i
int pvfs2_inode_removexattr(struct inode *inode, const char *name)
{
- int ret = -ENOMEM, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -ENOMEM;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -747,14 +731,10 @@ int pvfs2_inode_removexattr(struct inode
new_op->upcall.req.removexattr.key_sz =
strlen(new_op->upcall.req.removexattr.key) + 1;
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_removexattr", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_inode_removexattr", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
- error_exit:
- ret = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(new_op->downcall.status));
-
if (ret == -ENOENT)
{
ret = -ENODATA;
@@ -780,7 +760,7 @@ int pvfs2_inode_removexattr(struct inode
int pvfs2_inode_listxattr(struct inode *inode, char *buffer, size_t size)
{
ssize_t ret = -ENOMEM, total = 0;
- int i, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int i;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *pvfs2_inode = NULL;
ssize_t length = 0;
@@ -818,12 +798,9 @@ int pvfs2_inode_listxattr(struct inode *
new_op->upcall.req.listxattr.refn = pvfs2_inode->refn;
new_op->upcall.req.listxattr.token = token;
new_op->upcall.req.listxattr.requested_count = (size == 0) ? 0 : PVFS_MAX_XATTR_LISTLEN;
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_inode_listxattr", retries,
- error_exit, get_interruptible_flag(inode));
- error_exit:
- ret = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(new_op->downcall.status));
+ ret = service_operation(
+ new_op, "pvfs2_inode_listxattr", PVFS2_OP_RETRY_COUNT,
+ get_interruptible_flag(inode));
if (ret == 0)
{
if (size == 0)
@@ -889,7 +866,7 @@ static inline struct inode *pvfs2_create
int mode,
int *error_code)
{
- int ret = -1, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -1;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *parent = PVFS2_I(dir);
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -922,12 +899,10 @@ static inline struct inode *pvfs2_create
strncpy(new_op->upcall.req.create.d_name,
dentry->d_name.name, PVFS2_NAME_LEN);
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_create_file", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_create_file", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(dir));
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
-
pvfs2_print("Create Got PVFS2 handle %llu on fsid %d (ret=%d)\n",
llu(new_op->downcall.resp.create.refn.handle),
new_op->downcall.resp.create.refn.fs_id, ret);
@@ -961,10 +936,7 @@ static inline struct inode *pvfs2_create
}
else
{
- error_exit:
- *error_code = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(
- new_op->downcall.status));
+ *error_code = ret;
pvfs2_print("pvfs2_create_file: failed with error code %d\n",
*error_code);
@@ -980,7 +952,7 @@ static inline struct inode *pvfs2_create
int mode,
int *error_code)
{
- int ret = -1, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -1;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *parent = PVFS2_I(dir);
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -1013,15 +985,15 @@ static inline struct inode *pvfs2_create
strncpy(new_op->upcall.req.mkdir.d_name,
dentry->d_name.name, PVFS2_NAME_LEN);
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_create_dir", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_create_dir", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(dir));
pvfs2_print("Mkdir Got PVFS2 handle %llu on fsid %d\n",
llu(new_op->downcall.resp.mkdir.refn.handle),
new_op->downcall.resp.mkdir.refn.fs_id);
- if (new_op->downcall.status > -1)
+ if (ret > -1)
{
inode = pvfs2_get_custom_inode(
dir->i_sb, dir, (S_IFDIR | mode), 0, pvfs2_handle_to_ino(
@@ -1050,10 +1022,7 @@ static inline struct inode *pvfs2_create
}
else
{
- error_exit:
- *error_code = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(
- new_op->downcall.status));
+ *error_code = ret;
pvfs2_print("pvfs2_create_dir: failed with error code %d\n",
*error_code);
@@ -1070,7 +1039,7 @@ static inline struct inode *pvfs2_create
int mode,
int *error_code)
{
- int ret = -1, retries = PVFS2_OP_RETRY_COUNT, error_exit = 0;
+ int ret = -1;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *parent = PVFS2_I(dir);
pvfs2_inode_t *pvfs2_inode = NULL;
@@ -1104,12 +1073,10 @@ static inline struct inode *pvfs2_create
PVFS2_NAME_LEN);
strncpy(new_op->upcall.req.sym.target, symname, PVFS2_NAME_LEN);
- service_error_exit_op_with_timeout_retry(
- new_op, "pvfs2_symlink_file", retries, error_exit,
+ ret = service_operation(
+ new_op, "pvfs2_symlink_file", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(dir));
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
-
pvfs2_print("Symlink Got PVFS2 handle %llu on fsid %d (ret=%d)\n",
llu(new_op->downcall.resp.sym.refn.handle),
new_op->downcall.resp.sym.refn.fs_id, ret);
@@ -1143,10 +1110,7 @@ static inline struct inode *pvfs2_create
}
else
{
- error_exit:
- *error_code = (error_exit ? -EINTR :
- pvfs2_kernel_error_code_convert(
- new_op->downcall.status));
+ *error_code = ret;
pvfs2_print("pvfs2_create_symlink: failed with error code %d\n",
*error_code);
@@ -1205,7 +1169,7 @@ int pvfs2_remove_entry(
struct inode *dir,
struct dentry *dentry)
{
- int ret = -EINVAL, retries = PVFS2_OP_RETRY_COUNT;
+ int ret = -EINVAL;
pvfs2_kernel_op_t *new_op = NULL;
pvfs2_inode_t *parent = PVFS2_I(dir);
struct inode *inode = dentry->d_inode;
@@ -1238,15 +1202,15 @@ int pvfs2_remove_entry(
strncpy(new_op->upcall.req.remove.d_name,
dentry->d_name.name, PVFS2_NAME_LEN);
- service_operation_with_timeout_retry(
- new_op, "pvfs2_remove_entry", retries,
+ ret = service_operation(
+ new_op, "pvfs2_remove_entry", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
/*
the remove has no downcall members to retrieve, but
the status value tells us if it went through ok or not
*/
- if (new_op->downcall.status == 0)
+ if (ret == 0)
{
/*
adjust the readdir token if in fact we're in the middle
@@ -1256,9 +1220,7 @@ int pvfs2_remove_entry(
pvfs2_print("token adjustment is %d\n",
parent->readdir_token_adjustment);
}
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
- error_exit:
/* when request is serviced properly, free req op struct */
op_release(new_op);
}
@@ -1269,7 +1231,7 @@ int pvfs2_truncate_inode(
struct inode *inode,
loff_t size)
{
- int ret = -EINVAL, retries = 5;
+ int ret = -EINVAL;
pvfs2_inode_t *pvfs2_inode = PVFS2_I(inode);
pvfs2_kernel_op_t *new_op = NULL;
@@ -1287,20 +1249,16 @@ int pvfs2_truncate_inode(
new_op->upcall.req.truncate.refn = pvfs2_inode->refn;
new_op->upcall.req.truncate.size = (PVFS_size)size;
- service_operation_with_timeout_retry(
- new_op, "pvfs2_truncate_inode", retries,
+ ret = service_operation(
+ new_op, "pvfs2_truncate_inode", PVFS2_OP_RETRY_COUNT,
get_interruptible_flag(inode));
/*
the truncate has no downcall members to retrieve, but
the status value tells us if it went through ok or not
*/
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
-
pvfs2_print("pvfs2: pvfs2_truncate got return value of %d\n",ret);
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
return ret;
@@ -1325,18 +1283,13 @@ int pvfs2_flush_mmap_racache(struct inod
new_op->upcall.type = PVFS2_VFS_OP_MMAP_RA_FLUSH;
new_op->upcall.req.ra_cache_flush.refn = pvfs2_inode->refn;
- service_operation(new_op, "pvfs2_flush_mmap_racache",
+ ret = service_operation(new_op, "pvfs2_flush_mmap_racache", 0,
get_interruptible_flag(inode));
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
-
pvfs2_print("pvfs2_flush_mmap_racache got return "
"value of %d\n",ret);
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
-
return ret;
}
#endif
@@ -1362,8 +1315,7 @@ int pvfs2_unmount_sb(struct super_block
pvfs2_print("Attempting PVFS2 Unmount via host %s\n",
new_op->upcall.req.fs_umount.pvfs2_config_server);
- service_operation(new_op, "pvfs2_fs_umount", 0);
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
+ ret = service_operation(new_op, "pvfs2_fs_umount", 0, 0);
pvfs2_print("pvfs2_unmount: got return value of %d\n", ret);
if (ret)
@@ -1371,10 +1323,7 @@ int pvfs2_unmount_sb(struct super_block
sb = ERR_PTR(ret);
}
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
-
return ret;
}
@@ -1400,46 +1349,13 @@ int pvfs2_cancel_op_in_progress(unsigned
pvfs2_print("Attempting PVFS2 operation cancellation of tag %llu\n",
llu(new_op->upcall.req.cancel.op_tag));
- service_cancellation_operation(new_op);
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
+ ret = service_operation(new_op, "pvfs2_cancel", 0, PVFS2_OP_CANCELLATION);
pvfs2_print("pvfs2_cancel_op_in_progress: got return "
"value of %d\n", ret);
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
-
- return -EINTR;
-}
-
-/* macro defined in include/pvfs2-types.h */
-DECLARE_ERRNO_MAPPING_AND_FN();
-
-PVFS_error pvfs2_kernel_error_code_convert(PVFS_error pvfs2_error_code)
-{
- if ((pvfs2_error_code == PVFS2_WAIT_TIMEOUT_REACHED) ||
- (pvfs2_error_code == PVFS2_WAIT_SIGNAL_RECVD))
- {
- return pvfs2_error_code;
- }
-
- if (IS_PVFS_NON_ERRNO_ERROR(pvfs2_error_code))
- {
- PVFS_error ret = -EPERM;
- int index = PVFS_get_errno_mapping(pvfs2_error_code);
- switch(PINT_non_errno_mapping[index])
- {
- case PVFS_ECANCEL:
- ret = -EINTR;
- break;
- default:
- pvfs2_error("Unhandled pvfs2 error code: %d\n",
- pvfs2_error_code);
- }
- return ret;
- }
- return PVFS_get_errno_mapping(pvfs2_error_code);
+ return (ret);
}
void pvfs2_inode_initialize(pvfs2_inode_t *pvfs2_inode)
@@ -1542,6 +1458,33 @@ PVFS_time pvfs2_convert_time_field(void
pvfs2_time = (PVFS_time)((time_t)tspec->tv_sec);
#endif
return pvfs2_time;
+}
+
+/* macro defined in include/pvfs2-types.h */
+DECLARE_ERRNO_MAPPING_AND_FN();
+
+int pvfs2_normalize_to_errno(PVFS_error error_code)
+{
+ if(error_code > 0)
+ {
+ pvfs2_error("pvfs2: error status receieved.\n");
+ pvfs2_error("pvfs2: assuming error code is inverted.\n");
+ error_code = -error_code;
+ }
+
+ /* convert any error codes that are in pvfs2 format */
+ if(IS_PVFS_NON_ERRNO_ERROR(-error_code))
+ {
+ /* assume a default error code */
+ pvfs2_error("pvfs2: warning: "
+ "got error code without errno equivalent: %d.\n", error_code);
+ error_code = -EINVAL;
+ }
+ else if(IS_PVFS_ERROR(-error_code))
+ {
+ error_code = -PVFS_ERROR_TO_ERRNO(-error_code);
+ }
+ return(error_code);
}
/*
Index: super.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/super.c,v
diff -u -w -p -u -r1.68 -r1.69
--- super.c 10 Jan 2006 21:15:24 -0000 1.68
+++ super.c 18 Jan 2006 17:41:29 -0000 1.69
@@ -319,8 +319,9 @@ static int pvfs2_statfs(
struct kstatfs *buf)
#endif
{
- int ret = -ENOMEM, retries = 5;
+ int ret = -ENOMEM;
pvfs2_kernel_op_t *new_op = NULL;
+ int flags = 0;
pvfs2_print("pvfs2_statfs: called on sb %p (fs_id is %d)\n",
sb, (int)(PVFS2_SB(sb)->fs_id));
@@ -333,9 +334,13 @@ static int pvfs2_statfs(
new_op->upcall.type = PVFS2_VFS_OP_STATFS;
new_op->upcall.req.statfs.fs_id = PVFS2_SB(sb)->fs_id;
- service_operation_with_timeout_retry(
- new_op, "pvfs2_statfs", retries,
- PVFS2_SB(sb)->mnt_options.intr);
+ if(PVFS2_SB(sb)->mnt_options.intr)
+ {
+ flags = PVFS2_OP_INTERRUPTIBLE;
+ }
+
+ ret = service_operation(
+ new_op, "pvfs2_statfs", PVFS2_OP_RETRY_COUNT, flags);
if (new_op->downcall.status > -1)
{
@@ -408,11 +413,8 @@ static int pvfs2_statfs(
}
} while(0);
#endif
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
}
- error_exit:
- translate_error_if_wait_failed(ret, -ENOENT, 0);
op_release(new_op);
pvfs2_print("pvfs2_statfs: returning %d\n", ret);
@@ -429,6 +431,7 @@ static int pvfs2_statfs(
is waiting for servicing. this means that the pvfs2-client won't
fail to start several times for all other pending operations before
the client regains all of the mount information from us.
+ NOTE: this function assumes that the request_semaphore is already acquired!
*/
int pvfs2_remount(
struct super_block *sb,
@@ -469,15 +472,16 @@ int pvfs2_remount(
pvfs2_print("Attempting PVFS2 Remount via host %s\n",
new_op->upcall.req.fs_mount.pvfs2_config_server);
- service_priority_operation(new_op, "pvfs2_remount", 0);
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
+ /* we assume that the calling function has already acquire the
+ * request_semaphore to prevent other operations from bypassing this
+ * one
+ */
+ ret = service_operation(new_op, "pvfs2_remount", 0,
+ (PVFS2_OP_PRIORITY|PVFS2_OP_NO_SEMAPHORE));
pvfs2_print("pvfs2_remount: mount got return value of %d\n", ret);
- if (ret)
+ if (ret == 0)
{
- goto error_exit;
- }
-
/*
store the id assigned to this sb -- it's just a short-lived
mapping that the system interface uses to map this
@@ -489,9 +493,8 @@ int pvfs2_remount(
{
strncpy(PVFS2_SB(sb)->data, data, PVFS2_MAX_MOUNT_OPT_LEN);
}
+ }
- error_exit:
- translate_error_if_wait_failed(ret, 0, 0);
op_release(new_op);
}
return ret;
@@ -573,8 +576,7 @@ struct super_block* pvfs2_get_sb(
pvfs2_print("Attempting PVFS2 Mount via host %s\n",
new_op->upcall.req.fs_mount.pvfs2_config_server);
- service_operation(new_op, "pvfs2_get_sb", 0);
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
+ ret = service_operation(new_op, "pvfs2_get_sb", 0, 0);
pvfs2_print("%s: mount got return value of %d\n", __func__, ret);
if (ret)
@@ -644,7 +646,6 @@ struct super_block* pvfs2_get_sb(
}
}
- translate_error_if_wait_failed(ret, 0, 0);
if (ret)
{
sb = NULL;
@@ -766,8 +767,7 @@ struct super_block *pvfs2_get_sb(
pvfs2_print("Attempting PVFS2 Mount via host %s\n",
new_op->upcall.req.fs_mount.pvfs2_config_server);
- service_operation(new_op, "pvfs2_get_sb", 0);
- ret = pvfs2_kernel_error_code_convert(new_op->downcall.status);
+ ret = service_operation(new_op, "pvfs2_get_sb", 0, 0);
pvfs2_print("pvfs2_get_sb: mount got return value of %d\n", ret);
if (ret)
@@ -827,7 +827,6 @@ struct super_block *pvfs2_get_sb(
error_exit:
pvfs2_error("pvfs2_get_sb: mount request failed with %d\n", ret);
- translate_error_if_wait_failed(ret, 0, 0);
if (ret || IS_ERR(sb))
{
sb = ERR_PTR(ret);
Index: waitqueue.c
===================================================================
RCS file: /projects/cvsroot/pvfs2-1/src/kernel/linux-2.6/waitqueue.c,v
diff -u -w -p -u -r1.21 -r1.22
--- waitqueue.c 20 Dec 2005 16:58:56 -0000 1.21
+++ waitqueue.c 18 Jan 2006 17:41:29 -0000 1.22
@@ -1,6 +1,9 @@
/*
* (C) 2001 Clemson University and The University of Chicago
*
+ * Changes by Acxiom Corporation to implement generic service_operation()
+ * function, Copyright © Acxiom Corporation, 2005.
+ *
* See COPYING in top-level directory.
*/
@@ -18,6 +21,106 @@ extern spinlock_t pvfs2_request_list_loc
extern struct qhash_table *htable_ops_in_progress;
extern int debug;
extern int op_timeout_secs;
+extern wait_queue_head_t pvfs2_request_list_waitq;
+
+/**
+ * submits a PVFS2 operation and waits for it to complete
+ *
+ * \note op->downcall.status will contain the status of the operation (in
+ * errno format), whether provided by pvfs2-client or a result of failure to
+ * service the operation. If the caller wishes to distinguish, then
+ * op->state can be checked to see if it was serviced or not.
+ *
+ * \returns contents of op->downcall.status for convenience
+ */
+int service_operation(
+ pvfs2_kernel_op_t* op, /**< operation structure to process */
+ const char* op_name, /**< string name for operation */
+ int num_retries, /**< number of times to retry (may be zero) */
+ int flags) /**< flags to modify behavior */
+{
+ sigset_t orig_sigset;
+ int ret = 0;
+
+ pvfs2_print("pvfs2: service_operation: %s\n", op_name);
+
+ /* mask out signals if this operation is not to be interrupted */
+ if(!(flags & PVFS2_OP_INTERRUPTIBLE))
+ {
+ mask_blocked_signals(&orig_sigset);
+ }
+
+ if(!(flags & PVFS2_OP_NO_SEMAPHORE))
+ {
+ ret = down_interruptible(&request_semaphore);
+ /* check to see if we were interrupted while waiting for semaphore */
+ if(ret < 0)
+ {
+ if(!(flags & PVFS2_OP_INTERRUPTIBLE))
+ {
+ unmask_blocked_signals(&orig_sigset);
+ }
+ op->downcall.status = ret;
+ pvfs2_print("pvfs2: service_operation interrupted.\n");
+ return(ret);
+ }
+ }
+
+ /* queue up the operation */
+ if(flags & PVFS2_OP_PRIORITY)
+ {
+ add_priority_op_to_request_list(op);
+ }
+ else
+ {
+ add_op_to_request_list(op);
+ }
+
+ if(!(flags & PVFS2_OP_NO_SEMAPHORE))
+ {
+ up(&request_semaphore);
+ }
+
+ /* loop up to num_retries if we hit a timeout */
+ do
+ {
+ if(flags & PVFS2_OP_CANCELLATION)
+ {
+ ret = wait_for_cancellation_downcall(op);
+ }
+ else
+ {
+ ret = wait_for_matching_downcall(op);
+ }
+ num_retries--;
+ }while(ret == -ETIMEDOUT && num_retries >= 0);
+
+ if(ret < 0)
+ {
+ /* failed to get matching downcall */
+ if(ret == -ETIMEDOUT)
+ {
+ pvfs2_error("pvfs2: %s -- wait timed out and retries exhausted. "
+ "aborting attempt.\n", op_name);
+ }
+ op->downcall.status = ret;
+ }
+ else
+ {
+ /* got matching downcall; make sure status is in errno format */
+ op->downcall.status = pvfs2_normalize_to_errno(op->downcall.status);
+ ret = op->downcall.status;
+ }
+
+ if(!(flags & PVFS2_OP_INTERRUPTIBLE))
+ {
+ unmask_blocked_signals(&orig_sigset);
+ }
+
+ BUG_ON(ret != op->downcall.status);
+ pvfs2_print("pvfs2: service_operation returning: %d.\n", ret);
+ return(ret);
+}
void clean_up_interrupted_operation(
pvfs2_kernel_op_t * op)
@@ -64,21 +167,11 @@ void clean_up_interrupted_operation(
* \post when this call returns to the caller, the specified op will no
* longer be on any list or htable.
*
- * \return values and op status changes:
- *
- * \retval PVFS2_WAIT_ERROR an error occurred; op status unknown
- * \retval PVFS2_WAIT_SUCCESS success; everything ok. the op state will
- * be marked as serviced
- * \retval PVFS2_WAIT_TIMEOUT_REACHED timeout reached (before downcall
- * recv'd) the caller has the choice of either requeueing the op
- * or failing the operation when this occurs. the op observes no
- * state change.
- * \retval PVFS2_WAIT_SIGNAL_RECVD sleep interrupted (signal recv'd) the
- * op observes no state change.
+ * \returns 0 on success and -errno on failure
*/
int wait_for_matching_downcall(pvfs2_kernel_op_t * op)
{
- int ret = PVFS2_WAIT_ERROR;
+ int ret = -EINVAL;
DECLARE_WAITQUEUE(wait_entry, current);
spin_lock(&op->lock);
@@ -93,7 +186,7 @@ int wait_for_matching_downcall(pvfs2_ker
if (op->op_state == PVFS2_VFS_STATE_SERVICED)
{
spin_unlock(&op->lock);
- ret = PVFS2_WAIT_SUCCESS;
+ ret = 0;
break;
}
spin_unlock(&op->lock);
@@ -106,7 +199,7 @@ int wait_for_matching_downcall(pvfs2_ker
pvfs2_print("*** operation timed out (tag %lld)\n",
lld(op->tag));
clean_up_interrupted_operation(op);
- ret = PVFS2_WAIT_TIMEOUT_REACHED;
+ ret = -ETIMEDOUT;
break;
}
continue;
@@ -115,7 +208,7 @@ int wait_for_matching_downcall(pvfs2_ker
pvfs2_print("*** operation interrupted by a signal (tag %lld)\n",
lld(op->tag));
clean_up_interrupted_operation(op);
- ret = PVFS2_WAIT_SIGNAL_RECVD;
+ ret = -EINTR;
break;
}
@@ -138,7 +231,7 @@ int wait_for_matching_downcall(pvfs2_ker
*/
int wait_for_cancellation_downcall(pvfs2_kernel_op_t * op)
{
- int ret = PVFS2_WAIT_ERROR;
+ int ret = -EINVAL;
DECLARE_WAITQUEUE(wait_entry, current);
spin_lock(&op->lock);
@@ -153,7 +246,7 @@ int wait_for_cancellation_downcall(pvfs2
if (op->op_state == PVFS2_VFS_STATE_SERVICED)
{
spin_unlock(&op->lock);
- ret = PVFS2_WAIT_SUCCESS;
+ ret = 0;
break;
}
spin_unlock(&op->lock);
@@ -163,7 +256,7 @@ int wait_for_cancellation_downcall(pvfs2
{
pvfs2_print("*** operation timed out\n");
clean_up_interrupted_operation(op);
- ret = PVFS2_WAIT_TIMEOUT_REACHED;
+ ret = -ETIMEDOUT;
break;
}
}
@@ -176,6 +269,7 @@ int wait_for_cancellation_downcall(pvfs2
return ret;
}
+
/*
* Local variables:
More information about the PVFS2-CVS
mailing list