]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
flexfiles/pNFS: fix NULL checks on result of ff_layout_choose_ds_for_read
authorTigran Mkrtchyan <tigran.mkrtchyan@desy.de>
Thu, 28 Aug 2025 14:51:00 +0000 (16:51 +0200)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 6 Sep 2025 20:51:25 +0000 (16:51 -0400)
Recent commit f06bedfa62d5 ("pNFS/flexfiles: don't attempt pnfs on fatal DS
errors") has changed the error return type of ff_layout_choose_ds_for_read() from
NULL to an error pointer. However, not all code paths have been updated
to match the change. Thus, some non-NULL checks will accept error pointers
as a valid return value.

Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
Suggested-by: Dan Carpenter <dan.carpenter@linaro.org>
Fixes: f06bedfa62d5 ("pNFS/flexfiles: don't attempt pnfs on fatal DS errors")
Signed-off-by: Tigran Mkrtchyan <tigran.mkrtchyan@desy.de>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/flexfilelayout/flexfilelayout.c

index 8dc921d835388e755e18aeb338663d92311ca894..f8ab7b4e09e7e2940afc00ad8469ea357a5d1064 100644 (file)
@@ -773,8 +773,11 @@ ff_layout_choose_ds_for_read(struct pnfs_layout_segment *lseg,
                        continue;
 
                if (check_device &&
-                   nfs4_test_deviceid_unavailable(&mirror->mirror_ds->id_node))
+                   nfs4_test_deviceid_unavailable(&mirror->mirror_ds->id_node)) {
+                       // reinitialize the error state in case if this is the last iteration
+                       ds = ERR_PTR(-EINVAL);
                        continue;
+               }
 
                *best_idx = idx;
                break;
@@ -804,7 +807,7 @@ ff_layout_choose_best_ds_for_read(struct pnfs_layout_segment *lseg,
        struct nfs4_pnfs_ds *ds;
 
        ds = ff_layout_choose_valid_ds_for_read(lseg, start_idx, best_idx);
-       if (ds)
+       if (!IS_ERR(ds))
                return ds;
        return ff_layout_choose_any_ds_for_read(lseg, start_idx, best_idx);
 }
@@ -818,7 +821,7 @@ ff_layout_get_ds_for_read(struct nfs_pageio_descriptor *pgio,
 
        ds = ff_layout_choose_best_ds_for_read(lseg, pgio->pg_mirror_idx,
                                               best_idx);
-       if (ds || !pgio->pg_mirror_idx)
+       if (!IS_ERR(ds) || !pgio->pg_mirror_idx)
                return ds;
        return ff_layout_choose_best_ds_for_read(lseg, 0, best_idx);
 }
@@ -868,7 +871,7 @@ retry:
        req->wb_nio = 0;
 
        ds = ff_layout_get_ds_for_read(pgio, &ds_idx);
-       if (!ds) {
+       if (IS_ERR(ds)) {
                if (!ff_layout_no_fallback_to_mds(pgio->pg_lseg))
                        goto out_mds;
                pnfs_generic_pg_cleanup(pgio);
@@ -1072,11 +1075,13 @@ static void ff_layout_resend_pnfs_read(struct nfs_pgio_header *hdr)
 {
        u32 idx = hdr->pgio_mirror_idx + 1;
        u32 new_idx = 0;
+       struct nfs4_pnfs_ds *ds;
 
-       if (ff_layout_choose_any_ds_for_read(hdr->lseg, idx, &new_idx))
-               ff_layout_send_layouterror(hdr->lseg);
-       else
+       ds = ff_layout_choose_any_ds_for_read(hdr->lseg, idx, &new_idx);
+       if (IS_ERR(ds))
                pnfs_error_mark_layout_for_return(hdr->inode, hdr->lseg);
+       else
+               ff_layout_send_layouterror(hdr->lseg);
        pnfs_read_resend_pnfs(hdr, new_idx);
 }