kernelnewbies.kernelnewbies.org archive mirror
 help / color / mirror / Atom feed
From: sebastian@pipping.org (Sebastian Pipping)
To: kernelnewbies@lists.kernelnewbies.org
Subject: Question on mmap / expecting more calls to vfs_read
Date: Tue, 11 Jan 2011 20:16:38 +0100	[thread overview]
Message-ID: <4D2CAC96.2010503@pipping.org> (raw)
In-Reply-To: <AANLkTikyBpt8zLy6ZvEh7rPGErFR6F4NBQD_LRkfyJpL@mail.gmail.com>

On 01/07/11 07:26, Rajat Sharma wrote:
> so, suitable position is to add hooks on readpage a_op. And of-course
> for doing that, you may have to capture various path thorugh which inode
> can come in memory, e.g. lookup and create directory inode operation
> (for regular files). For your worst nightmare, NFS implements its
> readdir with an additional feature with v3 protocol called READDIR PLUS,
> which not only gives you name of children of a directory, but also
> initializes their inodes in memory, so you may have to hook readdir as
> well and trap aops of all regular file child after nfs_readdir is
finished.

I see.


> As far as offset and length of I/O are concerned, page->index gives you
> its index in the page cache which in turn is equivalent to file offset
> (page->index << PAGE_SHIFT). readpage is invoked to bring in complete
> page in memory. It may so happen that page is a partial page (e.g. last
> page of file), in that case your I/O lenght will be inode->i_size &
> ~PAGE_MASK, otherwise it can be PAGE_SIZE. don't worry about file
> wholes, that is taken care by filesystem's original readpage method.

That sounds great.  I have added these lines of code to read_pages() of
mm/readahead.c:

================================================
{
  struct page *page = list_to_page(pages);
  for (page_idx = 0; page_idx < nr_pages;
      page_idx++,
      page = list_to_page(page->lru.next)) {
    pgoff_t offset = 0;
    pgoff_t len = PAGE_SIZE;

    if (page) {
      offset = page->index << PAGE_SHIFT;

      if (page->mapping && page->mapping->host) {
        struct inode *inode = page->mapping->host;
        len = inode->i_size & ~PAGE_MASK;
      }
    }

    printk(KERN_DEBUG "VFS: BODY at 1 read_pages(...)["
        "page_idx=%u, offset=%lu, len=%lu, page_size=%lu]",
        page_idx, offset, len, PAGE_SIZE);
  }
}
================================================

Suprisingly I never get len != PAGE_SIZE, i.e. partial pages.
Also, in a list of pages given, the offsets are all the same, all 0 in
this case:

================================================
[ 2811.993564] VFS: BODY at 1 read_pages(...)[page_idx=0, offset=0,
len=4096, page_size=4096]
[ 2811.996456] VFS: BODY at 1 read_pages(...)[page_idx=1, offset=0,
len=4096, page_size=4096]
[ 2811.999305] VFS: BODY at 1 read_pages(...)[page_idx=2, offset=0,
len=4096, page_size=4096]
[ 2812.002152] VFS: BODY at 1 read_pages(...)[page_idx=3, offset=0,
len=4096, page_size=4096]
================================================

Is  page = list_to_page(page->lru.next)  the correct way of walking
pages?  I am wondering how the main loop of read_pages()

	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
		struct page *page = list_to_page(pages);
		[..]
	}

really iterates, if neither the address of pages changes in the loop nor
page_idx is passed to anything.  I would think the loop is actually
accessing the same page again and again, but somehow my own

  page = list_to_page(page->lru.next)

above doesn't seem to do better.  Any insights?

Thanks!


> Having said above, it will still be better if you can state what you
> want to achieve in little layman language.

I want to trace down all reads and writes to the file system including
filename, offset and byte count into a log that I can reply inside a
simulator.

Best,




Sebastian

  parent reply	other threads:[~2011-01-11 19:16 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-01-05 20:16 Question on mmap / expecting more calls to vfs_read Sebastian Pipping
2011-01-05 22:15 ` Mulyadi Santosa
2011-01-06  6:53   ` Rajat Sharma
2011-01-06 23:49     ` Sebastian Pipping
2011-01-07  0:09       ` Manish Katiyar
2011-01-07  6:26         ` Rajat Sharma
2011-01-07  6:30           ` Rajat Sharma
2011-01-11 19:16           ` Sebastian Pipping [this message]
2011-01-12  5:12             ` Rajat Sharma

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=4D2CAC96.2010503@pipping.org \
    --to=sebastian@pipping.org \
    --cc=kernelnewbies@lists.kernelnewbies.org \
    /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;
as well as URLs for NNTP newsgroup(s).