diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/Kconfig | 1 | ||||
-rw-r--r-- | fs/ext3/inode.c | 80 | ||||
-rw-r--r-- | fs/ext3/namei.c | 3 | ||||
-rw-r--r-- | fs/ext3/resize.c | 2 | ||||
-rw-r--r-- | fs/ext3/super.c | 17 |
5 files changed, 49 insertions, 54 deletions
diff --git a/fs/ext3/Kconfig b/fs/ext3/Kconfig index 522b15498f45..e8c6ba0e4a3e 100644 --- a/fs/ext3/Kconfig +++ b/fs/ext3/Kconfig | |||
@@ -31,6 +31,7 @@ config EXT3_FS | |||
31 | config EXT3_DEFAULTS_TO_ORDERED | 31 | config EXT3_DEFAULTS_TO_ORDERED |
32 | bool "Default to 'data=ordered' in ext3" | 32 | bool "Default to 'data=ordered' in ext3" |
33 | depends on EXT3_FS | 33 | depends on EXT3_FS |
34 | default y | ||
34 | help | 35 | help |
35 | The journal mode options for ext3 have different tradeoffs | 36 | The journal mode options for ext3 have different tradeoffs |
36 | between when data is guaranteed to be on disk and | 37 | between when data is guaranteed to be on disk and |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 735f0190ec2a..001eb0e2d48e 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1149,9 +1149,25 @@ static int walk_page_buffers( handle_t *handle, | |||
1149 | static int do_journal_get_write_access(handle_t *handle, | 1149 | static int do_journal_get_write_access(handle_t *handle, |
1150 | struct buffer_head *bh) | 1150 | struct buffer_head *bh) |
1151 | { | 1151 | { |
1152 | int dirty = buffer_dirty(bh); | ||
1153 | int ret; | ||
1154 | |||
1152 | if (!buffer_mapped(bh) || buffer_freed(bh)) | 1155 | if (!buffer_mapped(bh) || buffer_freed(bh)) |
1153 | return 0; | 1156 | return 0; |
1154 | return ext3_journal_get_write_access(handle, bh); | 1157 | /* |
1158 | * __block_prepare_write() could have dirtied some buffers. Clean | ||
1159 | * the dirty bit as jbd2_journal_get_write_access() could complain | ||
1160 | * otherwise about fs integrity issues. Setting of the dirty bit | ||
1161 | * by __block_prepare_write() isn't a real problem here as we clear | ||
1162 | * the bit before releasing a page lock and thus writeback cannot | ||
1163 | * ever write the buffer. | ||
1164 | */ | ||
1165 | if (dirty) | ||
1166 | clear_buffer_dirty(bh); | ||
1167 | ret = ext3_journal_get_write_access(handle, bh); | ||
1168 | if (!ret && dirty) | ||
1169 | ret = ext3_journal_dirty_metadata(handle, bh); | ||
1170 | return ret; | ||
1155 | } | 1171 | } |
1156 | 1172 | ||
1157 | /* | 1173 | /* |
@@ -1625,10 +1641,7 @@ static int ext3_writeback_writepage(struct page *page, | |||
1625 | goto out_fail; | 1641 | goto out_fail; |
1626 | } | 1642 | } |
1627 | 1643 | ||
1628 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | 1644 | ret = block_write_full_page(page, ext3_get_block, wbc); |
1629 | ret = nobh_writepage(page, ext3_get_block, wbc); | ||
1630 | else | ||
1631 | ret = block_write_full_page(page, ext3_get_block, wbc); | ||
1632 | 1645 | ||
1633 | err = ext3_journal_stop(handle); | 1646 | err = ext3_journal_stop(handle); |
1634 | if (!ret) | 1647 | if (!ret) |
@@ -1922,17 +1935,6 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page, | |||
1922 | length = blocksize - (offset & (blocksize - 1)); | 1935 | length = blocksize - (offset & (blocksize - 1)); |
1923 | iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); | 1936 | iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); |
1924 | 1937 | ||
1925 | /* | ||
1926 | * For "nobh" option, we can only work if we don't need to | ||
1927 | * read-in the page - otherwise we create buffers to do the IO. | ||
1928 | */ | ||
1929 | if (!page_has_buffers(page) && test_opt(inode->i_sb, NOBH) && | ||
1930 | ext3_should_writeback_data(inode) && PageUptodate(page)) { | ||
1931 | zero_user(page, offset, length); | ||
1932 | set_page_dirty(page); | ||
1933 | goto unlock; | ||
1934 | } | ||
1935 | |||
1936 | if (!page_has_buffers(page)) | 1938 | if (!page_has_buffers(page)) |
1937 | create_empty_buffers(page, blocksize, 0); | 1939 | create_empty_buffers(page, blocksize, 0); |
1938 | 1940 | ||
@@ -2284,27 +2286,6 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, | |||
2284 | depth); | 2286 | depth); |
2285 | 2287 | ||
2286 | /* | 2288 | /* |
2287 | * We've probably journalled the indirect block several | ||
2288 | * times during the truncate. But it's no longer | ||
2289 | * needed and we now drop it from the transaction via | ||
2290 | * journal_revoke(). | ||
2291 | * | ||
2292 | * That's easy if it's exclusively part of this | ||
2293 | * transaction. But if it's part of the committing | ||
2294 | * transaction then journal_forget() will simply | ||
2295 | * brelse() it. That means that if the underlying | ||
2296 | * block is reallocated in ext3_get_block(), | ||
2297 | * unmap_underlying_metadata() will find this block | ||
2298 | * and will try to get rid of it. damn, damn. | ||
2299 | * | ||
2300 | * If this block has already been committed to the | ||
2301 | * journal, a revoke record will be written. And | ||
2302 | * revoke records must be emitted *before* clearing | ||
2303 | * this block's bit in the bitmaps. | ||
2304 | */ | ||
2305 | ext3_forget(handle, 1, inode, bh, bh->b_blocknr); | ||
2306 | |||
2307 | /* | ||
2308 | * Everything below this this pointer has been | 2289 | * Everything below this this pointer has been |
2309 | * released. Now let this top-of-subtree go. | 2290 | * released. Now let this top-of-subtree go. |
2310 | * | 2291 | * |
@@ -2327,6 +2308,31 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, | |||
2327 | truncate_restart_transaction(handle, inode); | 2308 | truncate_restart_transaction(handle, inode); |
2328 | } | 2309 | } |
2329 | 2310 | ||
2311 | /* | ||
2312 | * We've probably journalled the indirect block several | ||
2313 | * times during the truncate. But it's no longer | ||
2314 | * needed and we now drop it from the transaction via | ||
2315 | * journal_revoke(). | ||
2316 | * | ||
2317 | * That's easy if it's exclusively part of this | ||
2318 | * transaction. But if it's part of the committing | ||
2319 | * transaction then journal_forget() will simply | ||
2320 | * brelse() it. That means that if the underlying | ||
2321 | * block is reallocated in ext3_get_block(), | ||
2322 | * unmap_underlying_metadata() will find this block | ||
2323 | * and will try to get rid of it. damn, damn. Thus | ||
2324 | * we don't allow a block to be reallocated until | ||
2325 | * a transaction freeing it has fully committed. | ||
2326 | * | ||
2327 | * We also have to make sure journal replay after a | ||
2328 | * crash does not overwrite non-journaled data blocks | ||
2329 | * with old metadata when the block got reallocated for | ||
2330 | * data. Thus we have to store a revoke record for a | ||
2331 | * block in the same transaction in which we free the | ||
2332 | * block. | ||
2333 | */ | ||
2334 | ext3_forget(handle, 1, inode, bh, bh->b_blocknr); | ||
2335 | |||
2330 | ext3_free_blocks(handle, inode, nr, 1); | 2336 | ext3_free_blocks(handle, inode, nr, 1); |
2331 | 2337 | ||
2332 | if (parent_bh) { | 2338 | if (parent_bh) { |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index ee184084ca42..2b35ddb70d65 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -1447,7 +1447,6 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, | |||
1447 | struct inode *inode) | 1447 | struct inode *inode) |
1448 | { | 1448 | { |
1449 | struct inode *dir = dentry->d_parent->d_inode; | 1449 | struct inode *dir = dentry->d_parent->d_inode; |
1450 | unsigned long offset; | ||
1451 | struct buffer_head * bh; | 1450 | struct buffer_head * bh; |
1452 | struct ext3_dir_entry_2 *de; | 1451 | struct ext3_dir_entry_2 *de; |
1453 | struct super_block * sb; | 1452 | struct super_block * sb; |
@@ -1469,7 +1468,7 @@ static int ext3_add_entry (handle_t *handle, struct dentry *dentry, | |||
1469 | ext3_mark_inode_dirty(handle, dir); | 1468 | ext3_mark_inode_dirty(handle, dir); |
1470 | } | 1469 | } |
1471 | blocks = dir->i_size >> sb->s_blocksize_bits; | 1470 | blocks = dir->i_size >> sb->s_blocksize_bits; |
1472 | for (block = 0, offset = 0; block < blocks; block++) { | 1471 | for (block = 0; block < blocks; block++) { |
1473 | bh = ext3_bread(handle, dir, block, 0, &retval); | 1472 | bh = ext3_bread(handle, dir, block, 0, &retval); |
1474 | if(!bh) | 1473 | if(!bh) |
1475 | return retval; | 1474 | return retval; |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index 54351ac7cef9..0ccd7b12b73c 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -964,7 +964,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
964 | ext3_fsblk_t n_blocks_count) | 964 | ext3_fsblk_t n_blocks_count) |
965 | { | 965 | { |
966 | ext3_fsblk_t o_blocks_count; | 966 | ext3_fsblk_t o_blocks_count; |
967 | unsigned long o_groups_count; | ||
968 | ext3_grpblk_t last; | 967 | ext3_grpblk_t last; |
969 | ext3_grpblk_t add; | 968 | ext3_grpblk_t add; |
970 | struct buffer_head * bh; | 969 | struct buffer_head * bh; |
@@ -976,7 +975,6 @@ int ext3_group_extend(struct super_block *sb, struct ext3_super_block *es, | |||
976 | * yet: we're going to revalidate es->s_blocks_count after | 975 | * yet: we're going to revalidate es->s_blocks_count after |
977 | * taking the s_resize_lock below. */ | 976 | * taking the s_resize_lock below. */ |
978 | o_blocks_count = le32_to_cpu(es->s_blocks_count); | 977 | o_blocks_count = le32_to_cpu(es->s_blocks_count); |
979 | o_groups_count = EXT3_SB(sb)->s_groups_count; | ||
980 | 978 | ||
981 | if (test_opt(sb, DEBUG)) | 979 | if (test_opt(sb, DEBUG)) |
982 | printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK" uto "E3FSBLK" blocks\n", | 980 | printk(KERN_DEBUG "EXT3-fs: extending last group from "E3FSBLK" uto "E3FSBLK" blocks\n", |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 6c953bb255e7..9650a956fd0e 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -661,9 +661,6 @@ static int ext3_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
661 | */ | 661 | */ |
662 | seq_puts(seq, ",barrier="); | 662 | seq_puts(seq, ",barrier="); |
663 | seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); | 663 | seq_puts(seq, test_opt(sb, BARRIER) ? "1" : "0"); |
664 | if (test_opt(sb, NOBH)) | ||
665 | seq_puts(seq, ",nobh"); | ||
666 | |||
667 | seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS))); | 664 | seq_printf(seq, ",data=%s", data_mode_string(test_opt(sb, DATA_FLAGS))); |
668 | if (test_opt(sb, DATA_ERR_ABORT)) | 665 | if (test_opt(sb, DATA_ERR_ABORT)) |
669 | seq_puts(seq, ",data_err=abort"); | 666 | seq_puts(seq, ",data_err=abort"); |
@@ -1255,10 +1252,12 @@ set_qf_format: | |||
1255 | *n_blocks_count = option; | 1252 | *n_blocks_count = option; |
1256 | break; | 1253 | break; |
1257 | case Opt_nobh: | 1254 | case Opt_nobh: |
1258 | set_opt(sbi->s_mount_opt, NOBH); | 1255 | ext3_msg(sb, KERN_WARNING, |
1256 | "warning: ignoring deprecated nobh option"); | ||
1259 | break; | 1257 | break; |
1260 | case Opt_bh: | 1258 | case Opt_bh: |
1261 | clear_opt(sbi->s_mount_opt, NOBH); | 1259 | ext3_msg(sb, KERN_WARNING, |
1260 | "warning: ignoring deprecated bh option"); | ||
1262 | break; | 1261 | break; |
1263 | default: | 1262 | default: |
1264 | ext3_msg(sb, KERN_ERR, | 1263 | ext3_msg(sb, KERN_ERR, |
@@ -2001,14 +2000,6 @@ static int ext3_fill_super (struct super_block *sb, void *data, int silent) | |||
2001 | break; | 2000 | break; |
2002 | } | 2001 | } |
2003 | 2002 | ||
2004 | if (test_opt(sb, NOBH)) { | ||
2005 | if (!(test_opt(sb, DATA_FLAGS) == EXT3_MOUNT_WRITEBACK_DATA)) { | ||
2006 | ext3_msg(sb, KERN_WARNING, | ||
2007 | "warning: ignoring nobh option - " | ||
2008 | "it is supported only with writeback mode"); | ||
2009 | clear_opt(sbi->s_mount_opt, NOBH); | ||
2010 | } | ||
2011 | } | ||
2012 | /* | 2003 | /* |
2013 | * The journal_load will have done any necessary log recovery, | 2004 | * The journal_load will have done any necessary log recovery, |
2014 | * so we can safely mount the rest of the filesystem now. | 2005 | * so we can safely mount the rest of the filesystem now. |