linux-fsdevel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Martin Jambor <jambormartin@gmail.com>
To: Linux FS Development List <linux-fsdevel@vger.kernel.org>
Subject: pagevec_lookup_tag() and pagevec_release() substitutes and an OOM
Date: Wed, 8 Feb 2006 01:29:44 +0100	[thread overview]
Message-ID: <9615ac9b0602071629y5054dc07w8d1f18e070b0b01f@mail.gmail.com> (raw)

Hi all,

I am implementing aops->writepages of a filesystem and for various
reasons I cannot use mpage_writepages. On the other hand, I would like
to do be able to get a vector of pages and process it page by page (in
my way) just like mpage_writepages gets pages.

However, pagevec functions are not exported (I don't understand why)
and so I cannot use them directly by my module but rather I had to do
a bit of cutting and pasting from 2.6.14 kernel source :-(

So my approach was to use a plain array of pointers to pages and
instead of calling

unsigned pagevec_lookup_tag(struct pagevec *pvec, struct address_space *mapping,
		pgoff_t *index, int tag, unsigned nr_pages)

I use my own function which is basically copied find_get_pages_tag()
(which also isn't exported):

static unsigned my_find_get_pages_tag(struct address_space *mapping,
				   pgoff_t *index, int tag, unsigned int nr_pages,
                                   struct page **pages)
{
	unsigned int i;
	unsigned int ret;

	read_lock_irq(&mapping->tree_lock);
	ret = radix_tree_gang_lookup_tag(&mapping->page_tree,
				(void **)pages, *index, nr_pages, tag);
	for (i = 0; i < ret; i++)
		page_cache_get(pages[i]);
	if (ret)
		*index = pages[ret - 1]->index + 1;
	read_unlock_irq(&mapping->tree_lock);
	return ret;
}

instead of pagevec_release() I use a much simpler function:

static void release_pagearray(struct page **pages, unsigned int nr_pages)
{
	unsigned i;
	
	for (i = 0; i < nr_pages; i++)
		page_cache_release(pages[i]);
}

Everything seems to be working well except that I get an OOM. The free
and vmstat utilities show that "cache" is the only thing that is
getting unreasonably bigger. There are many reasons why I believe the
page cache pages are still somehow pinned down by my code and cannot
be freed when I am done with them. I must admit that I find it quite
difficult to uderstand the pagevec source and if someone knew what I
am doing wrong, I would be very grateful.

(Yes, I have carefully checked several times very carefully that I
set&clear writeback as indicated in Documentation/filesystmes/Locking
and how it is done by mpage_writepages.)

Thank you very much in advance for any comment.

Martin

             reply	other threads:[~2006-02-08  0:29 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-02-08  0:29 Martin Jambor [this message]
2006-02-08  5:01 ` pagevec_lookup_tag() and pagevec_release() substitutes and an OOM Martin Jambor
2006-02-08  7:48   ` Andrew Morton
2006-02-08 14:55     ` Dave Kleikamp

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=9615ac9b0602071629y5054dc07w8d1f18e070b0b01f@mail.gmail.com \
    --to=jambormartin@gmail.com \
    --cc=linux-fsdevel@vger.kernel.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).