aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/bluetooth/hci_core.c8
-rw-r--r--net/core/dev.c42
-rw-r--r--net/core/request_sock.c2
-rw-r--r--net/decnet/dn_dev.c10
-rw-r--r--net/ipv4/devinet.c16
-rw-r--r--net/ipv4/netfilter/ip_conntrack_core.c6
-rw-r--r--net/ipv6/addrconf.c10
-rw-r--r--net/ipv6/ipcomp6.c5
-rw-r--r--net/irda/af_irda.c6
-rw-r--r--net/netfilter/nf_conntrack_core.c6
-rw-r--r--net/netlink/af_netlink.c9
-rw-r--r--net/nonet.c2
-rw-r--r--net/socket.c2
-rw-r--r--net/sunrpc/auth_gss/svcauth_gss.c182
-rw-r--r--net/sunrpc/cache.c163
-rw-r--r--net/sunrpc/rpc_pipe.c2
-rw-r--r--net/sunrpc/stats.c4
-rw-r--r--net/sunrpc/sunrpc_syms.c6
-rw-r--r--net/sunrpc/svcauth.c122
-rw-r--r--net/sunrpc/svcauth_unix.c229
20 files changed, 518 insertions, 314 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 9106354c781e..a49a6975092d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -73,23 +73,23 @@ DEFINE_RWLOCK(hci_cb_list_lock);
73struct hci_proto *hci_proto[HCI_MAX_PROTO]; 73struct hci_proto *hci_proto[HCI_MAX_PROTO];
74 74
75/* HCI notifiers list */ 75/* HCI notifiers list */
76static struct notifier_block *hci_notifier; 76static ATOMIC_NOTIFIER_HEAD(hci_notifier);
77 77
78/* ---- HCI notifications ---- */ 78/* ---- HCI notifications ---- */
79 79
80int hci_register_notifier(struct notifier_block *nb) 80int hci_register_notifier(struct notifier_block *nb)
81{ 81{
82 return notifier_chain_register(&hci_notifier, nb); 82 return atomic_notifier_chain_register(&hci_notifier, nb);
83} 83}
84 84
85int hci_unregister_notifier(struct notifier_block *nb) 85int hci_unregister_notifier(struct notifier_block *nb)
86{ 86{
87 return notifier_chain_unregister(&hci_notifier, nb); 87 return atomic_notifier_chain_unregister(&hci_notifier, nb);
88} 88}
89 89
90static void hci_notify(struct hci_dev *hdev, int event) 90static void hci_notify(struct hci_dev *hdev, int event)
91{ 91{
92 notifier_call_chain(&hci_notifier, event, hdev); 92 atomic_notifier_call_chain(&hci_notifier, event, hdev);
93} 93}
94 94
95/* ---- HCI requests ---- */ 95/* ---- HCI requests ---- */
diff --git a/net/core/dev.c b/net/core/dev.c
index 8e1dc3051222..a3ab11f34153 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -193,7 +193,7 @@ static inline struct hlist_head *dev_index_hash(int ifindex)
193 * Our notifier list 193 * Our notifier list
194 */ 194 */
195 195
196static struct notifier_block *netdev_chain; 196static BLOCKING_NOTIFIER_HEAD(netdev_chain);
197 197
198/* 198/*
199 * Device drivers call our routines to queue packets here. We empty the 199 * Device drivers call our routines to queue packets here. We empty the
@@ -736,7 +736,8 @@ int dev_change_name(struct net_device *dev, char *newname)
736 if (!err) { 736 if (!err) {
737 hlist_del(&dev->name_hlist); 737 hlist_del(&dev->name_hlist);
738 hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name)); 738 hlist_add_head(&dev->name_hlist, dev_name_hash(dev->name));
739 notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME, dev); 739 blocking_notifier_call_chain(&netdev_chain,
740 NETDEV_CHANGENAME, dev);
740 } 741 }
741 742
742 return err; 743 return err;
@@ -750,7 +751,7 @@ int dev_change_name(struct net_device *dev, char *newname)
750 */ 751 */
751void netdev_features_change(struct net_device *dev) 752void netdev_features_change(struct net_device *dev)
752{ 753{
753 notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev); 754 blocking_notifier_call_chain(&netdev_chain, NETDEV_FEAT_CHANGE, dev);
754} 755}
755EXPORT_SYMBOL(netdev_features_change); 756EXPORT_SYMBOL(netdev_features_change);
756 757
@@ -765,7 +766,8 @@ EXPORT_SYMBOL(netdev_features_change);
765void netdev_state_change(struct net_device *dev) 766void netdev_state_change(struct net_device *dev)
766{ 767{
767 if (dev->flags & IFF_UP) { 768 if (dev->flags & IFF_UP) {
768 notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); 769 blocking_notifier_call_chain(&netdev_chain,
770 NETDEV_CHANGE, dev);
769 rtmsg_ifinfo(RTM_NEWLINK, dev, 0); 771 rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
770 } 772 }
771} 773}
@@ -862,7 +864,7 @@ int dev_open(struct net_device *dev)
862 /* 864 /*
863 * ... and announce new interface. 865 * ... and announce new interface.
864 */ 866 */
865 notifier_call_chain(&netdev_chain, NETDEV_UP, dev); 867 blocking_notifier_call_chain(&netdev_chain, NETDEV_UP, dev);
866 } 868 }
867 return ret; 869 return ret;
868} 870}
@@ -885,7 +887,7 @@ int dev_close(struct net_device *dev)
885 * Tell people we are going down, so that they can 887 * Tell people we are going down, so that they can
886 * prepare to death, when device is still operating. 888 * prepare to death, when device is still operating.
887 */ 889 */
888 notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev); 890 blocking_notifier_call_chain(&netdev_chain, NETDEV_GOING_DOWN, dev);
889 891
890 dev_deactivate(dev); 892 dev_deactivate(dev);
891 893
@@ -922,7 +924,7 @@ int dev_close(struct net_device *dev)
922 /* 924 /*
923 * Tell people we are down 925 * Tell people we are down
924 */ 926 */
925 notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev); 927 blocking_notifier_call_chain(&netdev_chain, NETDEV_DOWN, dev);
926 928
927 return 0; 929 return 0;
928} 930}
@@ -953,7 +955,7 @@ int register_netdevice_notifier(struct notifier_block *nb)
953 int err; 955 int err;
954 956
955 rtnl_lock(); 957 rtnl_lock();
956 err = notifier_chain_register(&netdev_chain, nb); 958 err = blocking_notifier_chain_register(&netdev_chain, nb);
957 if (!err) { 959 if (!err) {
958 for (dev = dev_base; dev; dev = dev->next) { 960 for (dev = dev_base; dev; dev = dev->next) {
959 nb->notifier_call(nb, NETDEV_REGISTER, dev); 961 nb->notifier_call(nb, NETDEV_REGISTER, dev);
@@ -981,7 +983,7 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
981 int err; 983 int err;
982 984
983 rtnl_lock(); 985 rtnl_lock();
984 err = notifier_chain_unregister(&netdev_chain, nb); 986 err = blocking_notifier_chain_unregister(&netdev_chain, nb);
985 rtnl_unlock(); 987 rtnl_unlock();
986 return err; 988 return err;
987} 989}
@@ -992,12 +994,12 @@ int unregister_netdevice_notifier(struct notifier_block *nb)
992 * @v: pointer passed unmodified to notifier function 994 * @v: pointer passed unmodified to notifier function
993 * 995 *
994 * Call all network notifier blocks. Parameters and return value 996 * Call all network notifier blocks. Parameters and return value
995 * are as for notifier_call_chain(). 997 * are as for blocking_notifier_call_chain().
996 */ 998 */
997 999
998int call_netdevice_notifiers(unsigned long val, void *v) 1000int call_netdevice_notifiers(unsigned long val, void *v)
999{ 1001{
1000 return notifier_call_chain(&netdev_chain, val, v); 1002 return blocking_notifier_call_chain(&netdev_chain, val, v);
1001} 1003}
1002 1004
1003/* When > 0 there are consumers of rx skb time stamps */ 1005/* When > 0 there are consumers of rx skb time stamps */
@@ -2242,7 +2244,8 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
2242 if (dev->flags & IFF_UP && 2244 if (dev->flags & IFF_UP &&
2243 ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI | 2245 ((old_flags ^ dev->flags) &~ (IFF_UP | IFF_PROMISC | IFF_ALLMULTI |
2244 IFF_VOLATILE))) 2246 IFF_VOLATILE)))
2245 notifier_call_chain(&netdev_chain, NETDEV_CHANGE, dev); 2247 blocking_notifier_call_chain(&netdev_chain,
2248 NETDEV_CHANGE, dev);
2246 2249
2247 if ((flags ^ dev->gflags) & IFF_PROMISC) { 2250 if ((flags ^ dev->gflags) & IFF_PROMISC) {
2248 int inc = (flags & IFF_PROMISC) ? +1 : -1; 2251 int inc = (flags & IFF_PROMISC) ? +1 : -1;
@@ -2286,8 +2289,8 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
2286 else 2289 else
2287 dev->mtu = new_mtu; 2290 dev->mtu = new_mtu;
2288 if (!err && dev->flags & IFF_UP) 2291 if (!err && dev->flags & IFF_UP)
2289 notifier_call_chain(&netdev_chain, 2292 blocking_notifier_call_chain(&netdev_chain,
2290 NETDEV_CHANGEMTU, dev); 2293 NETDEV_CHANGEMTU, dev);
2291 return err; 2294 return err;
2292} 2295}
2293 2296
@@ -2303,7 +2306,8 @@ int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
2303 return -ENODEV; 2306 return -ENODEV;
2304 err = dev->set_mac_address(dev, sa); 2307 err = dev->set_mac_address(dev, sa);
2305 if (!err) 2308 if (!err)
2306 notifier_call_chain(&netdev_chain, NETDEV_CHANGEADDR, dev); 2309 blocking_notifier_call_chain(&netdev_chain,
2310 NETDEV_CHANGEADDR, dev);
2307 return err; 2311 return err;
2308} 2312}
2309 2313
@@ -2359,7 +2363,7 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
2359 return -EINVAL; 2363 return -EINVAL;
2360 memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data, 2364 memcpy(dev->broadcast, ifr->ifr_hwaddr.sa_data,
2361 min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len)); 2365 min(sizeof ifr->ifr_hwaddr.sa_data, (size_t) dev->addr_len));
2362 notifier_call_chain(&netdev_chain, 2366 blocking_notifier_call_chain(&netdev_chain,
2363 NETDEV_CHANGEADDR, dev); 2367 NETDEV_CHANGEADDR, dev);
2364 return 0; 2368 return 0;
2365 2369
@@ -2813,7 +2817,7 @@ int register_netdevice(struct net_device *dev)
2813 write_unlock_bh(&dev_base_lock); 2817 write_unlock_bh(&dev_base_lock);
2814 2818
2815 /* Notify protocols, that a new device appeared. */ 2819 /* Notify protocols, that a new device appeared. */
2816 notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev); 2820 blocking_notifier_call_chain(&netdev_chain, NETDEV_REGISTER, dev);
2817 2821
2818 /* Finish registration after unlock */ 2822 /* Finish registration after unlock */
2819 net_set_todo(dev); 2823 net_set_todo(dev);
@@ -2892,7 +2896,7 @@ static void netdev_wait_allrefs(struct net_device *dev)
2892 rtnl_lock(); 2896 rtnl_lock();
2893 2897
2894 /* Rebroadcast unregister notification */ 2898 /* Rebroadcast unregister notification */
2895 notifier_call_chain(&netdev_chain, 2899 blocking_notifier_call_chain(&netdev_chain,
2896 NETDEV_UNREGISTER, dev); 2900 NETDEV_UNREGISTER, dev);
2897 2901
2898 if (test_bit(__LINK_STATE_LINKWATCH_PENDING, 2902 if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
@@ -3148,7 +3152,7 @@ int unregister_netdevice(struct net_device *dev)
3148 /* Notify protocols, that we are about to destroy 3152 /* Notify protocols, that we are about to destroy
3149 this device. They should clean all the things. 3153 this device. They should clean all the things.
3150 */ 3154 */
3151 notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev); 3155 blocking_notifier_call_chain(&netdev_chain, NETDEV_UNREGISTER, dev);
3152 3156
3153 /* 3157 /*
3154 * Flush the multicast chain 3158 * Flush the multicast chain
diff --git a/net/core/request_sock.c b/net/core/request_sock.c
index 98f0fc923f91..1e44eda1fda9 100644
--- a/net/core/request_sock.c
+++ b/net/core/request_sock.c
@@ -51,7 +51,7 @@ int reqsk_queue_alloc(struct request_sock_queue *queue,
51 51
52 get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd)); 52 get_random_bytes(&lopt->hash_rnd, sizeof(lopt->hash_rnd));
53 rwlock_init(&queue->syn_wait_lock); 53 rwlock_init(&queue->syn_wait_lock);
54 queue->rskq_accept_head = queue->rskq_accept_head = NULL; 54 queue->rskq_accept_head = NULL;
55 lopt->nr_table_entries = nr_table_entries; 55 lopt->nr_table_entries = nr_table_entries;
56 56
57 write_lock_bh(&queue->syn_wait_lock); 57 write_lock_bh(&queue->syn_wait_lock);
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c
index cc7b9d9255ef..d2ae9893ca17 100644
--- a/net/decnet/dn_dev.c
+++ b/net/decnet/dn_dev.c
@@ -68,7 +68,7 @@ __le16 decnet_address = 0;
68 68
69static DEFINE_RWLOCK(dndev_lock); 69static DEFINE_RWLOCK(dndev_lock);
70static struct net_device *decnet_default_device; 70static struct net_device *decnet_default_device;
71static struct notifier_block *dnaddr_chain; 71static BLOCKING_NOTIFIER_HEAD(dnaddr_chain);
72 72
73static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); 73static struct dn_dev *dn_dev_create(struct net_device *dev, int *err);
74static void dn_dev_delete(struct net_device *dev); 74static void dn_dev_delete(struct net_device *dev);
@@ -446,7 +446,7 @@ static void dn_dev_del_ifa(struct dn_dev *dn_db, struct dn_ifaddr **ifap, int de
446 } 446 }
447 447
448 rtmsg_ifa(RTM_DELADDR, ifa1); 448 rtmsg_ifa(RTM_DELADDR, ifa1);
449 notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1); 449 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_DOWN, ifa1);
450 if (destroy) { 450 if (destroy) {
451 dn_dev_free_ifa(ifa1); 451 dn_dev_free_ifa(ifa1);
452 452
@@ -481,7 +481,7 @@ static int dn_dev_insert_ifa(struct dn_dev *dn_db, struct dn_ifaddr *ifa)
481 dn_db->ifa_list = ifa; 481 dn_db->ifa_list = ifa;
482 482
483 rtmsg_ifa(RTM_NEWADDR, ifa); 483 rtmsg_ifa(RTM_NEWADDR, ifa);
484 notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa); 484 blocking_notifier_call_chain(&dnaddr_chain, NETDEV_UP, ifa);
485 485
486 return 0; 486 return 0;
487} 487}
@@ -1285,12 +1285,12 @@ void dn_dev_devices_on(void)
1285 1285
1286int register_dnaddr_notifier(struct notifier_block *nb) 1286int register_dnaddr_notifier(struct notifier_block *nb)
1287{ 1287{
1288 return notifier_chain_register(&dnaddr_chain, nb); 1288 return blocking_notifier_chain_register(&dnaddr_chain, nb);
1289} 1289}
1290 1290
1291int unregister_dnaddr_notifier(struct notifier_block *nb) 1291int unregister_dnaddr_notifier(struct notifier_block *nb)
1292{ 1292{
1293 return notifier_chain_unregister(&dnaddr_chain, nb); 1293 return blocking_notifier_chain_unregister(&dnaddr_chain, nb);
1294} 1294}
1295 1295
1296#ifdef CONFIG_PROC_FS 1296#ifdef CONFIG_PROC_FS
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 44fdf1413e2c..81c2f7885292 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -81,7 +81,7 @@ static struct ipv4_devconf ipv4_devconf_dflt = {
81 81
82static void rtmsg_ifa(int event, struct in_ifaddr *); 82static void rtmsg_ifa(int event, struct in_ifaddr *);
83 83
84static struct notifier_block *inetaddr_chain; 84static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
85static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, 85static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
86 int destroy); 86 int destroy);
87#ifdef CONFIG_SYSCTL 87#ifdef CONFIG_SYSCTL
@@ -267,7 +267,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
267 *ifap1 = ifa->ifa_next; 267 *ifap1 = ifa->ifa_next;
268 268
269 rtmsg_ifa(RTM_DELADDR, ifa); 269 rtmsg_ifa(RTM_DELADDR, ifa);
270 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa); 270 blocking_notifier_call_chain(&inetaddr_chain,
271 NETDEV_DOWN, ifa);
271 inet_free_ifa(ifa); 272 inet_free_ifa(ifa);
272 } else { 273 } else {
273 promote = ifa; 274 promote = ifa;
@@ -291,7 +292,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
291 So that, this order is correct. 292 So that, this order is correct.
292 */ 293 */
293 rtmsg_ifa(RTM_DELADDR, ifa1); 294 rtmsg_ifa(RTM_DELADDR, ifa1);
294 notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1); 295 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
295 296
296 if (promote) { 297 if (promote) {
297 298
@@ -303,7 +304,8 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
303 304
304 promote->ifa_flags &= ~IFA_F_SECONDARY; 305 promote->ifa_flags &= ~IFA_F_SECONDARY;
305 rtmsg_ifa(RTM_NEWADDR, promote); 306 rtmsg_ifa(RTM_NEWADDR, promote);
306 notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote); 307 blocking_notifier_call_chain(&inetaddr_chain,
308 NETDEV_UP, promote);
307 for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) { 309 for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) {
308 if (ifa1->ifa_mask != ifa->ifa_mask || 310 if (ifa1->ifa_mask != ifa->ifa_mask ||
309 !inet_ifa_match(ifa1->ifa_address, ifa)) 311 !inet_ifa_match(ifa1->ifa_address, ifa))
@@ -366,7 +368,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa)
366 Notifier will trigger FIB update, so that 368 Notifier will trigger FIB update, so that
367 listeners of netlink will know about new ifaddr */ 369 listeners of netlink will know about new ifaddr */
368 rtmsg_ifa(RTM_NEWADDR, ifa); 370 rtmsg_ifa(RTM_NEWADDR, ifa);
369 notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); 371 blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
370 372
371 return 0; 373 return 0;
372} 374}
@@ -938,12 +940,12 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop
938 940
939int register_inetaddr_notifier(struct notifier_block *nb) 941int register_inetaddr_notifier(struct notifier_block *nb)
940{ 942{
941 return notifier_chain_register(&inetaddr_chain, nb); 943 return blocking_notifier_chain_register(&inetaddr_chain, nb);
942} 944}
943 945
944int unregister_inetaddr_notifier(struct notifier_block *nb) 946int unregister_inetaddr_notifier(struct notifier_block *nb)
945{ 947{
946 return notifier_chain_unregister(&inetaddr_chain, nb); 948 return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
947} 949}
948 950
949/* Rename ifa_labels for a device name change. Make some effort to preserve existing 951/* Rename ifa_labels for a device name change. Make some effort to preserve existing
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
index 9e34034729a6..ceaabc18202b 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -80,8 +80,8 @@ static int ip_conntrack_vmalloc;
80static unsigned int ip_conntrack_next_id; 80static unsigned int ip_conntrack_next_id;
81static unsigned int ip_conntrack_expect_next_id; 81static unsigned int ip_conntrack_expect_next_id;
82#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS 82#ifdef CONFIG_IP_NF_CONNTRACK_EVENTS
83struct notifier_block *ip_conntrack_chain; 83ATOMIC_NOTIFIER_HEAD(ip_conntrack_chain);
84struct notifier_block *ip_conntrack_expect_chain; 84ATOMIC_NOTIFIER_HEAD(ip_conntrack_expect_chain);
85 85
86DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); 86DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache);
87 87
@@ -92,7 +92,7 @@ __ip_ct_deliver_cached_events(struct ip_conntrack_ecache *ecache)
92{ 92{
93 DEBUGP("ecache: delivering events for %p\n", ecache->ct); 93 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
94 if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events) 94 if (is_confirmed(ecache->ct) && !is_dying(ecache->ct) && ecache->events)
95 notifier_call_chain(&ip_conntrack_chain, ecache->events, 95 atomic_notifier_call_chain(&ip_conntrack_chain, ecache->events,
96 ecache->ct); 96 ecache->ct);
97 ecache->events = 0; 97 ecache->events = 0;
98 ip_conntrack_put(ecache->ct); 98 ip_conntrack_put(ecache->ct);
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 01c62a0d3742..445006ee4522 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -143,7 +143,7 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev,
143 struct prefix_info *pinfo); 143 struct prefix_info *pinfo);
144static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); 144static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev);
145 145
146static struct notifier_block *inet6addr_chain; 146static ATOMIC_NOTIFIER_HEAD(inet6addr_chain);
147 147
148struct ipv6_devconf ipv6_devconf = { 148struct ipv6_devconf ipv6_devconf = {
149 .forwarding = 0, 149 .forwarding = 0,
@@ -593,7 +593,7 @@ out2:
593 read_unlock_bh(&addrconf_lock); 593 read_unlock_bh(&addrconf_lock);
594 594
595 if (likely(err == 0)) 595 if (likely(err == 0))
596 notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); 596 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa);
597 else { 597 else {
598 kfree(ifa); 598 kfree(ifa);
599 ifa = ERR_PTR(err); 599 ifa = ERR_PTR(err);
@@ -688,7 +688,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
688 688
689 ipv6_ifa_notify(RTM_DELADDR, ifp); 689 ipv6_ifa_notify(RTM_DELADDR, ifp);
690 690
691 notifier_call_chain(&inet6addr_chain,NETDEV_DOWN,ifp); 691 atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp);
692 692
693 addrconf_del_timer(ifp); 693 addrconf_del_timer(ifp);
694 694
@@ -3767,12 +3767,12 @@ static void addrconf_sysctl_unregister(struct ipv6_devconf *p)
3767 3767
3768int register_inet6addr_notifier(struct notifier_block *nb) 3768int register_inet6addr_notifier(struct notifier_block *nb)
3769{ 3769{
3770 return notifier_chain_register(&inet6addr_chain, nb); 3770 return atomic_notifier_chain_register(&inet6addr_chain, nb);
3771} 3771}
3772 3772
3773int unregister_inet6addr_notifier(struct notifier_block *nb) 3773int unregister_inet6addr_notifier(struct notifier_block *nb)
3774{ 3774{
3775 return notifier_chain_unregister(&inet6addr_chain,nb); 3775 return atomic_notifier_chain_unregister(&inet6addr_chain,nb);
3776} 3776}
3777 3777
3778/* 3778/*
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 028b636687ec..d4cfec3f414e 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -228,6 +228,9 @@ static struct xfrm_state *ipcomp6_tunnel_create(struct xfrm_state *x)
228 228
229 t->id.proto = IPPROTO_IPV6; 229 t->id.proto = IPPROTO_IPV6;
230 t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr); 230 t->id.spi = xfrm6_tunnel_alloc_spi((xfrm_address_t *)&x->props.saddr);
231 if (!t->id.spi)
232 goto error;
233
231 memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr)); 234 memcpy(t->id.daddr.a6, x->id.daddr.a6, sizeof(struct in6_addr));
232 memcpy(&t->sel, &x->sel, sizeof(t->sel)); 235 memcpy(&t->sel, &x->sel, sizeof(t->sel));
233 t->props.family = AF_INET6; 236 t->props.family = AF_INET6;
@@ -243,7 +246,9 @@ out:
243 return t; 246 return t;
244 247
245error: 248error:
249 t->km.state = XFRM_STATE_DEAD;
246 xfrm_state_put(t); 250 xfrm_state_put(t);
251 t = NULL;
247 goto out; 252 goto out;
248} 253}
249 254
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c
index 759445648667..627b11342233 100644
--- a/net/irda/af_irda.c
+++ b/net/irda/af_irda.c
@@ -1302,7 +1302,7 @@ static int irda_sendmsg(struct kiocb *iocb, struct socket *sock,
1302 if (sk->sk_state != TCP_ESTABLISHED) 1302 if (sk->sk_state != TCP_ESTABLISHED)
1303 return -ENOTCONN; 1303 return -ENOTCONN;
1304 1304
1305 /* Check that we don't send out to big frames */ 1305 /* Check that we don't send out too big frames */
1306 if (len > self->max_data_size) { 1306 if (len > self->max_data_size) {
1307 IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n", 1307 IRDA_DEBUG(2, "%s(), Chopping frame from %zd to %d bytes!\n",
1308 __FUNCTION__, len, self->max_data_size); 1308 __FUNCTION__, len, self->max_data_size);
@@ -1546,7 +1546,7 @@ static int irda_sendmsg_dgram(struct kiocb *iocb, struct socket *sock,
1546 IRDA_ASSERT(self != NULL, return -1;); 1546 IRDA_ASSERT(self != NULL, return -1;);
1547 1547
1548 /* 1548 /*
1549 * Check that we don't send out to big frames. This is an unreliable 1549 * Check that we don't send out too big frames. This is an unreliable
1550 * service, so we have no fragmentation and no coalescence 1550 * service, so we have no fragmentation and no coalescence
1551 */ 1551 */
1552 if (len > self->max_data_size) { 1552 if (len > self->max_data_size) {
@@ -1642,7 +1642,7 @@ static int irda_sendmsg_ultra(struct kiocb *iocb, struct socket *sock,
1642 } 1642 }
1643 1643
1644 /* 1644 /*
1645 * Check that we don't send out to big frames. This is an unreliable 1645 * Check that we don't send out too big frames. This is an unreliable
1646 * service, so we have no fragmentation and no coalescence 1646 * service, so we have no fragmentation and no coalescence
1647 */ 1647 */
1648 if (len > self->max_data_size) { 1648 if (len > self->max_data_size) {
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 0ae281d9bfc3..56389c83557c 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -90,8 +90,8 @@ static int nf_conntrack_vmalloc;
90static unsigned int nf_conntrack_next_id; 90static unsigned int nf_conntrack_next_id;
91static unsigned int nf_conntrack_expect_next_id; 91static unsigned int nf_conntrack_expect_next_id;
92#ifdef CONFIG_NF_CONNTRACK_EVENTS 92#ifdef CONFIG_NF_CONNTRACK_EVENTS
93struct notifier_block *nf_conntrack_chain; 93ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain);
94struct notifier_block *nf_conntrack_expect_chain; 94ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain);
95 95
96DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); 96DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache);
97 97
@@ -103,7 +103,7 @@ __nf_ct_deliver_cached_events(struct nf_conntrack_ecache *ecache)
103 DEBUGP("ecache: delivering events for %p\n", ecache->ct); 103 DEBUGP("ecache: delivering events for %p\n", ecache->ct);
104 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct) 104 if (nf_ct_is_confirmed(ecache->ct) && !nf_ct_is_dying(ecache->ct)
105 && ecache->events) 105 && ecache->events)
106 notifier_call_chain(&nf_conntrack_chain, ecache->events, 106 atomic_notifier_call_chain(&nf_conntrack_chain, ecache->events,
107 ecache->ct); 107 ecache->ct);
108 108
109 ecache->events = 0; 109 ecache->events = 0;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index d00a9034cb5f..2a233ffcf618 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -123,7 +123,7 @@ static void netlink_destroy_callback(struct netlink_callback *cb);
123static DEFINE_RWLOCK(nl_table_lock); 123static DEFINE_RWLOCK(nl_table_lock);
124static atomic_t nl_table_users = ATOMIC_INIT(0); 124static atomic_t nl_table_users = ATOMIC_INIT(0);
125 125
126static struct notifier_block *netlink_chain; 126static ATOMIC_NOTIFIER_HEAD(netlink_chain);
127 127
128static u32 netlink_group_mask(u32 group) 128static u32 netlink_group_mask(u32 group)
129{ 129{
@@ -469,7 +469,8 @@ static int netlink_release(struct socket *sock)
469 .protocol = sk->sk_protocol, 469 .protocol = sk->sk_protocol,
470 .pid = nlk->pid, 470 .pid = nlk->pid,
471 }; 471 };
472 notifier_call_chain(&netlink_chain, NETLINK_URELEASE, &n); 472 atomic_notifier_call_chain(&netlink_chain,
473 NETLINK_URELEASE, &n);
473 } 474 }
474 475
475 if (nlk->module) 476 if (nlk->module)
@@ -1695,12 +1696,12 @@ static struct file_operations netlink_seq_fops = {
1695 1696
1696int netlink_register_notifier(struct notifier_block *nb) 1697int netlink_register_notifier(struct notifier_block *nb)
1697{ 1698{
1698 return notifier_chain_register(&netlink_chain, nb); 1699 return atomic_notifier_chain_register(&netlink_chain, nb);
1699} 1700}
1700 1701
1701int netlink_unregister_notifier(struct notifier_block *nb) 1702int netlink_unregister_notifier(struct notifier_block *nb)
1702{ 1703{
1703 return notifier_chain_unregister(&netlink_chain, nb); 1704 return atomic_notifier_chain_unregister(&netlink_chain, nb);
1704} 1705}
1705 1706
1706static const struct proto_ops netlink_ops = { 1707static const struct proto_ops netlink_ops = {
diff --git a/net/nonet.c b/net/nonet.c
index 1230f0ae832e..92e76640c7cd 100644
--- a/net/nonet.c
+++ b/net/nonet.c
@@ -19,7 +19,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
19 return -ENXIO; 19 return -ENXIO;
20} 20}
21 21
22struct file_operations bad_sock_fops = { 22const struct file_operations bad_sock_fops = {
23 .owner = THIS_MODULE, 23 .owner = THIS_MODULE,
24 .open = sock_no_open, 24 .open = sock_no_open,
25}; 25};
diff --git a/net/socket.c b/net/socket.c
index 5211ba270375..fcd77eac0ccf 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -539,7 +539,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
539 return -ENXIO; 539 return -ENXIO;
540} 540}
541 541
542struct file_operations bad_sock_fops = { 542const struct file_operations bad_sock_fops = {
543 .owner = THIS_MODULE, 543 .owner = THIS_MODULE,
544 .open = sock_no_open, 544 .open = sock_no_open,
545}; 545};
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c
index 23632d84d8d7..4d7eb9e704da 100644
--- a/net/sunrpc/auth_gss/svcauth_gss.c
+++ b/net/sunrpc/auth_gss/svcauth_gss.c
@@ -78,7 +78,8 @@ struct rsi {
78 78
79static struct cache_head *rsi_table[RSI_HASHMAX]; 79static struct cache_head *rsi_table[RSI_HASHMAX];
80static struct cache_detail rsi_cache; 80static struct cache_detail rsi_cache;
81static struct rsi *rsi_lookup(struct rsi *item, int set); 81static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
82static struct rsi *rsi_lookup(struct rsi *item);
82 83
83static void rsi_free(struct rsi *rsii) 84static void rsi_free(struct rsi *rsii)
84{ 85{
@@ -88,13 +89,11 @@ static void rsi_free(struct rsi *rsii)
88 kfree(rsii->out_token.data); 89 kfree(rsii->out_token.data);
89} 90}
90 91
91static void rsi_put(struct cache_head *item, struct cache_detail *cd) 92static void rsi_put(struct kref *ref)
92{ 93{
93 struct rsi *rsii = container_of(item, struct rsi, h); 94 struct rsi *rsii = container_of(ref, struct rsi, h.ref);
94 if (cache_put(item, cd)) { 95 rsi_free(rsii);
95 rsi_free(rsii); 96 kfree(rsii);
96 kfree(rsii);
97 }
98} 97}
99 98
100static inline int rsi_hash(struct rsi *item) 99static inline int rsi_hash(struct rsi *item)
@@ -103,8 +102,10 @@ static inline int rsi_hash(struct rsi *item)
103 ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); 102 ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS);
104} 103}
105 104
106static inline int rsi_match(struct rsi *item, struct rsi *tmp) 105static int rsi_match(struct cache_head *a, struct cache_head *b)
107{ 106{
107 struct rsi *item = container_of(a, struct rsi, h);
108 struct rsi *tmp = container_of(b, struct rsi, h);
108 return netobj_equal(&item->in_handle, &tmp->in_handle) 109 return netobj_equal(&item->in_handle, &tmp->in_handle)
109 && netobj_equal(&item->in_token, &tmp->in_token); 110 && netobj_equal(&item->in_token, &tmp->in_token);
110} 111}
@@ -125,8 +126,11 @@ static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src)
125 return dup_to_netobj(dst, src->data, src->len); 126 return dup_to_netobj(dst, src->data, src->len);
126} 127}
127 128
128static inline void rsi_init(struct rsi *new, struct rsi *item) 129static void rsi_init(struct cache_head *cnew, struct cache_head *citem)
129{ 130{
131 struct rsi *new = container_of(cnew, struct rsi, h);
132 struct rsi *item = container_of(citem, struct rsi, h);
133
130 new->out_handle.data = NULL; 134 new->out_handle.data = NULL;
131 new->out_handle.len = 0; 135 new->out_handle.len = 0;
132 new->out_token.data = NULL; 136 new->out_token.data = NULL;
@@ -141,8 +145,11 @@ static inline void rsi_init(struct rsi *new, struct rsi *item)
141 item->in_token.data = NULL; 145 item->in_token.data = NULL;
142} 146}
143 147
144static inline void rsi_update(struct rsi *new, struct rsi *item) 148static void update_rsi(struct cache_head *cnew, struct cache_head *citem)
145{ 149{
150 struct rsi *new = container_of(cnew, struct rsi, h);
151 struct rsi *item = container_of(citem, struct rsi, h);
152
146 BUG_ON(new->out_handle.data || new->out_token.data); 153 BUG_ON(new->out_handle.data || new->out_token.data);
147 new->out_handle.len = item->out_handle.len; 154 new->out_handle.len = item->out_handle.len;
148 item->out_handle.len = 0; 155 item->out_handle.len = 0;
@@ -157,6 +164,15 @@ static inline void rsi_update(struct rsi *new, struct rsi *item)
157 new->minor_status = item->minor_status; 164 new->minor_status = item->minor_status;
158} 165}
159 166
167static struct cache_head *rsi_alloc(void)
168{
169 struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL);
170 if (rsii)
171 return &rsii->h;
172 else
173 return NULL;
174}
175
160static void rsi_request(struct cache_detail *cd, 176static void rsi_request(struct cache_detail *cd,
161 struct cache_head *h, 177 struct cache_head *h,
162 char **bpp, int *blen) 178 char **bpp, int *blen)
@@ -198,6 +214,10 @@ static int rsi_parse(struct cache_detail *cd,
198 if (dup_to_netobj(&rsii.in_token, buf, len)) 214 if (dup_to_netobj(&rsii.in_token, buf, len))
199 goto out; 215 goto out;
200 216
217 rsip = rsi_lookup(&rsii);
218 if (!rsip)
219 goto out;
220
201 rsii.h.flags = 0; 221 rsii.h.flags = 0;
202 /* expiry */ 222 /* expiry */
203 expiry = get_expiry(&mesg); 223 expiry = get_expiry(&mesg);
@@ -240,12 +260,14 @@ static int rsi_parse(struct cache_detail *cd,
240 goto out; 260 goto out;
241 } 261 }
242 rsii.h.expiry_time = expiry; 262 rsii.h.expiry_time = expiry;
243 rsip = rsi_lookup(&rsii, 1); 263 rsip = rsi_update(&rsii, rsip);
244 status = 0; 264 status = 0;
245out: 265out:
246 rsi_free(&rsii); 266 rsi_free(&rsii);
247 if (rsip) 267 if (rsip)
248 rsi_put(&rsip->h, &rsi_cache); 268 cache_put(&rsip->h, &rsi_cache);
269 else
270 status = -ENOMEM;
249 return status; 271 return status;
250} 272}
251 273
@@ -257,9 +279,37 @@ static struct cache_detail rsi_cache = {
257 .cache_put = rsi_put, 279 .cache_put = rsi_put,
258 .cache_request = rsi_request, 280 .cache_request = rsi_request,
259 .cache_parse = rsi_parse, 281 .cache_parse = rsi_parse,
282 .match = rsi_match,
283 .init = rsi_init,
284 .update = update_rsi,
285 .alloc = rsi_alloc,
260}; 286};
261 287
262static DefineSimpleCacheLookup(rsi, 0) 288static struct rsi *rsi_lookup(struct rsi *item)
289{
290 struct cache_head *ch;
291 int hash = rsi_hash(item);
292
293 ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash);
294 if (ch)
295 return container_of(ch, struct rsi, h);
296 else
297 return NULL;
298}
299
300static struct rsi *rsi_update(struct rsi *new, struct rsi *old)
301{
302 struct cache_head *ch;
303 int hash = rsi_hash(new);
304
305 ch = sunrpc_cache_update(&rsi_cache, &new->h,
306 &old->h, hash);
307 if (ch)
308 return container_of(ch, struct rsi, h);
309 else
310 return NULL;
311}
312
263 313
264/* 314/*
265 * The rpcsec_context cache is used to store a context that is 315 * The rpcsec_context cache is used to store a context that is
@@ -293,7 +343,8 @@ struct rsc {
293 343
294static struct cache_head *rsc_table[RSC_HASHMAX]; 344static struct cache_head *rsc_table[RSC_HASHMAX];
295static struct cache_detail rsc_cache; 345static struct cache_detail rsc_cache;
296static struct rsc *rsc_lookup(struct rsc *item, int set); 346static struct rsc *rsc_update(struct rsc *new, struct rsc *old);
347static struct rsc *rsc_lookup(struct rsc *item);
297 348
298static void rsc_free(struct rsc *rsci) 349static void rsc_free(struct rsc *rsci)
299{ 350{
@@ -304,14 +355,12 @@ static void rsc_free(struct rsc *rsci)
304 put_group_info(rsci->cred.cr_group_info); 355 put_group_info(rsci->cred.cr_group_info);
305} 356}
306 357
307static void rsc_put(struct cache_head *item, struct cache_detail *cd) 358static void rsc_put(struct kref *ref)
308{ 359{
309 struct rsc *rsci = container_of(item, struct rsc, h); 360 struct rsc *rsci = container_of(ref, struct rsc, h.ref);
310 361
311 if (cache_put(item, cd)) { 362 rsc_free(rsci);
312 rsc_free(rsci); 363 kfree(rsci);
313 kfree(rsci);
314 }
315} 364}
316 365
317static inline int 366static inline int
@@ -320,15 +369,21 @@ rsc_hash(struct rsc *rsci)
320 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS); 369 return hash_mem(rsci->handle.data, rsci->handle.len, RSC_HASHBITS);
321} 370}
322 371
323static inline int 372static int
324rsc_match(struct rsc *new, struct rsc *tmp) 373rsc_match(struct cache_head *a, struct cache_head *b)
325{ 374{
375 struct rsc *new = container_of(a, struct rsc, h);
376 struct rsc *tmp = container_of(b, struct rsc, h);
377
326 return netobj_equal(&new->handle, &tmp->handle); 378 return netobj_equal(&new->handle, &tmp->handle);
327} 379}
328 380
329static inline void 381static void
330rsc_init(struct rsc *new, struct rsc *tmp) 382rsc_init(struct cache_head *cnew, struct cache_head *ctmp)
331{ 383{
384 struct rsc *new = container_of(cnew, struct rsc, h);
385 struct rsc *tmp = container_of(ctmp, struct rsc, h);
386
332 new->handle.len = tmp->handle.len; 387 new->handle.len = tmp->handle.len;
333 tmp->handle.len = 0; 388 tmp->handle.len = 0;
334 new->handle.data = tmp->handle.data; 389 new->handle.data = tmp->handle.data;
@@ -337,9 +392,12 @@ rsc_init(struct rsc *new, struct rsc *tmp)
337 new->cred.cr_group_info = NULL; 392 new->cred.cr_group_info = NULL;
338} 393}
339 394
340static inline void 395static void
341rsc_update(struct rsc *new, struct rsc *tmp) 396update_rsc(struct cache_head *cnew, struct cache_head *ctmp)
342{ 397{
398 struct rsc *new = container_of(cnew, struct rsc, h);
399 struct rsc *tmp = container_of(ctmp, struct rsc, h);
400
343 new->mechctx = tmp->mechctx; 401 new->mechctx = tmp->mechctx;
344 tmp->mechctx = NULL; 402 tmp->mechctx = NULL;
345 memset(&new->seqdata, 0, sizeof(new->seqdata)); 403 memset(&new->seqdata, 0, sizeof(new->seqdata));
@@ -348,6 +406,16 @@ rsc_update(struct rsc *new, struct rsc *tmp)
348 tmp->cred.cr_group_info = NULL; 406 tmp->cred.cr_group_info = NULL;
349} 407}
350 408
409static struct cache_head *
410rsc_alloc(void)
411{
412 struct rsc *rsci = kmalloc(sizeof(*rsci), GFP_KERNEL);
413 if (rsci)
414 return &rsci->h;
415 else
416 return NULL;
417}
418
351static int rsc_parse(struct cache_detail *cd, 419static int rsc_parse(struct cache_detail *cd,
352 char *mesg, int mlen) 420 char *mesg, int mlen)
353{ 421{
@@ -373,6 +441,10 @@ static int rsc_parse(struct cache_detail *cd,
373 if (expiry == 0) 441 if (expiry == 0)
374 goto out; 442 goto out;
375 443
444 rscp = rsc_lookup(&rsci);
445 if (!rscp)
446 goto out;
447
376 /* uid, or NEGATIVE */ 448 /* uid, or NEGATIVE */
377 rv = get_int(&mesg, &rsci.cred.cr_uid); 449 rv = get_int(&mesg, &rsci.cred.cr_uid);
378 if (rv == -EINVAL) 450 if (rv == -EINVAL)
@@ -428,12 +500,14 @@ static int rsc_parse(struct cache_detail *cd,
428 gss_mech_put(gm); 500 gss_mech_put(gm);
429 } 501 }
430 rsci.h.expiry_time = expiry; 502 rsci.h.expiry_time = expiry;
431 rscp = rsc_lookup(&rsci, 1); 503 rscp = rsc_update(&rsci, rscp);
432 status = 0; 504 status = 0;
433out: 505out:
434 rsc_free(&rsci); 506 rsc_free(&rsci);
435 if (rscp) 507 if (rscp)
436 rsc_put(&rscp->h, &rsc_cache); 508 cache_put(&rscp->h, &rsc_cache);
509 else
510 status = -ENOMEM;
437 return status; 511 return status;
438} 512}
439 513
@@ -444,9 +518,37 @@ static struct cache_detail rsc_cache = {
444 .name = "auth.rpcsec.context", 518 .name = "auth.rpcsec.context",
445 .cache_put = rsc_put, 519 .cache_put = rsc_put,
446 .cache_parse = rsc_parse, 520 .cache_parse = rsc_parse,
521 .match = rsc_match,
522 .init = rsc_init,
523 .update = update_rsc,
524 .alloc = rsc_alloc,
447}; 525};
448 526
449static DefineSimpleCacheLookup(rsc, 0); 527static struct rsc *rsc_lookup(struct rsc *item)
528{
529 struct cache_head *ch;
530 int hash = rsc_hash(item);
531
532 ch = sunrpc_cache_lookup(&rsc_cache, &item->h, hash);
533 if (ch)
534 return container_of(ch, struct rsc, h);
535 else
536 return NULL;
537}
538
539static struct rsc *rsc_update(struct rsc *new, struct rsc *old)
540{
541 struct cache_head *ch;
542 int hash = rsc_hash(new);
543
544 ch = sunrpc_cache_update(&rsc_cache, &new->h,
545 &old->h, hash);
546 if (ch)
547 return container_of(ch, struct rsc, h);
548 else
549 return NULL;
550}
551
450 552
451static struct rsc * 553static struct rsc *
452gss_svc_searchbyctx(struct xdr_netobj *handle) 554gss_svc_searchbyctx(struct xdr_netobj *handle)
@@ -457,7 +559,7 @@ gss_svc_searchbyctx(struct xdr_netobj *handle)
457 memset(&rsci, 0, sizeof(rsci)); 559 memset(&rsci, 0, sizeof(rsci));
458 if (dup_to_netobj(&rsci.handle, handle->data, handle->len)) 560 if (dup_to_netobj(&rsci.handle, handle->data, handle->len))
459 return NULL; 561 return NULL;
460 found = rsc_lookup(&rsci, 0); 562 found = rsc_lookup(&rsci);
461 rsc_free(&rsci); 563 rsc_free(&rsci);
462 if (!found) 564 if (!found)
463 return NULL; 565 return NULL;
@@ -645,6 +747,8 @@ find_gss_auth_domain(struct gss_ctx *ctx, u32 svc)
645 return auth_domain_find(name); 747 return auth_domain_find(name);
646} 748}
647 749
750static struct auth_ops svcauthops_gss;
751
648int 752int
649svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) 753svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
650{ 754{
@@ -655,20 +759,18 @@ svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name)
655 new = kmalloc(sizeof(*new), GFP_KERNEL); 759 new = kmalloc(sizeof(*new), GFP_KERNEL);
656 if (!new) 760 if (!new)
657 goto out; 761 goto out;
658 cache_init(&new->h.h); 762 kref_init(&new->h.ref);
659 new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL); 763 new->h.name = kmalloc(strlen(name) + 1, GFP_KERNEL);
660 if (!new->h.name) 764 if (!new->h.name)
661 goto out_free_dom; 765 goto out_free_dom;
662 strcpy(new->h.name, name); 766 strcpy(new->h.name, name);
663 new->h.flavour = RPC_AUTH_GSS; 767 new->h.flavour = &svcauthops_gss;
664 new->pseudoflavor = pseudoflavor; 768 new->pseudoflavor = pseudoflavor;
665 new->h.h.expiry_time = NEVER;
666 769
667 test = auth_domain_lookup(&new->h, 1); 770 test = auth_domain_lookup(name, &new->h);
668 if (test == &new->h) { 771 if (test != &new->h) { /* XXX Duplicate registration? */
669 BUG_ON(atomic_dec_and_test(&new->h.h.refcnt));
670 } else { /* XXX Duplicate registration? */
671 auth_domain_put(&new->h); 772 auth_domain_put(&new->h);
773 /* dangling ref-count... */
672 goto out; 774 goto out;
673 } 775 }
674 return 0; 776 return 0;
@@ -895,7 +997,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp)
895 goto drop; 997 goto drop;
896 } 998 }
897 999
898 rsip = rsi_lookup(&rsikey, 0); 1000 rsip = rsi_lookup(&rsikey);
899 rsi_free(&rsikey); 1001 rsi_free(&rsikey);
900 if (!rsip) { 1002 if (!rsip) {
901 goto drop; 1003 goto drop;
@@ -970,7 +1072,7 @@ drop:
970 ret = SVC_DROP; 1072 ret = SVC_DROP;
971out: 1073out:
972 if (rsci) 1074 if (rsci)
973 rsc_put(&rsci->h, &rsc_cache); 1075 cache_put(&rsci->h, &rsc_cache);
974 return ret; 1076 return ret;
975} 1077}
976 1078
@@ -1062,7 +1164,7 @@ out_err:
1062 put_group_info(rqstp->rq_cred.cr_group_info); 1164 put_group_info(rqstp->rq_cred.cr_group_info);
1063 rqstp->rq_cred.cr_group_info = NULL; 1165 rqstp->rq_cred.cr_group_info = NULL;
1064 if (gsd->rsci) 1166 if (gsd->rsci)
1065 rsc_put(&gsd->rsci->h, &rsc_cache); 1167 cache_put(&gsd->rsci->h, &rsc_cache);
1066 gsd->rsci = NULL; 1168 gsd->rsci = NULL;
1067 1169
1068 return stat; 1170 return stat;
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c
index 0acccfeeb284..3ac4193a78ed 100644
--- a/net/sunrpc/cache.c
+++ b/net/sunrpc/cache.c
@@ -37,16 +37,138 @@
37static void cache_defer_req(struct cache_req *req, struct cache_head *item); 37static void cache_defer_req(struct cache_req *req, struct cache_head *item);
38static void cache_revisit_request(struct cache_head *item); 38static void cache_revisit_request(struct cache_head *item);
39 39
40void cache_init(struct cache_head *h) 40static void cache_init(struct cache_head *h)
41{ 41{
42 time_t now = get_seconds(); 42 time_t now = get_seconds();
43 h->next = NULL; 43 h->next = NULL;
44 h->flags = 0; 44 h->flags = 0;
45 atomic_set(&h->refcnt, 1); 45 kref_init(&h->ref);
46 h->expiry_time = now + CACHE_NEW_EXPIRY; 46 h->expiry_time = now + CACHE_NEW_EXPIRY;
47 h->last_refresh = now; 47 h->last_refresh = now;
48} 48}
49 49
50struct cache_head *sunrpc_cache_lookup(struct cache_detail *detail,
51 struct cache_head *key, int hash)
52{
53 struct cache_head **head, **hp;
54 struct cache_head *new = NULL;
55
56 head = &detail->hash_table[hash];
57
58 read_lock(&detail->hash_lock);
59
60 for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
61 struct cache_head *tmp = *hp;
62 if (detail->match(tmp, key)) {
63 cache_get(tmp);
64 read_unlock(&detail->hash_lock);
65 return tmp;
66 }
67 }
68 read_unlock(&detail->hash_lock);
69 /* Didn't find anything, insert an empty entry */
70
71 new = detail->alloc();
72 if (!new)
73 return NULL;
74 cache_init(new);
75
76 write_lock(&detail->hash_lock);
77
78 /* check if entry appeared while we slept */
79 for (hp=head; *hp != NULL ; hp = &(*hp)->next) {
80 struct cache_head *tmp = *hp;
81 if (detail->match(tmp, key)) {
82 cache_get(tmp);
83 write_unlock(&detail->hash_lock);
84 cache_put(new, detail);
85 return tmp;
86 }
87 }
88 detail->init(new, key);
89 new->next = *head;
90 *head = new;
91 detail->entries++;
92 cache_get(new);
93 write_unlock(&detail->hash_lock);
94
95 return new;
96}
97EXPORT_SYMBOL(sunrpc_cache_lookup);
98
99
100static void queue_loose(struct cache_detail *detail, struct cache_head *ch);
101
102static int cache_fresh_locked(struct cache_head *head, time_t expiry)
103{
104 head->expiry_time = expiry;
105 head->last_refresh = get_seconds();
106 return !test_and_set_bit(CACHE_VALID, &head->flags);
107}
108
109static void cache_fresh_unlocked(struct cache_head *head,
110 struct cache_detail *detail, int new)
111{
112 if (new)
113 cache_revisit_request(head);
114 if (test_and_clear_bit(CACHE_PENDING, &head->flags)) {
115 cache_revisit_request(head);
116 queue_loose(detail, head);
117 }
118}
119
120struct cache_head *sunrpc_cache_update(struct cache_detail *detail,
121 struct cache_head *new, struct cache_head *old, int hash)
122{
123 /* The 'old' entry is to be replaced by 'new'.
124 * If 'old' is not VALID, we update it directly,
125 * otherwise we need to replace it
126 */
127 struct cache_head **head;
128 struct cache_head *tmp;
129 int is_new;
130
131 if (!test_bit(CACHE_VALID, &old->flags)) {
132 write_lock(&detail->hash_lock);
133 if (!test_bit(CACHE_VALID, &old->flags)) {
134 if (test_bit(CACHE_NEGATIVE, &new->flags))
135 set_bit(CACHE_NEGATIVE, &old->flags);
136 else
137 detail->update(old, new);
138 is_new = cache_fresh_locked(old, new->expiry_time);
139 write_unlock(&detail->hash_lock);
140 cache_fresh_unlocked(old, detail, is_new);
141 return old;
142 }
143 write_unlock(&detail->hash_lock);
144 }
145 /* We need to insert a new entry */
146 tmp = detail->alloc();
147 if (!tmp) {
148 cache_put(old, detail);
149 return NULL;
150 }
151 cache_init(tmp);
152 detail->init(tmp, old);
153 head = &detail->hash_table[hash];
154
155 write_lock(&detail->hash_lock);
156 if (test_bit(CACHE_NEGATIVE, &new->flags))
157 set_bit(CACHE_NEGATIVE, &tmp->flags);
158 else
159 detail->update(tmp, new);
160 tmp->next = *head;
161 *head = tmp;
162 cache_get(tmp);
163 is_new = cache_fresh_locked(tmp, new->expiry_time);
164 cache_fresh_locked(old, 0);
165 write_unlock(&detail->hash_lock);
166 cache_fresh_unlocked(tmp, detail, is_new);
167 cache_fresh_unlocked(old, detail, 0);
168 cache_put(old, detail);
169 return tmp;
170}
171EXPORT_SYMBOL(sunrpc_cache_update);
50 172
51static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h); 173static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h);
52/* 174/*
@@ -94,7 +216,8 @@ int cache_check(struct cache_detail *detail,
94 clear_bit(CACHE_PENDING, &h->flags); 216 clear_bit(CACHE_PENDING, &h->flags);
95 if (rv == -EAGAIN) { 217 if (rv == -EAGAIN) {
96 set_bit(CACHE_NEGATIVE, &h->flags); 218 set_bit(CACHE_NEGATIVE, &h->flags);
97 cache_fresh(detail, h, get_seconds()+CACHE_NEW_EXPIRY); 219 cache_fresh_unlocked(h, detail,
220 cache_fresh_locked(h, get_seconds()+CACHE_NEW_EXPIRY));
98 rv = -ENOENT; 221 rv = -ENOENT;
99 } 222 }
100 break; 223 break;
@@ -110,25 +233,11 @@ int cache_check(struct cache_detail *detail,
110 if (rv == -EAGAIN) 233 if (rv == -EAGAIN)
111 cache_defer_req(rqstp, h); 234 cache_defer_req(rqstp, h);
112 235
113 if (rv && h) 236 if (rv)
114 detail->cache_put(h, detail); 237 cache_put(h, detail);
115 return rv; 238 return rv;
116} 239}
117 240
118static void queue_loose(struct cache_detail *detail, struct cache_head *ch);
119
120void cache_fresh(struct cache_detail *detail,
121 struct cache_head *head, time_t expiry)
122{
123
124 head->expiry_time = expiry;
125 head->last_refresh = get_seconds();
126 if (!test_and_set_bit(CACHE_VALID, &head->flags))
127 cache_revisit_request(head);
128 if (test_and_clear_bit(CACHE_PENDING, &head->flags))
129 queue_loose(detail, head);
130}
131
132/* 241/*
133 * caches need to be periodically cleaned. 242 * caches need to be periodically cleaned.
134 * For this we maintain a list of cache_detail and 243 * For this we maintain a list of cache_detail and
@@ -322,7 +431,7 @@ static int cache_clean(void)
322 if (test_and_clear_bit(CACHE_PENDING, &ch->flags)) 431 if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
323 queue_loose(current_detail, ch); 432 queue_loose(current_detail, ch);
324 433
325 if (atomic_read(&ch->refcnt) == 1) 434 if (atomic_read(&ch->ref.refcount) == 1)
326 break; 435 break;
327 } 436 }
328 if (ch) { 437 if (ch) {
@@ -337,7 +446,7 @@ static int cache_clean(void)
337 current_index ++; 446 current_index ++;
338 spin_unlock(&cache_list_lock); 447 spin_unlock(&cache_list_lock);
339 if (ch) 448 if (ch)
340 d->cache_put(ch, d); 449 cache_put(ch, d);
341 } else 450 } else
342 spin_unlock(&cache_list_lock); 451 spin_unlock(&cache_list_lock);
343 452
@@ -453,7 +562,7 @@ static void cache_defer_req(struct cache_req *req, struct cache_head *item)
453 /* there was one too many */ 562 /* there was one too many */
454 dreq->revisit(dreq, 1); 563 dreq->revisit(dreq, 1);
455 } 564 }
456 if (test_bit(CACHE_VALID, &item->flags)) { 565 if (!test_bit(CACHE_PENDING, &item->flags)) {
457 /* must have just been validated... */ 566 /* must have just been validated... */
458 cache_revisit_request(item); 567 cache_revisit_request(item);
459 } 568 }
@@ -614,7 +723,7 @@ cache_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
614 !test_bit(CACHE_PENDING, &rq->item->flags)) { 723 !test_bit(CACHE_PENDING, &rq->item->flags)) {
615 list_del(&rq->q.list); 724 list_del(&rq->q.list);
616 spin_unlock(&queue_lock); 725 spin_unlock(&queue_lock);
617 cd->cache_put(rq->item, cd); 726 cache_put(rq->item, cd);
618 kfree(rq->buf); 727 kfree(rq->buf);
619 kfree(rq); 728 kfree(rq);
620 } else 729 } else
@@ -794,10 +903,10 @@ static void queue_loose(struct cache_detail *detail, struct cache_head *ch)
794 if (cr->item != ch) 903 if (cr->item != ch)
795 continue; 904 continue;
796 if (cr->readers != 0) 905 if (cr->readers != 0)
797 break; 906 continue;
798 list_del(&cr->q.list); 907 list_del(&cr->q.list);
799 spin_unlock(&queue_lock); 908 spin_unlock(&queue_lock);
800 detail->cache_put(cr->item, detail); 909 cache_put(cr->item, detail);
801 kfree(cr->buf); 910 kfree(cr->buf);
802 kfree(cr); 911 kfree(cr);
803 return; 912 return;
@@ -1082,8 +1191,8 @@ static int c_show(struct seq_file *m, void *p)
1082 return cd->cache_show(m, cd, NULL); 1191 return cd->cache_show(m, cd, NULL);
1083 1192
1084 ifdebug(CACHE) 1193 ifdebug(CACHE)
1085 seq_printf(m, "# expiry=%ld refcnt=%d\n", 1194 seq_printf(m, "# expiry=%ld refcnt=%d flags=%lx\n",
1086 cp->expiry_time, atomic_read(&cp->refcnt)); 1195 cp->expiry_time, atomic_read(&cp->ref.refcount), cp->flags);
1087 cache_get(cp); 1196 cache_get(cp);
1088 if (cache_check(cd, cp, NULL)) 1197 if (cache_check(cd, cp, NULL))
1089 /* cache_check does a cache_put on failure */ 1198 /* cache_check does a cache_put on failure */
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index aa4158be9900..cc673dd8433f 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -395,7 +395,7 @@ enum {
395 */ 395 */
396struct rpc_filelist { 396struct rpc_filelist {
397 char *name; 397 char *name;
398 struct file_operations *i_fop; 398 const struct file_operations *i_fop;
399 int mode; 399 int mode;
400}; 400};
401 401
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c
index 790941e8af4d..dea529666d69 100644
--- a/net/sunrpc/stats.c
+++ b/net/sunrpc/stats.c
@@ -225,7 +225,7 @@ EXPORT_SYMBOL(rpc_print_iostats);
225 * Register/unregister RPC proc files 225 * Register/unregister RPC proc files
226 */ 226 */
227static inline struct proc_dir_entry * 227static inline struct proc_dir_entry *
228do_register(const char *name, void *data, struct file_operations *fops) 228do_register(const char *name, void *data, const struct file_operations *fops)
229{ 229{
230 struct proc_dir_entry *ent; 230 struct proc_dir_entry *ent;
231 231
@@ -253,7 +253,7 @@ rpc_proc_unregister(const char *name)
253} 253}
254 254
255struct proc_dir_entry * 255struct proc_dir_entry *
256svc_proc_register(struct svc_stat *statp, struct file_operations *fops) 256svc_proc_register(struct svc_stat *statp, const struct file_operations *fops)
257{ 257{
258 return do_register(statp->program->pg_name, statp, fops); 258 return do_register(statp->program->pg_name, statp, fops);
259} 259}
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 9f7373203592..769114f0f886 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -105,8 +105,6 @@ EXPORT_SYMBOL(auth_unix_lookup);
105EXPORT_SYMBOL(cache_check); 105EXPORT_SYMBOL(cache_check);
106EXPORT_SYMBOL(cache_flush); 106EXPORT_SYMBOL(cache_flush);
107EXPORT_SYMBOL(cache_purge); 107EXPORT_SYMBOL(cache_purge);
108EXPORT_SYMBOL(cache_fresh);
109EXPORT_SYMBOL(cache_init);
110EXPORT_SYMBOL(cache_register); 108EXPORT_SYMBOL(cache_register);
111EXPORT_SYMBOL(cache_unregister); 109EXPORT_SYMBOL(cache_unregister);
112EXPORT_SYMBOL(qword_add); 110EXPORT_SYMBOL(qword_add);
@@ -142,6 +140,7 @@ EXPORT_SYMBOL(nlm_debug);
142 140
143extern int register_rpc_pipefs(void); 141extern int register_rpc_pipefs(void);
144extern void unregister_rpc_pipefs(void); 142extern void unregister_rpc_pipefs(void);
143extern struct cache_detail ip_map_cache;
145 144
146static int __init 145static int __init
147init_sunrpc(void) 146init_sunrpc(void)
@@ -158,7 +157,6 @@ init_sunrpc(void)
158#ifdef CONFIG_PROC_FS 157#ifdef CONFIG_PROC_FS
159 rpc_proc_init(); 158 rpc_proc_init();
160#endif 159#endif
161 cache_register(&auth_domain_cache);
162 cache_register(&ip_map_cache); 160 cache_register(&ip_map_cache);
163out: 161out:
164 return err; 162 return err;
@@ -169,8 +167,6 @@ cleanup_sunrpc(void)
169{ 167{
170 unregister_rpc_pipefs(); 168 unregister_rpc_pipefs();
171 rpc_destroy_mempool(); 169 rpc_destroy_mempool();
172 if (cache_unregister(&auth_domain_cache))
173 printk(KERN_ERR "sunrpc: failed to unregister auth_domain cache\n");
174 if (cache_unregister(&ip_map_cache)) 170 if (cache_unregister(&ip_map_cache))
175 printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n"); 171 printk(KERN_ERR "sunrpc: failed to unregister ip_map cache\n");
176#ifdef RPC_DEBUG 172#ifdef RPC_DEBUG
diff --git a/net/sunrpc/svcauth.c b/net/sunrpc/svcauth.c
index dda4f0c63511..5b28c6176806 100644
--- a/net/sunrpc/svcauth.c
+++ b/net/sunrpc/svcauth.c
@@ -106,112 +106,56 @@ svc_auth_unregister(rpc_authflavor_t flavor)
106EXPORT_SYMBOL(svc_auth_unregister); 106EXPORT_SYMBOL(svc_auth_unregister);
107 107
108/************************************************** 108/**************************************************
109 * cache for domain name to auth_domain 109 * 'auth_domains' are stored in a hash table indexed by name.
110 * Entries are only added by flavours which will normally 110 * When the last reference to an 'auth_domain' is dropped,
111 * have a structure that 'inherits' from auth_domain. 111 * the object is unhashed and freed.
112 * e.g. when an IP -> domainname is given to auth_unix, 112 * If auth_domain_lookup fails to find an entry, it will return
113 * and the domain name doesn't exist, it will create a 113 * it's second argument 'new'. If this is non-null, it will
114 * auth_unix_domain and add it to this hash table. 114 * have been atomically linked into the table.
115 * If it finds the name does exist, but isn't AUTH_UNIX,
116 * it will complain.
117 */ 115 */
118 116
119/*
120 * Auth auth_domain cache is somewhat different to other caches,
121 * largely because the entries are possibly of different types:
122 * each auth flavour has it's own type.
123 * One consequence of this that DefineCacheLookup cannot
124 * allocate a new structure as it cannot know the size.
125 * Notice that the "INIT" code fragment is quite different
126 * from other caches. When auth_domain_lookup might be
127 * creating a new domain, the new domain is passed in
128 * complete and it is used as-is rather than being copied into
129 * another structure.
130 */
131#define DN_HASHBITS 6 117#define DN_HASHBITS 6
132#define DN_HASHMAX (1<<DN_HASHBITS) 118#define DN_HASHMAX (1<<DN_HASHBITS)
133#define DN_HASHMASK (DN_HASHMAX-1) 119#define DN_HASHMASK (DN_HASHMAX-1)
134 120
135static struct cache_head *auth_domain_table[DN_HASHMAX]; 121static struct hlist_head auth_domain_table[DN_HASHMAX];
136 122static spinlock_t auth_domain_lock = SPIN_LOCK_UNLOCKED;
137static void auth_domain_drop(struct cache_head *item, struct cache_detail *cd)
138{
139 struct auth_domain *dom = container_of(item, struct auth_domain, h);
140 if (cache_put(item,cd))
141 authtab[dom->flavour]->domain_release(dom);
142}
143
144
145struct cache_detail auth_domain_cache = {
146 .owner = THIS_MODULE,
147 .hash_size = DN_HASHMAX,
148 .hash_table = auth_domain_table,
149 .name = "auth.domain",
150 .cache_put = auth_domain_drop,
151};
152 123
153void auth_domain_put(struct auth_domain *dom) 124void auth_domain_put(struct auth_domain *dom)
154{ 125{
155 auth_domain_drop(&dom->h, &auth_domain_cache); 126 if (atomic_dec_and_lock(&dom->ref.refcount, &auth_domain_lock)) {
156} 127 hlist_del(&dom->hash);
157 128 dom->flavour->domain_release(dom);
158static inline int auth_domain_hash(struct auth_domain *item) 129 }
159{
160 return hash_str(item->name, DN_HASHBITS);
161}
162static inline int auth_domain_match(struct auth_domain *tmp, struct auth_domain *item)
163{
164 return strcmp(tmp->name, item->name) == 0;
165} 130}
166 131
167struct auth_domain * 132struct auth_domain *
168auth_domain_lookup(struct auth_domain *item, int set) 133auth_domain_lookup(char *name, struct auth_domain *new)
169{ 134{
170 struct auth_domain *tmp = NULL; 135 struct auth_domain *hp;
171 struct cache_head **hp, **head; 136 struct hlist_head *head;
172 head = &auth_domain_cache.hash_table[auth_domain_hash(item)]; 137 struct hlist_node *np;
173 138
174 if (set) 139 head = &auth_domain_table[hash_str(name, DN_HASHBITS)];
175 write_lock(&auth_domain_cache.hash_lock); 140
176 else 141 spin_lock(&auth_domain_lock);
177 read_lock(&auth_domain_cache.hash_lock); 142
178 for (hp=head; *hp != NULL; hp = &tmp->h.next) { 143 hlist_for_each_entry(hp, np, head, hash) {
179 tmp = container_of(*hp, struct auth_domain, h); 144 if (strcmp(hp->name, name)==0) {
180 if (!auth_domain_match(tmp, item)) 145 kref_get(&hp->ref);
181 continue; 146 spin_unlock(&auth_domain_lock);
182 if (!set) { 147 return hp;
183 cache_get(&tmp->h);
184 goto out_noset;
185 } 148 }
186 *hp = tmp->h.next;
187 tmp->h.next = NULL;
188 auth_domain_drop(&tmp->h, &auth_domain_cache);
189 goto out_set;
190 } 149 }
191 /* Didn't find anything */ 150 if (new) {
192 if (!set) 151 hlist_add_head(&new->hash, head);
193 goto out_nada; 152 kref_get(&new->ref);
194 auth_domain_cache.entries++; 153 }
195out_set: 154 spin_unlock(&auth_domain_lock);
196 item->h.next = *head; 155 return new;
197 *head = &item->h;
198 cache_get(&item->h);
199 write_unlock(&auth_domain_cache.hash_lock);
200 cache_fresh(&auth_domain_cache, &item->h, item->h.expiry_time);
201 cache_get(&item->h);
202 return item;
203out_nada:
204 tmp = NULL;
205out_noset:
206 read_unlock(&auth_domain_cache.hash_lock);
207 return tmp;
208} 156}
209 157
210struct auth_domain *auth_domain_find(char *name) 158struct auth_domain *auth_domain_find(char *name)
211{ 159{
212 struct auth_domain *rv, ad; 160 return auth_domain_lookup(name, NULL);
213
214 ad.name = name;
215 rv = auth_domain_lookup(&ad, 0);
216 return rv;
217} 161}
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
index 3e6c694bbad1..7e5707e2d6b6 100644
--- a/net/sunrpc/svcauth_unix.c
+++ b/net/sunrpc/svcauth_unix.c
@@ -27,41 +27,35 @@ struct unix_domain {
27 /* other stuff later */ 27 /* other stuff later */
28}; 28};
29 29
30extern struct auth_ops svcauth_unix;
31
30struct auth_domain *unix_domain_find(char *name) 32struct auth_domain *unix_domain_find(char *name)
31{ 33{
32 struct auth_domain *rv, ud; 34 struct auth_domain *rv;
33 struct unix_domain *new; 35 struct unix_domain *new = NULL;
34 36
35 ud.name = name; 37 rv = auth_domain_lookup(name, NULL);
36 38 while(1) {
37 rv = auth_domain_lookup(&ud, 0); 39 if (rv) {
38 40 if (new && rv != &new->h)
39 foundit: 41 auth_domain_put(&new->h);
40 if (rv && rv->flavour != RPC_AUTH_UNIX) { 42
41 auth_domain_put(rv); 43 if (rv->flavour != &svcauth_unix) {
42 return NULL; 44 auth_domain_put(rv);
43 } 45 return NULL;
44 if (rv) 46 }
45 return rv; 47 return rv;
46 48 }
47 new = kmalloc(sizeof(*new), GFP_KERNEL); 49
48 if (new == NULL) 50 new = kmalloc(sizeof(*new), GFP_KERNEL);
49 return NULL; 51 if (new == NULL)
50 cache_init(&new->h.h); 52 return NULL;
51 new->h.name = kstrdup(name, GFP_KERNEL); 53 kref_init(&new->h.ref);
52 new->h.flavour = RPC_AUTH_UNIX; 54 new->h.name = kstrdup(name, GFP_KERNEL);
53 new->addr_changes = 0; 55 new->h.flavour = &svcauth_unix;
54 new->h.h.expiry_time = NEVER; 56 new->addr_changes = 0;
55 57 rv = auth_domain_lookup(name, &new->h);
56 rv = auth_domain_lookup(&new->h, 2);
57 if (rv == &new->h) {
58 if (atomic_dec_and_test(&new->h.h.refcnt)) BUG();
59 } else {
60 auth_domain_put(&new->h);
61 goto foundit;
62 } 58 }
63
64 return rv;
65} 59}
66 60
67static void svcauth_unix_domain_release(struct auth_domain *dom) 61static void svcauth_unix_domain_release(struct auth_domain *dom)
@@ -90,15 +84,15 @@ struct ip_map {
90}; 84};
91static struct cache_head *ip_table[IP_HASHMAX]; 85static struct cache_head *ip_table[IP_HASHMAX];
92 86
93static void ip_map_put(struct cache_head *item, struct cache_detail *cd) 87static void ip_map_put(struct kref *kref)
94{ 88{
89 struct cache_head *item = container_of(kref, struct cache_head, ref);
95 struct ip_map *im = container_of(item, struct ip_map,h); 90 struct ip_map *im = container_of(item, struct ip_map,h);
96 if (cache_put(item, cd)) { 91
97 if (test_bit(CACHE_VALID, &item->flags) && 92 if (test_bit(CACHE_VALID, &item->flags) &&
98 !test_bit(CACHE_NEGATIVE, &item->flags)) 93 !test_bit(CACHE_NEGATIVE, &item->flags))
99 auth_domain_put(&im->m_client->h); 94 auth_domain_put(&im->m_client->h);
100 kfree(im); 95 kfree(im);
101 }
102} 96}
103 97
104#if IP_HASHBITS == 8 98#if IP_HASHBITS == 8
@@ -112,28 +106,38 @@ static inline int hash_ip(unsigned long ip)
112 return (hash ^ (hash>>8)) & 0xff; 106 return (hash ^ (hash>>8)) & 0xff;
113} 107}
114#endif 108#endif
115 109static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
116static inline int ip_map_hash(struct ip_map *item)
117{
118 return hash_str(item->m_class, IP_HASHBITS) ^
119 hash_ip((unsigned long)item->m_addr.s_addr);
120}
121static inline int ip_map_match(struct ip_map *item, struct ip_map *tmp)
122{ 110{
123 return strcmp(tmp->m_class, item->m_class) == 0 111 struct ip_map *orig = container_of(corig, struct ip_map, h);
124 && tmp->m_addr.s_addr == item->m_addr.s_addr; 112 struct ip_map *new = container_of(cnew, struct ip_map, h);
113 return strcmp(orig->m_class, new->m_class) == 0
114 && orig->m_addr.s_addr == new->m_addr.s_addr;
125} 115}
126static inline void ip_map_init(struct ip_map *new, struct ip_map *item) 116static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
127{ 117{
118 struct ip_map *new = container_of(cnew, struct ip_map, h);
119 struct ip_map *item = container_of(citem, struct ip_map, h);
120
128 strcpy(new->m_class, item->m_class); 121 strcpy(new->m_class, item->m_class);
129 new->m_addr.s_addr = item->m_addr.s_addr; 122 new->m_addr.s_addr = item->m_addr.s_addr;
130} 123}
131static inline void ip_map_update(struct ip_map *new, struct ip_map *item) 124static void update(struct cache_head *cnew, struct cache_head *citem)
132{ 125{
133 cache_get(&item->m_client->h.h); 126 struct ip_map *new = container_of(cnew, struct ip_map, h);
127 struct ip_map *item = container_of(citem, struct ip_map, h);
128
129 kref_get(&item->m_client->h.ref);
134 new->m_client = item->m_client; 130 new->m_client = item->m_client;
135 new->m_add_change = item->m_add_change; 131 new->m_add_change = item->m_add_change;
136} 132}
133static struct cache_head *ip_map_alloc(void)
134{
135 struct ip_map *i = kmalloc(sizeof(*i), GFP_KERNEL);
136 if (i)
137 return &i->h;
138 else
139 return NULL;
140}
137 141
138static void ip_map_request(struct cache_detail *cd, 142static void ip_map_request(struct cache_detail *cd,
139 struct cache_head *h, 143 struct cache_head *h,
@@ -154,7 +158,8 @@ static void ip_map_request(struct cache_detail *cd,
154 (*bpp)[-1] = '\n'; 158 (*bpp)[-1] = '\n';
155} 159}
156 160
157static struct ip_map *ip_map_lookup(struct ip_map *, int); 161static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
162static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
158 163
159static int ip_map_parse(struct cache_detail *cd, 164static int ip_map_parse(struct cache_detail *cd,
160 char *mesg, int mlen) 165 char *mesg, int mlen)
@@ -166,7 +171,11 @@ static int ip_map_parse(struct cache_detail *cd,
166 int len; 171 int len;
167 int b1,b2,b3,b4; 172 int b1,b2,b3,b4;
168 char c; 173 char c;
169 struct ip_map ipm, *ipmp; 174 char class[8];
175 struct in_addr addr;
176 int err;
177
178 struct ip_map *ipmp;
170 struct auth_domain *dom; 179 struct auth_domain *dom;
171 time_t expiry; 180 time_t expiry;
172 181
@@ -175,7 +184,7 @@ static int ip_map_parse(struct cache_detail *cd,
175 mesg[mlen-1] = 0; 184 mesg[mlen-1] = 0;
176 185
177 /* class */ 186 /* class */
178 len = qword_get(&mesg, ipm.m_class, sizeof(ipm.m_class)); 187 len = qword_get(&mesg, class, sizeof(class));
179 if (len <= 0) return -EINVAL; 188 if (len <= 0) return -EINVAL;
180 189
181 /* ip address */ 190 /* ip address */
@@ -200,25 +209,22 @@ static int ip_map_parse(struct cache_detail *cd,
200 } else 209 } else
201 dom = NULL; 210 dom = NULL;
202 211
203 ipm.m_addr.s_addr = 212 addr.s_addr =
204 htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4); 213 htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
205 ipm.h.flags = 0; 214
206 if (dom) { 215 ipmp = ip_map_lookup(class,addr);
207 ipm.m_client = container_of(dom, struct unix_domain, h); 216 if (ipmp) {
208 ipm.m_add_change = ipm.m_client->addr_changes; 217 err = ip_map_update(ipmp,
218 container_of(dom, struct unix_domain, h),
219 expiry);
209 } else 220 } else
210 set_bit(CACHE_NEGATIVE, &ipm.h.flags); 221 err = -ENOMEM;
211 ipm.h.expiry_time = expiry;
212 222
213 ipmp = ip_map_lookup(&ipm, 1);
214 if (ipmp)
215 ip_map_put(&ipmp->h, &ip_map_cache);
216 if (dom) 223 if (dom)
217 auth_domain_put(dom); 224 auth_domain_put(dom);
218 if (!ipmp) 225
219 return -ENOMEM;
220 cache_flush(); 226 cache_flush();
221 return 0; 227 return err;
222} 228}
223 229
224static int ip_map_show(struct seq_file *m, 230static int ip_map_show(struct seq_file *m,
@@ -262,32 +268,70 @@ struct cache_detail ip_map_cache = {
262 .cache_request = ip_map_request, 268 .cache_request = ip_map_request,
263 .cache_parse = ip_map_parse, 269 .cache_parse = ip_map_parse,
264 .cache_show = ip_map_show, 270 .cache_show = ip_map_show,
271 .match = ip_map_match,
272 .init = ip_map_init,
273 .update = update,
274 .alloc = ip_map_alloc,
265}; 275};
266 276
267static DefineSimpleCacheLookup(ip_map, 0) 277static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
278{
279 struct ip_map ip;
280 struct cache_head *ch;
281
282 strcpy(ip.m_class, class);
283 ip.m_addr = addr;
284 ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
285 hash_str(class, IP_HASHBITS) ^
286 hash_ip((unsigned long)addr.s_addr));
287
288 if (ch)
289 return container_of(ch, struct ip_map, h);
290 else
291 return NULL;
292}
268 293
294static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry)
295{
296 struct ip_map ip;
297 struct cache_head *ch;
298
299 ip.m_client = udom;
300 ip.h.flags = 0;
301 if (!udom)
302 set_bit(CACHE_NEGATIVE, &ip.h.flags);
303 else {
304 ip.m_add_change = udom->addr_changes;
305 /* if this is from the legacy set_client system call,
306 * we need m_add_change to be one higher
307 */
308 if (expiry == NEVER)
309 ip.m_add_change++;
310 }
311 ip.h.expiry_time = expiry;
312 ch = sunrpc_cache_update(&ip_map_cache,
313 &ip.h, &ipm->h,
314 hash_str(ipm->m_class, IP_HASHBITS) ^
315 hash_ip((unsigned long)ipm->m_addr.s_addr));
316 if (!ch)
317 return -ENOMEM;
318 cache_put(ch, &ip_map_cache);
319 return 0;
320}
269 321
270int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) 322int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
271{ 323{
272 struct unix_domain *udom; 324 struct unix_domain *udom;
273 struct ip_map ip, *ipmp; 325 struct ip_map *ipmp;
274 326
275 if (dom->flavour != RPC_AUTH_UNIX) 327 if (dom->flavour != &svcauth_unix)
276 return -EINVAL; 328 return -EINVAL;
277 udom = container_of(dom, struct unix_domain, h); 329 udom = container_of(dom, struct unix_domain, h);
278 strcpy(ip.m_class, "nfsd"); 330 ipmp = ip_map_lookup("nfsd", addr);
279 ip.m_addr = addr;
280 ip.m_client = udom;
281 ip.m_add_change = udom->addr_changes+1;
282 ip.h.flags = 0;
283 ip.h.expiry_time = NEVER;
284
285 ipmp = ip_map_lookup(&ip, 1);
286 331
287 if (ipmp) { 332 if (ipmp)
288 ip_map_put(&ipmp->h, &ip_map_cache); 333 return ip_map_update(ipmp, udom, NEVER);
289 return 0; 334 else
290 } else
291 return -ENOMEM; 335 return -ENOMEM;
292} 336}
293 337
@@ -295,7 +339,7 @@ int auth_unix_forget_old(struct auth_domain *dom)
295{ 339{
296 struct unix_domain *udom; 340 struct unix_domain *udom;
297 341
298 if (dom->flavour != RPC_AUTH_UNIX) 342 if (dom->flavour != &svcauth_unix)
299 return -EINVAL; 343 return -EINVAL;
300 udom = container_of(dom, struct unix_domain, h); 344 udom = container_of(dom, struct unix_domain, h);
301 udom->addr_changes++; 345 udom->addr_changes++;
@@ -310,7 +354,7 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr)
310 strcpy(key.m_class, "nfsd"); 354 strcpy(key.m_class, "nfsd");
311 key.m_addr = addr; 355 key.m_addr = addr;
312 356
313 ipm = ip_map_lookup(&key, 0); 357 ipm = ip_map_lookup("nfsd", addr);
314 358
315 if (!ipm) 359 if (!ipm)
316 return NULL; 360 return NULL;
@@ -323,31 +367,28 @@ struct auth_domain *auth_unix_lookup(struct in_addr addr)
323 rv = NULL; 367 rv = NULL;
324 } else { 368 } else {
325 rv = &ipm->m_client->h; 369 rv = &ipm->m_client->h;
326 cache_get(&rv->h); 370 kref_get(&rv->ref);
327 } 371 }
328 ip_map_put(&ipm->h, &ip_map_cache); 372 cache_put(&ipm->h, &ip_map_cache);
329 return rv; 373 return rv;
330} 374}
331 375
332void svcauth_unix_purge(void) 376void svcauth_unix_purge(void)
333{ 377{
334 cache_purge(&ip_map_cache); 378 cache_purge(&ip_map_cache);
335 cache_purge(&auth_domain_cache);
336} 379}
337 380
338static int 381static int
339svcauth_unix_set_client(struct svc_rqst *rqstp) 382svcauth_unix_set_client(struct svc_rqst *rqstp)
340{ 383{
341 struct ip_map key, *ipm; 384 struct ip_map *ipm;
342 385
343 rqstp->rq_client = NULL; 386 rqstp->rq_client = NULL;
344 if (rqstp->rq_proc == 0) 387 if (rqstp->rq_proc == 0)
345 return SVC_OK; 388 return SVC_OK;
346 389
347 strcpy(key.m_class, rqstp->rq_server->sv_program->pg_class); 390 ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
348 key.m_addr = rqstp->rq_addr.sin_addr; 391 rqstp->rq_addr.sin_addr);
349
350 ipm = ip_map_lookup(&key, 0);
351 392
352 if (ipm == NULL) 393 if (ipm == NULL)
353 return SVC_DENIED; 394 return SVC_DENIED;
@@ -361,8 +402,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp)
361 return SVC_DENIED; 402 return SVC_DENIED;
362 case 0: 403 case 0:
363 rqstp->rq_client = &ipm->m_client->h; 404 rqstp->rq_client = &ipm->m_client->h;
364 cache_get(&rqstp->rq_client->h); 405 kref_get(&rqstp->rq_client->ref);
365 ip_map_put(&ipm->h, &ip_map_cache); 406 cache_put(&ipm->h, &ip_map_cache);
366 break; 407 break;
367 } 408 }
368 return SVC_OK; 409 return SVC_OK;