* [PATCH 0/6] Rollup of buffer_head patches in the ext4 patch queue @ 2009-05-12 22:45 Theodore Ts'o 2009-05-12 22:45 ` [PATCH 1/6] ext4: Fix sub-block zeroing for writes into preallocated extents Theodore Ts'o 0 siblings, 1 reply; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List Since there have been multiple version of these patches, sent in two separate groups, and they've also been reordered to reflect the fact that we will be pushing the first three to Linus for 2.6.30, and the last three will wait until 2.6.31, I figured it would be best to send out the current set of patches in the ext4 patch queue so people can more easily look them over. - Ted ^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 1/6] ext4: Fix sub-block zeroing for writes into preallocated extents 2009-05-12 22:45 [PATCH 0/6] Rollup of buffer_head patches in the ext4 patch queue Theodore Ts'o @ 2009-05-12 22:45 ` Theodore Ts'o 2009-05-12 22:45 ` [PATCH 2/6] ext4: Use a fake block number for delayed new buffer_head Theodore Ts'o 0 siblings, 1 reply; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List; +Cc: Aneesh Kumar K.V, Theodore Ts'o From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> We need to mark the buffer_head mapping preallocated space as new during write_begin. Otherwise we don't zero out the page cache content properly for a partial write. This will cause file corruption with preallocation. Now that we mark the buffer_head new we also need to have a valid buffer_head blocknr so that unmap_underlying_metadata unmap the right block. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> --- fs/ext4/extents.c | 2 ++ fs/ext4/inode.c | 7 +++++++ 2 files changed, 9 insertions(+), 0 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index e403321..172656c 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2875,6 +2875,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, if (allocated > max_blocks) allocated = max_blocks; set_buffer_unwritten(bh_result); + bh_result->b_bdev = inode->i_sb->s_bdev; + bh_result->b_blocknr = newblock; goto out2; } diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e91f978..d4b634a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2323,6 +2323,13 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, set_buffer_delay(bh_result); } else if (ret > 0) { bh_result->b_size = (ret << inode->i_blkbits); + /* + * With sub-block writes into unwritten extents + * we also need to mark the buffer as new so that + * the unwritten parts of the buffer gets correctly zeroed. + */ + if (buffer_unwritten(bh_result)) + set_buffer_new(bh_result); ret = 0; } -- 1.6.3.rc4.1.g3e14.dirty ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/6] ext4: Use a fake block number for delayed new buffer_head 2009-05-12 22:45 ` [PATCH 1/6] ext4: Fix sub-block zeroing for writes into preallocated extents Theodore Ts'o @ 2009-05-12 22:45 ` Theodore Ts'o 2009-05-12 22:45 ` [PATCH 3/6] ext4: Clear the unwritten buffer_head flag after the extent is initialized Theodore Ts'o 0 siblings, 1 reply; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List; +Cc: Aneesh Kumar K.V, Theodore Ts'o From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Use a very large unsigned number (~0xffff) as as the fake block number for the delayed new buffer. The VFS should never try to write out this number, but if it does, this will make it obvious. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> --- fs/ext4/inode.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index d4b634a..0ac31a0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2297,6 +2297,10 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) { int ret = 0; + sector_t invalid_block = ~((sector_t) 0xffff); + + if (invalid_block < ext4_blocks_count(EXT4_SB(inode->i_sb)->s_es)) + invalid_block = ~0; BUG_ON(create == 0); BUG_ON(bh_result->b_size != inode->i_sb->s_blocksize); @@ -2318,7 +2322,7 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, /* not enough space to reserve */ return ret; - map_bh(bh_result, inode->i_sb, 0); + map_bh(bh_result, inode->i_sb, invalid_block); set_buffer_new(bh_result); set_buffer_delay(bh_result); } else if (ret > 0) { -- 1.6.3.rc4.1.g3e14.dirty ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 3/6] ext4: Clear the unwritten buffer_head flag after the extent is initialized 2009-05-12 22:45 ` [PATCH 2/6] ext4: Use a fake block number for delayed new buffer_head Theodore Ts'o @ 2009-05-12 22:45 ` Theodore Ts'o 2009-05-12 22:45 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Ts'o 0 siblings, 1 reply; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List; +Cc: Aneesh Kumar K.V, Theodore Ts'o From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> The BH_Unwritten flag indicates that the buffer is allocated on disk but has not been written; that is, the disk was part of a persistent preallocation area. That flag should only be set when a get_blocks() function is looking up a inode's logical to physical block mapping. When ext4_get_blocks_wrap() is called with create=1, the uninitialized extent is converted into an initialized one, so the BH_Unwritten flag is no longer appropriate. Hence, we need to make sure the BH_Unwritten is not left set, since the combination of BH_Mapped and BH_Unwritten is not allowed; among other things, it will result ext4's get_block() to be called over and over again during the write_begin phase of write(2). Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> --- fs/ext4/inode.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0ac31a0..8d0ff73 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1149,6 +1149,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, int retval; clear_buffer_mapped(bh); + clear_buffer_unwritten(bh); /* * Try to see if we can get the block without requesting @@ -1179,6 +1180,12 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, return retval; /* + * The above get_blocks can cause the buffer to be + * marked unwritten. So clear the same. + */ + clear_buffer_unwritten(bh); + + /* * New blocks allocate and/or writing to uninitialized extent * will possibly result in updating i_data, so we take * the write lock of i_data_sem, and call get_blocks() -- 1.6.3.rc4.1.g3e14.dirty ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 4/6] ext4: Properly initialize the buffer_head state 2009-05-12 22:45 ` [PATCH 3/6] ext4: Clear the unwritten buffer_head flag after the extent is initialized Theodore Ts'o @ 2009-05-12 22:45 ` Theodore Ts'o 2009-05-12 22:45 ` [PATCH 5/6] vfs: Add BUG_ON for delayed and unwritten flags in submit_bh() Theodore Ts'o 2009-05-13 12:38 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Tso 0 siblings, 2 replies; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List; +Cc: Aneesh Kumar K.V, Theodore Ts'o From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> These struct buffer_heads are allocated on the stack (and hence are initialized with stack garbage). They are only used to call a get_blocks() function, so that's mostly OK, but b_state must be initialized to be 0 so we don't have any unexpected BH_* flags set by accident, such as BH_Unwritten or BH_Delay. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> --- fs/ext4/extents.c | 1 + fs/ext4/inode.c | 2 +- fs/mpage.c | 6 ++++-- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 172656c..910e198 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -3143,6 +3143,7 @@ retry: ret = PTR_ERR(handle); break; } + map_bh.b_state = 0; ret = ext4_get_blocks_wrap(handle, inode, block, max_blocks, &map_bh, EXT4_CREATE_UNINITIALIZED_EXT, 0, 0); diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8d0ff73..475c3dd 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2049,7 +2049,7 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) if ((mpd->b_state & (1 << BH_Mapped)) && !(mpd->b_state & (1 << BH_Delay))) return 0; - new.b_state = mpd->b_state; + new.b_state = 0; new.b_blocknr = 0; new.b_size = mpd->b_size; next = mpd->b_blocknr; diff --git a/fs/mpage.c b/fs/mpage.c index 680ba60..42381bd 100644 --- a/fs/mpage.c +++ b/fs/mpage.c @@ -379,7 +379,8 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages, struct buffer_head map_bh; unsigned long first_logical_block = 0; - clear_buffer_mapped(&map_bh); + map_bh.b_state = 0; + map_bh.b_size = 0; for (page_idx = 0; page_idx < nr_pages; page_idx++) { struct page *page = list_entry(pages->prev, struct page, lru); @@ -412,7 +413,8 @@ int mpage_readpage(struct page *page, get_block_t get_block) struct buffer_head map_bh; unsigned long first_logical_block = 0; - clear_buffer_mapped(&map_bh); + map_bh.b_state = 0; + map_bh.b_size = 0; bio = do_mpage_readpage(bio, page, 1, &last_block_in_bio, &map_bh, &first_logical_block, get_block); if (bio) -- 1.6.3.rc4.1.g3e14.dirty ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 5/6] vfs: Add BUG_ON for delayed and unwritten flags in submit_bh() 2009-05-12 22:45 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Ts'o @ 2009-05-12 22:45 ` Theodore Ts'o 2009-05-12 22:45 ` [PATCH 6/6] ext4: Mark the unwritten buffer_head as mapped during write_begin Theodore Ts'o 2009-05-13 12:38 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Tso 1 sibling, 1 reply; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List; +Cc: Aneesh Kumar K.V, Theodore Ts'o, linux-fsdevel From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> The BH_Delay and BH_Unwritten flags should never leak out to submit_bh(). So add some BUG_ON() checks to submit_bh so we can get a stack trace and determine how and why this might have happened. (Note that only XFS and ext4 use these buffer head flags, and XFS does not use submit_bh(). So this patch should only modify behavior for ext4.) Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> Cc: linux-fsdevel@vger.kernel.org --- fs/buffer.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/fs/buffer.c b/fs/buffer.c index aed2977..ad01129 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -2933,6 +2933,8 @@ int submit_bh(int rw, struct buffer_head * bh) BUG_ON(!buffer_locked(bh)); BUG_ON(!buffer_mapped(bh)); BUG_ON(!bh->b_end_io); + BUG_ON(buffer_delay(bh)); + BUG_ON(buffer_unwritten(bh)); /* * Mask in barrier bit for a write (could be either a WRITE or a -- 1.6.3.rc4.1.g3e14.dirty ^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 6/6] ext4: Mark the unwritten buffer_head as mapped during write_begin 2009-05-12 22:45 ` [PATCH 5/6] vfs: Add BUG_ON for delayed and unwritten flags in submit_bh() Theodore Ts'o @ 2009-05-12 22:45 ` Theodore Ts'o 0 siblings, 0 replies; 8+ messages in thread From: Theodore Ts'o @ 2009-05-12 22:45 UTC (permalink / raw) To: Ext4 Developers List; +Cc: Aneesh Kumar K.V, Theodore Ts'o From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Setting BH_Unwritten buffer_heads as BH_Mapped avoids multiple (unnecessary) calls to get_block() during the call to the write(2) system call. Setting BH_Unwritten buffer heads as BH_Mapped requires that the writepages() functions can handle BH_Unwritten buffer_heads. After this commit, things work as follows: ext4_ext_get_block() returns unmapped, unwritten, buffer head when called with create = 0 for prealloc space. This makes sure we handle the read path and non-delayed allocation case correctly. Even though the buffer head is marked unmapped we have valid b_blocknr and b_bdev values in the buffer_head. ext4_da_get_block_prep() called for block resrevation will now return mapped, unwritten, new buffer_head for prealloc space. This avoids multiple calls to get_block() for write to same offset. By making such buffers as BH_New, we also assure that sub-block zeroing of buffered writes happens correctly. Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> --- fs/ext4/extents.c | 4 +- fs/ext4/inode.c | 82 +++++++++++++++++++++++++++++++++------------------- 2 files changed, 54 insertions(+), 32 deletions(-) diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 910e198..0f0d5dd 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2865,6 +2865,8 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, if (create == EXT4_CREATE_UNINITIALIZED_EXT) goto out; if (!create) { + if (allocated > max_blocks) + allocated = max_blocks; /* * We have blocks reserved already. We * return allocated blocks so that delalloc @@ -2872,8 +2874,6 @@ int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, * the buffer head will be unmapped so that * a read from the block returns 0s. */ - if (allocated > max_blocks) - allocated = max_blocks; set_buffer_unwritten(bh_result); bh_result->b_bdev = inode->i_sb->s_bdev; bh_result->b_blocknr = newblock; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 475c3dd..cbd3e24 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1846,7 +1846,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd) * @logical - first logical block to start assignment with * * the function goes through all passed space and put actual disk - * block numbers into buffer heads, dropping BH_Delay + * block numbers into buffer heads, dropping BH_Delay and BH_Unwritten */ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, struct buffer_head *exbh) @@ -1896,16 +1896,24 @@ static void mpage_put_bnr_to_bhs(struct mpage_da_data *mpd, sector_t logical, do { if (cur_logical >= logical + blocks) break; - if (buffer_delay(bh)) { - bh->b_blocknr = pblock; - clear_buffer_delay(bh); - bh->b_bdev = inode->i_sb->s_bdev; - } else if (buffer_unwritten(bh)) { - bh->b_blocknr = pblock; - clear_buffer_unwritten(bh); - set_buffer_mapped(bh); - set_buffer_new(bh); - bh->b_bdev = inode->i_sb->s_bdev; + + if (buffer_delay(bh) || + buffer_unwritten(bh)) { + + BUG_ON(bh->b_bdev != inode->i_sb->s_bdev); + + if (buffer_delay(bh)) { + clear_buffer_delay(bh); + bh->b_blocknr = pblock; + } else { + /* + * unwritten already should have + * blocknr assigned. Verify that + */ + clear_buffer_unwritten(bh); + BUG_ON(bh->b_blocknr != pblock); + } + } else if (buffer_mapped(bh)) BUG_ON(bh->b_blocknr != pblock); @@ -2047,7 +2055,8 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) * We consider only non-mapped and non-allocated blocks */ if ((mpd->b_state & (1 << BH_Mapped)) && - !(mpd->b_state & (1 << BH_Delay))) + !(mpd->b_state & (1 << BH_Delay)) && + !(mpd->b_state & (1 << BH_Unwritten))) return 0; new.b_state = 0; new.b_blocknr = 0; @@ -2186,6 +2195,17 @@ flush_it: return; } +static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) +{ + /* + * unmapped buffer is possible for holes. + * delay buffer is possible with delayed allocation. + * We also need to consider unwritten buffer as unmapped. + */ + return (!buffer_mapped(bh) || buffer_delay(bh) || + buffer_unwritten(bh)) && buffer_dirty(bh); +} + /* * __mpage_da_writepage - finds extent of pages and blocks * @@ -2270,8 +2290,7 @@ static int __mpage_da_writepage(struct page *page, * Otherwise we won't make progress * with the page in ext4_da_writepage */ - if (buffer_dirty(bh) && - (!buffer_mapped(bh) || buffer_delay(bh))) { + if (ext4_bh_unmapped_or_delay(NULL, bh)) { mpage_add_bh_to_extent(mpd, logical, bh->b_size, bh->b_state); @@ -2299,6 +2318,14 @@ static int __mpage_da_writepage(struct page *page, /* * this is a special callback for ->write_begin() only * it's intention is to return mapped block or reserve space + * + * For delayed buffer_head we have BH_Mapped, BH_New, BH_Delay set. + * We also have b_blocknr = -1 and b_bdev initialized properly + * + * For unwritten buffer_head we have BH_Mapped, BH_New, BH_Unwritten set. + * We also have b_blocknr = physicalblock mapping unwritten extent and b_bdev + * initialized properly. + * */ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create) @@ -2334,28 +2361,23 @@ static int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, set_buffer_delay(bh_result); } else if (ret > 0) { bh_result->b_size = (ret << inode->i_blkbits); - /* - * With sub-block writes into unwritten extents - * we also need to mark the buffer as new so that - * the unwritten parts of the buffer gets correctly zeroed. - */ - if (buffer_unwritten(bh_result)) + if (buffer_unwritten(bh_result)) { + /* A delayed write to unwritten bh should + * be marked new and mapped. Mapped ensures + * that we don't do get_block multiple times + * when we write to the same offset and new + * ensures that we do proper zero out for + * partial write. + */ set_buffer_new(bh_result); + set_buffer_mapped(bh_result); + } ret = 0; } return ret; } -static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) -{ - /* - * unmapped buffer is possible for holes. - * delay buffer is possible with delayed allocation - */ - return ((!buffer_mapped(bh) || buffer_delay(bh)) && buffer_dirty(bh)); -} ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 4/6] ext4: Properly initialize the buffer_head state 2009-05-12 22:45 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Ts'o 2009-05-12 22:45 ` [PATCH 5/6] vfs: Add BUG_ON for delayed and unwritten flags in submit_bh() Theodore Ts'o @ 2009-05-13 12:38 ` Theodore Tso 1 sibling, 0 replies; 8+ messages in thread From: Theodore Tso @ 2009-05-13 12:38 UTC (permalink / raw) To: Aneesh Kumar K.V; +Cc: Ext4 Developers List On Tue, May 12, 2009 at 06:45:25PM -0400, Theodore Ts'o wrote: > diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c > index 8d0ff73..475c3dd 100644 > --- a/fs/ext4/inode.c > +++ b/fs/ext4/inode.c > @@ -2049,7 +2049,7 @@ static int mpage_da_map_blocks(struct mpage_da_data *mpd) > if ((mpd->b_state & (1 << BH_Mapped)) && > !(mpd->b_state & (1 << BH_Delay))) > return 0; > - new.b_state = mpd->b_state; > + new.b_state = 0; > new.b_blocknr = 0; > new.b_size = mpd->b_size; > next = mpd->b_blocknr; Aneesh, Eric asked about this change, and it looks like this patch hunk is responsible for a regression. With this change, the delayed allocation accounting gets screwed up. It looks like if you delete a file which has blocks that haven't been allocated yet, the delayed allocation count doesn't get dropped, and so sbi->s_dirtyblocks_counter is left higher than it should be. You can replicate this by running "dbench 32" on an ext4 filesystem, hitting ^C after about ten seconds, and then running "sync", and then noting that "cat /sys/fs/ext4/<device>/delayed_allocation_blocks" is non-zero. The df command will show that the blocks in use is too high; if you run the df command, then unmount and remount the filesystem, and re-run the df command, you will see the blocks (in kilobytes) in use will have dropped by the amount reported by delayed_allocation_blocks times 4 (assuming a 4k blocksize). When I reverted just that patch hunk above, the problem went away. What was your reasonining behind changing how new.b_state was getting initialized. (And insert my standard worries that the buffer head flags accounting is getting horrifically complicated --- I have *no* idea why this should be making a difference, especially in the way that the symptoms expressed themselves, but I am very concerned about the fragility of this whole set up...) - Ted ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-05-13 12:38 UTC | newest] Thread overview: 8+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-05-12 22:45 [PATCH 0/6] Rollup of buffer_head patches in the ext4 patch queue Theodore Ts'o 2009-05-12 22:45 ` [PATCH 1/6] ext4: Fix sub-block zeroing for writes into preallocated extents Theodore Ts'o 2009-05-12 22:45 ` [PATCH 2/6] ext4: Use a fake block number for delayed new buffer_head Theodore Ts'o 2009-05-12 22:45 ` [PATCH 3/6] ext4: Clear the unwritten buffer_head flag after the extent is initialized Theodore Ts'o 2009-05-12 22:45 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Ts'o 2009-05-12 22:45 ` [PATCH 5/6] vfs: Add BUG_ON for delayed and unwritten flags in submit_bh() Theodore Ts'o 2009-05-12 22:45 ` [PATCH 6/6] ext4: Mark the unwritten buffer_head as mapped during write_begin Theodore Ts'o 2009-05-13 12:38 ` [PATCH 4/6] ext4: Properly initialize the buffer_head state Theodore Tso
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).