public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Andrew Morton <akpm@linux-foundation.org>
To: Boaz Harrosh <bharrosh@panasas.com>
Cc: avishay@gmail.com, jeff@garzik.org, viro@ZenIV.linux.org.uk,
	linux-fsdevel@vger.kernel.org, osd-dev@open-osd.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/9] exofs: address_space_operations
Date: Mon, 29 Dec 2008 12:45:14 -0800	[thread overview]
Message-ID: <20081229124514.71d29ae0.akpm@linux-foundation.org> (raw)
In-Reply-To: <4947C7BD.2050407@panasas.com>

On Tue, 16 Dec 2008 17:22:37 +0200
Boaz Harrosh <bharrosh@panasas.com> wrote:

> 
> OK Now we start to read and write from osd-objects, page-by-page.
> The page index is the object's offset.
> 
>
> ...
>
> +/*
> + * Callback function when writepage finishes.  Check for errors, unlock, clean
> + * up, etc.
> + */
> +void writepage_done(struct osd_request *req, void *p)
> +{
> +	int ret;
> +	struct page *page = (struct page *)p;

unneeded cast

> +	struct inode *inode = page->mapping->host;
> +	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
> +
> +	ret = check_ok(req);
> +	free_osd_req(req);
> +	atomic_dec(&sbi->s_curr_pending);
> +
> +	if (ret) {
> +		if (ret == -ENOSPC)
> +			set_bit(AS_ENOSPC, &page->mapping->flags);
> +		else
> +			set_bit(AS_EIO, &page->mapping->flags);
> +
> +		SetPageError(page);
> +	}
> +
> +	end_page_writeback(page);
> +	unlock_page(page);
> +}
> +
> +/*
> + * Write a page to disk.  page->index gives us the page number.  The page is
> + * locked before this function is called.  We write asynchronously and then the
> + * callback function (writepage_done) is called.  We signify that the operation
> + * has completed by unlocking the page and calling end_page_writeback().
> + */
> +static int exofs_writepage(struct page *page, struct writeback_control *wbc)
> +{
> +	struct inode *inode = page->mapping->host;
> +	struct exofs_i_info *oi = EXOFS_I(inode);
> +	loff_t i_size = i_size_read(inode);
> +	unsigned long end_index = i_size >> PAGE_CACHE_SHIFT;
> +	unsigned offset = 0;
> +	struct osd_request *req = NULL;
> +	struct exofs_sb_info *sbi;
> +	uint64_t start;
> +	uint64_t len = PAGE_CACHE_SIZE;
> +	unsigned char *kaddr;
> +	int ret = 0;
> +
> +	if (!PageLocked(page))
> +		BUG();

Could use BUG_ON(!PageLocked)

> +	/* if the object has not been created, and we are not in sync mode,
> +	 * just return.  otherwise, wait. */
> +	if (!ObjCreated(oi)) {
> +		if (!Obj2BCreated(oi))
> +			BUG();

BUG_ON()?

> +		if (wbc->sync_mode == WB_SYNC_NONE) {
> +			redirty_page_for_writepage(wbc, page);
> +			unlock_page(page);
> +			ret = 0;
> +			goto out;
> +		} else {
> +			wait_event(oi->i_wq, ObjCreated(oi));
> +		}
> +	}
> +
> +	/* in this case, the page is within the limits of the file */
> +	if (page->index < end_index)
> +		goto do_it;
> +
> +	offset = i_size & (PAGE_CACHE_SIZE - 1);
> +	len = offset;
> +
> +	/*in this case, the page is outside the limits (truncate in progress)*/
> +	if (page->index >= end_index + 1 || !offset) {
> +		unlock_page(page);
> +		goto out;
> +	}
> +
> +do_it:
> +	BUG_ON(PageWriteback(page));
> +	set_page_writeback(page);
> +	start = page->index << PAGE_CACHE_SHIFT;
> +	sbi = inode->i_sb->s_fs_info;
> +
> +	kaddr = page_address(page);
> +
> +	req = prepare_osd_write(sbi->s_dev, sbi->s_pid,
> +			      inode->i_ino + EXOFS_OBJ_OFF, len, start, 0,
> +			      kaddr);

Does prepare_osd_write() modify the memory at *kaddr?  If so, does it
do the needed flush_dcache_page()?

> +                           
> +	if (!req) {
> +		printk(KERN_ERR "ERROR: writepage failed.\n");
> +		ret = -ENOMEM;
> +		goto fail;
> +	}
> +
> +	oi->i_commit_size = min_t(uint64_t, oi->i_commit_size, len + start);
> +
> +	ret = exofs_async_op(req, writepage_done, (void *)page, oi->i_cred);
> +	if (ret) {
> +		free_osd_req(req);
> +		goto fail;
> +	}
> +	atomic_inc(&sbi->s_curr_pending);
> +out:
> +	return ret;
> +fail:
> +	set_bit(AS_EIO, &page->mapping->flags);
> +	end_page_writeback(page);
> +	unlock_page(page);
> +	goto out;
> +}
> +
> +/*
> + * Callback for readpage
> + */
> +int __readpage_done(struct osd_request *req, void *p, int unlock)
> +{
> +	struct page *page = (struct page *)p;

unneeded cast.

> +	struct inode *inode = page->mapping->host;
> +	struct exofs_sb_info *sbi = inode->i_sb->s_fs_info;
> +	int ret;
> +
> +	ret = check_ok(req);
> +	free_osd_req(req);
> +	atomic_dec(&sbi->s_curr_pending);
> +
> +	if (ret == 0) {
> +
> +		/* Everything is OK */
> +		SetPageUptodate(page);
> +		if (PageError(page))
> +			ClearPageError(page);
> +	} else if (ret == -EFAULT) {
> +		char *kaddr;
> +
> +		/* 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
> +		 * before this read, the read would be waiting with the page
> +		 * locked */
> +		kaddr = page_address(page);
> +		memset(kaddr, 0, PAGE_CACHE_SIZE);

There is I think a missing flsh_dcache_page() here.  Use of the
(somewhat misnamed) zero_user() would be an appropriate fix and
cleanup.

> +		SetPageUptodate(page);
> +		if (PageError(page))
> +			ClearPageError(page);
> +	} else /* Error */
> +		SetPageError(page);
> +
> +	if (unlock)
> +		unlock_page(page);
> +
> +	return ret;
> +}
> +
> +void readpage_done(struct osd_request *req, void *p)
> +{
> +	__readpage_done(req, p, true);
> +}
> +
> +/*
> + * Read a page from the OSD
> + */
> +static int __readpage_filler(struct page *page, bool is_async_unlock)
> +{
> +	struct osd_request *req = NULL;
> +	struct inode *inode = page->mapping->host;
> +	struct exofs_i_info *oi = EXOFS_I(inode);
> +	ino_t ino = inode->i_ino;
> +	loff_t i_size = i_size_read(inode);
> +	loff_t i_start = page->index << PAGE_CACHE_SHIFT;
> +	unsigned long end_index = i_size >> PAGE_CACHE_SHIFT;

Using pgoff_t for this would have some small documentation benefit.

> +	struct super_block *sb = inode->i_sb;
> +	struct exofs_sb_info *sbi = sb->s_fs_info;
> +	uint64_t amount;
> +	unsigned char *kaddr;
> +	int ret = 0;
> +
> +	if (!PageLocked(page))
> +		BUG();

BUG_ON?

> +	if (PageUptodate(page))
> +		goto out;
> +
> +	if (page->index < end_index)
> +		amount = PAGE_CACHE_SIZE;
> +	else
> +		amount = i_size & (PAGE_CACHE_SIZE - 1);
> +
> +	/* this will be out of bounds, or doesn't exist yet */
> +	if ((page->index >= end_index + 1) || !ObjCreated(oi) || !amount
> +	    /*|| (i_start >= oi->i_commit_size)*/) {
> +		kaddr = kmap_atomic(page, KM_USER0);
> +		memset(kaddr, 0, PAGE_CACHE_SIZE);
> +		flush_dcache_page(page);
> +		kunmap_atomic(page, KM_USER0);

There's a flush_dcache_page() ;)

Could use clear_highpage() here.

> +		SetPageUptodate(page);
> +		if (PageError(page))
> +			ClearPageError(page);
> +		if (is_async_unlock)
> +			unlock_page(page);
> +		goto out;
> +	}
> +
> +	if (amount != PAGE_CACHE_SIZE) {
> +		kaddr = kmap_atomic(page, KM_USER0);
> +		memset(kaddr + amount, 0, PAGE_CACHE_SIZE - amount);
> +		flush_dcache_page(page);
> +		kunmap_atomic(page, KM_USER0);

Use zero_user()?

> +	}
> +
> +	kaddr = page_address(page);
> +
> +	req = prepare_osd_read(sbi->s_dev, sbi->s_pid, ino + EXOFS_OBJ_OFF,
> +			       amount, i_start, 0, kaddr);

flush_dcache_page()?

> +	if (!req) {
> +		printk(KERN_ERR "ERROR: readpage failed.\n");
> +		ret = -ENOMEM;
> +		unlock_page(page);
> +		goto out;
> +	}
> +
> +	atomic_inc(&sbi->s_curr_pending);
> +	if (!is_async_unlock) {
> +		exofs_sync_op(req, sbi->s_timeout, oi->i_cred);
> +		ret = __readpage_done(req, page, false);
> +	} else {
> +		ret = exofs_async_op(req, readpage_done, page, oi->i_cred);
> +		if (ret) {
> +			free_osd_req(req);
> +			unlock_page(page);
> +			atomic_dec(&sbi->s_curr_pending);
> +		}
> +	}
> +
> +out:
> +	return ret;
> +}
> +
> +static int readpage_filler(struct page *page)
> +{
> +	int ret = __readpage_filler(page, true);
> +
> +	return ret;
> +}
> +
> +/*
> + * We don't need the file
> + */
> +static int exofs_readpage(struct file *file, struct page *page)
> +{
> +	return readpage_filler(page);
> +}
> +
> +/*
> + * We don't need the data
> + */
> +static int readpage_strip(void *data, struct page *page)
> +{
> +	return readpage_filler(page);
> +}
> +
> +/*
> + * read a bunch of pages - usually for readahead
> + */
> +static int exofs_readpages(struct file *file, struct address_space *mapping,
> +			   struct list_head *pages, unsigned nr_pages)
> +{
> +	return read_cache_pages(mapping, pages, readpage_strip, NULL);
> +}
> +
> +struct address_space_operations exofs_aops = {

const.

> +	.readpage	= exofs_readpage,
> +	.readpages	= exofs_readpages,
> +	.writepage	= exofs_writepage,
> +	.write_begin	= exofs_write_begin_export,
> +	.write_end	= simple_write_end,
> +	.writepages	= generic_writepages,
> +};


  reply	other threads:[~2008-12-29 20:46 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-12-16 14:48 [PATCHSET 0/9] exofs (was osdfs) Boaz Harrosh
2008-12-16 14:52 ` [PATCH 1/9] exofs: osd Swiss army knife Boaz Harrosh
2008-12-29 20:29   ` Andrew Morton
2008-12-31 15:33     ` Boaz Harrosh
2008-12-31 19:26       ` Andrew Morton
2009-01-01 14:44         ` Boaz Harrosh
2009-01-02 16:52     ` Pavel Machek
2009-01-04  8:43       ` Boaz Harrosh
2009-01-04 20:03         ` Pavel Machek
2009-01-05  9:01           ` Boaz Harrosh
2009-01-05  9:36             ` Pavel Machek
2008-12-16 15:15 ` Boaz Harrosh
2009-01-07 15:47   ` [osd-dev] " Benny Halevy
2009-01-13 13:55     ` Alan Cox
2009-01-13 14:43       ` Boaz Harrosh
2009-01-13 14:52         ` Boaz Harrosh
2009-01-13 15:09       ` Jamie Lokier
2009-01-13 15:17         ` Jeff Garzik
2009-01-13 15:28           ` Benny Halevy
2008-12-16 15:17 ` [PATCH 2/9] exofs: file and file_inode operations Boaz Harrosh
2008-12-29 20:34   ` Andrew Morton
2008-12-31 15:36     ` Boaz Harrosh
2008-12-16 15:21 ` [PATCH 3/9] exofs: symlink_inode and fast_symlink_inode operations Boaz Harrosh
2008-12-29 20:35   ` Andrew Morton
2008-12-16 15:22 ` [PATCH 4/9] exofs: address_space_operations Boaz Harrosh
2008-12-29 20:45   ` Andrew Morton [this message]
2008-12-31 15:35     ` Boaz Harrosh
2008-12-16 15:28 ` [PATCH 5/9] exofs: dir_inode and directory operations Boaz Harrosh
2008-12-29 20:47   ` Andrew Morton
2008-12-31 15:33     ` Boaz Harrosh
2008-12-16 15:31 ` [PATCH 6/9] exofs: super_operations and file_system_type Boaz Harrosh
2008-12-17 22:23   ` Marcin Slusarz
2008-12-18  8:41     ` Boaz Harrosh
2008-12-29 20:50   ` Andrew Morton
2008-12-16 15:33 ` [PATCH 7/9] exofs: mkexofs Boaz Harrosh
2008-12-29 20:14   ` Andrew Morton
2008-12-31 15:19     ` Boaz Harrosh
2008-12-31 15:57       ` James Bottomley
2009-01-01  9:22         ` [osd-dev] " Benny Halevy
2009-01-01  9:54           ` Jeff Garzik
2009-01-01 14:23             ` Benny Halevy
2009-01-01 14:28               ` Matthew Wilcox
2009-01-01 18:12               ` Jörn Engel
2009-01-01 23:26           ` J. Bruce Fields
2009-01-02  7:14             ` Benny Halevy
2009-01-04 15:20         ` Boaz Harrosh
2009-01-04 15:38           ` Christoph Hellwig
2009-01-12 18:12           ` James Bottomley
2009-01-12 19:23             ` Jeff Garzik
2009-01-12 19:56               ` James Bottomley
2009-01-12 20:22                 ` Jeff Garzik
2009-01-12 23:25                   ` James Bottomley
2009-01-13 13:03                     ` [osd-dev] " Benny Halevy
2009-01-13 13:24                       ` Jeff Garzik
2009-01-13 13:32                         ` Benny Halevy
2009-01-13 13:44                     ` Jeff Garzik
2009-01-13 14:03                       ` Alan Cox
2009-01-13 14:17                         ` Jeff Garzik
2009-01-13 16:14                           ` Alan Cox
2009-01-13 17:21                             ` Boaz Harrosh
2009-01-21 18:13                               ` Jeff Garzik
2009-01-21 18:44                                 ` Boaz Harrosh
2009-01-12 22:48             ` Jamie Lokier
2009-01-06  8:40         ` Andreas Dilger
2008-12-31 19:25       ` Andrew Morton
2009-01-01 13:33         ` Boaz Harrosh
2009-01-02 22:46           ` James Bottomley
2009-01-04  8:59             ` Boaz Harrosh
2008-12-16 15:36 ` [PATCH 8/9] exofs: Documentation Boaz Harrosh
2008-12-18  7:47   ` Pavel Machek
2008-12-18  8:32     ` Boaz Harrosh
2008-12-16 15:38 ` [PATCH 9/9] fs: Add exofs to Kernel build Boaz Harrosh

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081229124514.71d29ae0.akpm@linux-foundation.org \
    --to=akpm@linux-foundation.org \
    --cc=avishay@gmail.com \
    --cc=bharrosh@panasas.com \
    --cc=jeff@garzik.org \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=osd-dev@open-osd.org \
    --cc=viro@ZenIV.linux.org.uk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox