pNFS: Ensure we check layout segment validity in the pg_init() callback
If we have a layout segment cached in pgio->pg_lseg, we should check it for validity before reusing it in a new RPC request. Otherwise, if we recoalesce, we can end up looping forever. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
This commit is contained in:
parent
f30cb757f6
commit
b3230e80a6
|
@ -933,6 +933,7 @@ static void
|
|||
filelayout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req)
|
||||
{
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
if (!pgio->pg_lseg) {
|
||||
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
|
||||
req->wb_context,
|
||||
|
@ -959,6 +960,7 @@ filelayout_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
|||
struct nfs_commit_info cinfo;
|
||||
int status;
|
||||
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
if (!pgio->pg_lseg) {
|
||||
pgio->pg_lseg = fl_pnfs_update_layout(pgio->pg_inode,
|
||||
req->wb_context,
|
||||
|
|
|
@ -846,6 +846,7 @@ ff_layout_pg_init_read(struct nfs_pageio_descriptor *pgio,
|
|||
int ds_idx;
|
||||
|
||||
retry:
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
/* Use full layout for now */
|
||||
if (!pgio->pg_lseg)
|
||||
ff_layout_pg_get_read(pgio, req, false);
|
||||
|
@ -894,6 +895,7 @@ ff_layout_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
|||
int status;
|
||||
|
||||
retry:
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
if (!pgio->pg_lseg) {
|
||||
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
|
||||
req->wb_context,
|
||||
|
|
|
@ -2072,11 +2072,23 @@ void pnfs_error_mark_layout_for_return(struct inode *inode,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_error_mark_layout_for_return);
|
||||
|
||||
void
|
||||
pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio)
|
||||
{
|
||||
if (pgio->pg_lseg == NULL ||
|
||||
test_bit(NFS_LSEG_VALID, &pgio->pg_lseg->pls_flags))
|
||||
return;
|
||||
pnfs_put_lseg(pgio->pg_lseg);
|
||||
pgio->pg_lseg = NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pnfs_generic_pg_check_layout);
|
||||
|
||||
void
|
||||
pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
|
||||
{
|
||||
u64 rd_size = req->wb_bytes;
|
||||
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
if (pgio->pg_lseg == NULL) {
|
||||
if (pgio->pg_dreq == NULL)
|
||||
rd_size = i_size_read(pgio->pg_inode) - req_offset(req);
|
||||
|
@ -2107,6 +2119,7 @@ void
|
|||
pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
struct nfs_page *req, u64 wb_size)
|
||||
{
|
||||
pnfs_generic_pg_check_layout(pgio);
|
||||
if (pgio->pg_lseg == NULL) {
|
||||
pgio->pg_lseg = pnfs_update_layout(pgio->pg_inode,
|
||||
req->wb_context,
|
||||
|
|
|
@ -234,6 +234,7 @@ void pnfs_put_lseg_locked(struct pnfs_layout_segment *lseg);
|
|||
|
||||
void set_pnfs_layoutdriver(struct nfs_server *, const struct nfs_fh *, struct nfs_fsinfo *);
|
||||
void unset_pnfs_layoutdriver(struct nfs_server *);
|
||||
void pnfs_generic_pg_check_layout(struct nfs_pageio_descriptor *pgio);
|
||||
void pnfs_generic_pg_init_read(struct nfs_pageio_descriptor *, struct nfs_page *);
|
||||
int pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc);
|
||||
void pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio,
|
||||
|
|
Loading…
Reference in New Issue