diff options
Diffstat (limited to 'net/sunrpc')
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c index a35b2f402aaa..f94567b45bb3 100644 --- a/net/sunrpc/rpc_pipe.c +++ b/net/sunrpc/rpc_pipe.c | |||
@@ -982,6 +982,41 @@ rpc_remove_pipe_dir_object(struct net *net, | |||
982 | } | 982 | } |
983 | EXPORT_SYMBOL_GPL(rpc_remove_pipe_dir_object); | 983 | EXPORT_SYMBOL_GPL(rpc_remove_pipe_dir_object); |
984 | 984 | ||
985 | /** | ||
986 | * rpc_find_or_alloc_pipe_dir_object | ||
987 | * @net: pointer to struct net | ||
988 | * @pdh: pointer to struct rpc_pipe_dir_head | ||
989 | * @match: match struct rpc_pipe_dir_object to data | ||
990 | * @alloc: allocate a new struct rpc_pipe_dir_object | ||
991 | * @data: user defined data for match() and alloc() | ||
992 | * | ||
993 | */ | ||
994 | struct rpc_pipe_dir_object * | ||
995 | rpc_find_or_alloc_pipe_dir_object(struct net *net, | ||
996 | struct rpc_pipe_dir_head *pdh, | ||
997 | int (*match)(struct rpc_pipe_dir_object *, void *), | ||
998 | struct rpc_pipe_dir_object *(*alloc)(void *), | ||
999 | void *data) | ||
1000 | { | ||
1001 | struct sunrpc_net *sn = net_generic(net, sunrpc_net_id); | ||
1002 | struct rpc_pipe_dir_object *pdo; | ||
1003 | |||
1004 | mutex_lock(&sn->pipefs_sb_lock); | ||
1005 | list_for_each_entry(pdo, &pdh->pdh_entries, pdo_head) { | ||
1006 | if (!match(pdo, data)) | ||
1007 | continue; | ||
1008 | goto out; | ||
1009 | } | ||
1010 | pdo = alloc(data); | ||
1011 | if (!pdo) | ||
1012 | goto out; | ||
1013 | rpc_add_pipe_dir_object_locked(net, pdh, pdo); | ||
1014 | out: | ||
1015 | mutex_unlock(&sn->pipefs_sb_lock); | ||
1016 | return pdo; | ||
1017 | } | ||
1018 | EXPORT_SYMBOL_GPL(rpc_find_or_alloc_pipe_dir_object); | ||
1019 | |||
985 | static void | 1020 | static void |
986 | rpc_create_pipe_dir_objects(struct rpc_pipe_dir_head *pdh) | 1021 | rpc_create_pipe_dir_objects(struct rpc_pipe_dir_head *pdh) |
987 | { | 1022 | { |