Patch "pNFS/flexfiles: Fix an Oopsable condition when connection to the DS fails" has been added to the 4.7-stable tree
Subsystems (2)
This is a note to let you know that I've just added the patch titled
pNFS/flexfiles: Fix an Oopsable condition when connection to the DS fails
to the 4.7-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
pnfs-flexfiles-fix-an-oopsable-condition-when-connection-to-the-ds-fails.patch
and it can be found in the queue-4.7 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From
3dc147359e3dcdf0648f1e2c11f62cfae3160df0Mon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Mon, 29 Aug 2016 15:12:54 -0400
Subject: pNFS/flexfiles: Fix an Oopsable condition when connection to the DS fails
From: Trond Myklebust <[email protected]>
commit 3dc147359e3dcdf0648f1e2c11f62cfae3160df0 upstream.
If the attempt to connect to a DS fails inside ff_layout_pg_init_read or ff_layout_pg_init_write, then we currently end up clearing the layout segment carried by the struct nfs_pageio_descriptor, causing an Oops when we later call into ff_layout_read_pagelist/ff_layout_write_pagelist.
The fix is to ensure we return the layout and then retry.
--- fs/nfs/flexfilelayout/flexfilelayout.c | 37 ++++++++++++++---------------- fs/nfs/flexfilelayout/flexfilelayoutdev.c | 19 ++++++++------- 2 files changed, 28 insertions(+), 28 deletions(-)
fs/nfs/flexfilelayout/flexfilelayout.c +18 -19
@@ -806,11 +806,14 @@ ff_layout_choose_best_ds_for_read(struct {struct nfs4_ff_layout_segment *fls =FF_LAYOUT_LSEG (lseg);struct nfs4_pnfs_ds *ds; +bool fail_return = false;int idx;/* mirrors are sorted by efficiency */ for (idx = start_idx; idx < fls->mirror_array_cnt; idx++) { - ds =nfs4_ff_layout_prepare_ds (lseg, idx, false); +if (idx+1 == fls->mirror_array_cnt) + fail_return = true; + ds =nfs4_ff_layout_prepare_ds (lseg, idx, fail_return);if (ds) { *best_idx = idx;return ds;
@@ -859,6 +862,7 @@ ff_layout_pg_init_read(struct nfs_pageiostruct nfs4_pnfs_ds *ds;int ds_idx; +retry:/* Use full layout for now */ if (!pgio->pg_lseg)ff_layout_pg_get_read (pgio, req, false);
@@ -871,10 +875,13 @@ ff_layout_pg_init_read(struct nfs_pageio ds =ff_layout_choose_best_ds_for_read (pgio->pg_lseg,0 , &ds_idx);if (!ds) { -if (ff_layout_no_fallback_to_mds (pgio->pg_lseg)) - goto out_pnfs; -else +if (!ff_layout_no_fallback_to_mds (pgio->pg_lseg)) goto out_mds; +pnfs_put_lseg (pgio->pg_lseg); + pgio->pg_lseg =NULL ; +/* Sleep for 1 second before retrying */ +ssleep (1 ); + goto retry; } mirror =FF_LAYOUT_COMP (pgio->pg_lseg, ds_idx);
@@ -890,12 +897,6 @@ out_mds:pnfs_put_lseg (pgio->pg_lseg); pgio->pg_lseg =NULL ;nfs_pageio_reset_read_mds (pgio); -return ; - -out_pnfs: -pnfs_set_lo_fail (pgio->pg_lseg); -pnfs_put_lseg (pgio->pg_lseg); - pgio->pg_lseg =NULL ; } static void
@@ -909,6 +910,7 @@ ff_layout_pg_init_write(struct nfs_pageiint i;int status; +retry:if (!pgio->pg_lseg) { pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode, req->wb_context,
@@ -940,10 +942,13 @@ ff_layout_pg_init_write(struct nfs_pageifor (i =0 ; i < pgio->pg_mirror_count; i++) { ds =nfs4_ff_layout_prepare_ds (pgio->pg_lseg, i, true);if (!ds) { -if (ff_layout_no_fallback_to_mds (pgio->pg_lseg)) - goto out_pnfs; -else +if (!ff_layout_no_fallback_to_mds (pgio->pg_lseg)) goto out_mds; +pnfs_put_lseg (pgio->pg_lseg); + pgio->pg_lseg =NULL ; +/* Sleep for 1 second before retrying */ +ssleep (1 ); + goto retry; } pgm = &pgio->pg_mirrors[i]; mirror =FF_LAYOUT_COMP (pgio->pg_lseg, i);
@@ -956,12 +961,6 @@ out_mds:pnfs_put_lseg (pgio->pg_lseg); pgio->pg_lseg =NULL ;nfs_pageio_reset_write_mds (pgio); -return ; - -out_pnfs: -pnfs_set_lo_fail (pgio->pg_lseg); -pnfs_put_lseg (pgio->pg_lseg); - pgio->pg_lseg =NULL ; } static unsigned int
fs/nfs/flexfilelayout/flexfilelayoutdev.c +10 -9
@@ -379,7 +379,7 @@ nfs4_ff_layout_prepare_ds(struct pnfs_la devid = &mirror->mirror_ds->id_node;if (ff_layout_test_devid_unavailable (devid)) - goto out; + goto out_fail; ds = mirror->mirror_ds->ds;/* matching smp_wmb() in _nfs4_pnfs_v3/4_ds_connect */
@@ -405,15 +405,16 @@ nfs4_ff_layout_prepare_ds(struct pnfs_la mirror->mirror_ds->ds_versions[0 ].rsize = max_payload;if (mirror->mirror_ds->ds_versions[0 ].wsize > max_payload) mirror->mirror_ds->ds_versions[0 ].wsize = max_payload; - }else { -ff_layout_track_ds_error (FF_LAYOUT_FROM_HDR (lseg->pls_layout), - mirror, lseg->pls_range.offset, - lseg->pls_range.length,NFS4ERR_NXIO , -OP_ILLEGAL ,GFP_NOIO ); -if (fail_return || !ff_layout_has_available_ds (lseg)) -pnfs_error_mark_layout_for_return (ino, lseg); - ds =NULL ; + goto out; } +ff_layout_track_ds_error (FF_LAYOUT_FROM_HDR (lseg->pls_layout), + mirror, lseg->pls_range.offset, + lseg->pls_range.length,NFS4ERR_NXIO , +OP_ILLEGAL ,GFP_NOIO ); +out_fail: +if (fail_return || !ff_layout_has_available_ds (lseg)) +pnfs_error_mark_layout_for_return (ino, lseg); + ds =NULL ; out:return ds; }
Patches currently in stable-queue which might be from [email protected] are
queue-4.7/nfsv4.1-fix-oopsable-condition-in-server-callback-races.patch queue-4.7/pnfs-ensure-layoutget-and-layoutreturn-are-properly-serialised.patch queue-4.7/nfsv4.x-fix-a-refcount-leak-in-nfs_callback_up_net.patch queue-4.7/pnfs-flexfiles-fix-an-oopsable-condition-when-connection-to-the-ds-fails.patch queue-4.7/nfsv4.1-fix-the-create_session-slot-number-accounting.patch queue-4.7/pnfs-the-client-must-not-do-i-o-to-the-ds-if-it-s-lease-has-expired.patch