aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-03 14:33:49 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-04-05 17:03:55 -0400
commitb757144fd77cf5512f5b60179ba5ca8dcc5184b4 (patch)
tree8c83188cb1aa8e4ff5e8d25b48a3cf811d31772d /fs
parentdb4f2e637f6d5dff6d07112e62605275be6050b3 (diff)
NFSv4: Be less aggressive about returning delegations for open files
Currently, if the application that holds the file open isn't doing I/O, we may end up returning the delegation. This means that we can no longer cache the file as aggressively, and often also that we multiply the state that both the server and the client needs to track. This patch adds a check for open files to the routine that scans for delegations that are unreferenced. Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/delegation.c30
-rw-r--r--fs/nfs/delegation.h1
2 files changed, 28 insertions, 3 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index fc8a213497a1..a377ea36381e 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -389,6 +389,24 @@ out:
389 return err; 389 return err;
390} 390}
391 391
392static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
393{
394 bool ret = false;
395
396 if (test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
397 ret = true;
398 if (test_and_clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) && !ret) {
399 struct inode *inode;
400
401 spin_lock(&delegation->lock);
402 inode = delegation->inode;
403 if (inode && list_empty(&NFS_I(inode)->open_files))
404 ret = true;
405 spin_unlock(&delegation->lock);
406 }
407 return ret;
408}
409
392/** 410/**
393 * nfs_client_return_marked_delegations - return previously marked delegations 411 * nfs_client_return_marked_delegations - return previously marked delegations
394 * @clp: nfs_client to process 412 * @clp: nfs_client to process
@@ -411,8 +429,7 @@ restart:
411 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) { 429 list_for_each_entry_rcu(server, &clp->cl_superblocks, client_link) {
412 list_for_each_entry_rcu(delegation, &server->delegations, 430 list_for_each_entry_rcu(delegation, &server->delegations,
413 super_list) { 431 super_list) {
414 if (!test_and_clear_bit(NFS_DELEGATION_RETURN, 432 if (!nfs_delegation_need_return(delegation))
415 &delegation->flags))
416 continue; 433 continue;
417 inode = nfs_delegation_grab_inode(delegation); 434 inode = nfs_delegation_grab_inode(delegation);
418 if (inode == NULL) 435 if (inode == NULL)
@@ -471,6 +488,13 @@ int nfs4_inode_return_delegation(struct inode *inode)
471 return err; 488 return err;
472} 489}
473 490
491static void nfs_mark_return_if_closed_delegation(struct nfs_server *server,
492 struct nfs_delegation *delegation)
493{
494 set_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
495 set_bit(NFS4CLNT_DELEGRETURN, &server->nfs_client->cl_state);
496}
497
474static void nfs_mark_return_delegation(struct nfs_server *server, 498static void nfs_mark_return_delegation(struct nfs_server *server,
475 struct nfs_delegation *delegation) 499 struct nfs_delegation *delegation)
476{ 500{
@@ -574,7 +598,7 @@ static void nfs_mark_return_unreferenced_delegations(struct nfs_server *server)
574 list_for_each_entry_rcu(delegation, &server->delegations, super_list) { 598 list_for_each_entry_rcu(delegation, &server->delegations, super_list) {
575 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags)) 599 if (test_and_clear_bit(NFS_DELEGATION_REFERENCED, &delegation->flags))
576 continue; 600 continue;
577 nfs_mark_return_delegation(server, delegation); 601 nfs_mark_return_if_closed_delegation(server, delegation);
578 } 602 }
579} 603}
580 604
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 88573d107502..22f0a138e551 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -28,6 +28,7 @@ struct nfs_delegation {
28enum { 28enum {
29 NFS_DELEGATION_NEED_RECLAIM = 0, 29 NFS_DELEGATION_NEED_RECLAIM = 0,
30 NFS_DELEGATION_RETURN, 30 NFS_DELEGATION_RETURN,
31 NFS_DELEGATION_RETURN_IF_CLOSED,
31 NFS_DELEGATION_REFERENCED, 32 NFS_DELEGATION_REFERENCED,
32 NFS_DELEGATION_RETURNING, 33 NFS_DELEGATION_RETURNING,
33}; 34};