Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 124730
b: refs/heads/master
c: 515d861
h: refs/heads/master
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Dec 23, 2008
1 parent aabab14 commit 5a8c17e
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 56 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e33bed55239bdcee1746c31a11177d239bac1b5
refs/heads/master: 515d86117724abe39d7d57d7ccc7cc5c44480529
97 changes: 45 additions & 52 deletions trunk/fs/nfs/delegation.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,34 @@ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegat
return nfs_do_return_delegation(inode, delegation, 1);
}

/*
* Return all delegations that have been marked for return
*/
static void nfs_client_return_marked_delegations(struct nfs_client *clp)
{
struct nfs_delegation *delegation;
struct inode *inode;

restart:
rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
if (!test_and_clear_bit(NFS_DELEGATION_RETURN, &delegation->flags))
continue;
inode = nfs_delegation_grab_inode(delegation);
if (inode == NULL)
continue;
spin_lock(&clp->cl_lock);
delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
spin_unlock(&clp->cl_lock);
rcu_read_unlock();
if (delegation != NULL)
__nfs_inode_return_delegation(inode, delegation);
iput(inode);
goto restart;
}
rcu_read_unlock();
}

/*
* This function returns the delegation without reclaiming opens
* or protecting against delegation reclaims.
Expand Down Expand Up @@ -296,63 +324,46 @@ int nfs_inode_return_delegation(struct inode *inode)
/*
* Return all delegations associated to a super block
*/
void nfs_return_all_delegations(struct super_block *sb)
void nfs_super_return_all_delegations(struct super_block *sb)
{
struct nfs_client *clp = NFS_SB(sb)->nfs_client;
struct nfs_delegation *delegation;
struct inode *inode;

if (clp == NULL)
return;
restart:
rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
inode = NULL;
spin_lock(&delegation->lock);
if (delegation->inode != NULL && delegation->inode->i_sb == sb)
inode = igrab(delegation->inode);
set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
spin_unlock(&delegation->lock);
if (inode == NULL)
continue;
spin_lock(&clp->cl_lock);
delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
spin_unlock(&clp->cl_lock);
rcu_read_unlock();
if (delegation != NULL)
__nfs_inode_return_delegation(inode, delegation);
iput(inode);
goto restart;
}
rcu_read_unlock();
nfs_client_return_marked_delegations(clp);
}

static void nfs_client_return_all_delegations(struct nfs_client *clp)
{
struct nfs_delegation *delegation;

rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list)
set_bit(NFS_DELEGATION_RETURN, &delegation->flags);
rcu_read_unlock();
nfs_client_return_marked_delegations(clp);
}

static int nfs_do_expire_all_delegations(void *ptr)
{
struct nfs_client *clp = ptr;
struct nfs_delegation *delegation;
struct inode *inode;

allow_signal(SIGKILL);
restart:

if (test_bit(NFS4CLNT_STATE_RECOVER, &clp->cl_state) != 0)
goto out;
if (test_bit(NFS4CLNT_LEASE_EXPIRED, &clp->cl_state) == 0)
goto out;
rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
inode = nfs_delegation_grab_inode(delegation);
if (inode == NULL)
continue;
spin_lock(&clp->cl_lock);
delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
spin_unlock(&clp->cl_lock);
rcu_read_unlock();
if (delegation)
__nfs_inode_return_delegation(inode, delegation);
iput(inode);
goto restart;
}
rcu_read_unlock();
nfs_client_return_all_delegations(clp);
out:
nfs_put_client(clp);
module_put_and_exit(0);
Expand All @@ -379,27 +390,9 @@ void nfs_expire_all_delegations(struct nfs_client *clp)
*/
void nfs_handle_cb_pathdown(struct nfs_client *clp)
{
struct nfs_delegation *delegation;
struct inode *inode;

if (clp == NULL)
return;
restart:
rcu_read_lock();
list_for_each_entry_rcu(delegation, &clp->cl_delegations, super_list) {
inode = nfs_delegation_grab_inode(delegation);
if (inode == NULL)
continue;
spin_lock(&clp->cl_lock);
delegation = nfs_detach_delegation_locked(NFS_I(inode), NULL);
spin_unlock(&clp->cl_lock);
rcu_read_unlock();
if (delegation != NULL)
__nfs_inode_return_delegation(inode, delegation);
iput(inode);
goto restart;
}
rcu_read_unlock();
nfs_client_return_all_delegations(clp);
}

struct recall_threadargs {
Expand Down
8 changes: 6 additions & 2 deletions trunk/fs/nfs/delegation.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,24 @@ struct nfs_delegation {
int type;
loff_t maxsize;
__u64 change_attr;
#define NFS_DELEGATION_NEED_RECLAIM 0
unsigned long flags;
spinlock_t lock;
struct rcu_head rcu;
};

enum {
NFS_DELEGATION_NEED_RECLAIM = 0,
NFS_DELEGATION_RETURN,
};

int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
int nfs_inode_return_delegation(struct inode *inode);
int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
void nfs_inode_return_delegation_noreclaim(struct inode *inode);

struct inode *nfs_delegation_find_inode(struct nfs_client *clp, const struct nfs_fh *fhandle);
void nfs_return_all_delegations(struct super_block *sb);
void nfs_super_return_all_delegations(struct super_block *sb);
void nfs_expire_all_delegations(struct nfs_client *clp);
void nfs_handle_cb_pathdown(struct nfs_client *clp);

Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/nfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -2433,7 +2433,7 @@ static void nfs4_kill_super(struct super_block *sb)
{
struct nfs_server *server = NFS_SB(sb);

nfs_return_all_delegations(sb);
nfs_super_return_all_delegations(sb);
kill_anon_super(sb);

nfs4_renewd_prepare_shutdown(server);
Expand Down

0 comments on commit 5a8c17e

Please sign in to comment.