Skip to content

Commit a0eeb8d

Browse files
committed
Merge tag 'nfs-for-4.3-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
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
2 parents 00a3d66 + 39d0d3b commit a0eeb8d

File tree

6 files changed

+30
-15
lines changed

6 files changed

+30
-15
lines changed

fs/nfs/nfs4proc.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1458,12 +1458,18 @@ nfs4_opendata_check_deleg(struct nfs4_opendata *data, struct nfs4_state *state)
14581458
if (delegation)
14591459
delegation_flags = delegation->flags;
14601460
rcu_read_unlock();
1461-
if (data->o_arg.claim == NFS4_OPEN_CLAIM_DELEGATE_CUR) {
1461+
switch (data->o_arg.claim) {
1462+
default:
1463+
break;
1464+
case NFS4_OPEN_CLAIM_DELEGATE_CUR:
1465+
case NFS4_OPEN_CLAIM_DELEG_CUR_FH:
14621466
pr_err_ratelimited("NFS: Broken NFSv4 server %s is "
14631467
"returning a delegation for "
14641468
"OPEN(CLAIM_DELEGATE_CUR)\n",
14651469
clp->cl_hostname);
1466-
} else if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
1470+
return;
1471+
}
1472+
if ((delegation_flags & 1UL<<NFS_DELEGATION_NEED_RECLAIM) == 0)
14671473
nfs_inode_set_delegation(state->inode,
14681474
data->owner->so_cred,
14691475
&data->o_res);
@@ -1771,6 +1777,9 @@ int nfs4_open_delegation_recall(struct nfs_open_context *ctx,
17711777
if (IS_ERR(opendata))
17721778
return PTR_ERR(opendata);
17731779
nfs4_stateid_copy(&opendata->o_arg.u.delegation, stateid);
1780+
write_seqlock(&state->seqlock);
1781+
nfs4_stateid_copy(&state->stateid, &state->open_stateid);
1782+
write_sequnlock(&state->seqlock);
17741783
clear_bit(NFS_DELEGATED_STATE, &state->flags);
17751784
switch (type & (FMODE_READ|FMODE_WRITE)) {
17761785
case FMODE_READ|FMODE_WRITE:
@@ -1863,6 +1872,8 @@ static int _nfs4_proc_open_confirm(struct nfs4_opendata *data)
18631872
data->rpc_done = 0;
18641873
data->rpc_status = 0;
18651874
data->timestamp = jiffies;
1875+
if (data->is_recover)
1876+
nfs4_set_sequence_privileged(&data->c_arg.seq_args);
18661877
task = rpc_run_task(&task_setup_data);
18671878
if (IS_ERR(task))
18681879
return PTR_ERR(task);

fs/nfs/nfs4state.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1725,7 +1725,8 @@ static int nfs4_do_reclaim(struct nfs_client *clp, const struct nfs4_state_recov
17251725
if (!test_and_clear_bit(ops->owner_flag_bit,
17261726
&sp->so_flags))
17271727
continue;
1728-
atomic_inc(&sp->so_count);
1728+
if (!atomic_inc_not_zero(&sp->so_count))
1729+
continue;
17291730
spin_unlock(&clp->cl_lock);
17301731
rcu_read_unlock();
17311732

fs/nfs/nfs4trace.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ DECLARE_EVENT_CLASS(nfs4_open_event,
409409
__entry->flags = flags;
410410
__entry->fmode = (__force unsigned int)ctx->mode;
411411
__entry->dev = ctx->dentry->d_sb->s_dev;
412-
if (!IS_ERR(state))
412+
if (!IS_ERR_OR_NULL(state))
413413
inode = state->inode;
414414
if (inode != NULL) {
415415
__entry->fileid = NFS_FILEID(inode);

fs/nfs/write.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -569,19 +569,17 @@ static int nfs_page_async_flush(struct nfs_pageio_descriptor *pgio,
569569
if (!nfs_pageio_add_request(pgio, req)) {
570570
nfs_redirty_request(req);
571571
ret = pgio->pg_error;
572-
}
572+
} else
573+
nfs_add_stats(page_file_mapping(page)->host,
574+
NFSIOS_WRITEPAGES, 1);
573575
out:
574576
return ret;
575577
}
576578

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

582-
nfs_inc_stats(inode, NFSIOS_VFSWRITEPAGE);
583-
nfs_add_stats(inode, NFSIOS_WRITEPAGES, 1);
584-
585583
nfs_pageio_cond_complete(pgio, page_file_index(page));
586584
ret = nfs_page_async_flush(pgio, page, wbc->sync_mode == WB_SYNC_NONE);
587585
if (ret == -EAGAIN) {
@@ -597,9 +595,11 @@ static int nfs_do_writepage(struct page *page, struct writeback_control *wbc, st
597595
static int nfs_writepage_locked(struct page *page, struct writeback_control *wbc)
598596
{
599597
struct nfs_pageio_descriptor pgio;
598+
struct inode *inode = page_file_mapping(page)->host;
600599
int err;
601600

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

12281228
/* Check to see if there are whole file write locks */
12291229
ret = 0;

net/sunrpc/xprtrdma/transport.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,8 +270,8 @@ xprt_rdma_destroy(struct rpc_xprt *xprt)
270270

271271
xprt_clear_connected(xprt);
272272

273-
rpcrdma_buffer_destroy(&r_xprt->rx_buf);
274273
rpcrdma_ep_destroy(&r_xprt->rx_ep, &r_xprt->rx_ia);
274+
rpcrdma_buffer_destroy(&r_xprt->rx_buf);
275275
rpcrdma_ia_close(&r_xprt->rx_ia);
276276

277277
xprt_rdma_free_addresses(xprt);

net/sunrpc/xprtrdma/verbs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -755,19 +755,22 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
755755

756756
cancel_delayed_work_sync(&ep->rep_connect_worker);
757757

758-
if (ia->ri_id->qp) {
758+
if (ia->ri_id->qp)
759759
rpcrdma_ep_disconnect(ep, ia);
760+
761+
rpcrdma_clean_cq(ep->rep_attr.recv_cq);
762+
rpcrdma_clean_cq(ep->rep_attr.send_cq);
763+
764+
if (ia->ri_id->qp) {
760765
rdma_destroy_qp(ia->ri_id);
761766
ia->ri_id->qp = NULL;
762767
}
763768

764-
rpcrdma_clean_cq(ep->rep_attr.recv_cq);
765769
rc = ib_destroy_cq(ep->rep_attr.recv_cq);
766770
if (rc)
767771
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
768772
__func__, rc);
769773

770-
rpcrdma_clean_cq(ep->rep_attr.send_cq);
771774
rc = ib_destroy_cq(ep->rep_attr.send_cq);
772775
if (rc)
773776
dprintk("RPC: %s: ib_destroy_cq returned %i\n",

0 commit comments

Comments
 (0)