Skip to content

Commit c87fb4a

Browse files
author
J. Bruce Fields
committed
lockd: NLM grace period shouldn't block NFSv4 opens
NLM locks don't conflict with NFSv4 share reservations, so we're not going to learn anything new by watiting for them. They do conflict with NFSv4 locks and with delegations. Signed-off-by: J. Bruce Fields <[email protected]>
1 parent 4bc6603 commit c87fb4a

File tree

5 files changed

+37
-9
lines changed

5 files changed

+37
-9
lines changed

fs/lockd/svc.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -591,6 +591,7 @@ static int lockd_init_net(struct net *net)
591591

592592
INIT_DELAYED_WORK(&ln->grace_period_end, grace_ender);
593593
INIT_LIST_HEAD(&ln->lockd_manager.list);
594+
ln->lockd_manager.block_opens = false;
594595
spin_lock_init(&ln->nsm_clnt_lock);
595596
return 0;
596597
}

fs/nfs_common/grace.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,33 @@ EXPORT_SYMBOL_GPL(locks_end_grace);
6363
* lock reclaims.
6464
*/
6565
int
66-
locks_in_grace(struct net *net)
66+
__state_in_grace(struct net *net, bool open)
6767
{
6868
struct list_head *grace_list = net_generic(net, grace_net_id);
69+
struct lock_manager *lm;
6970

70-
return !list_empty(grace_list);
71+
if (!open)
72+
return !list_empty(grace_list);
73+
74+
list_for_each_entry(lm, grace_list, list) {
75+
if (lm->block_opens)
76+
return true;
77+
}
78+
return false;
79+
}
80+
81+
int locks_in_grace(struct net *net)
82+
{
83+
return __state_in_grace(net, 0);
7184
}
7285
EXPORT_SYMBOL_GPL(locks_in_grace);
7386

87+
int opens_in_grace(struct net *net)
88+
{
89+
return __state_in_grace(net, 1);
90+
}
91+
EXPORT_SYMBOL_GPL(opens_in_grace);
92+
7493
static int __net_init
7594
grace_init_net(struct net *net)
7695
{

fs/nfsd/nfs4proc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,10 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
415415
/* Openowner is now set, so sequence id will get bumped. Now we need
416416
* these checks before we do any creates: */
417417
status = nfserr_grace;
418-
if (locks_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
418+
if (opens_in_grace(net) && open->op_claim_type != NFS4_OPEN_CLAIM_PREVIOUS)
419419
goto out;
420420
status = nfserr_no_grace;
421-
if (!locks_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
421+
if (!opens_in_grace(net) && open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS)
422422
goto out;
423423

424424
switch (open->op_claim_type) {
@@ -827,7 +827,7 @@ nfsd4_remove(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
827827
{
828828
__be32 status;
829829

830-
if (locks_in_grace(SVC_NET(rqstp)))
830+
if (opens_in_grace(SVC_NET(rqstp)))
831831
return nfserr_grace;
832832
status = nfsd_unlink(rqstp, &cstate->current_fh, 0,
833833
remove->rm_name, remove->rm_namelen);
@@ -846,7 +846,7 @@ nfsd4_rename(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
846846

847847
if (!cstate->save_fh.fh_dentry)
848848
return status;
849-
if (locks_in_grace(SVC_NET(rqstp)) &&
849+
if (opens_in_grace(SVC_NET(rqstp)) &&
850850
!(cstate->save_fh.fh_export->ex_flags & NFSEXP_NOSUBTREECHECK))
851851
return nfserr_grace;
852852
status = nfsd_rename(rqstp, &cstate->save_fh, rename->rn_sname,

fs/nfsd/nfs4state.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4065,7 +4065,8 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open,
40654065
case NFS4_OPEN_CLAIM_FH:
40664066
/*
40674067
* Let's not give out any delegations till everyone's
4068-
* had the chance to reclaim theirs....
4068+
* had the chance to reclaim theirs, *and* until
4069+
* NLM locks have all been reclaimed:
40694070
*/
40704071
if (locks_in_grace(clp->net))
40714072
goto out_no_deleg;
@@ -4440,7 +4441,7 @@ check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid,
44404441
{
44414442
if (ONE_STATEID(stateid) && (flags & RD_STATE))
44424443
return nfs_ok;
4443-
else if (locks_in_grace(net)) {
4444+
else if (opens_in_grace(net)) {
44444445
/* Answer in remaining cases depends on existence of
44454446
* conflicting state; so we must wait out the grace period. */
44464447
return nfserr_grace;
@@ -4459,7 +4460,7 @@ check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid,
44594460
static inline int
44604461
grace_disallows_io(struct net *net, struct inode *inode)
44614462
{
4462-
return locks_in_grace(net) && mandatory_lock(inode);
4463+
return opens_in_grace(net) && mandatory_lock(inode);
44634464
}
44644465

44654466
/* Returns true iff a is later than b: */
@@ -6578,6 +6579,7 @@ nfs4_state_start_net(struct net *net)
65786579
return ret;
65796580
nn->boot_time = get_seconds();
65806581
nn->grace_ended = false;
6582+
nn->nfsd4_manager.block_opens = true;
65816583
locks_start_grace(net, &nn->nfsd4_manager);
65826584
nfsd4_client_tracking_init(net);
65836585
printk(KERN_INFO "NFSD: starting %ld-second grace period (net %p)\n",

include/linux/fs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -942,12 +942,18 @@ struct lock_manager_operations {
942942

943943
struct lock_manager {
944944
struct list_head list;
945+
/*
946+
* NFSv4 and up also want opens blocked during the grace period;
947+
* NLM doesn't care:
948+
*/
949+
bool block_opens;
945950
};
946951

947952
struct net;
948953
void locks_start_grace(struct net *, struct lock_manager *);
949954
void locks_end_grace(struct lock_manager *);
950955
int locks_in_grace(struct net *);
956+
int opens_in_grace(struct net *);
951957

952958
/* that will die - we need it for nfs_lock_info */
953959
#include <linux/nfs_fs_i.h>

0 commit comments

Comments
 (0)