summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorNeil Brown <neilb@cse.unsw.edu.au>2002-10-11 05:40:00 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-10-11 05:40:00 -0700
commitea2212232c15d28b58e817d374c7986b0190d7d4 (patch)
treeeaa024243ff1e5ab44fb706dc86f7c97c1b65ffd /include
parentac26cbd76d8f30304ef6790dbf631cb2da5b5cc3 (diff)
[PATCH] kNFSd: Provide support for request deferral and revisit.
cache.c gets code to allow a 'request' to be referred pending an update of a cache item, and revisited when the item is updates. svcsock.c gets code to store the relevant part of a request on deferral, and to re-queue it when the cache item that caused the deferral is filled in.
Diffstat (limited to 'include')
-rw-r--r--include/linux/nfsd/export.h16
-rw-r--r--include/linux/sunrpc/cache.h24
-rw-r--r--include/linux/sunrpc/svc.h14
-rw-r--r--include/linux/sunrpc/svcsock.h4
4 files changed, 51 insertions, 7 deletions
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 8e658be46c87..4d692bb2797f 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -86,13 +86,16 @@ void nfsd_export_shutdown(void);
void exp_readlock(void);
void exp_readunlock(void);
struct svc_expkey * exp_find_key(struct auth_domain *clp,
- int fsid_type, u32 *fsidv);
+ int fsid_type, u32 *fsidv,
+ struct cache_req *reqp);
struct svc_export * exp_get_by_name(struct auth_domain *clp,
struct vfsmount *mnt,
- struct dentry *dentry);
+ struct dentry *dentry,
+ struct cache_req *reqp);
struct svc_export * exp_parent(struct auth_domain *clp,
struct vfsmount *mnt,
- struct dentry *dentry);
+ struct dentry *dentry,
+ struct cache_req *reqp);
int exp_rootfh(struct auth_domain *,
char *path, struct knfsd_fh *, int maxsize);
int exp_pseudoroot(struct auth_domain *, struct svc_fh *fhp);
@@ -108,16 +111,17 @@ static inline void exp_put(struct svc_export *exp)
}
static inline struct svc_export *
-exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv)
+exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
+ struct cache_req *reqp)
{
- struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv);
+ struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp);
if (ek && !IS_ERR(ek)) {
struct svc_export *exp = ek->ek_export;
int err;
cache_get(&exp->h);
expkey_put(&ek->h, &svc_expkey_cache);
if (exp &&
- (err = cache_check(&svc_export_cache, &exp->h)))
+ (err = cache_check(&svc_export_cache, &exp->h, reqp)))
exp = ERR_PTR(err);
return exp;
} else
diff --git a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
index efbf31293a6c..ef69dfa21817 100644
--- a/include/linux/sunrpc/cache.h
+++ b/include/linux/sunrpc/cache.h
@@ -86,6 +86,25 @@ struct cache_detail {
};
+/* this must be embedded in any request structure that
+ * identifies an object that will want a callback on
+ * a cache fill
+ */
+struct cache_req {
+ struct cache_deferred_req *(*defer)(struct cache_req *req);
+};
+/* this must be embedded in a deferred_request that is being
+ * delayed awaiting cache-fill
+ */
+struct cache_deferred_req {
+ struct list_head hash; /* on hash chain */
+ struct list_head recent; /* on fifo */
+ struct cache_head *item; /* cache item we wait on */
+ time_t recv_time;
+ void (*revisit)(struct cache_deferred_req *req,
+ int too_many);
+};
+
/*
* just like a template in C++, this macro does cache lookup
* for us.
@@ -206,6 +225,9 @@ RTN *FNAME ARGS \
+extern void cache_defer_req(struct cache_req *req, struct cache_head *item);
+extern void cache_revisit_request(struct cache_head *item);
+
static inline struct cache_head *cache_get(struct cache_head *h)
{
atomic_inc(&h->refcnt);
@@ -230,7 +252,7 @@ extern void cache_init(struct cache_head *h);
extern void cache_fresh(struct cache_detail *detail,
struct cache_head *head, time_t expiry);
extern int cache_check(struct cache_detail *detail,
- struct cache_head *h);
+ struct cache_head *h, struct cache_req *rqstp);
extern int cache_clean(void);
extern void cache_flush(void);
extern void cache_purge(struct cache_detail *detail);
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index 95e6b8d20fd1..36fde12f8d3e 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -101,6 +101,7 @@ struct svc_rqst {
struct auth_ops * rq_authop; /* authentication flavour */
struct svc_cred rq_cred; /* auth info */
struct sk_buff * rq_skbuff; /* fast recv inet buffer */
+ struct svc_deferred_req*rq_deferred; /* deferred request we are replaying */
struct svc_buf rq_defbuf; /* default buffer */
struct svc_buf rq_argbuf; /* argument buffer */
struct svc_buf rq_resbuf; /* result buffer */
@@ -121,6 +122,9 @@ struct svc_rqst {
* reserved for this request
*/
+ struct cache_req rq_chandle; /* handle passed to caches for
+ * request delaying
+ */
/* Catering to nfsd */
struct auth_domain * rq_client; /* RPC peer info */
struct svc_cacherep * rq_cacherep; /* cache info */
@@ -132,6 +136,16 @@ struct svc_rqst {
wait_queue_head_t rq_wait; /* synchronization */
};
+struct svc_deferred_req {
+ struct svc_serv *serv;
+ u32 prot; /* protocol (UDP or TCP) */
+ struct sockaddr_in addr;
+ struct svc_sock *svsk; /* where reply must go */
+ struct cache_deferred_req handle;
+ int argslen;
+ u32 args[0];
+};
+
/*
* RPC program
*/
diff --git a/include/linux/sunrpc/svcsock.h b/include/linux/sunrpc/svcsock.h
index af29406521bc..2f90342e4c76 100644
--- a/include/linux/sunrpc/svcsock.h
+++ b/include/linux/sunrpc/svcsock.h
@@ -31,9 +31,13 @@ struct svc_sock {
#define SK_QUED 5 /* on serv->sk_sockets */
#define SK_DEAD 6 /* socket closed */
#define SK_CHNGBUF 7 /* need to change snd/rcv buffer sizes */
+#define SK_DEFERRED 8 /* request on sk_deferred */
int sk_reserved; /* space on outq that is reserved */
+ struct list_head sk_deferred; /* deferred requests that need to
+ * be revisted */
+
int (*sk_recvfrom)(struct svc_rqst *rqstp);
int (*sk_sendto)(struct svc_rqst *rqstp);