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.11-2' of git://git.linux-nfs.org/projects/anna/linux-nfs

Pull NFS client fixes from Anna Schumaker:
"We have a handful of stable fixes to fix kernel warnings and other
bugs that have been around for a while. We've also found a few other
reference counting bugs and memory leaks since the initial 4.11 pull.

Stable Bugfixes:
- Fix decrementing nrequests in NFS v4.2 COPY to fix kernel warnings
- Prevent a double free in async nfs4_exchange_id()
- Squelch a kbuild sparse complaint for xprtrdma

Other Bugfixes:
- Fix a typo (NFS_ATTR_FATTR_GROUP_NAME) that causes a memory leak
- Fix a reference leak that causes kernel warnings
- Make nfs4_cb_sv_ops static to fix a sparse warning
- Respect a server's max size in CREATE_SESSION
- Handle errors from nfs4_pnfs_ds_connect
- Flexfiles layout shouldn't mark devices as unavailable"

* tag 'nfs-for-4.11-2' of git://git.linux-nfs.org/projects/anna/linux-nfs:
pNFS/flexfiles: never nfs4_mark_deviceid_unavailable
pNFS: return status from nfs4_pnfs_ds_connect
NFSv4.1 respect server's max size in CREATE_SESSION
NFS prevent double free in async nfs4_exchange_id
nfs: make nfs4_cb_sv_ops static
xprtrdma: Squelch kbuild sparse complaint
NFS: fix the fault nrequests decreasing for nfs_inode COPY
NFSv4: fix a reference leak caused WARNING messages
nfs4: fix a typo of NFS_ATTR_FATTR_GROUP_NAME

