nfsd: don't kill nfsd_files because of lease break error
authorJeff Layton <jlayton@kernel.org>
Thu, 5 Jan 2023 12:15:11 +0000 (07:15 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Wed, 26 Apr 2023 13:04:58 +0000 (09:04 -0400)
An error from break_lease is non-fatal, so we needn't destroy the
nfsd_file in that case. Just put the reference like we normally would
and return the error.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/filecache.c

index 568963b8a4777b85a66cbf5c3076c3ff816581e7..ab37b85b72077c2d6cc2e5bb10d04b9adee0e1ca 100644 (file)
@@ -1102,7 +1102,7 @@ retry:
        nf = nfsd_file_alloc(&key, may_flags);
        if (!nf) {
                status = nfserr_jukebox;
-               goto out_status;
+               goto out;
        }
 
        ret = rhashtable_lookup_insert_key(&nfsd_file_rhash_tbl,
@@ -1111,13 +1111,11 @@ retry:
        if (likely(ret == 0))
                goto open_file;
 
-       nfsd_file_slab_free(&nf->nf_rcu);
-       nf = NULL;
        if (ret == -EEXIST)
                goto retry;
        trace_nfsd_file_insert_err(rqstp, key.inode, may_flags, ret);
        status = nfserr_jukebox;
-       goto out_status;
+       goto construction_err;
 
 wait_for_construction:
        wait_on_bit(&nf->nf_flags, NFSD_FILE_PENDING, TASK_UNINTERRUPTIBLE);
@@ -1127,29 +1125,25 @@ wait_for_construction:
                trace_nfsd_file_cons_err(rqstp, key.inode, may_flags, nf);
                if (!open_retry) {
                        status = nfserr_jukebox;
-                       goto out;
+                       goto construction_err;
                }
                open_retry = false;
-               if (refcount_dec_and_test(&nf->nf_ref))
-                       nfsd_file_free(nf);
                goto retry;
        }
-
        this_cpu_inc(nfsd_file_cache_hits);
 
        status = nfserrno(nfsd_open_break_lease(file_inode(nf->nf_file), may_flags));
+       if (status != nfs_ok) {
+               nfsd_file_put(nf);
+               nf = NULL;
+       }
+
 out:
        if (status == nfs_ok) {
                this_cpu_inc(nfsd_file_acquisitions);
                nfsd_file_check_write_error(nf);
                *pnf = nf;
-       } else {
-               if (refcount_dec_and_test(&nf->nf_ref))
-                       nfsd_file_free(nf);
-               nf = NULL;
        }
-
-out_status:
        put_cred(key.cred);
        trace_nfsd_file_acquire(rqstp, key.inode, may_flags, nf, status);
        return status;
@@ -1179,6 +1173,13 @@ open_file:
        if (status != nfs_ok)
                nfsd_file_unhash(nf);
        clear_and_wake_up_bit(NFSD_FILE_PENDING, &nf->nf_flags);
+       if (status == nfs_ok)
+               goto out;
+
+construction_err:
+       if (refcount_dec_and_test(&nf->nf_ref))
+               nfsd_file_free(nf);
+       nf = NULL;
        goto out;
 }