Skip to content

Commit f657f8e

Browse files
J. Bruce Fieldschucklever
authored andcommitted
nfs: don't atempt blocking locks on nfs reexports
NFS implements blocking locks by blocking inside its lock method. In the reexport case, this blocks the nfs server thread, which could lead to deadlocks since an nfs server thread might be required to unlock the conflicting lock. It also causes a crash, since the nfs server thread assumes it can free the lock when its lm_notify lock callback is called. Ideal would be to make the nfs lock method return without blocking in this case, but for now it works just not to attempt blocking locks. The difference is just that the original client will have to poll (as it does in the v4.0 case) instead of getting a callback when the lock's available. Signed-off-by: J. Bruce Fields <[email protected]> Acked-by: Anna Schumaker <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 7f024fc commit f657f8e

File tree

3 files changed

+9
-3
lines changed

3 files changed

+9
-3
lines changed

fs/nfs/export.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,5 @@ const struct export_operations nfs_export_ops = {
180180
.fetch_iversion = nfs_fetch_iversion,
181181
.flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK|
182182
EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS|
183-
EXPORT_OP_NOATOMIC_ATTR,
183+
EXPORT_OP_NOATOMIC_ATTR|EXPORT_OP_SYNC_LOCKS,
184184
};

fs/nfsd/nfs4state.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6835,6 +6835,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
68356835
struct nfsd4_blocked_lock *nbl = NULL;
68366836
struct file_lock *file_lock = NULL;
68376837
struct file_lock *conflock = NULL;
6838+
struct super_block *sb;
68386839
__be32 status = 0;
68396840
int lkflg;
68406841
int err;
@@ -6856,6 +6857,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
68566857
dprintk("NFSD: nfsd4_lock: permission denied!\n");
68576858
return status;
68586859
}
6860+
sb = cstate->current_fh.fh_dentry->d_sb;
68596861

68606862
if (lock->lk_is_new) {
68616863
if (nfsd4_has_session(cstate))
@@ -6904,7 +6906,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
69046906
fp = lock_stp->st_stid.sc_file;
69056907
switch (lock->lk_type) {
69066908
case NFS4_READW_LT:
6907-
if (nfsd4_has_session(cstate))
6909+
if (nfsd4_has_session(cstate) &&
6910+
!(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS))
69086911
fl_flags |= FL_SLEEP;
69096912
fallthrough;
69106913
case NFS4_READ_LT:
@@ -6916,7 +6919,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
69166919
fl_type = F_RDLCK;
69176920
break;
69186921
case NFS4_WRITEW_LT:
6919-
if (nfsd4_has_session(cstate))
6922+
if (nfsd4_has_session(cstate) &&
6923+
!(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS))
69206924
fl_flags |= FL_SLEEP;
69216925
fallthrough;
69226926
case NFS4_WRITE_LT:

include/linux/exportfs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ struct export_operations {
221221
#define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply
222222
atomic attribute updates
223223
*/
224+
#define EXPORT_OP_SYNC_LOCKS (0x20) /* Filesystem can't do
225+
asychronous blocking locks */
224226
unsigned long flags;
225227
};
226228

0 commit comments

Comments
 (0)