+90 -27
+2 -2
fs/nfs/callback.c
··· 232 232 .svo_module = THIS_MODULE, 233 233 }; 234 234 235 - struct svc_serv_ops *nfs4_cb_sv_ops[] = { 235 + static struct svc_serv_ops *nfs4_cb_sv_ops[] = { 236 236 [0] = &nfs40_cb_sv_ops, 237 237 [1] = &nfs41_cb_sv_ops, 238 238 }; 239 239 #else 240 - struct svc_serv_ops *nfs4_cb_sv_ops[] = { 240 + static struct svc_serv_ops *nfs4_cb_sv_ops[] = { 241 241 [0] = &nfs40_cb_sv_ops, 242 242 [1] = NULL, 243 243 };
+24 -1
fs/nfs/client.c
··· 325 325 return NULL; 326 326 } 327 327 328 - static bool nfs_client_init_is_complete(const struct nfs_client *clp) 328 + /* 329 + * Return true if @clp is done initializing, false if still working on it. 330 + * 331 + * Use nfs_client_init_status to check if it was successful. 332 + */ 333 + bool nfs_client_init_is_complete(const struct nfs_client *clp) 329 334 { 330 335 return clp->cl_cons_state <= NFS_CS_READY; 331 336 } 337 + EXPORT_SYMBOL_GPL(nfs_client_init_is_complete); 338 + 339 + /* 340 + * Return 0 if @clp was successfully initialized, -errno otherwise. 341 + * 342 + * This must be called *after* nfs_client_init_is_complete() returns true, 343 + * otherwise it will pop WARN_ON_ONCE and return -EINVAL 344 + */ 345 + int nfs_client_init_status(const struct nfs_client *clp) 346 + { 347 + /* called without checking nfs_client_init_is_complete */ 348 + if (clp->cl_cons_state > NFS_CS_READY) { 349 + WARN_ON_ONCE(1); 350 + return -EINVAL; 351 + } 352 + return clp->cl_cons_state; 353 + } 354 + EXPORT_SYMBOL_GPL(nfs_client_init_status); 332 355 333 356 int nfs_wait_client_init_complete(const struct nfs_client *clp) 334 357 {
+7 -1
fs/nfs/filelayout/filelayoutdev.c
··· 266 266 struct nfs4_deviceid_node *devid = FILELAYOUT_DEVID_NODE(lseg); 267 267 struct nfs4_pnfs_ds *ret = ds; 268 268 struct nfs_server *s = NFS_SERVER(lseg->pls_layout->plh_inode); 269 + int status; 269 270 270 271 if (ds == NULL) { 271 272 printk(KERN_ERR "NFS: %s: No data server for offset index %d\n", ··· 278 277 if (ds->ds_clp) 279 278 goto out_test_devid; 280 279 281 - nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, 280 + status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, 282 281 dataserver_retrans, 4, 283 282 s->nfs_client->cl_minorversion); 283 + if (status) { 284 + nfs4_mark_deviceid_unavailable(devid); 285 + ret = NULL; 286 + goto out; 287 + } 284 288 285 289 out_test_devid: 286 290 if (ret->ds_clp == NULL ||
+13 -1
fs/nfs/flexfilelayout/flexfilelayout.h
··· 175 175 static inline bool 176 176 ff_layout_test_devid_unavailable(struct nfs4_deviceid_node *node) 177 177 { 178 - return nfs4_test_deviceid_unavailable(node); 178 + /* 179 + * Flexfiles should never mark a DS unavailable, but if it does 180 + * print a (ratelimited) warning as this can affect performance. 181 + */ 182 + if (nfs4_test_deviceid_unavailable(node)) { 183 + u32 *p = (u32 *)node->deviceid.data; 184 + 185 + pr_warn_ratelimited("NFS: flexfiles layout referencing an " 186 + "unavailable device [%x%x%x%x]\n", 187 + p[0], p[1], p[2], p[3]); 188 + return true; 189 + } 190 + return false; 179 191 } 180 192 181 193 static inline int
+3 -2
fs/nfs/flexfilelayout/flexfilelayoutdev.c
··· 384 384 struct inode *ino = lseg->pls_layout->plh_inode; 385 385 struct nfs_server *s = NFS_SERVER(ino); 386 386 unsigned int max_payload; 387 + int status; 387 388 388 389 if (!ff_layout_mirror_valid(lseg, mirror, true)) { 389 390 pr_err_ratelimited("NFS: %s: No data server for offset index %d\n", ··· 405 404 /* FIXME: For now we assume the server sent only one version of NFS 406 405 * to use for the DS. 407 406 */ 408 - nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, 407 + status = nfs4_pnfs_ds_connect(s, ds, devid, dataserver_timeo, 409 408 dataserver_retrans, 410 409 mirror->mirror_ds->ds_versions[0].version, 411 410 mirror->mirror_ds->ds_versions[0].minor_version); ··· 421 420 mirror->mirror_ds->ds_versions[0].wsize = max_payload; 422 421 goto out; 423 422 } 423 + out_fail: 424 424 ff_layout_track_ds_error(FF_LAYOUT_FROM_HDR(lseg->pls_layout), 425 425 mirror, lseg->pls_range.offset, 426 426 lseg->pls_range.length, NFS4ERR_NXIO, 427 427 OP_ILLEGAL, GFP_NOIO); 428 - out_fail: 429 428 if (fail_return || !ff_layout_has_available_ds(lseg)) 430 429 pnfs_error_mark_layout_for_return(ino, lseg); 431 430 ds = NULL;
+2
fs/nfs/internal.h
··· 186 186 struct nfs_fh *, 187 187 struct nfs_fattr *, 188 188 rpc_authflavor_t); 189 + extern bool nfs_client_init_is_complete(const struct nfs_client *clp); 190 + extern int nfs_client_init_status(const struct nfs_client *clp); 189 191 extern int nfs_wait_client_init_complete(const struct nfs_client *clp); 190 192 extern void nfs_mark_client_ready(struct nfs_client *clp, int state); 191 193 extern struct nfs_client *nfs4_set_ds_client(struct nfs_server *mds_srv,
+2 -2
fs/nfs/nfs4client.c
··· 1023 1023 server_resp_sz = sess->fc_attrs.max_resp_sz - nfs41_maxread_overhead; 1024 1024 server_rqst_sz = sess->fc_attrs.max_rqst_sz - nfs41_maxwrite_overhead; 1025 1025 1026 - if (server->rsize > server_resp_sz) 1026 + if (!server->rsize || server->rsize > server_resp_sz) 1027 1027 server->rsize = server_resp_sz; 1028 - if (server->wsize > server_rqst_sz) 1028 + if (!server->wsize || server->wsize > server_rqst_sz) 1029 1029 server->wsize = server_rqst_sz; 1030 1030 #endif /* CONFIG_NFS_V4_1 */ 1031 1031 }
+4 -7
fs/nfs/nfs4proc.c
··· 2258 2258 if ((mask & ~cache.mask & (MAY_READ | MAY_EXEC)) == 0) 2259 2259 return 0; 2260 2260 2261 - /* even though OPEN succeeded, access is denied. Close the file */ 2262 - nfs4_close_state(state, fmode); 2263 2261 return -EACCES; 2264 2262 } 2265 2263 ··· 7425 7427 struct nfs41_exchange_id_data *cdata = 7426 7428 (struct nfs41_exchange_id_data *)data; 7427 7429 7428 - nfs_put_client(cdata->args.client); 7429 7430 if (cdata->xprt) { 7430 7431 xprt_put(cdata->xprt); 7431 7432 rpc_clnt_xprt_switch_put(cdata->args.client->cl_rpcclient); 7432 7433 } 7434 + nfs_put_client(cdata->args.client); 7433 7435 kfree(cdata->res.impl_id); 7434 7436 kfree(cdata->res.server_scope); 7435 7437 kfree(cdata->res.server_owner); ··· 7536 7538 task_setup_data.callback_data = calldata; 7537 7539 7538 7540 task = rpc_run_task(&task_setup_data); 7539 - if (IS_ERR(task)) { 7540 - status = PTR_ERR(task); 7541 - goto out_impl_id; 7542 - } 7541 + if (IS_ERR(task)) 7542 + return PTR_ERR(task); 7543 7543 7544 7544 if (!xprt) { 7545 7545 status = rpc_wait_for_completion_task(task); ··· 7565 7569 kfree(calldata->res.server_owner); 7566 7570 out_calldata: 7567 7571 kfree(calldata); 7572 + nfs_put_client(clp); 7568 7573 goto out; 7569 7574 } 7570 7575
+1 -1
fs/nfs/nfs4xdr.c
··· 3942 3942 if (len <= 0) 3943 3943 goto out; 3944 3944 dprintk("%s: name=%s\n", __func__, group_name->data); 3945 - return NFS_ATTR_FATTR_OWNER_NAME; 3945 + return NFS_ATTR_FATTR_GROUP_NAME; 3946 3946 } else { 3947 3947 len = xdr_stream_decode_opaque_inline(xdr, (void **)&p, 3948 3948 XDR_MAX_NETOBJ);
+1 -1
fs/nfs/pnfs.h
··· 367 367 struct nfs4_pnfs_ds *nfs4_pnfs_ds_add(struct list_head *dsaddrs, 368 368 gfp_t gfp_flags); 369 369 void nfs4_pnfs_v3_ds_connect_unload(void); 370 - void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, 370 + int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, 371 371 struct nfs4_deviceid_node *devid, unsigned int timeo, 372 372 unsigned int retrans, u32 version, u32 minor_version); 373 373 struct nfs4_pnfs_ds_addr *nfs4_decode_mp_ds_addr(struct net *net,
+25 -6
fs/nfs/pnfs_nfs.c
··· 745 745 /* 746 746 * Create an rpc connection to the nfs4_pnfs_ds data server. 747 747 * Currently only supports IPv4 and IPv6 addresses. 748 - * If connection fails, make devid unavailable. 748 + * If connection fails, make devid unavailable and return a -errno. 749 749 */ 750 - void nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, 750 + int nfs4_pnfs_ds_connect(struct nfs_server *mds_srv, struct nfs4_pnfs_ds *ds, 751 751 struct nfs4_deviceid_node *devid, unsigned int timeo, 752 752 unsigned int retrans, u32 version, u32 minor_version) 753 753 { 754 - if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { 755 - int err = 0; 754 + int err; 756 755 756 + again: 757 + err = 0; 758 + if (test_and_set_bit(NFS4DS_CONNECTING, &ds->ds_state) == 0) { 757 759 if (version == 3) { 758 760 err = _nfs4_pnfs_v3_ds_connect(mds_srv, ds, timeo, 759 761 retrans); ··· 768 766 err = -EPROTONOSUPPORT; 769 767 } 770 768 771 - if (err) 772 - nfs4_mark_deviceid_unavailable(devid); 773 769 nfs4_clear_ds_conn_bit(ds); 774 770 } else { 775 771 nfs4_wait_ds_connect(ds); 772 + 773 + /* what was waited on didn't connect AND didn't mark unavail */ 774 + if (!ds->ds_clp && !nfs4_test_deviceid_unavailable(devid)) 775 + goto again; 776 776 } 777 + 778 + /* 779 + * At this point the ds->ds_clp should be ready, but it might have 780 + * hit an error. 781 + */ 782 + if (!err) { 783 + if (!ds->ds_clp || !nfs_client_init_is_complete(ds->ds_clp)) { 784 + WARN_ON_ONCE(ds->ds_clp || 785 + !nfs4_test_deviceid_unavailable(devid)); 786 + return -EINVAL; 787 + } 788 + err = nfs_client_init_status(ds->ds_clp); 789 + } 790 + 791 + return err; 777 792 } 778 793 EXPORT_SYMBOL_GPL(nfs4_pnfs_ds_connect); 779 794
+4 -2
fs/nfs/write.c
··· 1784 1784 (long long)req_offset(req)); 1785 1785 if (status < 0) { 1786 1786 nfs_context_set_write_error(req->wb_context, status); 1787 - nfs_inode_remove_request(req); 1787 + if (req->wb_page) 1788 + nfs_inode_remove_request(req); 1788 1789 dprintk_cont(", error = %d\n", status); 1789 1790 goto next; 1790 1791 } ··· 1794 1793 * returned by the server against all stored verfs. */ 1795 1794 if (!nfs_write_verifier_cmp(&req->wb_verf, &data->verf.verifier)) { 1796 1795 /* We have a match */ 1797 - nfs_inode_remove_request(req); 1796 + if (req->wb_page) 1797 + nfs_inode_remove_request(req); 1798 1798 dprintk_cont(" OK\n"); 1799 1799 goto next; 1800 1800 }
+2 -1
net/sunrpc/xprtrdma/verbs.c
··· 503 503 struct ib_cq *sendcq, *recvcq; 504 504 int rc; 505 505 506 - max_sge = min(ia->ri_device->attrs.max_sge, RPCRDMA_MAX_SEND_SGES); 506 + max_sge = min_t(unsigned int, ia->ri_device->attrs.max_sge, 507 + RPCRDMA_MAX_SEND_SGES); 507 508 if (max_sge < RPCRDMA_MIN_SEND_SGES) { 508 509 pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge); 509 510 return -ENOMEM;