pnfs: release lseg in pnfs_generic_pg_cleanup
This is needed to support mirrored writes - the first write can't just trash the lseg, we need to keep it around until all mirrors have written. Signed-off-by: Weston Andros Adamson <dros@primarydata.com>
This commit is contained in:
		
							parent
							
								
									2176bf4269
								
							
						
					
					
						commit
						180bb5ec06
					
				| @ -860,12 +860,14 @@ static const struct nfs_pageio_ops bl_pg_read_ops = { | ||||
| 	.pg_init = bl_pg_init_read, | ||||
| 	.pg_test = bl_pg_test_read, | ||||
| 	.pg_doio = pnfs_generic_pg_readpages, | ||||
| 	.pg_cleanup = pnfs_generic_pg_cleanup, | ||||
| }; | ||||
| 
 | ||||
| static const struct nfs_pageio_ops bl_pg_write_ops = { | ||||
| 	.pg_init = bl_pg_init_write, | ||||
| 	.pg_test = bl_pg_test_write, | ||||
| 	.pg_doio = pnfs_generic_pg_writepages, | ||||
| 	.pg_cleanup = pnfs_generic_pg_cleanup, | ||||
| }; | ||||
| 
 | ||||
| static struct pnfs_layoutdriver_type blocklayout_type = { | ||||
|  | ||||
| @ -933,12 +933,14 @@ static const struct nfs_pageio_ops filelayout_pg_read_ops = { | ||||
| 	.pg_init = filelayout_pg_init_read, | ||||
| 	.pg_test = filelayout_pg_test, | ||||
| 	.pg_doio = pnfs_generic_pg_readpages, | ||||
| 	.pg_cleanup = pnfs_generic_pg_cleanup, | ||||
| }; | ||||
| 
 | ||||
| static const struct nfs_pageio_ops filelayout_pg_write_ops = { | ||||
| 	.pg_init = filelayout_pg_init_write, | ||||
| 	.pg_test = filelayout_pg_test, | ||||
| 	.pg_doio = pnfs_generic_pg_writepages, | ||||
| 	.pg_cleanup = pnfs_generic_pg_cleanup, | ||||
| }; | ||||
| 
 | ||||
| static u32 select_bucket_index(struct nfs4_filelayout_segment *fl, u32 j) | ||||
|  | ||||
| @ -607,12 +607,14 @@ static const struct nfs_pageio_ops objio_pg_read_ops = { | ||||
| 	.pg_init = objio_init_read, | ||||
| 	.pg_test = objio_pg_test, | ||||
| 	.pg_doio = pnfs_generic_pg_readpages, | ||||
| 	.pg_cleanup = pnfs_generic_pg_cleanup, | ||||
| }; | ||||
| 
 | ||||
| static const struct nfs_pageio_ops objio_pg_write_ops = { | ||||
| 	.pg_init = objio_init_write, | ||||
| 	.pg_test = objio_pg_test, | ||||
| 	.pg_doio = pnfs_generic_pg_writepages, | ||||
| 	.pg_cleanup = pnfs_generic_pg_cleanup, | ||||
| }; | ||||
| 
 | ||||
| static struct pnfs_layoutdriver_type objlayout_type = { | ||||
|  | ||||
| @ -1631,6 +1631,16 @@ pnfs_generic_pg_init_write(struct nfs_pageio_descriptor *pgio, | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(pnfs_generic_pg_init_write); | ||||
| 
 | ||||
| void | ||||
| pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *desc) | ||||
| { | ||||
| 	if (desc->pg_lseg) { | ||||
| 		pnfs_put_lseg(desc->pg_lseg); | ||||
| 		desc->pg_lseg = NULL; | ||||
| 	} | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(pnfs_generic_pg_cleanup); | ||||
| 
 | ||||
| /*
 | ||||
|  * Return 0 if @req cannot be coalesced into @pgio, otherwise return the number | ||||
|  * of bytes (maximum @req->wb_bytes) that can be coalesced. | ||||
| @ -1756,11 +1766,9 @@ pnfs_do_write(struct nfs_pageio_descriptor *desc, | ||||
| 	struct pnfs_layout_segment *lseg = desc->pg_lseg; | ||||
| 	enum pnfs_try_status trypnfs; | ||||
| 
 | ||||
| 	desc->pg_lseg = NULL; | ||||
| 	trypnfs = pnfs_try_to_write_data(hdr, call_ops, lseg, how); | ||||
| 	if (trypnfs == PNFS_NOT_ATTEMPTED) | ||||
| 		pnfs_write_through_mds(desc, hdr); | ||||
| 	pnfs_put_lseg(lseg); | ||||
| } | ||||
| 
 | ||||
| static void pnfs_writehdr_free(struct nfs_pgio_header *hdr) | ||||
| @ -1779,17 +1787,13 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | ||||
| 	hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); | ||||
| 	if (!hdr) { | ||||
| 		desc->pg_completion_ops->error_cleanup(&desc->pg_list); | ||||
| 		pnfs_put_lseg(desc->pg_lseg); | ||||
| 		desc->pg_lseg = NULL; | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	nfs_pgheader_init(desc, hdr, pnfs_writehdr_free); | ||||
| 
 | ||||
| 	hdr->lseg = pnfs_get_lseg(desc->pg_lseg); | ||||
| 	ret = nfs_generic_pgio(desc, hdr); | ||||
| 	if (ret != 0) { | ||||
| 		pnfs_put_lseg(desc->pg_lseg); | ||||
| 		desc->pg_lseg = NULL; | ||||
| 	} else | ||||
| 	if (!ret) | ||||
| 		pnfs_do_write(desc, hdr, desc->pg_ioflags); | ||||
| 	return ret; | ||||
| } | ||||
| @ -1874,11 +1878,9 @@ pnfs_do_read(struct nfs_pageio_descriptor *desc, struct nfs_pgio_header *hdr) | ||||
| 	struct pnfs_layout_segment *lseg = desc->pg_lseg; | ||||
| 	enum pnfs_try_status trypnfs; | ||||
| 
 | ||||
| 	desc->pg_lseg = NULL; | ||||
| 	trypnfs = pnfs_try_to_read_data(hdr, call_ops, lseg); | ||||
| 	if (trypnfs == PNFS_NOT_ATTEMPTED) | ||||
| 		pnfs_read_through_mds(desc, hdr); | ||||
| 	pnfs_put_lseg(lseg); | ||||
| } | ||||
| 
 | ||||
| static void pnfs_readhdr_free(struct nfs_pgio_header *hdr) | ||||
| @ -1897,18 +1899,12 @@ pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | ||||
| 	hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); | ||||
| 	if (!hdr) { | ||||
| 		desc->pg_completion_ops->error_cleanup(&desc->pg_list); | ||||
| 		ret = -ENOMEM; | ||||
| 		pnfs_put_lseg(desc->pg_lseg); | ||||
| 		desc->pg_lseg = NULL; | ||||
| 		return ret; | ||||
| 		return -ENOMEM; | ||||
| 	} | ||||
| 	nfs_pgheader_init(desc, hdr, pnfs_readhdr_free); | ||||
| 	hdr->lseg = pnfs_get_lseg(desc->pg_lseg); | ||||
| 	ret = nfs_generic_pgio(desc, hdr); | ||||
| 	if (ret != 0) { | ||||
| 		pnfs_put_lseg(desc->pg_lseg); | ||||
| 		desc->pg_lseg = NULL; | ||||
| 	} else | ||||
| 	if (!ret) | ||||
| 		pnfs_do_read(desc, hdr); | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| @ -230,6 +230,7 @@ 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, | ||||
| 			        struct nfs_page *req, u64 wb_size); | ||||
| void pnfs_generic_pg_cleanup(struct nfs_pageio_descriptor *); | ||||
| int pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc); | ||||
| size_t pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, | ||||
| 			    struct nfs_page *prev, struct nfs_page *req); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user