diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:43 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-03-20 13:44:43 -0500 |
commit | d72b7a6b26b9009b7a05117fe2e04b3a73ae4a5c (patch) | |
tree | dcdbc9386b19e4976cf156baf35985016c1d28f4 /fs | |
parent | 6b45d858ed6821dd687efd3b68929de2e4954fec (diff) |
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: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/direct.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 58830429e42a..cbef57a16ffb 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -72,7 +72,6 @@ struct nfs_direct_req { | |||
72 | rewrite_list; /* saved nfs_write_data structs */ | 72 | rewrite_list; /* saved nfs_write_data structs */ |
73 | struct nfs_open_context *ctx; /* file open context info */ | 73 | struct nfs_open_context *ctx; /* file open context info */ |
74 | struct kiocb * iocb; /* controlling i/o request */ | 74 | struct kiocb * iocb; /* controlling i/o request */ |
75 | wait_queue_head_t wait; /* wait for i/o completion */ | ||
76 | struct inode * inode; /* target file of i/o */ | 75 | struct inode * inode; /* target file of i/o */ |
77 | unsigned long user_addr; /* location of user's buffer */ | 76 | unsigned long user_addr; /* location of user's buffer */ |
78 | size_t user_count; /* total bytes to move */ | 77 | size_t user_count; /* total bytes to move */ |
@@ -85,6 +84,7 @@ struct nfs_direct_req { | |||
85 | int outstanding; /* i/os we're waiting for */ | 84 | int outstanding; /* i/os we're waiting for */ |
86 | ssize_t count, /* bytes actually processed */ | 85 | ssize_t count, /* bytes actually processed */ |
87 | error; /* any reported error */ | 86 | error; /* any reported error */ |
87 | struct completion completion; /* wait for i/o completion */ | ||
88 | 88 | ||
89 | /* commit state */ | 89 | /* commit state */ |
90 | struct nfs_write_data * commit_data; /* special write_data for commits */ | 90 | 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 | return NULL; | 175 | return NULL; |
176 | 176 | ||
177 | kref_init(&dreq->kref); | 177 | kref_init(&dreq->kref); |
178 | init_waitqueue_head(&dreq->wait); | 178 | init_completion(&dreq->completion); |
179 | INIT_LIST_HEAD(&dreq->list); | 179 | INIT_LIST_HEAD(&dreq->list); |
180 | INIT_LIST_HEAD(&dreq->rewrite_list); | 180 | INIT_LIST_HEAD(&dreq->rewrite_list); |
181 | dreq->iocb = NULL; | 181 | dreq->iocb = NULL; |
@@ -209,7 +209,7 @@ static ssize_t nfs_direct_wait(struct nfs_direct_req *dreq) | |||
209 | if (dreq->iocb) | 209 | if (dreq->iocb) |
210 | goto out; | 210 | goto out; |
211 | 211 | ||
212 | result = wait_event_interruptible(dreq->wait, (dreq->outstanding == 0)); | 212 | result = wait_for_completion_interruptible(&dreq->completion); |
213 | 213 | ||
214 | if (!result) | 214 | if (!result) |
215 | result = dreq->error; | 215 | result = dreq->error; |
@@ -239,8 +239,8 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq) | |||
239 | if (!res) | 239 | if (!res) |
240 | res = (long) dreq->count; | 240 | res = (long) dreq->count; |
241 | aio_complete(dreq->iocb, res, 0); | 241 | aio_complete(dreq->iocb, res, 0); |
242 | } else | 242 | } |
243 | wake_up(&dreq->wait); | 243 | complete_all(&dreq->completion); |
244 | 244 | ||
245 | kref_put(&dreq->kref, nfs_direct_req_release); | 245 | kref_put(&dreq->kref, nfs_direct_req_release); |
246 | } | 246 | } |