diff options
Diffstat (limited to 'fs/exofs/inode.c')
| -rw-r--r-- | fs/exofs/inode.c | 473 | 
1 files changed, 328 insertions, 145 deletions
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 42685424817..3f9cafd7393 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c @@ -37,17 +37,20 @@  #define EXOFS_DBGMSG2(M...) do {} while (0) -enum { BIO_MAX_PAGES_KMALLOC = -		(PAGE_SIZE - sizeof(struct bio)) / sizeof(struct bio_vec), -	MAX_PAGES_KMALLOC = -		PAGE_SIZE / sizeof(struct page *), -}; +unsigned exofs_max_io_pages(struct ore_layout *layout, +			    unsigned expected_pages) +{ +	unsigned pages = min_t(unsigned, expected_pages, +			       layout->max_io_length / PAGE_SIZE); + +	return pages; +}  struct page_collect {  	struct exofs_sb_info *sbi;  	struct inode *inode;  	unsigned expected_pages; -	struct exofs_io_state *ios; +	struct ore_io_state *ios;  	struct page **pages;  	unsigned alloc_pages; @@ -57,6 +60,7 @@ struct page_collect {  	bool read_4_write; /* This means two things: that the read is sync  			    * And the pages should not be unlocked.  			    */ +	struct page *that_locked_page;  };  static void _pcol_init(struct page_collect *pcol, unsigned expected_pages, @@ -75,6 +79,7 @@ static void _pcol_init(struct page_collect *pcol, unsigned expected_pages,  	pcol->length = 0;  	pcol->pg_first = -1;  	pcol->read_4_write = false; +	pcol->that_locked_page = NULL;  }  static void _pcol_reset(struct page_collect *pcol) @@ -87,29 +92,22 @@ static void _pcol_reset(struct page_collect *pcol)  	pcol->length = 0;  	pcol->pg_first = -1;  	pcol->ios = NULL; +	pcol->that_locked_page = NULL;  	/* this is probably the end of the loop but in writes  	 * it might not end here. don't be left with nothing  	 */  	if (!pcol->expected_pages) -		pcol->expected_pages = MAX_PAGES_KMALLOC; +		pcol->expected_pages = +				exofs_max_io_pages(&pcol->sbi->layout, ~0);  }  static int pcol_try_alloc(struct page_collect *pcol)  { -	unsigned pages = min_t(unsigned, pcol->expected_pages, -			  MAX_PAGES_KMALLOC); - -	if (!pcol->ios) { /* First time allocate io_state */ -		int ret = exofs_get_io_state(&pcol->sbi->layout, &pcol->ios); - -		if (ret) -			return ret; -	} +	unsigned pages;  	/* TODO: easily support bio chaining */ -	pages =  min_t(unsigned, pages, -		       pcol->sbi->layout.group_width * BIO_MAX_PAGES_KMALLOC); +	pages =  exofs_max_io_pages(&pcol->sbi->layout, pcol->expected_pages);  	for (; pages; pages >>= 1) {  		pcol->pages = kmalloc(pages * sizeof(struct page *), @@ -131,7 +129,7 @@ static void pcol_free(struct page_collect *pcol)  	pcol->pages = NULL;  	if (pcol->ios) { -		exofs_put_io_state(pcol->ios); +		ore_put_io_state(pcol->ios);  		pcol->ios = NULL;  	}  } @@ -147,14 +145,17 @@ static int pcol_add_page(struct page_collect *pcol, struct page *page,  	return 0;  } +enum {PAGE_WAS_NOT_IN_IO = 17};  static int update_read_page(struct page *page, int ret)  { -	if (ret == 0) { +	switch (ret) { +	case 0:  		/* Everything is OK */  		SetPageUptodate(page);  		if (PageError(page))  			ClearPageError(page); -	} else if (ret == -EFAULT) { +		break; +	case -EFAULT:  		/* In this case we were trying to read something that wasn't on  		 * disk yet - return a page full of zeroes.  This should be OK,  		 * because the object should be empty (if there was a write @@ -165,16 +166,22 @@ static int update_read_page(struct page *page, int ret)  		SetPageUptodate(page);  		if (PageError(page))  			ClearPageError(page); -		ret = 0; /* recovered error */  		EXOFS_DBGMSG("recovered read error\n"); -	} else /* Error */ +		/* fall through */ +	case PAGE_WAS_NOT_IN_IO: +		ret = 0; /* recovered error */ +		break; +	default:  		SetPageError(page); - +	}  	return ret;  }  static void update_write_page(struct page *page, int ret)  { +	if (unlikely(ret == PAGE_WAS_NOT_IN_IO)) +		return; /* don't pass start don't collect $200 */ +  	if (ret) {  		mapping_set_error(page->mapping, ret);  		SetPageError(page); @@ -188,15 +195,16 @@ static void update_write_page(struct page *page, int ret)  static int __readpages_done(struct page_collect *pcol)  {  	int i; -	u64 resid;  	u64 good_bytes;  	u64 length = 0; -	int ret = exofs_check_io(pcol->ios, &resid); +	int ret = ore_check_io(pcol->ios, NULL); -	if (likely(!ret)) +	if (likely(!ret)) {  		good_bytes = pcol->length; -	else -		good_bytes = pcol->length - resid; +		ret = PAGE_WAS_NOT_IN_IO; +	} else { +		good_bytes = 0; +	}  	EXOFS_DBGMSG2("readpages_done(0x%lx) good_bytes=0x%llx"  		     " length=0x%lx nr_pages=%u\n", @@ -232,7 +240,7 @@ static int __readpages_done(struct page_collect *pcol)  }  /* callback of async reads */ -static void readpages_done(struct exofs_io_state *ios, void *p) +static void readpages_done(struct ore_io_state *ios, void *p)  {  	struct page_collect *pcol = p; @@ -257,23 +265,70 @@ static void _unlock_pcol_pages(struct page_collect *pcol, int ret, int rw)  	}  } +static int _maybe_not_all_in_one_io(struct ore_io_state *ios, +	struct page_collect *pcol_src, struct page_collect *pcol) +{ +	/* length was wrong or offset was not page aligned */ +	BUG_ON(pcol_src->nr_pages < ios->nr_pages); + +	if (pcol_src->nr_pages > ios->nr_pages) { +		struct page **src_page; +		unsigned pages_less = pcol_src->nr_pages - ios->nr_pages; +		unsigned long len_less = pcol_src->length - ios->length; +		unsigned i; +		int ret; + +		/* This IO was trimmed */ +		pcol_src->nr_pages = ios->nr_pages; +		pcol_src->length = ios->length; + +		/* Left over pages are passed to the next io */ +		pcol->expected_pages += pages_less; +		pcol->nr_pages = pages_less; +		pcol->length = len_less; +		src_page = pcol_src->pages + pcol_src->nr_pages; +		pcol->pg_first = (*src_page)->index; + +		ret = pcol_try_alloc(pcol); +		if (unlikely(ret)) +			return ret; + +		for (i = 0; i < pages_less; ++i) +			pcol->pages[i] = *src_page++; + +		EXOFS_DBGMSG("Length was adjusted nr_pages=0x%x " +			"pages_less=0x%x expected_pages=0x%x " +			"next_offset=0x%llx next_len=0x%lx\n", +			pcol_src->nr_pages, pages_less, pcol->expected_pages, +			pcol->pg_first * PAGE_SIZE, pcol->length); +	} +	return 0; +} +  static int read_exec(struct page_collect *pcol)  {  	struct exofs_i_info *oi = exofs_i(pcol->inode); -	struct exofs_io_state *ios = pcol->ios; +	struct ore_io_state *ios;  	struct page_collect *pcol_copy = NULL;  	int ret;  	if (!pcol->pages)  		return 0; +	if (!pcol->ios) { +		int ret = ore_get_rw_state(&pcol->sbi->layout, &oi->oc, true, +					     pcol->pg_first << PAGE_CACHE_SHIFT, +					     pcol->length, &pcol->ios); + +		if (ret) +			return ret; +	} + +	ios = pcol->ios;  	ios->pages = pcol->pages; -	ios->nr_pages = pcol->nr_pages; -	ios->length = pcol->length; -	ios->offset = pcol->pg_first << PAGE_CACHE_SHIFT;  	if (pcol->read_4_write) { -		exofs_oi_read(oi, pcol->ios); +		ore_read(pcol->ios);  		return __readpages_done(pcol);  	} @@ -286,26 +341,32 @@ static int read_exec(struct page_collect *pcol)  	*pcol_copy = *pcol;  	ios->done = readpages_done;  	ios->private = pcol_copy; -	ret = exofs_oi_read(oi, ios); + +	/* pages ownership was passed to pcol_copy */ +	_pcol_reset(pcol); + +	ret = _maybe_not_all_in_one_io(ios, pcol_copy, pcol);  	if (unlikely(ret))  		goto err; -	atomic_inc(&pcol->sbi->s_curr_pending); +	EXOFS_DBGMSG2("read_exec(0x%lx) offset=0x%llx length=0x%llx\n", +		pcol->inode->i_ino, _LLU(ios->offset), _LLU(ios->length)); + +	ret = ore_read(ios); +	if (unlikely(ret)) +		goto err; -	EXOFS_DBGMSG2("read_exec obj=0x%llx start=0x%llx length=0x%lx\n", -		  ios->obj.id, _LLU(ios->offset), pcol->length); +	atomic_inc(&pcol->sbi->s_curr_pending); -	/* pages ownership was passed to pcol_copy */ -	_pcol_reset(pcol);  	return 0;  err: -	if (!pcol->read_4_write) -		_unlock_pcol_pages(pcol, ret, READ); - -	pcol_free(pcol); - +	if (!pcol_copy) /* Failed before ownership transfer */ +		pcol_copy = pcol; +	_unlock_pcol_pages(pcol_copy, ret, READ); +	pcol_free(pcol_copy);  	kfree(pcol_copy); +  	return ret;  } @@ -326,11 +387,15 @@ static int readpage_strip(void *data, struct page *page)  	size_t len;  	int ret; +	BUG_ON(!PageLocked(page)); +  	/* FIXME: Just for debugging, will be removed */  	if (PageUptodate(page))  		EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino,  			  page->index); +	pcol->that_locked_page = page; +  	if (page->index < end_index)  		len = PAGE_CACHE_SIZE;  	else if (page->index == end_index) @@ -350,8 +415,10 @@ static int readpage_strip(void *data, struct page *page)  		if (!pcol->read_4_write)  			unlock_page(page); -		EXOFS_DBGMSG("readpage_strip(0x%lx, 0x%lx) empty page," -			     " splitting\n", inode->i_ino, page->index); +		EXOFS_DBGMSG("readpage_strip(0x%lx) empty page len=%zx " +			     "read_4_write=%d index=0x%lx end_index=0x%lx " +			     "splitting\n", inode->i_ino, len, +			     pcol->read_4_write, page->index, end_index);  		return read_exec(pcol);  	} @@ -417,6 +484,10 @@ static int exofs_readpages(struct file *file, struct address_space *mapping,  		return ret;  	} +	ret = read_exec(&pcol); +	if (unlikely(ret)) +		return ret; +  	return read_exec(&pcol);  } @@ -446,21 +517,22 @@ static int exofs_readpage(struct file *file, struct page *page)  }  /* Callback for osd_write. All writes are asynchronous */ -static void writepages_done(struct exofs_io_state *ios, void *p) +static void writepages_done(struct ore_io_state *ios, void *p)  {  	struct page_collect *pcol = p;  	int i; -	u64 resid;  	u64  good_bytes;  	u64  length = 0; -	int ret = exofs_check_io(ios, &resid); +	int ret = ore_check_io(ios, NULL);  	atomic_dec(&pcol->sbi->s_curr_pending); -	if (likely(!ret)) +	if (likely(!ret)) {  		good_bytes = pcol->length; -	else -		good_bytes = pcol->length - resid; +		ret = PAGE_WAS_NOT_IN_IO; +	} else { +		good_bytes = 0; +	}  	EXOFS_DBGMSG2("writepages_done(0x%lx) good_bytes=0x%llx"  		     " length=0x%lx nr_pages=%u\n", @@ -493,16 +565,82 @@ static void writepages_done(struct exofs_io_state *ios, void *p)  	EXOFS_DBGMSG2("writepages_done END\n");  } +static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) +{ +	struct page_collect *pcol = priv; +	pgoff_t index = offset / PAGE_SIZE; + +	if (!pcol->that_locked_page || +	    (pcol->that_locked_page->index != index)) { +		struct page *page; +		loff_t i_size = i_size_read(pcol->inode); + +		if (offset >= i_size) { +			*uptodate = true; +			EXOFS_DBGMSG2("offset >= i_size index=0x%lx\n", index); +			return ZERO_PAGE(0); +		} + +		page =  find_get_page(pcol->inode->i_mapping, index); +		if (!page) { +			page = find_or_create_page(pcol->inode->i_mapping, +						   index, GFP_NOFS); +			if (unlikely(!page)) { +				EXOFS_DBGMSG("grab_cache_page Failed " +					"index=0x%llx\n", _LLU(index)); +				return NULL; +			} +			unlock_page(page); +		} +		if (PageDirty(page) || PageWriteback(page)) +			*uptodate = true; +		else +			*uptodate = PageUptodate(page); +		EXOFS_DBGMSG2("index=0x%lx uptodate=%d\n", index, *uptodate); +		return page; +	} else { +		EXOFS_DBGMSG2("YES that_locked_page index=0x%lx\n", +			     pcol->that_locked_page->index); +		*uptodate = true; +		return pcol->that_locked_page; +	} +} + +static void __r4w_put_page(void *priv, struct page *page) +{ +	struct page_collect *pcol = priv; + +	if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) { +		EXOFS_DBGMSG2("index=0x%lx\n", page->index); +		page_cache_release(page); +		return; +	} +	EXOFS_DBGMSG2("that_locked_page index=0x%lx\n", +		     ZERO_PAGE(0) == page ? -1 : page->index); +} + +static const struct _ore_r4w_op _r4w_op = { +	.get_page = &__r4w_get_page, +	.put_page = &__r4w_put_page, +}; +  static int write_exec(struct page_collect *pcol)  {  	struct exofs_i_info *oi = exofs_i(pcol->inode); -	struct exofs_io_state *ios = pcol->ios; +	struct ore_io_state *ios;  	struct page_collect *pcol_copy = NULL;  	int ret;  	if (!pcol->pages)  		return 0; +	BUG_ON(pcol->ios); +	ret = ore_get_rw_state(&pcol->sbi->layout, &oi->oc, false, +				 pcol->pg_first << PAGE_CACHE_SHIFT, +				 pcol->length, &pcol->ios); +	if (unlikely(ret)) +		goto err; +  	pcol_copy = kmalloc(sizeof(*pcol_copy), GFP_KERNEL);  	if (!pcol_copy) {  		EXOFS_ERR("write_exec: Failed to kmalloc(pcol)\n"); @@ -512,30 +650,36 @@ static int write_exec(struct page_collect *pcol)  	*pcol_copy = *pcol; +	ios = pcol->ios;  	ios->pages = pcol_copy->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->r4w = &_r4w_op;  	ios->private = pcol_copy; -	ret = exofs_oi_write(oi, ios); +	/* pages ownership was passed to pcol_copy */ +	_pcol_reset(pcol); + +	ret = _maybe_not_all_in_one_io(ios, pcol_copy, pcol); +	if (unlikely(ret)) +		goto err; + +	EXOFS_DBGMSG2("write_exec(0x%lx) offset=0x%llx length=0x%llx\n", +		pcol->inode->i_ino, _LLU(ios->offset), _LLU(ios->length)); + +	ret = ore_write(ios);  	if (unlikely(ret)) { -		EXOFS_ERR("write_exec: exofs_oi_write() Failed\n"); +		EXOFS_ERR("write_exec: ore_write() Failed\n");  		goto err;  	}  	atomic_inc(&pcol->sbi->s_curr_pending); -	EXOFS_DBGMSG2("write_exec(0x%lx, 0x%llx) start=0x%llx length=0x%lx\n", -		  pcol->inode->i_ino, pcol->pg_first, _LLU(ios->offset), -		  pcol->length); -	/* pages ownership was passed to pcol_copy */ -	_pcol_reset(pcol);  	return 0;  err: -	_unlock_pcol_pages(pcol, ret, WRITE); -	pcol_free(pcol); +	if (!pcol_copy) /* Failed before ownership transfer */ +		pcol_copy = pcol; +	_unlock_pcol_pages(pcol_copy, ret, WRITE); +	pcol_free(pcol_copy);  	kfree(pcol_copy);  	return ret; @@ -670,14 +814,33 @@ static int exofs_writepages(struct address_space *mapping,  	_pcol_init(&pcol, expected_pages, mapping->host);  	ret = write_cache_pages(mapping, wbc, writepage_strip, &pcol); -	if (ret) { +	if (unlikely(ret)) {  		EXOFS_ERR("write_cache_pages => %d\n", ret);  		return ret;  	} -	return write_exec(&pcol); +	ret = write_exec(&pcol); +	if (unlikely(ret)) +		return ret; + +	if (wbc->sync_mode == WB_SYNC_ALL) { +		return write_exec(&pcol); /* pump the last reminder */ +	} else if (pcol.nr_pages) { +		/* not SYNC let the reminder join the next writeout */ +		unsigned i; + +		for (i = 0; i < pcol.nr_pages; i++) { +			struct page *page = pcol.pages[i]; + +			end_page_writeback(page); +			set_page_dirty(page); +			unlock_page(page); +		} +	} +	return 0;  } +/*  static int exofs_writepage(struct page *page, struct writeback_control *wbc)  {  	struct page_collect pcol; @@ -693,12 +856,12 @@ static int exofs_writepage(struct page *page, struct writeback_control *wbc)  	return write_exec(&pcol);  } - +*/  /* i_mutex held using inode->i_size directly */  static void _write_failed(struct inode *inode, loff_t to)  {  	if (to > inode->i_size) -		truncate_pagecache(inode, to, inode->i_size); +		truncate_pagecache(inode, inode->i_size);  }  int exofs_write_begin(struct file *file, struct address_space *mapping, @@ -722,11 +885,28 @@ int exofs_write_begin(struct file *file, struct address_space *mapping,  	 /* read modify write */  	if (!PageUptodate(page) && (len != PAGE_CACHE_SIZE)) { +		loff_t i_size = i_size_read(mapping->host); +		pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT; +		size_t rlen; + +		if (page->index < end_index) +			rlen = PAGE_CACHE_SIZE; +		else if (page->index == end_index) +			rlen = i_size & ~PAGE_CACHE_MASK; +		else +			rlen = 0; + +		if (!rlen) { +			clear_highpage(page); +			SetPageUptodate(page); +			goto out; +		} +  		ret = _readpage(page, true);  		if (ret) {  			/*SetPageError was done by _readpage. Is it ok?*/  			unlock_page(page); -			EXOFS_DBGMSG("__readpage_filler failed\n"); +			EXOFS_DBGMSG("__readpage failed\n");  		}  	}  out: @@ -773,16 +953,26 @@ static int exofs_releasepage(struct page *page, gfp_t gfp)  	return 0;  } -static void exofs_invalidatepage(struct page *page, unsigned long offset) +static void exofs_invalidatepage(struct page *page, unsigned int offset, +				 unsigned int length)  { -	EXOFS_DBGMSG("page 0x%lx offset 0x%lx\n", page->index, offset); +	EXOFS_DBGMSG("page 0x%lx offset 0x%x length 0x%x\n", +		     page->index, offset, length);  	WARN_ON(1);  } + + /* TODO: Should be easy enough to do proprly */ +static ssize_t exofs_direct_IO(int rw, struct kiocb *iocb, +		struct iov_iter *iter, loff_t offset) +{ +	return 0; +} +  const struct address_space_operations exofs_aops = {  	.readpage	= exofs_readpage,  	.readpages	= exofs_readpages, -	.writepage	= exofs_writepage, +	.writepage	= NULL,  	.writepages	= exofs_writepages,  	.write_begin	= exofs_write_begin_export,  	.write_end	= exofs_write_end, @@ -792,10 +982,9 @@ const struct address_space_operations exofs_aops = {  	/* Not implemented Yet */  	.bmap		= NULL, /* TODO: use osd's OSD_ACT_READ_MAP */ -	.direct_IO	= NULL, /* TODO: Should be trivial to do */ +	.direct_IO	= exofs_direct_IO,  	/* With these NULL has special meaning or default is not exported */ -	.sync_page	= NULL,  	.get_xip_mem	= NULL,  	.migratepage	= NULL,  	.launder_page	= NULL, @@ -817,21 +1006,19 @@ static inline int exofs_inode_is_fast_symlink(struct inode *inode)  	return S_ISLNK(inode->i_mode) && (oi->i_data[0] != 0);  } -const struct osd_attr g_attr_logical_length = ATTR_DEF( -	OSD_APAGE_OBJECT_INFORMATION, OSD_ATTR_OI_LOGICAL_LENGTH, 8); -  static int _do_truncate(struct inode *inode, loff_t newsize)  {  	struct exofs_i_info *oi = exofs_i(inode); +	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;  	int ret;  	inode->i_mtime = inode->i_ctime = CURRENT_TIME; -	ret = exofs_oi_truncate(oi, (u64)newsize); +	ret = ore_truncate(&sbi->layout, &oi->oc, (u64)newsize);  	if (likely(!ret))  		truncate_setsize(inode, newsize); -	EXOFS_DBGMSG("(0x%lx) size=0x%llx ret=>%d\n", +	EXOFS_DBGMSG2("(0x%lx) size=0x%llx ret=>%d\n",  		     inode->i_ino, newsize, ret);  	return ret;  } @@ -890,43 +1077,38 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,  		[1] = g_attr_inode_file_layout,  		[2] = g_attr_inode_dir_layout,  	}; -	struct exofs_io_state *ios; +	struct ore_io_state *ios;  	struct exofs_on_disk_inode_layout *layout;  	int ret; -	ret = exofs_get_io_state(&sbi->layout, &ios); +	ret = ore_get_io_state(&sbi->layout, &oi->oc, &ios);  	if (unlikely(ret)) { -		EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); +		EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__);  		return ret;  	} -	ios->obj.id = exofs_oi_objno(oi); -	exofs_make_credential(oi->i_cred, &ios->obj); -	ios->cred = oi->i_cred; - -	attrs[1].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs); -	attrs[2].len = exofs_on_disk_inode_layout_size(sbi->layout.s_numdevs); +	attrs[1].len = exofs_on_disk_inode_layout_size(sbi->oc.numdevs); +	attrs[2].len = exofs_on_disk_inode_layout_size(sbi->oc.numdevs);  	ios->in_attr = attrs;  	ios->in_attr_len = ARRAY_SIZE(attrs); -	ret = exofs_sbi_read(ios); +	ret = ore_read(ios);  	if (unlikely(ret)) {  		EXOFS_ERR("object(0x%llx) corrupted, return empty file=>%d\n", -			  _LLU(ios->obj.id), ret); +			  _LLU(oi->one_comp.obj.id), ret);  		memset(inode, 0, sizeof(*inode));  		inode->i_mode = 0040000 | (0777 & ~022);  		/* If object is lost on target we might as well enable it's  		 * delete.  		 */ -		if ((ret == -ENOENT) || (ret == -EINVAL)) -			ret = 0; +		ret = 0;  		goto out;  	}  	ret = extract_attr_from_ios(ios, &attrs[0]);  	if (ret) { -		EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); +		EXOFS_ERR("%s: extract_attr 0 of inode failed\n", __func__);  		goto out;  	}  	WARN_ON(attrs[0].len != EXOFS_INO_ATTR_SIZE); @@ -934,7 +1116,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,  	ret = extract_attr_from_ios(ios, &attrs[1]);  	if (ret) { -		EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); +		EXOFS_ERR("%s: extract_attr 1 of inode failed\n", __func__);  		goto out;  	}  	if (attrs[1].len) { @@ -949,7 +1131,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,  	ret = extract_attr_from_ios(ios, &attrs[2]);  	if (ret) { -		EXOFS_ERR("%s: extract_attr of inode_data failed\n", __func__); +		EXOFS_ERR("%s: extract_attr 2 of inode failed\n", __func__);  		goto out;  	}  	if (attrs[2].len) { @@ -963,7 +1145,7 @@ static int exofs_get_inode(struct super_block *sb, struct exofs_i_info *oi,  	}  out: -	exofs_put_io_state(ios); +	ore_put_io_state(ios);  	return ret;  } @@ -989,6 +1171,8 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino)  		return inode;  	oi = exofs_i(inode);  	__oi_init(oi); +	exofs_init_comps(&oi->oc, &oi->one_comp, sb->s_fs_info, +			 exofs_oi_objno(oi));  	/* read the inode from the osd */  	ret = exofs_get_inode(sb, oi, &fcb); @@ -999,9 +1183,9 @@ struct inode *exofs_iget(struct super_block *sb, unsigned long ino)  	/* copy stuff from on-disk struct to in-memory struct */  	inode->i_mode = le16_to_cpu(fcb.i_mode); -	inode->i_uid = le32_to_cpu(fcb.i_uid); -	inode->i_gid = le32_to_cpu(fcb.i_gid); -	inode->i_nlink = le16_to_cpu(fcb.i_links_count); +	i_uid_write(inode, le32_to_cpu(fcb.i_uid)); +	i_gid_write(inode, le32_to_cpu(fcb.i_gid)); +	set_nlink(inode, le16_to_cpu(fcb.i_links_count));  	inode->i_ctime.tv_sec = (signed)le32_to_cpu(fcb.i_ctime);  	inode->i_atime.tv_sec = (signed)le32_to_cpu(fcb.i_atime);  	inode->i_mtime.tv_sec = (signed)le32_to_cpu(fcb.i_mtime); @@ -1074,26 +1258,28 @@ int __exofs_wait_obj_created(struct exofs_i_info *oi)  	}  	return unlikely(is_bad_inode(&oi->vfs_inode)) ? -EIO : 0;  } +  /*   * Callback function from exofs_new_inode().  The important thing is that we   * set the obj_created flag so that other methods know that the object exists on   * the OSD.   */ -static void create_done(struct exofs_io_state *ios, void *p) +static void create_done(struct ore_io_state *ios, void *p)  {  	struct inode *inode = p;  	struct exofs_i_info *oi = exofs_i(inode);  	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;  	int ret; -	ret = exofs_check_io(ios, NULL); -	exofs_put_io_state(ios); +	ret = ore_check_io(ios, NULL); +	ore_put_io_state(ios);  	atomic_dec(&sbi->s_curr_pending);  	if (unlikely(ret)) {  		EXOFS_ERR("object=0x%llx creation failed in pid=0x%llx", -			  _LLU(exofs_oi_objno(oi)), _LLU(sbi->layout.s_pid)); +			  _LLU(exofs_oi_objno(oi)), +			  _LLU(oi->one_comp.obj.partition));  		/*TODO: When FS is corrupted creation can fail, object already  		 * exist. Get rid of this asynchronous creation, if exist  		 * increment the obj counter and try the next object. Until we @@ -1110,16 +1296,15 @@ static void create_done(struct exofs_io_state *ios, void *p)  /*   * Set up a new inode and create an object for it on the OSD   */ -struct inode *exofs_new_inode(struct inode *dir, int mode) +struct inode *exofs_new_inode(struct inode *dir, umode_t mode)  { -	struct super_block *sb; +	struct super_block *sb = dir->i_sb; +	struct exofs_sb_info *sbi = sb->s_fs_info;  	struct inode *inode;  	struct exofs_i_info *oi; -	struct exofs_sb_info *sbi; -	struct exofs_io_state *ios; +	struct ore_io_state *ios;  	int ret; -	sb = dir->i_sb;  	inode = new_inode(sb);  	if (!inode)  		return ERR_PTR(-ENOMEM); @@ -1129,10 +1314,7 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)  	set_obj_2bcreated(oi); -	sbi = sb->s_fs_info; -  	inode->i_mapping->backing_dev_info = sb->s_bdi; -	sb->s_dirt = 1;  	inode_init_owner(inode, dir, mode);  	inode->i_ino = sbi->s_nextid++;  	inode->i_blkbits = EXOFS_BLKSHIFT; @@ -1143,23 +1325,24 @@ struct inode *exofs_new_inode(struct inode *dir, int mode)  	spin_unlock(&sbi->s_next_gen_lock);  	insert_inode_hash(inode); +	exofs_init_comps(&oi->oc, &oi->one_comp, sb->s_fs_info, +			 exofs_oi_objno(oi)); +	exofs_sbi_write_stats(sbi); /* Make sure new sbi->s_nextid is on disk */ +  	mark_inode_dirty(inode); -	ret = exofs_get_io_state(&sbi->layout, &ios); +	ret = ore_get_io_state(&sbi->layout, &oi->oc, &ios);  	if (unlikely(ret)) { -		EXOFS_ERR("exofs_new_inode: exofs_get_io_state failed\n"); +		EXOFS_ERR("exofs_new_inode: ore_get_io_state failed\n");  		return ERR_PTR(ret);  	} -	ios->obj.id = exofs_oi_objno(oi); -	exofs_make_credential(oi->i_cred, &ios->obj); -  	ios->done = create_done;  	ios->private = inode; -	ios->cred = oi->i_cred; -	ret = exofs_sbi_create(ios); + +	ret = ore_create(ios);  	if (ret) { -		exofs_put_io_state(ios); +		ore_put_io_state(ios);  		return ERR_PTR(ret);  	}  	atomic_inc(&sbi->s_curr_pending); @@ -1178,11 +1361,11 @@ struct updatei_args {  /*   * Callback function from exofs_update_inode().   */ -static void updatei_done(struct exofs_io_state *ios, void *p) +static void updatei_done(struct ore_io_state *ios, void *p)  {  	struct updatei_args *args = p; -	exofs_put_io_state(ios); +	ore_put_io_state(ios);  	atomic_dec(&args->sbi->s_curr_pending); @@ -1198,7 +1381,7 @@ static int exofs_update_inode(struct inode *inode, int do_sync)  	struct exofs_i_info *oi = exofs_i(inode);  	struct super_block *sb = inode->i_sb;  	struct exofs_sb_info *sbi = sb->s_fs_info; -	struct exofs_io_state *ios; +	struct ore_io_state *ios;  	struct osd_attr attr;  	struct exofs_fcb *fcb;  	struct updatei_args *args; @@ -1213,8 +1396,8 @@ static int exofs_update_inode(struct inode *inode, int do_sync)  	fcb = &args->fcb;  	fcb->i_mode = cpu_to_le16(inode->i_mode); -	fcb->i_uid = cpu_to_le32(inode->i_uid); -	fcb->i_gid = cpu_to_le32(inode->i_gid); +	fcb->i_uid = cpu_to_le32(i_uid_read(inode)); +	fcb->i_gid = cpu_to_le32(i_gid_read(inode));  	fcb->i_links_count = cpu_to_le16(inode->i_nlink);  	fcb->i_ctime = cpu_to_le32(inode->i_ctime.tv_sec);  	fcb->i_atime = cpu_to_le32(inode->i_atime.tv_sec); @@ -1237,9 +1420,9 @@ static int exofs_update_inode(struct inode *inode, int do_sync)  	} else  		memcpy(fcb->i_data, oi->i_data, sizeof(fcb->i_data)); -	ret = exofs_get_io_state(&sbi->layout, &ios); +	ret = ore_get_io_state(&sbi->layout, &oi->oc, &ios);  	if (unlikely(ret)) { -		EXOFS_ERR("%s: exofs_get_io_state failed.\n", __func__); +		EXOFS_ERR("%s: ore_get_io_state failed.\n", __func__);  		goto free_args;  	} @@ -1256,13 +1439,13 @@ static int exofs_update_inode(struct inode *inode, int do_sync)  		ios->private = args;  	} -	ret = exofs_oi_write(oi, ios); +	ret = ore_write(ios);  	if (!do_sync && !ret) {  		atomic_inc(&sbi->s_curr_pending);  		goto out; /* deallocation in updatei_done */  	} -	exofs_put_io_state(ios); +	ore_put_io_state(ios);  free_args:  	kfree(args);  out: @@ -1273,18 +1456,19 @@ out:  int exofs_write_inode(struct inode *inode, struct writeback_control *wbc)  { -	return exofs_update_inode(inode, wbc->sync_mode == WB_SYNC_ALL); +	/* FIXME: fix fsync and use wbc->sync_mode == WB_SYNC_ALL */ +	return exofs_update_inode(inode, 1);  }  /*   * Callback function from exofs_delete_inode() - don't have much cleaning up to   * do.   */ -static void delete_done(struct exofs_io_state *ios, void *p) +static void delete_done(struct ore_io_state *ios, void *p)  {  	struct exofs_sb_info *sbi = p; -	exofs_put_io_state(ios); +	ore_put_io_state(ios);  	atomic_dec(&sbi->s_curr_pending);  } @@ -1299,17 +1483,17 @@ void exofs_evict_inode(struct inode *inode)  	struct exofs_i_info *oi = exofs_i(inode);  	struct super_block *sb = inode->i_sb;  	struct exofs_sb_info *sbi = sb->s_fs_info; -	struct exofs_io_state *ios; +	struct ore_io_state *ios;  	int ret; -	truncate_inode_pages(&inode->i_data, 0); +	truncate_inode_pages_final(&inode->i_data);  	/* TODO: should do better here */  	if (inode->i_nlink || is_bad_inode(inode))  		goto no_delete;  	inode->i_size = 0; -	end_writeback(inode); +	clear_inode(inode);  	/* if we are deleting an obj that hasn't been created yet, wait.  	 * This also makes sure that create_done cannot be called with an @@ -1319,20 +1503,19 @@ void exofs_evict_inode(struct inode *inode)  	/* ignore the error, attempt a remove anyway */  	/* Now Remove the OSD objects */ -	ret = exofs_get_io_state(&sbi->layout, &ios); +	ret = ore_get_io_state(&sbi->layout, &oi->oc, &ios);  	if (unlikely(ret)) { -		EXOFS_ERR("%s: exofs_get_io_state failed\n", __func__); +		EXOFS_ERR("%s: ore_get_io_state failed\n", __func__);  		return;  	} -	ios->obj.id = exofs_oi_objno(oi);  	ios->done = delete_done;  	ios->private = sbi; -	ios->cred = oi->i_cred; -	ret = exofs_sbi_remove(ios); + +	ret = ore_remove(ios);  	if (ret) { -		EXOFS_ERR("%s: exofs_sbi_remove failed\n", __func__); -		exofs_put_io_state(ios); +		EXOFS_ERR("%s: ore_remove failed\n", __func__); +		ore_put_io_state(ios);  		return;  	}  	atomic_inc(&sbi->s_curr_pending); @@ -1340,5 +1523,5 @@ void exofs_evict_inode(struct inode *inode)  	return;  no_delete: -	end_writeback(inode); +	clear_inode(inode);  }  | 
