mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 03:27:30 -04:00
sunrpc: add helpers to count and snapshot pending cache requests
Add sunrpc_cache_requests_count() and sunrpc_cache_requests_snapshot() to allow callers to count and snapshot the pending upcall request list without exposing struct cache_request outside of cache.c. Both functions skip entries that no longer have CACHE_PENDING set. The snapshot function takes a cache_get() reference on each item so the caller can safely use them after the queue_lock is released. These will be used by the nfsd generic netlink dumpit handler for svc_export upcall requests. Signed-off-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
@@ -251,6 +251,12 @@ extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
|
||||
extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
|
||||
extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *);
|
||||
|
||||
int sunrpc_cache_requests_count(struct cache_detail *cd);
|
||||
int sunrpc_cache_requests_snapshot(struct cache_detail *cd,
|
||||
struct cache_head **items,
|
||||
u64 *seqnos, int max,
|
||||
u64 min_seqno);
|
||||
|
||||
/* Must store cache_detail in seq_file->private if using next three functions */
|
||||
extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
|
||||
extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos);
|
||||
|
||||
@@ -1902,3 +1902,64 @@ void sunrpc_cache_unhash(struct cache_detail *cd, struct cache_head *h)
|
||||
spin_unlock(&cd->hash_lock);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sunrpc_cache_unhash);
|
||||
|
||||
/**
|
||||
* sunrpc_cache_requests_count - count pending upcall requests
|
||||
* @cd: cache_detail to query
|
||||
*
|
||||
* Returns the number of requests on the cache's request list that
|
||||
* still have CACHE_PENDING set.
|
||||
*/
|
||||
int sunrpc_cache_requests_count(struct cache_detail *cd)
|
||||
{
|
||||
struct cache_request *crq;
|
||||
int cnt = 0;
|
||||
|
||||
spin_lock(&cd->queue_lock);
|
||||
list_for_each_entry(crq, &cd->requests, list) {
|
||||
if (test_bit(CACHE_PENDING, &crq->item->flags))
|
||||
cnt++;
|
||||
}
|
||||
spin_unlock(&cd->queue_lock);
|
||||
return cnt;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sunrpc_cache_requests_count);
|
||||
|
||||
/**
|
||||
* sunrpc_cache_requests_snapshot - snapshot pending upcall requests
|
||||
* @cd: cache_detail to query
|
||||
* @items: array to fill with cache_head pointers (caller-allocated)
|
||||
* @seqnos: array to fill with sequence numbers (caller-allocated)
|
||||
* @max: size of the arrays
|
||||
* @min_seqno: only include entries with seqno > min_seqno (0 for all)
|
||||
*
|
||||
* Only entries with CACHE_PENDING set are included. Takes a reference
|
||||
* on each cache_head via cache_get(). Caller must call cache_put()
|
||||
* on each returned item when done.
|
||||
*
|
||||
* Returns the number of entries filled.
|
||||
*/
|
||||
int sunrpc_cache_requests_snapshot(struct cache_detail *cd,
|
||||
struct cache_head **items,
|
||||
u64 *seqnos, int max,
|
||||
u64 min_seqno)
|
||||
{
|
||||
struct cache_request *crq;
|
||||
int i = 0;
|
||||
|
||||
spin_lock(&cd->queue_lock);
|
||||
list_for_each_entry(crq, &cd->requests, list) {
|
||||
if (i >= max)
|
||||
break;
|
||||
if (!test_bit(CACHE_PENDING, &crq->item->flags))
|
||||
continue;
|
||||
if (crq->seqno <= min_seqno)
|
||||
continue;
|
||||
items[i] = cache_get(crq->item);
|
||||
seqnos[i] = crq->seqno;
|
||||
i++;
|
||||
}
|
||||
spin_unlock(&cd->queue_lock);
|
||||
return i;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sunrpc_cache_requests_snapshot);
|
||||
|
||||
Reference in New Issue
Block a user