Re: Trying to cause a writepage from commit_write?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> > Any suggestions or pointers would be greatly appreciated.
>
> Well, given  the information  you provided it  is anyone's  guess,

Yes, sorry about that :-)  It's just nice to have a sanity check on the basic 
principle - to check that I hadn't missed anything glaringly obvious...  I do 
have a strange feeling this isn't as hard as I'm finding it.

> 1) Check that you have a  handler for the commit_write() address space
>    operation.

Got that, and it's definitely being called.

> 2) Check  that  the  handler  marks  the  page  as  dirty  by  calling
>    set_page_dirty().  Its variants like __set_page_dirty_buffers() and
>    __set_page_dirty_nobuffers() may  also be ok but since  you are not
>    block device based I don't  think you should be using buffer_heads.
>    Specifically SetPageDirty() is NOT  enough because it does not mark
>    the     page     dirty     in     the     mapping     tree     (See
>    documentation/filesystems/Locking for other details).

I've experimented with various versions of set_page_dirty(), and now have 
settled back on the vanilla version.

I'd figured out that SetPageDirty() wasn't enough - eventually :-)  Thanks for 
noting it though.

> 3) If you have your own set_page_dirty() address space operation, make
>    sure   it   does   the    right   thing   by   eventually   calling
>    __set_page_dirty_nobuffers() (assuming you don't use buffer heads).

I'm not overriding set_page_dirty() anywhere (at the moment)

> 4) Check that  writepages() does not kick  in earlier and  does not do
>    the job instead.

I'm not implementing a writepages() method either, at the moment.

For more concrete discussion, here's a snippet of the code.  This is my 
current implementation of commit_write:

static int xenfs_commit_write(struct file *file, struct page *page, unsigned 
from, unsigned to)
{
	/* Some code taken from buffer.c::generic_commit_write */
	struct inode *inode = page->mapping->host;
	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;

	/*
	 * No need to use i_size_read() here, the i_size
	 * cannot change under us because we hold i_mutex.
	 */
	if (pos > inode->i_size) {
		i_size_write(inode, pos);
		mark_inode_dirty(inode);
	}
	
	printk("xenfs_commit_write\n");
	
 /* dumps out some data from the buffer so I can check it's correct. */
	dumpbuf(page_address(page) + from, to - from);
	
	printk("Setting page dirty!\n");

	set_page_dirty(page);

	printk("PageLocked = %d, PageUpToDate = %d, PageDirty = %d\n",
	       PageLocked(page), PageUptodate(page), PageDirty(page));	
	printk("Inode size = %lu", file->f_mapping->host->i_size);
	
	/* Queue a writepage? */	

	return 0;
}

The first section of the code is just copied from the generic_commit_write() 
function, comment included.

My printks here tell me:
PageLocked = 1, PageUpToDate = 1, PageDirty = 1

By the end of the function, as expected.

However, as far as I can tell, I don't get a call to my writepage() method at 
any point after this, even if I run sync (although that does cause the 
modified inode to get written out).

Am I doing something wrong in my commit_write() - where I've been assuming the 
problem is - or should I be looking elsewhere?

Any help would be greatly appreciated!

Thanks very much,
Mark

-- 
Dave: Just a question. What use is a unicyle with no seat?  And no pedals!
Mark: To answer a question with a question: What use is a skateboard?
Dave: Skateboards have wheels.
Mark: My wheel has a wheel!
-
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux