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.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index d4f669f0683e..af05b918cb5b 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -70,15 +70,24 @@ static int nfs_delegation_claim_locks(struct nfs_open_context *ctx, struct nfs4_
70 struct file_lock *fl; 70 struct file_lock *fl;
71 int status = 0; 71 int status = 0;
72 72
73 if (inode->i_flock == NULL)
74 goto out;
75
76 /* Protect inode->i_flock using the BKL */
77 lock_kernel();
73 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 78 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) {
74 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK))) 79 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
75 continue; 80 continue;
76 if (nfs_file_open_context(fl->fl_file) != ctx) 81 if (nfs_file_open_context(fl->fl_file) != ctx)
77 continue; 82 continue;
83 unlock_kernel();
78 status = nfs4_lock_delegation_recall(state, fl); 84 status = nfs4_lock_delegation_recall(state, fl);
79 if (status < 0) 85 if (status < 0)
80 break; 86 goto out;
87 lock_kernel();
81 } 88 }
89 unlock_kernel();
90out:
82 return status; 91 return status;
83} 92}
84 93
@@ -256,7 +265,10 @@ static int __nfs_inode_return_delegation(struct inode *inode, struct nfs_delegat
256 struct nfs_inode *nfsi = NFS_I(inode); 265 struct nfs_inode *nfsi = NFS_I(inode);
257 266
258 nfs_msync_inode(inode); 267 nfs_msync_inode(inode);
259 /* Guard against new delegated open calls */ 268 /*
269 * Guard against new delegated open/lock/unlock calls and against
270 * state recovery
271 */
260 down_write(&nfsi->rwsem); 272 down_write(&nfsi->rwsem);
261 nfs_delegation_claim_opens(inode, &delegation->stateid); 273 nfs_delegation_claim_opens(inode, &delegation->stateid);
262 up_write(&nfsi->rwsem); 274 up_write(&nfsi->rwsem);