Commit d72b7a6b authored by Trond Myklebust's avatar Trond Myklebust

NFS: O_DIRECT needs to use a completion

Now that we have aio writes, it is possible for dreq->outstanding to be
zero, but for the I/O not to have completed. Convert struct nfs_direct_req
to use a completion to signal when the I/O is done.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 6b45d858
...@@ -72,7 +72,6 @@ struct nfs_direct_req { ...@@ -72,7 +72,6 @@ struct nfs_direct_req {
rewrite_list; /* saved nfs_write_data structs */ rewrite_list; /* saved nfs_write_data structs */
struct nfs_open_context *ctx; /* file open context info */ struct nfs_open_context *ctx; /* file open context info */
struct kiocb * iocb; /* controlling i/o request */ struct kiocb * iocb; /* controlling i/o request */
wait_queue_head_t wait; /* wait for i/o completion */
struct inode * inode; /* target file of i/o */ struct inode * inode; /* target file of i/o */
unsigned long user_addr; /* location of user's buffer */ unsigned long user_addr; /* location of user's buffer */
size_t user_count; /* total bytes to move */ size_t user_count; /* total bytes to move */
...@@ -85,6 +84,7 @@ struct nfs_direct_req { ...@@ -85,6 +84,7 @@ struct nfs_direct_req {
int outstanding; /* i/os we're waiting for */ int outstanding; /* i/os we're waiting for */
ssize_t count, /* bytes actually processed */ ssize_t count, /* bytes actually processed */
error; /* any reported error */ error; /* any reported error */
struct completion completion; /* wait for i/o completion */
/* commit state */ /* commit state */
struct nfs_write_data * commit_data; /* special write_data for commits */ struct nfs_write_data * commit_data; /* special write_data for commits */
...@@ -175,7 +175,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void) ...@@ -175,7 +175,7 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
return NULL; return NULL;
kref_init(&dreq->kref); kref_init(&dreq->kref);
init_waitqueue_head(&dreq->wait); init_completion(&dreq->completion);
INIT_LIST_HEAD(&dreq->list); INIT_LIST_HEAD(&dreq->list);
INIT_LIST_HEAD(&dreq->rewrite_list); INIT_LIST_HEAD(&dreq->rewrite_list);
dreq->iocb = NULL; dreq->iocb = NULL;
...@@ -209,7 +209,7 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq) ...@@ -209,7 +209,7 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq)
if (dreq->iocb) if (dreq->iocb)
goto out; goto out;
result = wait_event_interruptible(dreq->wait, (dreq->outstanding == 0)); result = wait_for_completion_interruptible(&dreq->completion);
if (!result) if (!result)
result = dreq->error; result = dreq->error;
...@@ -239,8 +239,8 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq) ...@@ -239,8 +239,8 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq)
if (!res) if (!res)
res = (long) dreq->count; res = (long) dreq->count;
aio_complete(dreq->iocb, res, 0); aio_complete(dreq->iocb, res, 0);
} else }
wake_up(&dreq->wait); complete_all(&dreq->completion);
kref_put(&dreq->kref, nfs_direct_req_release); kref_put(&dreq->kref, nfs_direct_req_release);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment