aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/delegation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r--fs/nfs/delegation.c362
1 files changed, 259 insertions, 103 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 1fd62fc49be3..364e4328f392 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -40,11 +40,23 @@ static void nfs_free_delegation(struct nfs_delegation *delegation)
40 call_rcu(&delegation->rcu, nfs_free_delegation_callback); 40 call_rcu(&delegation->rcu, nfs_free_delegation_callback);
41} 41}
42 42
43/**
44 * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
45 * @delegation: delegation to process
46 *
47 */
43void nfs_mark_delegation_referenced(struct nfs_delegation *delegation) 48void nfs_mark_delegation_referenced(struct nfs_delegation *delegation)
44{ 49{
45 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags); 50 set_bit(NFS_DELEGATION_REFERENCED, &delegation->flags);
46} 51}
47 52
53/**
54 * nfs_have_delegation - check if inode has a delegation
55 * @inode: inode to check
56 * @flags: delegation types to check for
57 *
58 * Returns one if inode has the indicated delegation, otherwise zero.
59 */
48int nfs_have_delegation(struct inode *inode, fmode_t flags) 60int nfs_have_delegation(struct inode *inode, fmode_t flags)
49{ 61{
50 struct nfs_delegation *delegation; 62 struct nfs_delegation *delegation;
@@ -119,10 +131,15 @@ again:
119 return 0; 131 return 0;
120} 132}
121 133
122/* 134/**
123 * Set up a delegation on an inode 135 * nfs_inode_reclaim_delegation - process a delegation reclaim request
136 * @inode: inode to process
137 * @cred: credential to use for request
138 * @res: new delegation state from server
139 *
124 */ 140 */
125void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) 141void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred,
142 struct nfs_openres *res)
126{ 143{
127 struct nfs_delegation *delegation; 144 struct nfs_delegation *delegation;
128 struct rpc_cred *oldcred = NULL; 145 struct rpc_cred *oldcred = NULL;
@@ -175,38 +192,52 @@ static struct inode *nfs_delegation_grab_inode(struct nfs_delegation *delegation
175 return inode; 192 return inode;
176} 193}
177 194
178static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfsi, 195static struct nfs_delegation *
179 const nfs4_stateid *stateid, 196nfs_detach_delegation_locked(struct nfs_inode *nfsi,
180 struct nfs_client *clp) 197 struct nfs_server *server)
181{ 198{
182 struct nfs_delegation *delegation = 199 struct nfs_delegation *delegation =
183 rcu_dereference_protected(nfsi->delegation, 200 rcu_dereference_protected(nfsi->delegation,
184 lockdep_is_held(&clp->cl_lock)); 201 lockdep_is_held(&server->nfs_client->cl_lock));
185 202
186 if (delegation == NULL) 203 if (delegation == NULL)
187 goto nomatch; 204 goto nomatch;
205
188 spin_lock(&delegation->lock); 206 spin_lock(&delegation->lock);
189 if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data,
190 sizeof(delegation->stateid.data)) != 0)
191 goto nomatch_unlock;
192 list_del_rcu(&delegation->super_list); 207 list_del_rcu(&delegation->super_list);
193 delegation->inode = NULL; 208 delegation->inode = NULL;
194 nfsi->delegation_state = 0; 209 nfsi->delegation_state = 0;
195 rcu_assign_pointer(nfsi->delegation, NULL); 210 rcu_assign_pointer(nfsi->delegation, NULL);
196 spin_unlock(&delegation->lock); 211 spin_unlock(&delegation->lock);
197 return delegation; 212 return delegation;
198nomatch_unlock:
199 spin_unlock(&delegation->lock);
200nomatch: 213nomatch:
201 return NULL; 214 return NULL;
202} 215}
203 216
204/* 217static struct nfs_delegation *nfs_detach_delegation(struct nfs_inode *nfsi,
205 * Set up a delegation on an inode 218 struct nfs_server *server)
219{
220 struct nfs_client *clp = server->nfs_client;
221 struct nfs_delegation *delegation;
222
223 spin_lock(&clp->cl_lock);
224 delegation = nfs_detach_delegation_locked(nfsi, server);
225 spin_unlock(&clp->cl_lock);
226 return delegation;
227}
228
229/**
230 * nfs_inode_set_delegation - set up a delegation on an inode
231 * @inode: inode to which delegation applies
232 * @cred: cred to use for subsequent delegation processing
233 * @res: new delegation state from server
234 *
235 * Returns zero on success, or a negative errno value.
206 */ 236 */
207int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res) 237int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res)
208{ 238{
209 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 239 struct nfs_server *server = NFS_SERVER(inode);
240 struct nfs_client *clp = server->nfs_client;
210 struct nfs_inode *nfsi = NFS_I(inode); 241 struct nfs_inode *nfsi = NFS_I(inode);
211 struct nfs_delegation *delegation, *old_delegation; 242 struct nfs_delegation *delegation, *old_delegation;
212 struct nfs_delegation *freeme = NULL; 243 struct nfs_delegation *freeme = NULL;
@@ -227,7 +258,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
227 258
228 spin_lock(&clp->cl_lock); 259 spin_lock(&clp->cl_lock);
229 old_delegation = rcu_dereference_protected(nfsi->delegation, 260 old_delegation = rcu_dereference_protected(nfsi->delegation,
230 lockdep_is_held(&clp->cl_lock)); 261 lockdep_is_held(&clp->cl_lock));
231 if (old_delegation != NULL) { 262 if (old_delegation != NULL) {
232 if (memcmp(&delegation->stateid, &old_delegation->stateid, 263 if (memcmp(&delegation->stateid, &old_delegation->stateid,
233 sizeof(old_delegation->stateid)) == 0 && 264 sizeof(old_delegation->stateid)) == 0 &&
@@ -246,9 +277,9 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct
246 delegation = NULL; 277 delegation = NULL;
247 goto out; 278 goto out;
248 } 279 }
249 freeme = nfs_detach_delegation_locked(nfsi, NULL, clp); 280 freeme = nfs_detach_delegation_locked(nfsi, server);
250 } 281 }
251 list_add_rcu(&delegation->super_list, &clp->cl_delegations); 282 list_add_rcu(&delegation->super_list, &server->delegations);
252 nfsi->delegation_state = delegation->type; 283 nfsi->delegation_state = delegation->type;
253 rcu_assign_pointer(nfsi->delegation, delegation); 284 rcu_assign_pointer(nfsi->delegation, delegation);
254 delegation = NULL; 285 delegation = NULL;
@@ -290,73 +321,85 @@ out:
290 return err; 321 return err;
291} 322}
292 323
293/* 324/**
294 * Return all delegations that have been marked for return 325 * nfs_client_return_marked_delegations - return previously marked delegations
326 * @clp: nfs_client to process
327 *
328 * Returns zero on success, or a negative errno value.
295 */ 329 */
296int nfs_client_return_marked_delegations(struct nfs_client *clp) 330int nfs_client_return_marked_delegations(struct nfs_client *clp)
297{ 331{
298 struct nfs_delegation *delegation; 332 struct nfs_delegation *delegation;
333 struct nfs_server *server;
299 struct inode *inode; 334 struct inode *inode;
300 int err = 0; 335 int err = 0;
301 336
302restart: 337restart:
303 rcu_read_lock(); 338 rcu_read_lock();
304 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 339 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
305 if (!test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags)) 340 list_for_each_entry_rcu(delegation, &server->delegations,
306 continue; 341 super_list) {
307 inode = nfs_delegation_grab_inode(delegation); 342 if (!test_and_clear_bit(NFS_DELEGATION_RETURN,
308 if (inode == NULL) 343 &delegation->flags))
309 continue; 344 continue;
310 spin_lock(&clp->cl_lock); 345 inode = nfs_delegation_grab_inode(delegation);
311 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp); 346 if (inode == NULL)
312 spin_unlock(&clp->cl_lock); 347 continue;
313 rcu_read_unlock(); 348 delegation = nfs_detach_delegation(NFS_I(inode),
314 if (delegation != NULL) { 349 server);
315 filemap_flush(inode->i_mapping); 350 rcu_read_unlock();
316 err = __nfs_inode_return_delegation(inode, delegation, 0); 351
352 if (delegation != NULL) {
353 filemap_flush(inode->i_mapping);
354 err = __nfs_inode_return_delegation(inode,
355 delegation, 0);
356 }
357 iput(inode);
358 if (!err)
359 goto restart;
360 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
361 return err;
317 } 362 }
318 iput(inode);
319 if (!err)
320 goto restart;
321 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
322 return err;
323 } 363 }
324 rcu_read_unlock(); 364 rcu_read_unlock();
325 return 0; 365 return 0;
326} 366}
327 367
328/* 368/**
329 * This function returns the delegation without reclaiming opens 369 * nfs_inode_return_delegation_noreclaim - return delegation, don't reclaim opens
330 * or protecting against delegation reclaims. 370 * @inode: inode to process
331 * It is therefore really only safe to be called from 371 *
332 * nfs4_clear_inode() 372 * Does not protect against delegation reclaims, therefore really only safe
373 * to be called from nfs4_clear_inode().
333 */ 374 */
334void nfs_inode_return_delegation_noreclaim(struct inode *inode) 375void nfs_inode_return_delegation_noreclaim(struct inode *inode)
335{ 376{
336 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 377 struct nfs_server *server = NFS_SERVER(inode);
337 struct nfs_inode *nfsi = NFS_I(inode); 378 struct nfs_inode *nfsi = NFS_I(inode);
338 struct nfs_delegation *delegation; 379 struct nfs_delegation *delegation;
339 380
340 if (rcu_access_pointer(nfsi->delegation) != NULL) { 381 if (rcu_access_pointer(nfsi->delegation) != NULL) {
341 spin_lock(&clp->cl_lock); 382 delegation = nfs_detach_delegation(nfsi, server);
342 delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
343 spin_unlock(&clp->cl_lock);
344 if (delegation != NULL) 383 if (delegation != NULL)
345 nfs_do_return_delegation(inode, delegation, 0); 384 nfs_do_return_delegation(inode, delegation, 0);
346 } 385 }
347} 386}
348 387
388/**
389 * nfs_inode_return_delegation - synchronously return a delegation
390 * @inode: inode to process
391 *
392 * Returns zero on success, or a negative errno value.
393 */
349int nfs_inode_return_delegation(struct inode *inode) 394int nfs_inode_return_delegation(struct inode *inode)
350{ 395{
351 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 396 struct nfs_server *server = NFS_SERVER(inode);
352 struct nfs_inode *nfsi = NFS_I(inode); 397 struct nfs_inode *nfsi = NFS_I(inode);
353 struct nfs_delegation *delegation; 398 struct nfs_delegation *delegation;
354 int err = 0; 399 int err = 0;
355 400
356 if (rcu_access_pointer(nfsi->delegation) != NULL) { 401 if (rcu_access_pointer(nfsi->delegation) != NULL) {
357 spin_lock(&clp->cl_lock); 402 delegation = nfs_detach_delegation(nfsi, server);
358 delegation = nfs_detach_delegation_locked(nfsi, NULL, clp);
359 spin_unlock(&clp->cl_lock);
360 if (delegation != NULL) { 403 if (delegation != NULL) {
361 nfs_wb_all(inode); 404 nfs_wb_all(inode);
362 err = __nfs_inode_return_delegation(inode, delegation, 1); 405 err = __nfs_inode_return_delegation(inode, delegation, 1);
@@ -365,46 +408,61 @@ int nfs_inode_return_delegation(struct inode *inode)
365 return err; 408 return err;
366} 409}
367 410
368static void nfs_mark_return_delegation(struct nfs_client *clp, struct nfs_delegation *delegation) 411static void nfs_mark_return_delegation(struct nfs_delegation *delegation)
369{ 412{
413 struct nfs_client *clp = NFS_SERVER(delegation->inode)->nfs_client;
414
370 set_bit(NFS_DELEGATION_RETURN, &delegation->flags); 415 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
371 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state); 416 set_bit(NFS4CLNT_DELEGRETURN, &clp->cl_state);
372} 417}
373 418
374/* 419/**
375 * Return all delegations associated to a super block 420 * nfs_super_return_all_delegations - return delegations for one superblock
421 * @sb: sb to process
422 *
376 */ 423 */
377void nfs_super_return_all_delegations(struct super_block *sb) 424void nfs_super_return_all_delegations(struct super_block *sb)
378{ 425{
379 struct nfs_client *clp = NFS_SB(sb)->nfs_client; 426 struct nfs_server *server = NFS_SB(sb);
427 struct nfs_client *clp = server->nfs_client;
380 struct nfs_delegation *delegation; 428 struct nfs_delegation *delegation;
381 429
382 if (clp == NULL) 430 if (clp == NULL)
383 return; 431 return;
432
384 rcu_read_lock(); 433 rcu_read_lock();
385 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 434 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
386 spin_lock(&delegation->lock); 435 spin_lock(&delegation->lock);
387 if (delegation->inode != NULL && delegation->inode->i_sb == sb) 436 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
388 set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
389 spin_unlock(&delegation->lock); 437 spin_unlock(&delegation->lock);
390 } 438 }
391 rcu_read_unlock(); 439 rcu_read_unlock();
440
392 if (nfs_client_return_marked_delegations(clp) != 0) 441 if (nfs_client_return_marked_delegations(clp) != 0)
393 nfs4_schedule_state_manager(clp); 442 nfs4_schedule_state_manager(clp);
394} 443}
395 444
396static 445static void nfs_mark_return_all_delegation_types(struct nfs_server *server,
397void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp, fmode_t flags) 446 fmode_t flags)
398{ 447{
399 struct nfs_delegation *delegation; 448 struct nfs_delegation *delegation;
400 449
401 rcu_read_lock(); 450 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
402 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
403 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE)) 451 if ((delegation->type == (FMODE_READ|FMODE_WRITE)) && !(flags & FMODE_WRITE))
404 continue; 452 continue;
405 if (delegation->type & flags) 453 if (delegation->type & flags)
406 nfs_mark_return_delegation(clp, delegation); 454 nfs_mark_return_delegation(delegation);
407 } 455 }
456}
457
458static void nfs_client_mark_return_all_delegation_types(struct nfs_client *clp,
459 fmode_t flags)
460{
461 struct nfs_server *server;
462
463 rcu_read_lock();
464 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
465 nfs_mark_return_all_delegation_types(server, flags);
408 rcu_read_unlock(); 466 rcu_read_unlock();
409} 467}
410 468
@@ -419,19 +477,32 @@ static void nfs_delegation_run_state_manager(struct nfs_client *clp)
419 nfs4_schedule_state_manager(clp); 477 nfs4_schedule_state_manager(clp);
420} 478}
421 479
480/**
481 * nfs_expire_all_delegation_types
482 * @clp: client to process
483 * @flags: delegation types to expire
484 *
485 */
422void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags) 486void nfs_expire_all_delegation_types(struct nfs_client *clp, fmode_t flags)
423{ 487{
424 nfs_client_mark_return_all_delegation_types(clp, flags); 488 nfs_client_mark_return_all_delegation_types(clp, flags);
425 nfs_delegation_run_state_manager(clp); 489 nfs_delegation_run_state_manager(clp);
426} 490}
427 491
492/**
493 * nfs_expire_all_delegations
494 * @clp: client to process
495 *
496 */
428void nfs_expire_all_delegations(struct nfs_client *clp) 497void nfs_expire_all_delegations(struct nfs_client *clp)
429{ 498{
430 nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE); 499 nfs_expire_all_delegation_types(clp, FMODE_READ|FMODE_WRITE);
431} 500}
432 501
433/* 502/**
434 * Return all delegations following an NFS4ERR_CB_PATH_DOWN error. 503 * nfs_handle_cb_pathdown - return all delegations after NFS4ERR_CB_PATH_DOWN
504 * @clp: client to process
505 *
435 */ 506 */
436void nfs_handle_cb_pathdown(struct nfs_client *clp) 507void nfs_handle_cb_pathdown(struct nfs_client *clp)
437{ 508{
@@ -440,29 +511,43 @@ void nfs_handle_cb_pathdown(struct nfs_client *clp)
440 nfs_client_mark_return_all_delegations(clp); 511 nfs_client_mark_return_all_delegations(clp);
441} 512}
442 513
443static void nfs_client_mark_return_unreferenced_delegations(struct nfs_client *clp) 514static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
444{ 515{
445 struct nfs_delegation *delegation; 516 struct nfs_delegation *delegation;
446 517
447 rcu_read_lock(); 518 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
448 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
449 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) 519 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
450 continue; 520 continue;
451 nfs_mark_return_delegation(clp, delegation); 521 nfs_mark_return_delegation(delegation);
452 } 522 }
453 rcu_read_unlock();
454} 523}
455 524
525/**
526 * nfs_expire_unreferenced_delegations - Eliminate unused delegations
527 * @clp: nfs_client to process
528 *
529 */
456void nfs_expire_unreferenced_delegations(struct nfs_client *clp) 530void nfs_expire_unreferenced_delegations(struct nfs_client *clp)
457{ 531{
458 nfs_client_mark_return_unreferenced_delegations(clp); 532 struct nfs_server *server;
533
534 rcu_read_lock();
535 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
536 nfs_mark_return_unreferenced_delegations(server);
537 rcu_read_unlock();
538
459 nfs_delegation_run_state_manager(clp); 539 nfs_delegation_run_state_manager(clp);
460} 540}
461 541
462/* 542/**
463 * Asynchronous delegation recall! 543 * nfs_async_inode_return_delegation - asynchronously return a delegation
544 * @inode: inode to process
545 * @stateid: state ID information from CB_RECALL arguments
546 *
547 * Returns zero on success, or a negative errno value.
464 */ 548 */
465int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid) 549int nfs_async_inode_return_delegation(struct inode *inode,
550 const nfs4_stateid *stateid)
466{ 551{
467 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client; 552 struct nfs_client *clp = NFS_SERVER(inode)->nfs_client;
468 struct nfs_delegation *delegation; 553 struct nfs_delegation *delegation;
@@ -474,22 +559,21 @@ int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *s
474 rcu_read_unlock(); 559 rcu_read_unlock();
475 return -ENOENT; 560 return -ENOENT;
476 } 561 }
477 562 nfs_mark_return_delegation(delegation);
478 nfs_mark_return_delegation(clp, delegation);
479 rcu_read_unlock(); 563 rcu_read_unlock();
564
480 nfs_delegation_run_state_manager(clp); 565 nfs_delegation_run_state_manager(clp);
481 return 0; 566 return 0;
482} 567}
483 568
484/* 569static struct inode *
485 * Retrieve the inode associated with a delegation 570nfs_delegation_find_inode_server(struct nfs_server *server,
486 */ 571 const struct nfs_fh *fhandle)
487struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle)
488{ 572{
489 struct nfs_delegation *delegation; 573 struct nfs_delegation *delegation;
490 struct inode *res = NULL; 574 struct inode *res = NULL;
491 rcu_read_lock(); 575
492 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 576 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
493 spin_lock(&delegation->lock); 577 spin_lock(&delegation->lock);
494 if (delegation->inode != NULL && 578 if (delegation->inode != NULL &&
495 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { 579 nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) {
@@ -499,49 +583,121 @@ struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs
499 if (res != NULL) 583 if (res != NULL)
500 break; 584 break;
501 } 585 }
586 return res;
587}
588
589/**
590 * nfs_delegation_find_inode - retrieve the inode associated with a delegation
591 * @clp: client state handle
592 * @fhandle: filehandle from a delegation recall
593 *
594 * Returns pointer to inode matching "fhandle," or NULL if a matching inode
595 * cannot be found.
596 */
597struct inode *nfs_delegation_find_inode(struct nfs_client *clp,
598 const struct nfs_fh *fhandle)
599{
600 struct nfs_server *server;
601 struct inode *res = NULL;
602
603 rcu_read_lock();
604 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
605 res = nfs_delegation_find_inode_server(server, fhandle);
606 if (res != NULL)
607 break;
608 }
502 rcu_read_unlock(); 609 rcu_read_unlock();
503 return res; 610 return res;
504} 611}
505 612
506/* 613static void nfs_delegation_mark_reclaim_server(struct nfs_server *server)
507 * Mark all delegations as needing to be reclaimed 614{
615 struct nfs_delegation *delegation;
616
617 list_for_each_entry_rcu(delegation, &server->delegations, super_list)
618 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags);
619}
620
621/**
622 * nfs_delegation_mark_reclaim - mark all delegations as needing to be reclaimed
623 * @clp: nfs_client to process
624 *
508 */ 625 */
509void nfs_delegation_mark_reclaim(struct nfs_client *clp) 626void nfs_delegation_mark_reclaim(struct nfs_client *clp)
510{ 627{
511 struct nfs_delegation *delegation; 628 struct nfs_server *server;
629
512 rcu_read_lock(); 630 rcu_read_lock();
513 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) 631 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
514 set_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags); 632 nfs_delegation_mark_reclaim_server(server);
515 rcu_read_unlock(); 633 rcu_read_unlock();
516} 634}
517 635
518/* 636/**
519 * Reap all unclaimed delegations after reboot recovery is done 637 * nfs_delegation_reap_unclaimed - reap unclaimed delegations after reboot recovery is done
638 * @clp: nfs_client to process
639 *
520 */ 640 */
521void nfs_delegation_reap_unclaimed(struct nfs_client *clp) 641void nfs_delegation_reap_unclaimed(struct nfs_client *clp)
522{ 642{
523 struct nfs_delegation *delegation; 643 struct nfs_delegation *delegation;
644 struct nfs_server *server;
524 struct inode *inode; 645 struct inode *inode;
646
525restart: 647restart:
526 rcu_read_lock(); 648 rcu_read_lock();
527 list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) { 649 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
528 if (test_bit(NFS_DELEGATION_NEED_RECLAIM, &delegation->flags) == 0) 650 list_for_each_entry_rcu(delegation, &server->delegations,
529 continue; 651 super_list) {
530 inode = nfs_delegation_grab_inode(delegation); 652 if (test_bit(NFS_DELEGATION_NEED_RECLAIM,
531 if (inode == NULL) 653 &delegation->flags) == 0)
532 continue; 654 continue;
533 spin_lock(&clp->cl_lock); 655 inode = nfs_delegation_grab_inode(delegation);
534 delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL, clp); 656 if (inode == NULL)
535 spin_unlock(&clp->cl_lock); 657 continue;
536 rcu_read_unlock(); 658 delegation = nfs_detach_delegation(NFS_I(inode),
537 if (delegation != NULL) 659 server);
538 nfs_free_delegation(delegation); 660 rcu_read_unlock();
539 iput(inode); 661
540 goto restart; 662 if (delegation != NULL)
663 nfs_free_delegation(delegation);
664 iput(inode);
665 goto restart;
666 }
541 } 667 }
542 rcu_read_unlock(); 668 rcu_read_unlock();
543} 669}
544 670
671/**
672 * nfs_delegations_present - check for existence of delegations
673 * @clp: client state handle
674 *
675 * Returns one if there are any nfs_delegation structures attached
676 * to this nfs_client.
677 */
678int nfs_delegations_present(struct nfs_client *clp)
679{
680 struct nfs_server *server;
681 int ret = 0;
682
683 rcu_read_lock();
684 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link)
685 if (!list_empty(&server->delegations)) {
686 ret = 1;
687 break;
688 }
689 rcu_read_unlock();
690 return ret;
691}
692
693/**
694 * nfs4_copy_delegation_stateid - Copy inode's state ID information
695 * @dst: stateid data structure to fill in
696 * @inode: inode to check
697 *
698 * Returns one and fills in "dst->data" * if inode had a delegation,
699 * otherwise zero is returned.
700 */
545int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode) 701int nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode)
546{ 702{
547 struct nfs_inode *nfsi = NFS_I(inode); 703 struct nfs_inode *nfsi = NFS_I(inode);