diff options
Diffstat (limited to 'fs/nfs/delegation.c')
-rw-r--r-- | fs/nfs/delegation.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index cc563cfa6940..e0cb4ee3b23e 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -140,13 +140,17 @@ static struct nfs_delegation *nfs_detach_delegation_locked(struct nfs_inode *nfs | |||
140 | 140 | ||
141 | if (delegation == NULL) | 141 | if (delegation == NULL) |
142 | goto nomatch; | 142 | goto nomatch; |
143 | spin_lock(&delegation->lock); | ||
143 | if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data, | 144 | if (stateid != NULL && memcmp(delegation->stateid.data, stateid->data, |
144 | sizeof(delegation->stateid.data)) != 0) | 145 | sizeof(delegation->stateid.data)) != 0) |
145 | goto nomatch; | 146 | goto nomatch_unlock; |
146 | list_del_rcu(&delegation->super_list); | 147 | list_del_rcu(&delegation->super_list); |
147 | nfsi->delegation_state = 0; | 148 | nfsi->delegation_state = 0; |
148 | rcu_assign_pointer(nfsi->delegation, NULL); | 149 | rcu_assign_pointer(nfsi->delegation, NULL); |
150 | spin_unlock(&delegation->lock); | ||
149 | return delegation; | 151 | return delegation; |
152 | nomatch_unlock: | ||
153 | spin_unlock(&delegation->lock); | ||
150 | nomatch: | 154 | nomatch: |
151 | return NULL; | 155 | return NULL; |
152 | } | 156 | } |
@@ -172,6 +176,7 @@ int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct | |||
172 | delegation->change_attr = nfsi->change_attr; | 176 | delegation->change_attr = nfsi->change_attr; |
173 | delegation->cred = get_rpccred(cred); | 177 | delegation->cred = get_rpccred(cred); |
174 | delegation->inode = inode; | 178 | delegation->inode = inode; |
179 | spin_lock_init(&delegation->lock); | ||
175 | 180 | ||
176 | spin_lock(&clp->cl_lock); | 181 | spin_lock(&clp->cl_lock); |
177 | if (rcu_dereference(nfsi->delegation) != NULL) { | 182 | if (rcu_dereference(nfsi->delegation) != NULL) { |