提交 5a683ee2 编写于 作者: T Trond Myklebust 提交者: Yang Yingliang

NFS/pnfs: Fix pnfs_generic_prepare_to_resend_writes()

stable inclusion
from linux-4.19.104
commit 056d1656704016990311ecae5a751c91942192c8

--------------------------------

commit 221203ce upstream.

Instead of making assumptions about the commit verifier contents, change
the commit code to ensure we always check that the verifier was set
by the XDR code.

Fixes: f54bcf2e ("pnfs: Prepare for flexfiles by pulling out common code")
Signed-off-by: NTrond Myklebust <trond.myklebust@hammerspace.com>
Signed-off-by: NAnna Schumaker <Anna.Schumaker@Netapp.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Reviewed-by: NHou Tao <houtao1@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
上级 2af9d671
...@@ -261,10 +261,10 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq, ...@@ -261,10 +261,10 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq,
data->ds_commit_index); data->ds_commit_index);
/* verifier not set so always fail */ /* verifier not set so always fail */
if (verfp->committed < 0) if (verfp->committed < 0 || data->res.verf->committed <= NFS_UNSTABLE)
return 1; return 1;
return nfs_direct_cmp_verf(verfp, &data->verf); return nfs_direct_cmp_verf(verfp, data->res.verf);
} }
/** /**
......
...@@ -2381,6 +2381,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, ...@@ -2381,6 +2381,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
void *data) void *data)
{ {
struct nfs_commitres *result = data; struct nfs_commitres *result = data;
struct nfs_writeverf *verf = result->verf;
enum nfs_stat status; enum nfs_stat status;
int error; int error;
...@@ -2393,7 +2394,9 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, ...@@ -2393,7 +2394,9 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
result->op_status = status; result->op_status = status;
if (status != NFS3_OK) if (status != NFS3_OK)
goto out_status; goto out_status;
error = decode_writeverf3(xdr, &result->verf->verifier); error = decode_writeverf3(xdr, &verf->verifier);
if (!error)
verf->committed = NFS_FILE_SYNC;
out: out:
return error; return error;
out_status: out_status:
......
...@@ -4443,11 +4443,14 @@ static int decode_write_verifier(struct xdr_stream *xdr, struct nfs_write_verifi ...@@ -4443,11 +4443,14 @@ static int decode_write_verifier(struct xdr_stream *xdr, struct nfs_write_verifi
static int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res) static int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res)
{ {
struct nfs_writeverf *verf = res->verf;
int status; int status;
status = decode_op_hdr(xdr, OP_COMMIT); status = decode_op_hdr(xdr, OP_COMMIT);
if (!status) if (!status)
status = decode_write_verifier(xdr, &res->verf->verifier); status = decode_write_verifier(xdr, &verf->verifier);
if (!status)
verf->committed = NFS_FILE_SYNC;
return status; return status;
} }
......
...@@ -30,12 +30,11 @@ EXPORT_SYMBOL_GPL(pnfs_generic_rw_release); ...@@ -30,12 +30,11 @@ EXPORT_SYMBOL_GPL(pnfs_generic_rw_release);
/* Fake up some data that will cause nfs_commit_release to retry the writes. */ /* Fake up some data that will cause nfs_commit_release to retry the writes. */
void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data) void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data)
{ {
struct nfs_page *first = nfs_list_entry(data->pages.next); struct nfs_writeverf *verf = data->res.verf;
data->task.tk_status = 0; data->task.tk_status = 0;
memcpy(&data->verf.verifier, &first->wb_verf, memset(&verf->verifier, 0, sizeof(verf->verifier));
sizeof(data->verf.verifier)); verf->committed = NFS_UNSTABLE;
data->verf.verifier.data[0]++; /* ensure verifier mismatch */
} }
EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes); EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes);
......
...@@ -1821,6 +1821,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata) ...@@ -1821,6 +1821,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
static void nfs_commit_release_pages(struct nfs_commit_data *data) static void nfs_commit_release_pages(struct nfs_commit_data *data)
{ {
const struct nfs_writeverf *verf = data->res.verf;
struct nfs_page *req; struct nfs_page *req;
int status = data->task.tk_status; int status = data->task.tk_status;
struct nfs_commit_info cinfo; struct nfs_commit_info cinfo;
...@@ -1847,7 +1848,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data) ...@@ -1847,7 +1848,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
/* Okay, COMMIT succeeded, apparently. Check the verifier /* Okay, COMMIT succeeded, apparently. Check the verifier
* returned by the server against all stored verfs. */ * returned by the server against all stored verfs. */
if (!nfs_write_verifier_cmp(&req->wb_verf, &data->verf.verifier)) { if (verf->committed > NFS_UNSTABLE &&
!nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier)) {
/* We have a match */ /* We have a match */
if (req->wb_page) if (req->wb_page)
nfs_inode_remove_request(req); nfs_inode_remove_request(req);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册