diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-09-01 15:06:54 -0400 |
---|---|---|
committer | Jeff Layton <jlayton@primarydata.com> | 2014-10-07 14:06:13 -0400 |
commit | 4d01b7f5e7576858b71cbaa72b541e17a229cb91 (patch) | |
tree | 5ea9a839335ca6159ac24f1cf5ddfbe3ff1e7c74 /fs/nfsd | |
parent | 03d12ddf845a4eb874ffa558d65a548aee9b715b (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.c | 17 |
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. */ |
3394 | static void nfsd_break_deleg_cb(struct file_lock *fl) | 3394 | static bool |
3395 | nfsd_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 | ||
3430 | static int | 3431 | static int |