diff options
author | Paul Mackerras <paulus@samba.org> | 2006-03-28 21:24:50 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-03-28 21:24:50 -0500 |
commit | bac30d1a78d0f11c613968fc8b351a91ed465386 (patch) | |
tree | e52f3c876522a2f6047a6ec1c27df2e8a79486b8 /net | |
parent | e8222502ee6157e2713da9e0792c21f4ad458d50 (diff) | |
parent | ca9ba4471c1203bb6e759b76e83167fec54fe590 (diff) |
Merge ../linux-2.6
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 8 | ||||
-rw-r--r-- | net/core/dev.c | 42 | ||||
-rw-r--r-- | net/core/request_sock.c | 2 | ||||
-rw-r--r-- | net/decnet/dn_dev.c | 10 | ||||
-rw-r--r-- | net/ipv4/devinet.c | 16 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 6 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 10 | ||||
-rw-r--r-- | net/ipv6/ipcomp6.c | 5 | ||||
-rw-r--r-- | net/irda/af_irda.c | 6 | ||||
-rw-r--r-- | net/netfilter/nf_conntrack_core.c | 6 | ||||
-rw-r--r-- | net/netlink/af_netlink.c | 9 | ||||
-rw-r--r-- | net/nonet.c | 2 | ||||
-rw-r--r-- | net/socket.c | 2 | ||||
-rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 182 | ||||
-rw-r--r-- | net/sunrpc/cache.c | 163 | ||||
-rw-r--r-- | net/sunrpc/rpc_pipe.c | 2 | ||||
-rw-r--r-- | net/sunrpc/stats.c | 4 | ||||
-rw-r--r-- | net/sunrpc/sunrpc_syms.c | 6 | ||||
-rw-r--r-- | net/sunrpc/svcauth.c | 122 | ||||
-rw-r--r-- | net/sunrpc/svcauth_unix.c | 229 |
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); | |||
73 | struct hci_proto *hci_proto[HCI_MAX_PROTO]; | 73 | struct hci_proto *hci_proto[HCI_MAX_PROTO]; |
74 | 74 | ||
75 | /* HCI notifiers list */ | 75 | /* HCI notifiers list */ |
76 | static struct notifier_block *hci_notifier; | 76 | static ATOMIC_NOTIFIER_HEAD(hci_notifier); |
77 | 77 | ||
78 | /* ---- HCI notifications ---- */ | 78 | /* ---- HCI notifications ---- */ |
79 | 79 | ||
80 | int hci_register_notifier(struct notifier_block *nb) | 80 | int 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 | ||
85 | int hci_unregister_notifier(struct notifier_block *nb) | 85 | int 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 | ||
90 | static void hci_notify(struct hci_dev *hdev, int event) | 90 | static 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 | ||
196 | static struct notifier_block *netdev_chain; | 196 | static 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 | */ |
751 | void netdev_features_change(struct net_device *dev) | 752 | void 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 | } |
755 | EXPORT_SYMBOL(netdev_features_change); | 756 | EXPORT_SYMBOL(netdev_features_change); |
756 | 757 | ||
@@ -765,7 +766,8 @@ EXPORT_SYMBOL(netdev_features_change); | |||
765 | void netdev_state_change(struct net_device *dev) | 766 | void 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 | ||
998 | int call_netdevice_notifiers(unsigned long val, void *v) | 1000 | int 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 | ||
69 | static DEFINE_RWLOCK(dndev_lock); | 69 | static DEFINE_RWLOCK(dndev_lock); |
70 | static struct net_device *decnet_default_device; | 70 | static struct net_device *decnet_default_device; |
71 | static struct notifier_block *dnaddr_chain; | 71 | static BLOCKING_NOTIFIER_HEAD(dnaddr_chain); |
72 | 72 | ||
73 | static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); | 73 | static struct dn_dev *dn_dev_create(struct net_device *dev, int *err); |
74 | static void dn_dev_delete(struct net_device *dev); | 74 | static 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 | ||
1286 | int register_dnaddr_notifier(struct notifier_block *nb) | 1286 | int 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 | ||
1291 | int unregister_dnaddr_notifier(struct notifier_block *nb) | 1291 | int 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 | ||
82 | static void rtmsg_ifa(int event, struct in_ifaddr *); | 82 | static void rtmsg_ifa(int event, struct in_ifaddr *); |
83 | 83 | ||
84 | static struct notifier_block *inetaddr_chain; | 84 | static BLOCKING_NOTIFIER_HEAD(inetaddr_chain); |
85 | static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap, | 85 | static 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 | ||
939 | int register_inetaddr_notifier(struct notifier_block *nb) | 941 | int 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 | ||
944 | int unregister_inetaddr_notifier(struct notifier_block *nb) | 946 | int 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; | |||
80 | static unsigned int ip_conntrack_next_id; | 80 | static unsigned int ip_conntrack_next_id; |
81 | static unsigned int ip_conntrack_expect_next_id; | 81 | static unsigned int ip_conntrack_expect_next_id; |
82 | #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS | 82 | #ifdef CONFIG_IP_NF_CONNTRACK_EVENTS |
83 | struct notifier_block *ip_conntrack_chain; | 83 | ATOMIC_NOTIFIER_HEAD(ip_conntrack_chain); |
84 | struct notifier_block *ip_conntrack_expect_chain; | 84 | ATOMIC_NOTIFIER_HEAD(ip_conntrack_expect_chain); |
85 | 85 | ||
86 | DEFINE_PER_CPU(struct ip_conntrack_ecache, ip_conntrack_ecache); | 86 | DEFINE_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); |
144 | static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); | 144 | static int ipv6_chk_same_addr(const struct in6_addr *addr, struct net_device *dev); |
145 | 145 | ||
146 | static struct notifier_block *inet6addr_chain; | 146 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); |
147 | 147 | ||
148 | struct ipv6_devconf ipv6_devconf = { | 148 | struct 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 | ||
3768 | int register_inet6addr_notifier(struct notifier_block *nb) | 3768 | int 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 | ||
3773 | int unregister_inet6addr_notifier(struct notifier_block *nb) | 3773 | int 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 | ||
245 | error: | 248 | error: |
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; | |||
90 | static unsigned int nf_conntrack_next_id; | 90 | static unsigned int nf_conntrack_next_id; |
91 | static unsigned int nf_conntrack_expect_next_id; | 91 | static unsigned int nf_conntrack_expect_next_id; |
92 | #ifdef CONFIG_NF_CONNTRACK_EVENTS | 92 | #ifdef CONFIG_NF_CONNTRACK_EVENTS |
93 | struct notifier_block *nf_conntrack_chain; | 93 | ATOMIC_NOTIFIER_HEAD(nf_conntrack_chain); |
94 | struct notifier_block *nf_conntrack_expect_chain; | 94 | ATOMIC_NOTIFIER_HEAD(nf_conntrack_expect_chain); |
95 | 95 | ||
96 | DEFINE_PER_CPU(struct nf_conntrack_ecache, nf_conntrack_ecache); | 96 | DEFINE_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); | |||
123 | static DEFINE_RWLOCK(nl_table_lock); | 123 | static DEFINE_RWLOCK(nl_table_lock); |
124 | static atomic_t nl_table_users = ATOMIC_INIT(0); | 124 | static atomic_t nl_table_users = ATOMIC_INIT(0); |
125 | 125 | ||
126 | static struct notifier_block *netlink_chain; | 126 | static ATOMIC_NOTIFIER_HEAD(netlink_chain); |
127 | 127 | ||
128 | static u32 netlink_group_mask(u32 group) | 128 | static 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 | ||
1696 | int netlink_register_notifier(struct notifier_block *nb) | 1697 | int 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 | ||
1701 | int netlink_unregister_notifier(struct notifier_block *nb) | 1702 | int 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 | ||
1706 | static const struct proto_ops netlink_ops = { | 1707 | static 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 | ||
22 | struct file_operations bad_sock_fops = { | 22 | const 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 | ||
542 | struct file_operations bad_sock_fops = { | 542 | const 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 | ||
79 | static struct cache_head *rsi_table[RSI_HASHMAX]; | 79 | static struct cache_head *rsi_table[RSI_HASHMAX]; |
80 | static struct cache_detail rsi_cache; | 80 | static struct cache_detail rsi_cache; |
81 | static struct rsi *rsi_lookup(struct rsi *item, int set); | 81 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old); |
82 | static struct rsi *rsi_lookup(struct rsi *item); | ||
82 | 83 | ||
83 | static void rsi_free(struct rsi *rsii) | 84 | static 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 | ||
91 | static void rsi_put(struct cache_head *item, struct cache_detail *cd) | 92 | static 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 | ||
100 | static inline int rsi_hash(struct rsi *item) | 99 | static 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 | ||
106 | static inline int rsi_match(struct rsi *item, struct rsi *tmp) | 105 | static 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 | ||
128 | static inline void rsi_init(struct rsi *new, struct rsi *item) | 129 | static 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 | ||
144 | static inline void rsi_update(struct rsi *new, struct rsi *item) | 148 | static 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 | ||
167 | static 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 | |||
160 | static void rsi_request(struct cache_detail *cd, | 176 | static 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; |
245 | out: | 265 | out: |
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 | ||
262 | static DefineSimpleCacheLookup(rsi, 0) | 288 | static 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 | |||
300 | static 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 | ||
294 | static struct cache_head *rsc_table[RSC_HASHMAX]; | 344 | static struct cache_head *rsc_table[RSC_HASHMAX]; |
295 | static struct cache_detail rsc_cache; | 345 | static struct cache_detail rsc_cache; |
296 | static struct rsc *rsc_lookup(struct rsc *item, int set); | 346 | static struct rsc *rsc_update(struct rsc *new, struct rsc *old); |
347 | static struct rsc *rsc_lookup(struct rsc *item); | ||
297 | 348 | ||
298 | static void rsc_free(struct rsc *rsci) | 349 | static 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 | ||
307 | static void rsc_put(struct cache_head *item, struct cache_detail *cd) | 358 | static 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 | ||
317 | static inline int | 366 | static 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 | ||
323 | static inline int | 372 | static int |
324 | rsc_match(struct rsc *new, struct rsc *tmp) | 373 | rsc_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 | ||
329 | static inline void | 381 | static void |
330 | rsc_init(struct rsc *new, struct rsc *tmp) | 382 | rsc_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 | ||
340 | static inline void | 395 | static void |
341 | rsc_update(struct rsc *new, struct rsc *tmp) | 396 | update_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 | ||
409 | static struct cache_head * | ||
410 | rsc_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 | |||
351 | static int rsc_parse(struct cache_detail *cd, | 419 | static 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; |
433 | out: | 505 | out: |
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 | ||
449 | static DefineSimpleCacheLookup(rsc, 0); | 527 | static 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 | |||
539 | static 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 | ||
451 | static struct rsc * | 553 | static struct rsc * |
452 | gss_svc_searchbyctx(struct xdr_netobj *handle) | 554 | gss_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 | ||
750 | static struct auth_ops svcauthops_gss; | ||
751 | |||
648 | int | 752 | int |
649 | svcauth_gss_register_pseudoflavor(u32 pseudoflavor, char * name) | 753 | svcauth_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; |
971 | out: | 1073 | out: |
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 @@ | |||
37 | static void cache_defer_req(struct cache_req *req, struct cache_head *item); | 37 | static void cache_defer_req(struct cache_req *req, struct cache_head *item); |
38 | static void cache_revisit_request(struct cache_head *item); | 38 | static void cache_revisit_request(struct cache_head *item); |
39 | 39 | ||
40 | void cache_init(struct cache_head *h) | 40 | static 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 | ||
50 | struct 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 | } | ||
97 | EXPORT_SYMBOL(sunrpc_cache_lookup); | ||
98 | |||
99 | |||
100 | static void queue_loose(struct cache_detail *detail, struct cache_head *ch); | ||
101 | |||
102 | static 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 | |||
109 | static 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 | |||
120 | struct 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 | } | ||
171 | EXPORT_SYMBOL(sunrpc_cache_update); | ||
50 | 172 | ||
51 | static int cache_make_upcall(struct cache_detail *detail, struct cache_head *h); | 173 | static 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 | ||
118 | static void queue_loose(struct cache_detail *detail, struct cache_head *ch); | ||
119 | |||
120 | void 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 | */ |
396 | struct rpc_filelist { | 396 | struct 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 | */ |
227 | static inline struct proc_dir_entry * | 227 | static inline struct proc_dir_entry * |
228 | do_register(const char *name, void *data, struct file_operations *fops) | 228 | do_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 | ||
255 | struct proc_dir_entry * | 255 | struct proc_dir_entry * |
256 | svc_proc_register(struct svc_stat *statp, struct file_operations *fops) | 256 | svc_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); | |||
105 | EXPORT_SYMBOL(cache_check); | 105 | EXPORT_SYMBOL(cache_check); |
106 | EXPORT_SYMBOL(cache_flush); | 106 | EXPORT_SYMBOL(cache_flush); |
107 | EXPORT_SYMBOL(cache_purge); | 107 | EXPORT_SYMBOL(cache_purge); |
108 | EXPORT_SYMBOL(cache_fresh); | ||
109 | EXPORT_SYMBOL(cache_init); | ||
110 | EXPORT_SYMBOL(cache_register); | 108 | EXPORT_SYMBOL(cache_register); |
111 | EXPORT_SYMBOL(cache_unregister); | 109 | EXPORT_SYMBOL(cache_unregister); |
112 | EXPORT_SYMBOL(qword_add); | 110 | EXPORT_SYMBOL(qword_add); |
@@ -142,6 +140,7 @@ EXPORT_SYMBOL(nlm_debug); | |||
142 | 140 | ||
143 | extern int register_rpc_pipefs(void); | 141 | extern int register_rpc_pipefs(void); |
144 | extern void unregister_rpc_pipefs(void); | 142 | extern void unregister_rpc_pipefs(void); |
143 | extern struct cache_detail ip_map_cache; | ||
145 | 144 | ||
146 | static int __init | 145 | static int __init |
147 | init_sunrpc(void) | 146 | init_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); |
163 | out: | 161 | out: |
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) | |||
106 | EXPORT_SYMBOL(svc_auth_unregister); | 106 | EXPORT_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 | ||
135 | static struct cache_head *auth_domain_table[DN_HASHMAX]; | 121 | static struct hlist_head auth_domain_table[DN_HASHMAX]; |
136 | 122 | static spinlock_t auth_domain_lock = SPIN_LOCK_UNLOCKED; | |
137 | static 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 | |||
145 | struct 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 | ||
153 | void auth_domain_put(struct auth_domain *dom) | 124 | void 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); | |
158 | static inline int auth_domain_hash(struct auth_domain *item) | 129 | } |
159 | { | ||
160 | return hash_str(item->name, DN_HASHBITS); | ||
161 | } | ||
162 | static 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 | ||
167 | struct auth_domain * | 132 | struct auth_domain * |
168 | auth_domain_lookup(struct auth_domain *item, int set) | 133 | auth_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 | } |
195 | out_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; | ||
203 | out_nada: | ||
204 | tmp = NULL; | ||
205 | out_noset: | ||
206 | read_unlock(&auth_domain_cache.hash_lock); | ||
207 | return tmp; | ||
208 | } | 156 | } |
209 | 157 | ||
210 | struct auth_domain *auth_domain_find(char *name) | 158 | struct 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 | ||
30 | extern struct auth_ops svcauth_unix; | ||
31 | |||
30 | struct auth_domain *unix_domain_find(char *name) | 32 | struct 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 | ||
67 | static void svcauth_unix_domain_release(struct auth_domain *dom) | 61 | static void svcauth_unix_domain_release(struct auth_domain *dom) |
@@ -90,15 +84,15 @@ struct ip_map { | |||
90 | }; | 84 | }; |
91 | static struct cache_head *ip_table[IP_HASHMAX]; | 85 | static struct cache_head *ip_table[IP_HASHMAX]; |
92 | 86 | ||
93 | static void ip_map_put(struct cache_head *item, struct cache_detail *cd) | 87 | static 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 | 109 | static int ip_map_match(struct cache_head *corig, struct cache_head *cnew) | |
116 | static 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 | } | ||
121 | static 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 | } |
126 | static inline void ip_map_init(struct ip_map *new, struct ip_map *item) | 116 | static 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 | } |
131 | static inline void ip_map_update(struct ip_map *new, struct ip_map *item) | 124 | static 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 | } |
133 | static 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 | ||
138 | static void ip_map_request(struct cache_detail *cd, | 142 | static 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 | ||
157 | static struct ip_map *ip_map_lookup(struct ip_map *, int); | 161 | static struct ip_map *ip_map_lookup(char *class, struct in_addr addr); |
162 | static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry); | ||
158 | 163 | ||
159 | static int ip_map_parse(struct cache_detail *cd, | 164 | static 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 | ||
224 | static int ip_map_show(struct seq_file *m, | 230 | static 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 | ||
267 | static DefineSimpleCacheLookup(ip_map, 0) | 277 | static 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 | ||
294 | static 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 | ||
270 | int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom) | 322 | int 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 | ||
332 | void svcauth_unix_purge(void) | 376 | void 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 | ||
338 | static int | 381 | static int |
339 | svcauth_unix_set_client(struct svc_rqst *rqstp) | 382 | svcauth_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; |