Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0eeb8dd authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull NFS client bugfixes from Trond Myklebust:
 "Highlights include:

  Bugfixes:
   - Fix a use-after-free bug in the RPC/RDMA client
   - Fix a write performance regression
   - Fix up page writeback accounting
   - Don't try to reclaim unused state owners
   - Fix a NFSv4 nograce recovery hang
   - reset states to use open_stateid when returning delegation
     voluntarily
   - Fix a tracepoint NULL-pointer dereference"

* tag 'nfs-for-4.3-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFS: Fix a tracepoint NULL-pointer dereference
  nfs4: reset states to use open_stateid when returning delegation voluntarily
  NFSv4: Fix a nograce recovery hang
  NFSv4.1: nfs4_opendata_check_deleg needs to handle NFS4_OPEN_CLAIM_DELEG_CUR_FH
  NFSv4: Don't try to reclaim unused state owners
  NFS: Fix a write performance regression
  NFS: Fix up page writeback accounting
  xprtrdma: disconnect and flush cqs before freeing buffers
parents 00a3d660 39d0d3bd
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
@@ -1458,12 +1458,18 @@ nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
	if (delegation)
	if (delegation)
		delegation_flags = delegation->flags;
		delegation_flags = delegation->flags;
	rcu_read_unlock();
	rcu_read_unlock();
	if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
	switch (data->o_arg.claim) {
	default:
		break;
	case NFS4_OPEN_CLAIM_DELEGATE_CUR:
	case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
		pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
		pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
				   "returning a delegation for "
				   "returning a delegation for "
				   "OPEN(CLAIM_DELEGATE_CUR)\n",
				   "OPEN(CLAIM_DELEGATE_CUR)\n",
				   clp->cl_hostname);
				   clp->cl_hostname);
	} else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
		return;
	}
	if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
		nfs_inode_set_delegation(state->inode,
		nfs_inode_set_delegation(state->inode,
					 data->owner->so_cred,
					 data->owner->so_cred,
					 &data->o_res);
					 &data->o_res);
@@ -1771,6 +1777,9 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
	if (IS_ERR(opendata))
	if (IS_ERR(opendata))
		return PTR_ERR(opendata);
		return PTR_ERR(opendata);
	nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
	nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
	write_seqlock(&state->seqlock);
	nfs4_stateid_copy(&state->stateid, &state->open_stateid);
	write_sequnlock(&state->seqlock);
	clear_bit(NFS_DELEGATED_STATE, &state->flags);
	clear_bit(NFS_DELEGATED_STATE, &state->flags);
	switch (type & (FMODE_READ|FMODE_WRITE)) {
	switch (type & (FMODE_READ|FMODE_WRITE)) {
	case FMODE_READ|FMODE_WRITE:
	case FMODE_READ|FMODE_WRITE:
@@ -1863,6 +1872,8 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
	data->rpc_done = 0;
	data->rpc_done = 0;
	data->rpc_status = 0;
	data->rpc_status = 0;
	data->timestamp = jiffies;
	data->timestamp = jiffies;
	if (data->is_recover)
		nfs4_set_sequence_privileged(&data->c_arg.seq_args);
	task = rpc_run_task(&task_setup_data);
	task = rpc_run_task(&task_setup_data);
	if (IS_ERR(task))
	if (IS_ERR(task))
		return PTR_ERR(task);
		return PTR_ERR(task);
+2 −1
Original line number Original line Diff line number Diff line
@@ -1725,7 +1725,8 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov
			if (!test_and_clear_bit(ops->owner_flag_bit,
			if (!test_and_clear_bit(ops->owner_flag_bit,
							&sp->so_flags))
							&sp->so_flags))
				continue;
				continue;
			atomic_inc(&sp->so_count);
			if (!atomic_inc_not_zero(&sp->so_count))
				continue;
			spin_unlock(&clp->cl_lock);
			spin_unlock(&clp->cl_lock);
			rcu_read_unlock();
			rcu_read_unlock();


+1 −1
Original line number Original line Diff line number Diff line
@@ -409,7 +409,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
			__entry->flags = flags;
			__entry->flags = flags;
			__entry->fmode = (__force unsigned int)ctx->mode;
			__entry->fmode = (__force unsigned int)ctx->mode;
			__entry->dev = ctx->dentry->d_sb->s_dev;
			__entry->dev = ctx->dentry->d_sb->s_dev;
			if (!IS_ERR(state))
			if (!IS_ERR_OR_NULL(state))
				inode = state->inode;
				inode = state->inode;
			if (inode != NULL) {
			if (inode != NULL) {
				__entry->fileid = NFS_FILEID(inode);
				__entry->fileid = NFS_FILEID(inode);
+7 −7
Original line number Original line Diff line number Diff line
@@ -569,19 +569,17 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
	if (!nfs_pageio_add_request(pgio, req)) {
	if (!nfs_pageio_add_request(pgio, req)) {
		nfs_redirty_request(req);
		nfs_redirty_request(req);
		ret = pgio->pg_error;
		ret = pgio->pg_error;
	}
	} else
		nfs_add_stats(page_file_mapping(page)->host,
				NFSIOS_WRITEPAGES, 1);
out:
out:
	return ret;
	return ret;
}
}


static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio)
static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, struct nfs_pageio_descriptor *pgio)
{
{
	struct inode *inode = page_file_mapping(page)->host;
	int ret;
	int ret;


	nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
	nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);

	nfs_pageio_cond_complete(pgio, page_file_index(page));
	nfs_pageio_cond_complete(pgio, page_file_index(page));
	ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE);
	ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE);
	if (ret == -EAGAIN) {
	if (ret == -EAGAIN) {
@@ -597,9 +595,11 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st
static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc)
static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc)
{
{
	struct nfs_pageio_descriptor pgio;
	struct nfs_pageio_descriptor pgio;
	struct inode *inode = page_file_mapping(page)->host;
	int err;
	int err;


	nfs_pageio_init_write(&pgio, page->mapping->host, wb_priority(wbc),
	nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
	nfs_pageio_init_write(&pgio, inode, wb_priority(wbc),
				false, &nfs_async_write_completion_ops);
				false, &nfs_async_write_completion_ops);
	err = nfs_do_writepage(page, wbc, &pgio);
	err = nfs_do_writepage(page, wbc, &pgio);
	nfs_pageio_complete(&pgio);
	nfs_pageio_complete(&pgio);
@@ -1223,7 +1223,7 @@ static int nfs_can_extend_write(struct file *file, struct page *page, struct ino
		return 1;
		return 1;
	if (!flctx || (list_empty_careful(&flctx->flc_flock) &&
	if (!flctx || (list_empty_careful(&flctx->flc_flock) &&
		       list_empty_careful(&flctx->flc_posix)))
		       list_empty_careful(&flctx->flc_posix)))
		return 0;
		return 1;


	/* Check to see if there are whole file write locks */
	/* Check to see if there are whole file write locks */
	ret = 0;
	ret = 0;
+1 −1
Original line number Original line Diff line number Diff line
@@ -270,8 +270,8 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)


	xprt_clear_connected(xprt);
	xprt_clear_connected(xprt);


	rpcrdma_buffer_destroy(&r_xprt->rx_buf);
	rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
	rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
	rpcrdma_buffer_destroy(&r_xprt->rx_buf);
	rpcrdma_ia_close(&r_xprt->rx_ia);
	rpcrdma_ia_close(&r_xprt->rx_ia);


	xprt_rdma_free_addresses(xprt);
	xprt_rdma_free_addresses(xprt);
Loading