Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <bfields@redhat.com>
Acked-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

J. Bruce Fields and committed by
Chuck Lever
f657f8ee 7f024fcd

+9 -3
+1 -1
fs/nfs/export.c
··· 180 180 .fetch_iversion = nfs_fetch_iversion, 181 181 .flags = EXPORT_OP_NOWCC|EXPORT_OP_NOSUBTREECHK| 182 182 EXPORT_OP_CLOSE_BEFORE_UNLINK|EXPORT_OP_REMOTE_FS| 183 - EXPORT_OP_NOATOMIC_ATTR, 183 + EXPORT_OP_NOATOMIC_ATTR|EXPORT_OP_SYNC_LOCKS, 184 184 };
+6 -2
fs/nfsd/nfs4state.c
··· 6835 6835 struct nfsd4_blocked_lock *nbl = NULL; 6836 6836 struct file_lock *file_lock = NULL; 6837 6837 struct file_lock *conflock = NULL; 6838 + struct super_block *sb; 6838 6839 __be32 status = 0; 6839 6840 int lkflg; 6840 6841 int err; ··· 6857 6856 dprintk("NFSD: nfsd4_lock: permission denied!\n"); 6858 6857 return status; 6859 6858 } 6859 + sb = cstate->current_fh.fh_dentry->d_sb; 6860 6860 6861 6861 if (lock->lk_is_new) { 6862 6862 if (nfsd4_has_session(cstate)) ··· 6906 6904 fp = lock_stp->st_stid.sc_file; 6907 6905 switch (lock->lk_type) { 6908 6906 case NFS4_READW_LT: 6909 - if (nfsd4_has_session(cstate)) 6907 + if (nfsd4_has_session(cstate) && 6908 + !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS)) 6910 6909 fl_flags |= FL_SLEEP; 6911 6910 fallthrough; 6912 6911 case NFS4_READ_LT: ··· 6919 6916 fl_type = F_RDLCK; 6920 6917 break; 6921 6918 case NFS4_WRITEW_LT: 6922 - if (nfsd4_has_session(cstate)) 6919 + if (nfsd4_has_session(cstate) && 6920 + !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS)) 6923 6921 fl_flags |= FL_SLEEP; 6924 6922 fallthrough; 6925 6923 case NFS4_WRITE_LT:
+2
include/linux/exportfs.h
··· 221 221 #define EXPORT_OP_NOATOMIC_ATTR (0x10) /* Filesystem cannot supply 222 222 atomic attribute updates 223 223 */ 224 + #define EXPORT_OP_SYNC_LOCKS (0x20) /* Filesystem can't do 225 + asychronous blocking locks */ 224 226 unsigned long flags; 225 227 }; 226 228