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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.