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.

Merge tag 'nfs-for-4.9-3' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client bugfixes from Anna Schumaker:
"Most of these fix regressions in 4.9, and none are going to stable
this time around.

Bugfixes:
- Trim extra slashes in v4 nfs_paths to fix tools that use this
- Fix a -Wmaybe-uninitialized warnings
- Fix suspicious RCU usages
- Fix Oops when mounting multiple servers at once
- Suppress a false-positive pNFS error
- Fix a DMAR failure in NFS over RDMA"

* tag 'nfs-for-4.9-3' of git://git.linux-nfs.org/projects/anna/linux-nfs:
xprtrdma: Fix DMAR failure in frwr_op_map() after reconnect
fs/nfs: Fix used uninitialized warn in nfs4_slot_seqid_in_use()
NFS: Don't print a pNFS error if we aren't using pNFS
NFS: Ignore connections that have cl_rpcclient uninitialized
SUNRPC: Fix suspicious RCU usage
NFSv4.1: work around -Wmaybe-uninitialized warning
NFS: Trim extra slash in v4 nfs_path

+41 -25
+2 -1
fs/nfs/client.c
··· 314 314 /* Match the full socket address */ 315 315 if (!rpc_cmp_addr_port(sap, clap)) 316 316 /* Match all xprt_switch full socket addresses */ 317 - if (!rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient, 317 + if (IS_ERR(clp->cl_rpcclient) || 318 + !rpc_clnt_xprt_switch_has_addr(clp->cl_rpcclient, 318 319 sap)) 319 320 continue; 320 321
+1 -1
fs/nfs/namespace.c
··· 98 98 return end; 99 99 } 100 100 namelen = strlen(base); 101 - if (flags & NFS_PATH_CANONICAL) { 101 + if (*end == '/') { 102 102 /* Strip off excess slashes in base string */ 103 103 while (namelen > 0 && base[namelen - 1] == '/') 104 104 namelen--;
+7 -5
fs/nfs/nfs4session.c
··· 178 178 __must_hold(&tbl->slot_tbl_lock) 179 179 { 180 180 struct nfs4_slot *slot; 181 + int ret; 181 182 182 183 slot = nfs4_lookup_slot(tbl, slotid); 183 - if (IS_ERR(slot)) 184 - return PTR_ERR(slot); 185 - *seq_nr = slot->seq_nr; 186 - return 0; 184 + ret = PTR_ERR_OR_ZERO(slot); 185 + if (!ret) 186 + *seq_nr = slot->seq_nr; 187 + 188 + return ret; 187 189 } 188 190 189 191 /* ··· 198 196 static bool nfs4_slot_seqid_in_use(struct nfs4_slot_table *tbl, 199 197 u32 slotid, u32 seq_nr) 200 198 { 201 - u32 cur_seq; 199 + u32 cur_seq = 0; 202 200 bool ret = false; 203 201 204 202 spin_lock(&tbl->slot_tbl_lock);
+2
fs/nfs/pnfs.c
··· 146 146 u32 id; 147 147 int i; 148 148 149 + if (fsinfo->nlayouttypes == 0) 150 + goto out_no_driver; 149 151 if (!(server->nfs_client->cl_exchange_flags & 150 152 (EXCHGID4_FLAG_USE_NON_PNFS | EXCHGID4_FLAG_USE_PNFS_MDS))) { 151 153 printk(KERN_ERR "NFS: %s: cl_exchange_flags 0x%x\n",
+5 -2
net/sunrpc/clnt.c
··· 2753 2753 2754 2754 void rpc_clnt_xprt_switch_put(struct rpc_clnt *clnt) 2755 2755 { 2756 + rcu_read_lock(); 2756 2757 xprt_switch_put(rcu_dereference(clnt->cl_xpi.xpi_xpswitch)); 2758 + rcu_read_unlock(); 2757 2759 } 2758 2760 EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_put); 2759 2761 2760 2762 void rpc_clnt_xprt_switch_add_xprt(struct rpc_clnt *clnt, struct rpc_xprt *xprt) 2761 2763 { 2764 + rcu_read_lock(); 2762 2765 rpc_xprt_switch_add_xprt(rcu_dereference(clnt->cl_xpi.xpi_xpswitch), 2763 2766 xprt); 2767 + rcu_read_unlock(); 2764 2768 } 2765 2769 EXPORT_SYMBOL_GPL(rpc_clnt_xprt_switch_add_xprt); 2766 2770 ··· 2774 2770 struct rpc_xprt_switch *xps; 2775 2771 bool ret; 2776 2772 2777 - xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch); 2778 - 2779 2773 rcu_read_lock(); 2774 + xps = rcu_dereference(clnt->cl_xpi.xpi_xpswitch); 2780 2775 ret = rpc_xprt_switch_has_addr(xps, sap); 2781 2776 rcu_read_unlock(); 2782 2777 return ret;
+22 -15
net/sunrpc/xprtrdma/frwr_ops.c
··· 44 44 * being done. 45 45 * 46 46 * When the underlying transport disconnects, MRs are left in one of 47 - * three states: 47 + * four states: 48 48 * 49 49 * INVALID: The MR was not in use before the QP entered ERROR state. 50 - * (Or, the LOCAL_INV WR has not completed or flushed yet). 51 - * 52 - * STALE: The MR was being registered or unregistered when the QP 53 - * entered ERROR state, and the pending WR was flushed. 54 50 * 55 51 * VALID: The MR was registered before the QP entered ERROR state. 56 52 * 57 - * When frwr_op_map encounters STALE and VALID MRs, they are recovered 58 - * with ib_dereg_mr and then are re-initialized. Beause MR recovery 53 + * FLUSHED_FR: The MR was being registered when the QP entered ERROR 54 + * state, and the pending WR was flushed. 55 + * 56 + * FLUSHED_LI: The MR was being invalidated when the QP entered ERROR 57 + * state, and the pending WR was flushed. 58 + * 59 + * When frwr_op_map encounters FLUSHED and VALID MRs, they are recovered 60 + * with ib_dereg_mr and then are re-initialized. Because MR recovery 59 61 * allocates fresh resources, it is deferred to a workqueue, and the 60 62 * recovered MRs are placed back on the rb_mws list when recovery is 61 63 * complete. frwr_op_map allocates another MR for the current RPC while ··· 179 177 static void 180 178 frwr_op_recover_mr(struct rpcrdma_mw *mw) 181 179 { 180 + enum rpcrdma_frmr_state state = mw->frmr.fr_state; 182 181 struct rpcrdma_xprt *r_xprt = mw->mw_xprt; 183 182 struct rpcrdma_ia *ia = &r_xprt->rx_ia; 184 183 int rc; 185 184 186 185 rc = __frwr_reset_mr(ia, mw); 187 - ib_dma_unmap_sg(ia->ri_device, mw->mw_sg, mw->mw_nents, mw->mw_dir); 186 + if (state != FRMR_FLUSHED_LI) 187 + ib_dma_unmap_sg(ia->ri_device, 188 + mw->mw_sg, mw->mw_nents, mw->mw_dir); 188 189 if (rc) 189 190 goto out_release; 190 191 ··· 267 262 } 268 263 269 264 static void 270 - __frwr_sendcompletion_flush(struct ib_wc *wc, struct rpcrdma_frmr *frmr, 271 - const char *wr) 265 + __frwr_sendcompletion_flush(struct ib_wc *wc, const char *wr) 272 266 { 273 - frmr->fr_state = FRMR_IS_STALE; 274 267 if (wc->status != IB_WC_WR_FLUSH_ERR) 275 268 pr_err("rpcrdma: %s: %s (%u/0x%x)\n", 276 269 wr, ib_wc_status_msg(wc->status), ··· 291 288 if (wc->status != IB_WC_SUCCESS) { 292 289 cqe = wc->wr_cqe; 293 290 frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe); 294 - __frwr_sendcompletion_flush(wc, frmr, "fastreg"); 291 + frmr->fr_state = FRMR_FLUSHED_FR; 292 + __frwr_sendcompletion_flush(wc, "fastreg"); 295 293 } 296 294 } 297 295 ··· 312 308 if (wc->status != IB_WC_SUCCESS) { 313 309 cqe = wc->wr_cqe; 314 310 frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe); 315 - __frwr_sendcompletion_flush(wc, frmr, "localinv"); 311 + frmr->fr_state = FRMR_FLUSHED_LI; 312 + __frwr_sendcompletion_flush(wc, "localinv"); 316 313 } 317 314 } 318 315 ··· 333 328 /* WARNING: Only wr_cqe and status are reliable at this point */ 334 329 cqe = wc->wr_cqe; 335 330 frmr = container_of(cqe, struct rpcrdma_frmr, fr_cqe); 336 - if (wc->status != IB_WC_SUCCESS) 337 - __frwr_sendcompletion_flush(wc, frmr, "localinv"); 331 + if (wc->status != IB_WC_SUCCESS) { 332 + frmr->fr_state = FRMR_FLUSHED_LI; 333 + __frwr_sendcompletion_flush(wc, "localinv"); 334 + } 338 335 complete(&frmr->fr_linv_done); 339 336 } 340 337
+2 -1
net/sunrpc/xprtrdma/xprt_rdma.h
··· 216 216 enum rpcrdma_frmr_state { 217 217 FRMR_IS_INVALID, /* ready to be used */ 218 218 FRMR_IS_VALID, /* in use */ 219 - FRMR_IS_STALE, /* failed completion */ 219 + FRMR_FLUSHED_FR, /* flushed FASTREG WR */ 220 + FRMR_FLUSHED_LI, /* flushed LOCALINV WR */ 220 221 }; 221 222 222 223 struct rpcrdma_frmr {