Skip to content

Commit c13ecd4

Browse files
jtlaytonchucklever
authored andcommitted
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>
1 parent d52db76 commit c13ecd4

2 files changed

Lines changed: 67 additions & 0 deletions

File tree

include/linux/sunrpc/cache.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,12 @@ extern int sunrpc_cache_register_pipefs(struct dentry *parent, const char *,
251251
extern void sunrpc_cache_unregister_pipefs(struct cache_detail *);
252252
extern void sunrpc_cache_unhash(struct cache_detail *, struct cache_head *);
253253

254+
int sunrpc_cache_requests_count(struct cache_detail *cd);
255+
int sunrpc_cache_requests_snapshot(struct cache_detail *cd,
256+
struct cache_head **items,
257+
u64 *seqnos, int max,
258+
u64 min_seqno);
259+
254260
/* Must store cache_detail in seq_file->private if using next three functions */
255261
extern void *cache_seq_start_rcu(struct seq_file *file, loff_t *pos);
256262
extern void *cache_seq_next_rcu(struct seq_file *file, void *p, loff_t *pos);

net/sunrpc/cache.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1902,3 +1902,64 @@ void sunrpc_cache_unhash(struct cache_detail *cd, struct cache_head *h)
19021902
spin_unlock(&cd->hash_lock);
19031903
}
19041904
EXPORT_SYMBOL_GPL(sunrpc_cache_unhash);
1905+
1906+
/**
1907+
* sunrpc_cache_requests_count - count pending upcall requests
1908+
* @cd: cache_detail to query
1909+
*
1910+
* Returns the number of requests on the cache's request list that
1911+
* still have CACHE_PENDING set.
1912+
*/
1913+
int sunrpc_cache_requests_count(struct cache_detail *cd)
1914+
{
1915+
struct cache_request *crq;
1916+
int cnt = 0;
1917+
1918+
spin_lock(&cd->queue_lock);
1919+
list_for_each_entry(crq, &cd->requests, list) {
1920+
if (test_bit(CACHE_PENDING, &crq->item->flags))
1921+
cnt++;
1922+
}
1923+
spin_unlock(&cd->queue_lock);
1924+
return cnt;
1925+
}
1926+
EXPORT_SYMBOL_GPL(sunrpc_cache_requests_count);
1927+
1928+
/**
1929+
* sunrpc_cache_requests_snapshot - snapshot pending upcall requests
1930+
* @cd: cache_detail to query
1931+
* @items: array to fill with cache_head pointers (caller-allocated)
1932+
* @seqnos: array to fill with sequence numbers (caller-allocated)
1933+
* @max: size of the arrays
1934+
* @min_seqno: only include entries with seqno > min_seqno (0 for all)
1935+
*
1936+
* Only entries with CACHE_PENDING set are included. Takes a reference
1937+
* on each cache_head via cache_get(). Caller must call cache_put()
1938+
* on each returned item when done.
1939+
*
1940+
* Returns the number of entries filled.
1941+
*/
1942+
int sunrpc_cache_requests_snapshot(struct cache_detail *cd,
1943+
struct cache_head **items,
1944+
u64 *seqnos, int max,
1945+
u64 min_seqno)
1946+
{
1947+
struct cache_request *crq;
1948+
int i = 0;
1949+
1950+
spin_lock(&cd->queue_lock);
1951+
list_for_each_entry(crq, &cd->requests, list) {
1952+
if (i >= max)
1953+
break;
1954+
if (!test_bit(CACHE_PENDING, &crq->item->flags))
1955+
continue;
1956+
if (crq->seqno <= min_seqno)
1957+
continue;
1958+
items[i] = cache_get(crq->item);
1959+
seqnos[i] = crq->seqno;
1960+
i++;
1961+
}
1962+
spin_unlock(&cd->queue_lock);
1963+
return i;
1964+
}
1965+
EXPORT_SYMBOL_GPL(sunrpc_cache_requests_snapshot);

0 commit comments

Comments
 (0)