forked from Minki/linux
NFS client bugfixes for Linux 4.3
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 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJWFIgBAAoJEGcL54qWCgDy3qwQAJrMvwiO0shZe9+PsUZcDIhw 1CnDmWYafJmpNGK+YEZatI+tdR9pwSYXdfiCGj/Ijfvl1PXUgyVAmNARAB9oFUza DVvZjqJ6aiFzeawGC8f2IfwY4XcAy4+BIZOiwp2JafepRnoSgZl24olKbO4cQ7UD i5IaDrYYvAxefsUoRogEF19H1y8zC1yUA2aDKrriV6A9rEZSbaZLRfS8BHppXBjY w0OP74neD4rnn/rL0YDEdsjiI17W7QwoMk05yzOJH3wQt/Y4Ll/lwLO4y3URpIGF wzHzMIeggGPPEM9e1JixPc3Y9F9kCHW8YjGJ3xxY2C6q8vt7dzpaVhh10AxycZtZ gcbepjMhoL7gJqu5DQ/0S86Sb5jNaL0KlUDsEnqtOfe3/UiyTJ/f57TMfdscm+wI pdyFFtxUHcFueO1a2XuEOuSIUFzFuwIQ2aiHlbu90ev04dd7dqzU0PffhRlzu3tJ 8+ZHQMbSmotUmhxlpI+VA4rG0JUsaLY09chH5r0NvsXm0LR+z3vX7Q6oONN7IBDv 5hULj4ecB69smBv+FjQyVUAu0LiahINAGu0p0wEjTdBwFMic5qpVVfhTs8qrkGRZ M8RYrANtVhY17fJf5WF7Wyt58icAWRKDHslGdzUav+2VFBfNK1ZeG+QhYYqDNF5k SkJsG4iCIN9JazwqfqJI =aoNS -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
a0eeb8dd34
@ -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);
|
||||||
|
@ -1725,7 +1725,8 @@ restart:
|
|||||||
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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -755,19 +755,22 @@ rpcrdma_ep_destroy(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
|
|||||||
|
|
||||||
cancel_delayed_work_sync(&ep->rep_connect_worker);
|
cancel_delayed_work_sync(&ep->rep_connect_worker);
|
||||||
|
|
||||||
if (ia->ri_id->qp) {
|
if (ia->ri_id->qp)
|
||||||
rpcrdma_ep_disconnect(ep, ia);
|
rpcrdma_ep_disconnect(ep, ia);
|
||||||
|
|
||||||
|
rpcrdma_clean_cq(ep->rep_attr.recv_cq);
|
||||||
|
rpcrdma_clean_cq(ep->rep_attr.send_cq);
|
||||||
|
|
||||||
|
if (ia->ri_id->qp) {
|
||||||
rdma_destroy_qp(ia->ri_id);
|
rdma_destroy_qp(ia->ri_id);
|
||||||
ia->ri_id->qp = NULL;
|
ia->ri_id->qp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpcrdma_clean_cq(ep->rep_attr.recv_cq);
|
|
||||||
rc = ib_destroy_cq(ep->rep_attr.recv_cq);
|
rc = ib_destroy_cq(ep->rep_attr.recv_cq);
|
||||||
if (rc)
|
if (rc)
|
||||||
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
||||||
__func__, rc);
|
__func__, rc);
|
||||||
|
|
||||||
rpcrdma_clean_cq(ep->rep_attr.send_cq);
|
|
||||||
rc = ib_destroy_cq(ep->rep_attr.send_cq);
|
rc = ib_destroy_cq(ep->rep_attr.send_cq);
|
||||||
if (rc)
|
if (rc)
|
||||||
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
dprintk("RPC: %s: ib_destroy_cq returned %i\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user