aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-03 03:55:06 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-01-06 14:58:40 -0500
commit44c288732fdbd7e38460d156a40d29590bf93bce (patch)
treed4239fe37529b4799e85443f803db754ef66f874 /include
parent4ce70ada1ff1d0b80916ec9ec5764ce44a50a54f (diff)
NFSv4: stateful NFSv4 RPC call interface
The NFSv4 model requires us to complete all RPC calls that might establish state on the server whether or not the user wants to interrupt it. We may also need to schedule new work (including new RPC calls) in order to cancel the new state. The asynchronous RPC model will allow us to ensure that RPC calls always complete, but in order to allow for "synchronous" RPC, we want to add the ability to wait for completion. The waits are, of course, interruptible. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'include')
-rw-r--r--include/linux/sunrpc/sched.h21
1 files changed, 19 insertions, 2 deletions
diff --git a/include/linux/sunrpc/sched.h b/include/linux/sunrpc/sched.h
index ac1326fc3e1a..94b0afa4ab05 100644
--- a/include/linux/sunrpc/sched.h
+++ b/include/linux/sunrpc/sched.h
@@ -42,6 +42,7 @@ struct rpc_task {
42#ifdef RPC_DEBUG 42#ifdef RPC_DEBUG
43 unsigned long tk_magic; /* 0xf00baa */ 43 unsigned long tk_magic; /* 0xf00baa */
44#endif 44#endif
45 atomic_t tk_count; /* Reference count */
45 struct list_head tk_task; /* global list of tasks */ 46 struct list_head tk_task; /* global list of tasks */
46 struct rpc_clnt * tk_client; /* RPC client */ 47 struct rpc_clnt * tk_client; /* RPC client */
47 struct rpc_rqst * tk_rqstp; /* RPC request */ 48 struct rpc_rqst * tk_rqstp; /* RPC request */
@@ -78,7 +79,6 @@ struct rpc_task {
78 struct timer_list tk_timer; /* kernel timer */ 79 struct timer_list tk_timer; /* kernel timer */
79 unsigned long tk_timeout; /* timeout for rpc_sleep() */ 80 unsigned long tk_timeout; /* timeout for rpc_sleep() */
80 unsigned short tk_flags; /* misc flags */ 81 unsigned short tk_flags; /* misc flags */
81 unsigned char tk_active : 1;/* Task has been activated */
82 unsigned char tk_priority : 2;/* Task priority */ 82 unsigned char tk_priority : 2;/* Task priority */
83 unsigned long tk_runstate; /* Task run status */ 83 unsigned long tk_runstate; /* Task run status */
84 struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could 84 struct workqueue_struct *tk_workqueue; /* Normally rpciod, but could
@@ -136,7 +136,6 @@ struct rpc_call_ops {
136#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER) 136#define RPC_IS_SWAPPER(t) ((t)->tk_flags & RPC_TASK_SWAPPER)
137#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS) 137#define RPC_DO_ROOTOVERRIDE(t) ((t)->tk_flags & RPC_TASK_ROOTCREDS)
138#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED) 138#define RPC_ASSASSINATED(t) ((t)->tk_flags & RPC_TASK_KILLED)
139#define RPC_IS_ACTIVATED(t) ((t)->tk_active)
140#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL) 139#define RPC_DO_CALLBACK(t) ((t)->tk_callback != NULL)
141#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT) 140#define RPC_IS_SOFT(t) ((t)->tk_flags & RPC_TASK_SOFT)
142#define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR) 141#define RPC_TASK_UNINTERRUPTIBLE(t) ((t)->tk_flags & RPC_TASK_NOINTR)
@@ -145,6 +144,7 @@ struct rpc_call_ops {
145#define RPC_TASK_QUEUED 1 144#define RPC_TASK_QUEUED 1
146#define RPC_TASK_WAKEUP 2 145#define RPC_TASK_WAKEUP 2
147#define RPC_TASK_HAS_TIMER 3 146#define RPC_TASK_HAS_TIMER 3
147#define RPC_TASK_ACTIVE 4
148 148
149#define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) 149#define RPC_IS_RUNNING(t) (test_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
150#define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate)) 150#define rpc_set_running(t) (set_bit(RPC_TASK_RUNNING, &(t)->tk_runstate))
@@ -175,6 +175,15 @@ struct rpc_call_ops {
175 smp_mb__after_clear_bit(); \ 175 smp_mb__after_clear_bit(); \
176 } while (0) 176 } while (0)
177 177
178#define RPC_IS_ACTIVATED(t) (test_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
179#define rpc_set_active(t) (set_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate))
180#define rpc_clear_active(t) \
181 do { \
182 smp_mb__before_clear_bit(); \
183 clear_bit(RPC_TASK_ACTIVE, &(t)->tk_runstate); \
184 smp_mb__after_clear_bit(); \
185 } while(0)
186
178/* 187/*
179 * Task priorities. 188 * Task priorities.
180 * Note: if you change these, you must also change 189 * Note: if you change these, you must also change
@@ -237,6 +246,8 @@ struct rpc_wait_queue {
237 */ 246 */
238struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags, 247struct rpc_task *rpc_new_task(struct rpc_clnt *, int flags,
239 const struct rpc_call_ops *ops, void *data); 248 const struct rpc_call_ops *ops, void *data);
249struct rpc_task *rpc_run_task(struct rpc_clnt *clnt, int flags,
250 const struct rpc_call_ops *ops, void *data);
240struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent); 251struct rpc_task *rpc_new_child(struct rpc_clnt *, struct rpc_task *parent);
241void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt, 252void rpc_init_task(struct rpc_task *task, struct rpc_clnt *clnt,
242 int flags, const struct rpc_call_ops *ops, 253 int flags, const struct rpc_call_ops *ops,
@@ -260,6 +271,7 @@ void * rpc_malloc(struct rpc_task *, size_t);
260int rpciod_up(void); 271int rpciod_up(void);
261void rpciod_down(void); 272void rpciod_down(void);
262void rpciod_wake_up(void); 273void rpciod_wake_up(void);
274int __rpc_wait_for_completion_task(struct rpc_task *task, int (*)(void *));
263#ifdef RPC_DEBUG 275#ifdef RPC_DEBUG
264void rpc_show_tasks(void); 276void rpc_show_tasks(void);
265#endif 277#endif
@@ -272,6 +284,11 @@ static inline void rpc_exit(struct rpc_task *task, int status)
272 task->tk_action = rpc_exit_task; 284 task->tk_action = rpc_exit_task;
273} 285}
274 286
287static inline int rpc_wait_for_completion_task(struct rpc_task *task)
288{
289 return __rpc_wait_for_completion_task(task, NULL);
290}
291
275#ifdef RPC_DEBUG 292#ifdef RPC_DEBUG
276static inline const char * rpc_qname(struct rpc_wait_queue *q) 293static inline const char * rpc_qname(struct rpc_wait_queue *q)
277{ 294{