[PATCH] knfsd: lockd: make nlm_traverse_* more flexible

This patch makes nlm_traverse{locks,blocks,shares} and friends use a function
pointer rather than a "action" enum.

This function pointer is given two nlm_hosts (one given by the caller, the
other taken from the lock/block/share currently visited), and is free to do
with them as it wants.  If it returns a non-zero value, the lockd/block/share
is released.

Signed-off-by: Olaf Kirch <okir@suse.de>
Signed-off-by: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 7209712..1f91567 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -265,24 +265,20 @@
 		kref_put(&block->b_count, nlmsvc_free_block);
 }
 
-static void nlmsvc_act_mark(struct nlm_host *host, struct nlm_file *file)
-{
-	struct nlm_block *block;
-
-	down(&file->f_sema);
-	list_for_each_entry(block, &file->f_blocks, b_flist)
-		block->b_host->h_inuse = 1;
-	up(&file->f_sema);
-}
-
-static void nlmsvc_act_unlock(struct nlm_host *host, struct nlm_file *file)
+/*
+ * Loop over all blocks and delete blocks held by
+ * a matching host.
+ */
+void nlmsvc_traverse_blocks(struct nlm_host *host,
+			struct nlm_file *file,
+			nlm_host_match_fn_t match)
 {
 	struct nlm_block *block, *next;
 
 restart:
 	down(&file->f_sema);
 	list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) {
-		if (host != NULL && host != block->b_host)
+		if (!match(block->b_host, host))
 			continue;
 		/* Do not destroy blocks that are not on
 		 * the global retry list - why? */
@@ -298,19 +294,6 @@
 }
 
 /*
- * Loop over all blocks and perform the action specified.
- * (NLM_ACT_CHECK handled by nlmsvc_inspect_file).
- */
-void
-nlmsvc_traverse_blocks(struct nlm_host *host, struct nlm_file *file, int action)
-{
-	if (action == NLM_ACT_MARK)
-		nlmsvc_act_mark(host, file);
-	else
-		nlmsvc_act_unlock(host, file);
-}
-
-/*
  * Initialize arguments for GRANTED call. The nlm_rqst structure
  * has been cleared already.
  */