diff options
| -rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 66 |
1 files changed, 59 insertions, 7 deletions
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index aadb4e8d6aa7..237d935747a5 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 | { |
| @@ -103,8 +104,10 @@ static inline int rsi_hash(struct rsi *item) | |||
| 103 | ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); | 104 | ^ hash_mem(item->in_token.data, item->in_token.len, RSI_HASHBITS); |
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | static inline int rsi_match(struct rsi *item, struct rsi *tmp) | 107 | static int rsi_match(struct cache_head *a, struct cache_head *b) |
| 107 | { | 108 | { |
| 109 | struct rsi *item = container_of(a, struct rsi, h); | ||
| 110 | struct rsi *tmp = container_of(b, struct rsi, h); | ||
| 108 | return netobj_equal(&item->in_handle, &tmp->in_handle) | 111 | return netobj_equal(&item->in_handle, &tmp->in_handle) |
| 109 | && netobj_equal(&item->in_token, &tmp->in_token); | 112 | && netobj_equal(&item->in_token, &tmp->in_token); |
| 110 | } | 113 | } |
| @@ -125,8 +128,11 @@ static inline int dup_netobj(struct xdr_netobj *dst, struct xdr_netobj *src) | |||
| 125 | return dup_to_netobj(dst, src->data, src->len); | 128 | return dup_to_netobj(dst, src->data, src->len); |
| 126 | } | 129 | } |
| 127 | 130 | ||
| 128 | static inline void rsi_init(struct rsi *new, struct rsi *item) | 131 | static void rsi_init(struct cache_head *cnew, struct cache_head *citem) |
| 129 | { | 132 | { |
| 133 | struct rsi *new = container_of(cnew, struct rsi, h); | ||
| 134 | struct rsi *item = container_of(citem, struct rsi, h); | ||
| 135 | |||
| 130 | new->out_handle.data = NULL; | 136 | new->out_handle.data = NULL; |
| 131 | new->out_handle.len = 0; | 137 | new->out_handle.len = 0; |
| 132 | new->out_token.data = NULL; | 138 | new->out_token.data = NULL; |
| @@ -141,8 +147,11 @@ static inline void rsi_init(struct rsi *new, struct rsi *item) | |||
| 141 | item->in_token.data = NULL; | 147 | item->in_token.data = NULL; |
| 142 | } | 148 | } |
| 143 | 149 | ||
| 144 | static inline void rsi_update(struct rsi *new, struct rsi *item) | 150 | static void update_rsi(struct cache_head *cnew, struct cache_head *citem) |
| 145 | { | 151 | { |
| 152 | struct rsi *new = container_of(cnew, struct rsi, h); | ||
| 153 | struct rsi *item = container_of(citem, struct rsi, h); | ||
| 154 | |||
| 146 | BUG_ON(new->out_handle.data || new->out_token.data); | 155 | BUG_ON(new->out_handle.data || new->out_token.data); |
| 147 | new->out_handle.len = item->out_handle.len; | 156 | new->out_handle.len = item->out_handle.len; |
| 148 | item->out_handle.len = 0; | 157 | item->out_handle.len = 0; |
| @@ -157,6 +166,15 @@ static inline void rsi_update(struct rsi *new, struct rsi *item) | |||
| 157 | new->minor_status = item->minor_status; | 166 | new->minor_status = item->minor_status; |
| 158 | } | 167 | } |
| 159 | 168 | ||
| 169 | static struct cache_head *rsi_alloc(void) | ||
| 170 | { | ||
| 171 | struct rsi *rsii = kmalloc(sizeof(*rsii), GFP_KERNEL); | ||
| 172 | if (rsii) | ||
| 173 | return &rsii->h; | ||
| 174 | else | ||
| 175 | return NULL; | ||
| 176 | } | ||
| 177 | |||
| 160 | static void rsi_request(struct cache_detail *cd, | 178 | static void rsi_request(struct cache_detail *cd, |
| 161 | struct cache_head *h, | 179 | struct cache_head *h, |
| 162 | char **bpp, int *blen) | 180 | char **bpp, int *blen) |
| @@ -198,6 +216,10 @@ static int rsi_parse(struct cache_detail *cd, | |||
| 198 | if (dup_to_netobj(&rsii.in_token, buf, len)) | 216 | if (dup_to_netobj(&rsii.in_token, buf, len)) |
| 199 | goto out; | 217 | goto out; |
| 200 | 218 | ||
| 219 | rsip = rsi_lookup(&rsii); | ||
| 220 | if (!rsip) | ||
| 221 | goto out; | ||
| 222 | |||
| 201 | rsii.h.flags = 0; | 223 | rsii.h.flags = 0; |
| 202 | /* expiry */ | 224 | /* expiry */ |
| 203 | expiry = get_expiry(&mesg); | 225 | expiry = get_expiry(&mesg); |
| @@ -240,12 +262,14 @@ static int rsi_parse(struct cache_detail *cd, | |||
| 240 | goto out; | 262 | goto out; |
| 241 | } | 263 | } |
| 242 | rsii.h.expiry_time = expiry; | 264 | rsii.h.expiry_time = expiry; |
| 243 | rsip = rsi_lookup(&rsii, 1); | 265 | rsip = rsi_update(&rsii, rsip); |
| 244 | status = 0; | 266 | status = 0; |
| 245 | out: | 267 | out: |
| 246 | rsi_free(&rsii); | 268 | rsi_free(&rsii); |
| 247 | if (rsip) | 269 | if (rsip) |
| 248 | rsi_put(&rsip->h, &rsi_cache); | 270 | rsi_put(&rsip->h, &rsi_cache); |
| 271 | else | ||
| 272 | status = -ENOMEM; | ||
| 249 | return status; | 273 | return status; |
| 250 | } | 274 | } |
| 251 | 275 | ||
| @@ -257,9 +281,37 @@ static struct cache_detail rsi_cache = { | |||
| 257 | .cache_put = rsi_put, | 281 | .cache_put = rsi_put, |
| 258 | .cache_request = rsi_request, | 282 | .cache_request = rsi_request, |
| 259 | .cache_parse = rsi_parse, | 283 | .cache_parse = rsi_parse, |
| 284 | .match = rsi_match, | ||
| 285 | .init = rsi_init, | ||
| 286 | .update = update_rsi, | ||
| 287 | .alloc = rsi_alloc, | ||
| 260 | }; | 288 | }; |
| 261 | 289 | ||
| 262 | static DefineSimpleCacheLookup(rsi, rsi) | 290 | static struct rsi *rsi_lookup(struct rsi *item) |
| 291 | { | ||
| 292 | struct cache_head *ch; | ||
| 293 | int hash = rsi_hash(item); | ||
| 294 | |||
| 295 | ch = sunrpc_cache_lookup(&rsi_cache, &item->h, hash); | ||
| 296 | if (ch) | ||
| 297 | return container_of(ch, struct rsi, h); | ||
| 298 | else | ||
| 299 | return NULL; | ||
| 300 | } | ||
| 301 | |||
| 302 | static struct rsi *rsi_update(struct rsi *new, struct rsi *old) | ||
| 303 | { | ||
| 304 | struct cache_head *ch; | ||
| 305 | int hash = rsi_hash(new); | ||
| 306 | |||
| 307 | ch = sunrpc_cache_update(&rsi_cache, &new->h, | ||
| 308 | &old->h, hash); | ||
| 309 | if (ch) | ||
| 310 | return container_of(ch, struct rsi, h); | ||
| 311 | else | ||
| 312 | return NULL; | ||
| 313 | } | ||
| 314 | |||
| 263 | 315 | ||
| 264 | /* | 316 | /* |
| 265 | * The rpcsec_context cache is used to store a context that is | 317 | * The rpcsec_context cache is used to store a context that is |
| @@ -895,7 +947,7 @@ svcauth_gss_accept(struct svc_rqst *rqstp, u32 *authp) | |||
| 895 | goto drop; | 947 | goto drop; |
| 896 | } | 948 | } |
| 897 | 949 | ||
| 898 | rsip = rsi_lookup(&rsikey, 0); | 950 | rsip = rsi_lookup(&rsikey); |
| 899 | rsi_free(&rsikey); | 951 | rsi_free(&rsikey); |
| 900 | if (!rsip) { | 952 | if (!rsip) { |
| 901 | goto drop; | 953 | goto drop; |
