From: Oleg Nesterov <oleg@tv-sign.ru>
To: Jens Axboe <axboe@suse.de>
Cc: linux-kernel@vger.kernel.org, Linus Torvalds <torvalds@osdl.org>,
Ingo Molnar <mingo@elte.hu>
Subject: Re: splice(SPLICE_F_MOVE) problems
Date: Wed, 3 May 2006 08:14:55 +0400 [thread overview]
Message-ID: <20060503041455.GA158@oleg> (raw)
In-Reply-To: <20060502052850.GP3814@suse.de>
I am looking at current fs/splice.c from
http://kernel.org/git/?p=linux/kernel/git/torvalds/....
pipe_to_file:
if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) {
/*
* If steal succeeds, buf->page is now pruned from the vm
* side (page cache) and we can reuse it. The page will also
* be locked on successful return.
*/
if (buf->ops->steal(info, buf))
goto find_page;
page = buf->page;
page_cache_get(page);
Isn't it better to do this after successful successful add_to_page_cache() ?
This way you don't need to do page_cache_release() if add_to_page_cache fails.
/*
* page must be on the LRU for adding to the pagecache.
Is it true? (looking at add_to_page_cache_lru).
* Check this without grabbing the zone lock, if it isn't
* the do grab the zone lock, recheck, and add if necessary.
*/
if (!PageLRU(page)) {
struct zone *zone = page_zone(page);
spin_lock_irq(&zone->lru_lock);
if (!PageLRU(page)) {
SetPageLRU(page);
add_page_to_inactive_list(zone, page);
}
spin_unlock_irq(&zone->lru_lock);
Why not lru_cache_add() ?
if (add_to_page_cache(page, mapping, index, gfp_mask)) {
page_cache_release(page);
unlock_page(page);
goto find_page;
This leaves unmapped page on ->inactive_list. page_count(page) == 1. What if
shrink_inactive_list() finds this page, increments page->count, and calls
shrink_page_list()->remove_mapping() again? Hmm... So page_cache_pipe_buf_steal()
has a reason to return a locked page (I am not an expert, please correct me).
However, user_page_pipe_buf_steal() returns unlocked page in PIPE_BUF_FLAG_GIFT
case. So, if add_to_page_cache() fails, unlock_page() will trigger BUG().
ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
if (ret == AOP_TRUNCATED_PAGE) {
page_cache_release(page);
goto find_page;
We also need to unlock(page) if it was stealed.
Oleg.
next prev parent reply other threads:[~2006-05-03 0:14 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-05-01 6:59 splice(SPLICE_F_MOVE) problems Oleg Nesterov
2006-05-01 6:54 ` Jens Axboe
2006-05-01 19:06 ` Oleg Nesterov
2006-05-01 17:41 ` Jens Axboe
2006-05-02 0:11 ` Oleg Nesterov
2006-05-02 5:28 ` Jens Axboe
2006-05-03 4:14 ` Oleg Nesterov [this message]
2006-05-03 6:56 ` Jens Axboe
2006-05-03 14:35 ` Oleg Nesterov
2006-05-03 10:48 ` Jens Axboe
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=20060503041455.GA158@oleg \
--to=oleg@tv-sign.ru \
--cc=axboe@suse.de \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=torvalds@osdl.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