aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/client.c1
-rw-r--r--fs/nfs/pagelist.c34
-rw-r--r--include/linux/nfs_fs.h1
-rw-r--r--include/linux/nfs_fs_sb.h1
-rw-r--r--include/linux/nfs_page.h1
5 files changed, 37 insertions, 1 deletions
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 3ffbffe8f39f..3e7b2e6a7cfb 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -218,6 +218,7 @@ static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
218static void pnfs_init_server(struct nfs_server *server) 218static void pnfs_init_server(struct nfs_server *server)
219{ 219{
220 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC"); 220 rpc_init_wait_queue(&server->roc_rpcwaitq, "pNFS ROC");
221 rpc_init_wait_queue(&server->uoc_rpcwaitq, "NFS UOC");
221} 222}
222 223
223#else 224#else
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index f53610672f03..ad92b401326c 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -102,6 +102,35 @@ nfs_iocounter_wait(struct nfs_lock_context *l_ctx)
102 TASK_KILLABLE); 102 TASK_KILLABLE);
103} 103}
104 104
105/**
106 * nfs_async_iocounter_wait - wait on a rpc_waitqueue for I/O
107 * to complete
108 * @task: the rpc_task that should wait
109 * @l_ctx: nfs_lock_context with io_counter to check
110 *
111 * Returns true if there is outstanding I/O to wait on and the
112 * task has been put to sleep.
113 */
114bool
115nfs_async_iocounter_wait(struct rpc_task *task, struct nfs_lock_context *l_ctx)
116{
117 struct inode *inode = d_inode(l_ctx->open_context->dentry);
118 bool ret = false;
119
120 if (atomic_read(&l_ctx->io_count) > 0) {
121 rpc_sleep_on(&NFS_SERVER(inode)->uoc_rpcwaitq, task, NULL);
122 ret = true;
123 }
124
125 if (atomic_read(&l_ctx->io_count) == 0) {
126 rpc_wake_up_queued_task(&NFS_SERVER(inode)->uoc_rpcwaitq, task);
127 ret = false;
128 }
129
130 return ret;
131}
132EXPORT_SYMBOL_GPL(nfs_async_iocounter_wait);
133
105/* 134/*
106 * nfs_page_group_lock - lock the head of the page group 135 * nfs_page_group_lock - lock the head of the page group
107 * @req - request in group that is to be locked 136 * @req - request in group that is to be locked
@@ -385,8 +414,11 @@ static void nfs_clear_request(struct nfs_page *req)
385 req->wb_page = NULL; 414 req->wb_page = NULL;
386 } 415 }
387 if (l_ctx != NULL) { 416 if (l_ctx != NULL) {
388 if (atomic_dec_and_test(&l_ctx->io_count)) 417 if (atomic_dec_and_test(&l_ctx->io_count)) {
389 wake_up_atomic_t(&l_ctx->io_count); 418 wake_up_atomic_t(&l_ctx->io_count);
419 if (test_bit(NFS_CONTEXT_UNLOCK, &ctx->flags))
420 rpc_wake_up(&NFS_SERVER(d_inode(ctx->dentry))->uoc_rpcwaitq);
421 }
390 nfs_put_lock_context(l_ctx); 422 nfs_put_lock_context(l_ctx);
391 req->wb_lock_context = NULL; 423 req->wb_lock_context = NULL;
392 } 424 }
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 1b29915247b2..9aa044e76820 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -76,6 +76,7 @@ struct nfs_open_context {
76#define NFS_CONTEXT_ERROR_WRITE (0) 76#define NFS_CONTEXT_ERROR_WRITE (0)
77#define NFS_CONTEXT_RESEND_WRITES (1) 77#define NFS_CONTEXT_RESEND_WRITES (1)
78#define NFS_CONTEXT_BAD (2) 78#define NFS_CONTEXT_BAD (2)
79#define NFS_CONTEXT_UNLOCK (3)
79 int error; 80 int error;
80 81
81 struct list_head list; 82 struct list_head list;
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h
index b34097c67848..2a70f34dffe8 100644
--- a/include/linux/nfs_fs_sb.h
+++ b/include/linux/nfs_fs_sb.h
@@ -222,6 +222,7 @@ struct nfs_server {
222 u32 mountd_version; 222 u32 mountd_version;
223 unsigned short mountd_port; 223 unsigned short mountd_port;
224 unsigned short mountd_protocol; 224 unsigned short mountd_protocol;
225 struct rpc_wait_queue uoc_rpcwaitq;
225}; 226};
226 227
227/* Server capabilities */ 228/* Server capabilities */
diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h
index 6f01e28bba27..247cc3d3498f 100644
--- a/include/linux/nfs_page.h
+++ b/include/linux/nfs_page.h
@@ -141,6 +141,7 @@ extern int nfs_page_group_lock(struct nfs_page *, bool);
141extern void nfs_page_group_lock_wait(struct nfs_page *); 141extern void nfs_page_group_lock_wait(struct nfs_page *);
142extern void nfs_page_group_unlock(struct nfs_page *); 142extern void nfs_page_group_unlock(struct nfs_page *);
143extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); 143extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int);
144extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *);
144 145
145/* 146/*
146 * Lock the page of an asynchronous request 147 * Lock the page of an asynchronous request