From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Tue, 10 Oct 2006 01:07:42 -0700 From: Andrew Morton Subject: Re: [patch] mm: bug in set_page_dirty_buffers Message-Id: <20061010010742.50cbe1b1.akpm@osdl.org> In-Reply-To: <20061010072129.GB14557@wotan.suse.de> References: <20061009220127.c4721d2d.akpm@osdl.org> <20061010052248.GB24600@wotan.suse.de> <20061009222905.ddd270a6.akpm@osdl.org> <20061010054832.GC24600@wotan.suse.de> <20061009230832.7245814e.akpm@osdl.org> <20061010061958.GA25500@wotan.suse.de> <20061009232714.b52f678d.akpm@osdl.org> <20061010063900.GB25500@wotan.suse.de> <20061010065217.GC25500@wotan.suse.de> <20061010000652.bed6f901.akpm@osdl.org> <20061010072129.GB14557@wotan.suse.de> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-linux-mm@kvack.org Return-Path: To: Nick Piggin Cc: Linus Torvalds , Peter Zijlstra , Linux Memory Management List , Greg KH List-ID: On Tue, 10 Oct 2006 09:21:29 +0200 Nick Piggin wrote: > void block_invalidatepage(struct page *page, unsigned long offset) > { > + struct address_space *mapping = page->mapping; > struct buffer_head *head, *bh, *next; > - unsigned int curr_off = 0; > + unsigned int curr_off; > > BUG_ON(!PageLocked(page)); > if (!page_has_buffers(page)) > goto out; > > + curr_off = 0; > head = page_buffers(page); > bh = head; > do { > @@ -1455,6 +1457,24 @@ void block_invalidatepage(struct page *p > bh = next; > } while (bh != head); > > + /* strip the dirty bits and protect against concurrent set_page_dirty */ > + spin_lock(&mapping->private_lock); > + curr_off = 0; > + head = page_buffers(page); > + bh = head; > + do { > + unsigned int next_off = curr_off + bh->b_size; > + next = bh->b_this_page; > + > + if (offset <= curr_off) { > + clear_buffer_dirty(bh); > + set_buffer_invalid(bh); > + } > + curr_off = next_off; > + bh = next; > + } while (bh != head); > + spin_unlock(&mapping->private_lock); If the buffer's redirtied after discard_buffer() got at it, we've got some nasty problems in there. Are you sure this race can happen? Nobody's allowed to have a page mapped while it's undergoing truncation (vmtruncate()). There might be a problem with the final blocks in the page outside i_size. iirc what happens here is that the bh outside i_size _is_ marked dirty, but writepage() will notice that it's outside i_size and will just mark it clean again without doing IO. -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org