aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-09-01 15:06:54 -0400
committerJeff Layton <jlayton@primarydata.com>2014-10-07 14:06:13 -0400
commit4d01b7f5e7576858b71cbaa72b541e17a229cb91 (patch)
tree5ea9a839335ca6159ac24f1cf5ddfbe3ff1e7c74 /fs/nfsd
parent03d12ddf845a4eb874ffa558d65a548aee9b715b (diff)
locks: give lm_break a return value
Christoph suggests: "Add a return value to lm_break so that the lock manager can tell the core code "you can delete this lease right now". That gets rid of the games with the timeout which require all kinds of race avoidance code in the users." Do that here and have the nfsd lease break routine use it when it detects that there was a race between setting up the lease and it being broken. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Reviewed-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c17
1 files changed, 9 insertions, 8 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 604ab6decd28..d1b851548b7a 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -3391,18 +3391,20 @@ static void nfsd_break_one_deleg(struct nfs4_delegation *dp)
3391} 3391}
3392 3392
3393/* Called from break_lease() with i_lock held. */ 3393/* Called from break_lease() with i_lock held. */
3394static void nfsd_break_deleg_cb(struct file_lock *fl) 3394static bool
3395nfsd_break_deleg_cb(struct file_lock *fl)
3395{ 3396{
3397 bool ret = false;
3396 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner; 3398 struct nfs4_file *fp = (struct nfs4_file *)fl->fl_owner;
3397 struct nfs4_delegation *dp; 3399 struct nfs4_delegation *dp;
3398 3400
3399 if (!fp) { 3401 if (!fp) {
3400 WARN(1, "(%p)->fl_owner NULL\n", fl); 3402 WARN(1, "(%p)->fl_owner NULL\n", fl);
3401 return; 3403 return ret;
3402 } 3404 }
3403 if (fp->fi_had_conflict) { 3405 if (fp->fi_had_conflict) {
3404 WARN(1, "duplicate break on %p\n", fp); 3406 WARN(1, "duplicate break on %p\n", fp);
3405 return; 3407 return ret;
3406 } 3408 }
3407 /* 3409 /*
3408 * We don't want the locks code to timeout the lease for us; 3410 * We don't want the locks code to timeout the lease for us;
@@ -3414,17 +3416,16 @@ static void nfsd_break_deleg_cb(struct file_lock *fl)
3414 spin_lock(&fp->fi_lock); 3416 spin_lock(&fp->fi_lock);
3415 fp->fi_had_conflict = true; 3417 fp->fi_had_conflict = true;
3416 /* 3418 /*
3417 * If there are no delegations on the list, then we can't count on this 3419 * If there are no delegations on the list, then return true
3418 * lease ever being cleaned up. Set the fl_break_time to jiffies so that 3420 * so that the lease code will go ahead and delete it.
3419 * time_out_leases will do it ASAP. The fact that fi_had_conflict is now
3420 * true should keep any new delegations from being hashed.
3421 */ 3421 */
3422 if (list_empty(&fp->fi_delegations)) 3422 if (list_empty(&fp->fi_delegations))
3423 fl->fl_break_time = jiffies; 3423 ret = true;
3424 else 3424 else
3425 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile) 3425 list_for_each_entry(dp, &fp->fi_delegations, dl_perfile)
3426 nfsd_break_one_deleg(dp); 3426 nfsd_break_one_deleg(dp);
3427 spin_unlock(&fp->fi_lock); 3427 spin_unlock(&fp->fi_lock);
3428 return ret;
3428} 3429}
3429 3430
3430static int 3431static int