diff options
Diffstat (limited to 'fs/nfs/objlayout/objio_osd.c')
| -rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 55 | 
1 files changed, 52 insertions, 3 deletions
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index f50d3e8d6f2..ea6d111b03e 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c @@ -570,17 +570,66 @@ static bool objio_pg_test(struct nfs_pageio_descriptor *pgio,  		return false;  	return pgio->pg_count + req->wb_bytes <= -			OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; +			(unsigned long)pgio->pg_layout_private; +} + +void objio_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) +{ +	pnfs_generic_pg_init_read(pgio, req); +	if (unlikely(pgio->pg_lseg == NULL)) +		return; /* Not pNFS */ + +	pgio->pg_layout_private = (void *) +				OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; +} + +static bool aligned_on_raid_stripe(u64 offset, struct ore_layout *layout, +				   unsigned long *stripe_end) +{ +	u32 stripe_off; +	unsigned stripe_size; + +	if (layout->raid_algorithm == PNFS_OSD_RAID_0) +		return true; + +	stripe_size = layout->stripe_unit * +				(layout->group_width - layout->parity); + +	div_u64_rem(offset, stripe_size, &stripe_off); +	if (!stripe_off) +		return true; + +	*stripe_end = stripe_size - stripe_off; +	return false; +} + +void objio_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) +{ +	unsigned long stripe_end = 0; + +	pnfs_generic_pg_init_write(pgio, req); +	if (unlikely(pgio->pg_lseg == NULL)) +		return; /* Not pNFS */ + +	if (req->wb_offset || +	    !aligned_on_raid_stripe(req->wb_index * PAGE_SIZE, +			       &OBJIO_LSEG(pgio->pg_lseg)->layout, +			       &stripe_end)) { +		pgio->pg_layout_private = (void *)stripe_end; +	} else { +		pgio->pg_layout_private = (void *) +				OBJIO_LSEG(pgio->pg_lseg)->layout.max_io_length; +	}  }  static const struct nfs_pageio_ops objio_pg_read_ops = { -	.pg_init = pnfs_generic_pg_init_read, +	.pg_init = objio_init_read,  	.pg_test = objio_pg_test,  	.pg_doio = pnfs_generic_pg_readpages,  };  static const struct nfs_pageio_ops objio_pg_write_ops = { -	.pg_init = pnfs_generic_pg_init_write, +	.pg_init = objio_init_write,  	.pg_test = objio_pg_test,  	.pg_doio = pnfs_generic_pg_writepages,  };  |