diff options
| author | Neil Brown <neilb@cse.unsw.edu.au> | 2002-10-11 05:40:00 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-10-11 05:40:00 -0700 |
| commit | ea2212232c15d28b58e817d374c7986b0190d7d4 (patch) | |
| tree | eaa024243ff1e5ab44fb706dc86f7c97c1b65ffd /include | |
| parent | ac26cbd76d8f30304ef6790dbf631cb2da5b5cc3 (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.h | 16 | ||||
| -rw-r--r-- | include/linux/sunrpc/cache.h | 24 | ||||
| -rw-r--r-- | include/linux/sunrpc/svc.h | 14 | ||||
| -rw-r--r-- | include/linux/sunrpc/svcsock.h | 4 |
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); |
