Merge tag 'nfsd-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/cel/linux
[linux-2.6-microblaze.git] / fs / nfsd / nfs4state.c
index fa67ecd..4235641 100644 (file)
@@ -2687,9 +2687,9 @@ static void force_expire_client(struct nfs4_client *clp)
 
        trace_nfsd_clid_admin_expired(&clp->cl_clientid);
 
-       spin_lock(&clp->cl_lock);
+       spin_lock(&nn->client_lock);
        clp->cl_time = 0;
-       spin_unlock(&clp->cl_lock);
+       spin_unlock(&nn->client_lock);
 
        wait_event(expiry_wq, atomic_read(&clp->cl_rpc_users) == 0);
        spin_lock(&nn->client_lock);
@@ -5735,16 +5735,6 @@ check_special_stateids(struct net *net, svc_fh *current_fh, stateid_t *stateid,
                                NFS4_SHARE_DENY_READ);
 }
 
-/*
- * Allow READ/WRITE during grace period on recovered state only for files
- * that are not able to provide mandatory locking.
- */
-static inline int
-grace_disallows_io(struct net *net, struct inode *inode)
-{
-       return opens_in_grace(net) && mandatory_lock(inode);
-}
-
 static __be32 check_stateid_generation(stateid_t *in, stateid_t *ref, bool has_session)
 {
        /*
@@ -6026,7 +6016,6 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
                stateid_t *stateid, int flags, struct nfsd_file **nfp,
                struct nfs4_stid **cstid)
 {
-       struct inode *ino = d_inode(fhp->fh_dentry);
        struct net *net = SVC_NET(rqstp);
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
        struct nfs4_stid *s = NULL;
@@ -6035,9 +6024,6 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
        if (nfp)
                *nfp = NULL;
 
-       if (grace_disallows_io(net, ino))
-               return nfserr_grace;
-
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid)) {
                status = check_special_stateids(net, fhp, stateid, flags);
                goto done;
@@ -6835,6 +6821,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        struct nfsd4_blocked_lock *nbl = NULL;
        struct file_lock *file_lock = NULL;
        struct file_lock *conflock = NULL;
+       struct super_block *sb;
        __be32 status = 0;
        int lkflg;
        int err;
@@ -6856,6 +6843,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                dprintk("NFSD: nfsd4_lock: permission denied!\n");
                return status;
        }
+       sb = cstate->current_fh.fh_dentry->d_sb;
 
        if (lock->lk_is_new) {
                if (nfsd4_has_session(cstate))
@@ -6901,10 +6889,14 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (!locks_in_grace(net) && lock->lk_reclaim)
                goto out;
 
+       if (lock->lk_reclaim)
+               fl_flags |= FL_RECLAIM;
+
        fp = lock_stp->st_stid.sc_file;
        switch (lock->lk_type) {
                case NFS4_READW_LT:
-                       if (nfsd4_has_session(cstate))
+                       if (nfsd4_has_session(cstate) &&
+                           !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS))
                                fl_flags |= FL_SLEEP;
                        fallthrough;
                case NFS4_READ_LT:
@@ -6916,7 +6908,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                        fl_type = F_RDLCK;
                        break;
                case NFS4_WRITEW_LT:
-                       if (nfsd4_has_session(cstate))
+                       if (nfsd4_has_session(cstate) &&
+                           !(sb->s_export_op->flags & EXPORT_OP_SYNC_LOCKS))
                                fl_flags |= FL_SLEEP;
                        fallthrough;
                case NFS4_WRITE_LT:
@@ -7036,8 +7029,7 @@ out:
 /*
  * The NFSv4 spec allows a client to do a LOCKT without holding an OPEN,
  * so we do a temporary open here just to get an open file to pass to
- * vfs_test_lock.  (Arguably perhaps test_lock should be done with an
- * inode operation.)
+ * vfs_test_lock.
  */
 static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file_lock *lock)
 {
@@ -7052,7 +7044,9 @@ static __be32 nfsd_test_lock(struct svc_rqst *rqstp, struct svc_fh *fhp, struct
                                                        NFSD_MAY_READ));
        if (err)
                goto out;
+       lock->fl_file = nf->nf_file;
        err = nfserrno(vfs_test_lock(nf->nf_file, lock));
+       lock->fl_file = NULL;
 out:
        fh_unlock(fhp);
        nfsd_file_put(nf);