Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e1042ba0 authored by Boaz Harrosh's avatar Boaz Harrosh
Browse files

exofs: Add offset/length to exofs_get_io_state



In future raid code we will need to know the IO offset/length
and if it's a read or write to determine some of the array
sizes we'll need.

So add a new exofs_get_rw_state() API for use when
writeing/reading. All other simple cases are left using the
old way.

The major change to this is that now we need to call
exofs_get_io_state later at inode.c::read_exec and
inode.c::write_exec when we actually know these things. So this
patch is kept separate so I can test things apart from other
changes.

Signed-off-by: default avatarBoaz Harrosh <bharrosh@panasas.com>
parent 16f75bb3
Loading
Loading
Loading
Loading
+5 −1
Original line number Original line Diff line number Diff line
@@ -109,7 +109,7 @@ static inline osd_id exofs_oi_objno(struct exofs_i_info *oi)
}
}


struct exofs_io_state;
struct exofs_io_state;
typedef void (*exofs_io_done_fn)(struct exofs_io_state *or, void *private);
typedef void (*exofs_io_done_fn)(struct exofs_io_state *ios, void *private);


struct exofs_io_state {
struct exofs_io_state {
	struct kref		kref;
	struct kref		kref;
@@ -137,6 +137,8 @@ struct exofs_io_state {
	unsigned		out_attr_len;
	unsigned		out_attr_len;
	struct osd_attr 	*out_attr;
	struct osd_attr 	*out_attr;


	bool			reading;

	/* Variable array of size numdevs */
	/* Variable array of size numdevs */
	unsigned numdevs;
	unsigned numdevs;
	struct exofs_per_dev_state {
	struct exofs_per_dev_state {
@@ -218,6 +220,8 @@ void exofs_make_credential(u8 cred_a[OSD_CAP_LEN],
int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
		    u64 offset, void *p, unsigned length);
		    u64 offset, void *p, unsigned length);


int  exofs_get_rw_state(struct exofs_layout *layout, bool is_reading,
			u64 offset, u64 length, struct exofs_io_state **ios);
int  exofs_get_io_state(struct exofs_layout *layout,
int  exofs_get_io_state(struct exofs_layout *layout,
			struct exofs_io_state **ios);
			struct exofs_io_state **ios);
void exofs_put_io_state(struct exofs_io_state *ios);
void exofs_put_io_state(struct exofs_io_state *ios);
+21 −13
Original line number Original line Diff line number Diff line
@@ -110,13 +110,6 @@ static int pcol_try_alloc(struct page_collect *pcol)
{
{
	unsigned pages;
	unsigned pages;


	if (!pcol->ios) { /* First time allocate io_state */
		int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios);

		if (ret)
			return ret;
	}

	/* TODO: easily support bio chaining */
	/* TODO: easily support bio chaining */
	pages =  exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages);
	pages =  exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages);


@@ -269,17 +262,25 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw)
static int read_exec(struct page_collect *pcol)
static int read_exec(struct page_collect *pcol)
{
{
	struct exofs_i_info *oi = exofs_i(pcol->inode);
	struct exofs_i_info *oi = exofs_i(pcol->inode);
	struct exofs_io_state *ios = pcol->ios;
	struct exofs_io_state *ios;
	struct page_collect *pcol_copy = NULL;
	struct page_collect *pcol_copy = NULL;
	int ret;
	int ret;


	if (!pcol->pages)
	if (!pcol->pages)
		return 0;
		return 0;


	if (!pcol->ios) {
		int ret = exofs_get_rw_state(&pcol->sbi->layout, true,
					     pcol->pg_first << PAGE_CACHE_SHIFT,
					     pcol->length, &pcol->ios);

		if (ret)
			return ret;
	}

	ios = pcol->ios;
	ios->pages = pcol->pages;
	ios->pages = pcol->pages;
	ios->nr_pages = pcol->nr_pages;
	ios->nr_pages = pcol->nr_pages;
	ios->length = pcol->length;
	ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT;


	if (pcol->read_4_write) {
	if (pcol->read_4_write) {
		exofs_oi_read(oi, pcol->ios);
		exofs_oi_read(oi, pcol->ios);
@@ -507,13 +508,21 @@ static void writepages_done(struct exofs_io_state *ios, void *p)
static int write_exec(struct page_collect *pcol)
static int write_exec(struct page_collect *pcol)
{
{
	struct exofs_i_info *oi = exofs_i(pcol->inode);
	struct exofs_i_info *oi = exofs_i(pcol->inode);
	struct exofs_io_state *ios = pcol->ios;
	struct exofs_io_state *ios;
	struct page_collect *pcol_copy = NULL;
	struct page_collect *pcol_copy = NULL;
	int ret;
	int ret;


	if (!pcol->pages)
	if (!pcol->pages)
		return 0;
		return 0;


	BUG_ON(pcol->ios);
	ret = exofs_get_rw_state(&pcol->sbi->layout, false,
				 pcol->pg_first << PAGE_CACHE_SHIFT,
				 pcol->length, &pcol->ios);

	if (unlikely(ret))
		goto err;

	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);
	if (!pcol_copy) {
	if (!pcol_copy) {
		EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n");
		EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n");
@@ -523,10 +532,9 @@ static int write_exec(struct page_collect *pcol)


	*pcol_copy = *pcol;
	*pcol_copy = *pcol;


	ios = pcol->ios;
	ios->pages = pcol_copy->pages;
	ios->pages = pcol_copy->pages;
	ios->nr_pages = pcol_copy->nr_pages;
	ios->nr_pages = pcol_copy->nr_pages;
	ios->offset = pcol_copy->pg_first << PAGE_CACHE_SHIFT;
	ios->length = pcol_copy->length;
	ios->done = writepages_done;
	ios->done = writepages_done;
	ios->private = pcol_copy;
	ios->private = pcol_copy;


+12 −2
Original line number Original line Diff line number Diff line
@@ -69,8 +69,8 @@ int exofs_read_kern(struct osd_dev *od, u8 *cred, struct osd_obj_id *obj,
	return ret;
	return ret;
}
}


int exofs_get_io_state(struct exofs_layout *layout,
int  exofs_get_rw_state(struct exofs_layout *layout, bool is_reading,
		       struct exofs_io_state **pios)
			u64 offset, u64 length, struct exofs_io_state **pios)
{
{
	struct exofs_io_state *ios;
	struct exofs_io_state *ios;


@@ -87,10 +87,20 @@ int exofs_get_io_state(struct exofs_layout *layout,


	ios->layout = layout;
	ios->layout = layout;
	ios->obj.partition = layout->s_pid;
	ios->obj.partition = layout->s_pid;
	ios->offset = offset;
	ios->length = length;
	ios->reading = is_reading;

	*pios = ios;
	*pios = ios;
	return 0;
	return 0;
}
}


int  exofs_get_io_state(struct exofs_layout *layout,
			struct exofs_io_state **ios)
{
	return exofs_get_rw_state(layout, true, 0, 0, ios);
}

void exofs_put_io_state(struct exofs_io_state *ios)
void exofs_put_io_state(struct exofs_io_state *ios)
{
{
	if (ios) {
	if (ios) {