diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 325 |
1 files changed, 235 insertions, 90 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index be21a5ae33cb..03ba20be1329 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/writeback.h> | 34 | #include <linux/writeback.h> |
35 | #include <linux/pagevec.h> | 35 | #include <linux/pagevec.h> |
36 | #include <linux/mpage.h> | 36 | #include <linux/mpage.h> |
37 | #include <linux/namei.h> | ||
37 | #include <linux/uio.h> | 38 | #include <linux/uio.h> |
38 | #include <linux/bio.h> | 39 | #include <linux/bio.h> |
39 | #include "ext4_jbd2.h" | 40 | #include "ext4_jbd2.h" |
@@ -71,12 +72,17 @@ static int ext4_inode_is_fast_symlink(struct inode *inode) | |||
71 | * "bh" may be NULL: a metadata block may have been freed from memory | 72 | * "bh" may be NULL: a metadata block may have been freed from memory |
72 | * but there may still be a record of it in the journal, and that record | 73 | * but there may still be a record of it in the journal, and that record |
73 | * still needs to be revoked. | 74 | * still needs to be revoked. |
75 | * | ||
76 | * If the handle isn't valid we're not journaling so there's nothing to do. | ||
74 | */ | 77 | */ |
75 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | 78 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, |
76 | struct buffer_head *bh, ext4_fsblk_t blocknr) | 79 | struct buffer_head *bh, ext4_fsblk_t blocknr) |
77 | { | 80 | { |
78 | int err; | 81 | int err; |
79 | 82 | ||
83 | if (!ext4_handle_valid(handle)) | ||
84 | return 0; | ||
85 | |||
80 | might_sleep(); | 86 | might_sleep(); |
81 | 87 | ||
82 | BUFFER_TRACE(bh, "enter"); | 88 | BUFFER_TRACE(bh, "enter"); |
@@ -169,7 +175,9 @@ static handle_t *start_transaction(struct inode *inode) | |||
169 | */ | 175 | */ |
170 | static int try_to_extend_transaction(handle_t *handle, struct inode *inode) | 176 | static int try_to_extend_transaction(handle_t *handle, struct inode *inode) |
171 | { | 177 | { |
172 | if (handle->h_buffer_credits > EXT4_RESERVE_TRANS_BLOCKS) | 178 | if (!ext4_handle_valid(handle)) |
179 | return 0; | ||
180 | if (ext4_handle_has_enough_credits(handle, EXT4_RESERVE_TRANS_BLOCKS+1)) | ||
173 | return 0; | 181 | return 0; |
174 | if (!ext4_journal_extend(handle, blocks_for_truncate(inode))) | 182 | if (!ext4_journal_extend(handle, blocks_for_truncate(inode))) |
175 | return 0; | 183 | return 0; |
@@ -183,6 +191,7 @@ static int try_to_extend_transaction(handle_t *handle, struct inode *inode) | |||
183 | */ | 191 | */ |
184 | static int ext4_journal_test_restart(handle_t *handle, struct inode *inode) | 192 | static int ext4_journal_test_restart(handle_t *handle, struct inode *inode) |
185 | { | 193 | { |
194 | BUG_ON(EXT4_JOURNAL(inode) == NULL); | ||
186 | jbd_debug(2, "restarting handle %p\n", handle); | 195 | jbd_debug(2, "restarting handle %p\n", handle); |
187 | return ext4_journal_restart(handle, blocks_for_truncate(inode)); | 196 | return ext4_journal_restart(handle, blocks_for_truncate(inode)); |
188 | } | 197 | } |
@@ -215,7 +224,7 @@ void ext4_delete_inode(struct inode *inode) | |||
215 | } | 224 | } |
216 | 225 | ||
217 | if (IS_SYNC(inode)) | 226 | if (IS_SYNC(inode)) |
218 | handle->h_sync = 1; | 227 | ext4_handle_sync(handle); |
219 | inode->i_size = 0; | 228 | inode->i_size = 0; |
220 | err = ext4_mark_inode_dirty(handle, inode); | 229 | err = ext4_mark_inode_dirty(handle, inode); |
221 | if (err) { | 230 | if (err) { |
@@ -232,7 +241,7 @@ void ext4_delete_inode(struct inode *inode) | |||
232 | * enough credits left in the handle to remove the inode from | 241 | * enough credits left in the handle to remove the inode from |
233 | * the orphan list and set the dtime field. | 242 | * the orphan list and set the dtime field. |
234 | */ | 243 | */ |
235 | if (handle->h_buffer_credits < 3) { | 244 | if (!ext4_handle_has_enough_credits(handle, 3)) { |
236 | err = ext4_journal_extend(handle, 3); | 245 | err = ext4_journal_extend(handle, 3); |
237 | if (err > 0) | 246 | if (err > 0) |
238 | err = ext4_journal_restart(handle, 3); | 247 | err = ext4_journal_restart(handle, 3); |
@@ -351,9 +360,9 @@ static int ext4_block_to_path(struct inode *inode, | |||
351 | final = ptrs; | 360 | final = ptrs; |
352 | } else { | 361 | } else { |
353 | ext4_warning(inode->i_sb, "ext4_block_to_path", | 362 | ext4_warning(inode->i_sb, "ext4_block_to_path", |
354 | "block %lu > max", | 363 | "block %lu > max in inode %lu", |
355 | i_block + direct_blocks + | 364 | i_block + direct_blocks + |
356 | indirect_blocks + double_blocks); | 365 | indirect_blocks + double_blocks, inode->i_ino); |
357 | } | 366 | } |
358 | if (boundary) | 367 | if (boundary) |
359 | *boundary = final - 1 - (i_block & (ptrs - 1)); | 368 | *boundary = final - 1 - (i_block & (ptrs - 1)); |
@@ -505,10 +514,10 @@ static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, | |||
505 | * return the total number of blocks to be allocate, including the | 514 | * return the total number of blocks to be allocate, including the |
506 | * direct and indirect blocks. | 515 | * direct and indirect blocks. |
507 | */ | 516 | */ |
508 | static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned long blks, | 517 | static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned int blks, |
509 | int blocks_to_boundary) | 518 | int blocks_to_boundary) |
510 | { | 519 | { |
511 | unsigned long count = 0; | 520 | unsigned int count = 0; |
512 | 521 | ||
513 | /* | 522 | /* |
514 | * Simple case, [t,d]Indirect block(s) has not allocated yet | 523 | * Simple case, [t,d]Indirect block(s) has not allocated yet |
@@ -546,6 +555,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, | |||
546 | int indirect_blks, int blks, | 555 | int indirect_blks, int blks, |
547 | ext4_fsblk_t new_blocks[4], int *err) | 556 | ext4_fsblk_t new_blocks[4], int *err) |
548 | { | 557 | { |
558 | struct ext4_allocation_request ar; | ||
549 | int target, i; | 559 | int target, i; |
550 | unsigned long count = 0, blk_allocated = 0; | 560 | unsigned long count = 0, blk_allocated = 0; |
551 | int index = 0; | 561 | int index = 0; |
@@ -594,10 +604,17 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, | |||
594 | if (!target) | 604 | if (!target) |
595 | goto allocated; | 605 | goto allocated; |
596 | /* Now allocate data blocks */ | 606 | /* Now allocate data blocks */ |
597 | count = target; | 607 | memset(&ar, 0, sizeof(ar)); |
598 | /* allocating blocks for data blocks */ | 608 | ar.inode = inode; |
599 | current_block = ext4_new_blocks(handle, inode, iblock, | 609 | ar.goal = goal; |
600 | goal, &count, err); | 610 | ar.len = target; |
611 | ar.logical = iblock; | ||
612 | if (S_ISREG(inode->i_mode)) | ||
613 | /* enable in-core preallocation only for regular files */ | ||
614 | ar.flags = EXT4_MB_HINT_DATA; | ||
615 | |||
616 | current_block = ext4_mb_new_blocks(handle, &ar, err); | ||
617 | |||
601 | if (*err && (target == blks)) { | 618 | if (*err && (target == blks)) { |
602 | /* | 619 | /* |
603 | * if the allocation failed and we didn't allocate | 620 | * if the allocation failed and we didn't allocate |
@@ -613,7 +630,7 @@ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, | |||
613 | */ | 630 | */ |
614 | new_blocks[index] = current_block; | 631 | new_blocks[index] = current_block; |
615 | } | 632 | } |
616 | blk_allocated += count; | 633 | blk_allocated += ar.len; |
617 | } | 634 | } |
618 | allocated: | 635 | allocated: |
619 | /* total number of blocks allocated for direct blocks */ | 636 | /* total number of blocks allocated for direct blocks */ |
@@ -708,8 +725,8 @@ static int ext4_alloc_branch(handle_t *handle, struct inode *inode, | |||
708 | set_buffer_uptodate(bh); | 725 | set_buffer_uptodate(bh); |
709 | unlock_buffer(bh); | 726 | unlock_buffer(bh); |
710 | 727 | ||
711 | BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); | 728 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
712 | err = ext4_journal_dirty_metadata(handle, bh); | 729 | err = ext4_handle_dirty_metadata(handle, inode, bh); |
713 | if (err) | 730 | if (err) |
714 | goto failed; | 731 | goto failed; |
715 | } | 732 | } |
@@ -791,8 +808,8 @@ static int ext4_splice_branch(handle_t *handle, struct inode *inode, | |||
791 | * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode. | 808 | * generic_commit_write->__mark_inode_dirty->ext4_dirty_inode. |
792 | */ | 809 | */ |
793 | jbd_debug(5, "splicing indirect only\n"); | 810 | jbd_debug(5, "splicing indirect only\n"); |
794 | BUFFER_TRACE(where->bh, "call ext4_journal_dirty_metadata"); | 811 | BUFFER_TRACE(where->bh, "call ext4_handle_dirty_metadata"); |
795 | err = ext4_journal_dirty_metadata(handle, where->bh); | 812 | err = ext4_handle_dirty_metadata(handle, inode, where->bh); |
796 | if (err) | 813 | if (err) |
797 | goto err_out; | 814 | goto err_out; |
798 | } else { | 815 | } else { |
@@ -839,10 +856,10 @@ err_out: | |||
839 | * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block | 856 | * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block |
840 | * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) | 857 | * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) |
841 | */ | 858 | */ |
842 | int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, | 859 | static int ext4_get_blocks_handle(handle_t *handle, struct inode *inode, |
843 | ext4_lblk_t iblock, unsigned long maxblocks, | 860 | ext4_lblk_t iblock, unsigned int maxblocks, |
844 | struct buffer_head *bh_result, | 861 | struct buffer_head *bh_result, |
845 | int create, int extend_disksize) | 862 | int create, int extend_disksize) |
846 | { | 863 | { |
847 | int err = -EIO; | 864 | int err = -EIO; |
848 | ext4_lblk_t offsets[4]; | 865 | ext4_lblk_t offsets[4]; |
@@ -1044,7 +1061,7 @@ static void ext4_da_update_reserve_space(struct inode *inode, int used) | |||
1044 | * It returns the error in case of allocation failure. | 1061 | * It returns the error in case of allocation failure. |
1045 | */ | 1062 | */ |
1046 | int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | 1063 | int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, |
1047 | unsigned long max_blocks, struct buffer_head *bh, | 1064 | unsigned int max_blocks, struct buffer_head *bh, |
1048 | int create, int extend_disksize, int flag) | 1065 | int create, int extend_disksize, int flag) |
1049 | { | 1066 | { |
1050 | int retval; | 1067 | int retval; |
@@ -1220,8 +1237,8 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode, | |||
1220 | set_buffer_uptodate(bh); | 1237 | set_buffer_uptodate(bh); |
1221 | } | 1238 | } |
1222 | unlock_buffer(bh); | 1239 | unlock_buffer(bh); |
1223 | BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); | 1240 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
1224 | err = ext4_journal_dirty_metadata(handle, bh); | 1241 | err = ext4_handle_dirty_metadata(handle, inode, bh); |
1225 | if (!fatal) | 1242 | if (!fatal) |
1226 | fatal = err; | 1243 | fatal = err; |
1227 | } else { | 1244 | } else { |
@@ -1334,6 +1351,10 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping, | |||
1334 | pgoff_t index; | 1351 | pgoff_t index; |
1335 | unsigned from, to; | 1352 | unsigned from, to; |
1336 | 1353 | ||
1354 | trace_mark(ext4_write_begin, | ||
1355 | "dev %s ino %lu pos %llu len %u flags %u", | ||
1356 | inode->i_sb->s_id, inode->i_ino, | ||
1357 | (unsigned long long) pos, len, flags); | ||
1337 | index = pos >> PAGE_CACHE_SHIFT; | 1358 | index = pos >> PAGE_CACHE_SHIFT; |
1338 | from = pos & (PAGE_CACHE_SIZE - 1); | 1359 | from = pos & (PAGE_CACHE_SIZE - 1); |
1339 | to = from + len; | 1360 | to = from + len; |
@@ -1345,7 +1366,7 @@ retry: | |||
1345 | goto out; | 1366 | goto out; |
1346 | } | 1367 | } |
1347 | 1368 | ||
1348 | page = __grab_cache_page(mapping, index); | 1369 | page = grab_cache_page_write_begin(mapping, index, flags); |
1349 | if (!page) { | 1370 | if (!page) { |
1350 | ext4_journal_stop(handle); | 1371 | ext4_journal_stop(handle); |
1351 | ret = -ENOMEM; | 1372 | ret = -ENOMEM; |
@@ -1386,7 +1407,7 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh) | |||
1386 | if (!buffer_mapped(bh) || buffer_freed(bh)) | 1407 | if (!buffer_mapped(bh) || buffer_freed(bh)) |
1387 | return 0; | 1408 | return 0; |
1388 | set_buffer_uptodate(bh); | 1409 | set_buffer_uptodate(bh); |
1389 | return ext4_journal_dirty_metadata(handle, bh); | 1410 | return ext4_handle_dirty_metadata(handle, NULL, bh); |
1390 | } | 1411 | } |
1391 | 1412 | ||
1392 | /* | 1413 | /* |
@@ -1405,6 +1426,10 @@ static int ext4_ordered_write_end(struct file *file, | |||
1405 | struct inode *inode = mapping->host; | 1426 | struct inode *inode = mapping->host; |
1406 | int ret = 0, ret2; | 1427 | int ret = 0, ret2; |
1407 | 1428 | ||
1429 | trace_mark(ext4_ordered_write_end, | ||
1430 | "dev %s ino %lu pos %llu len %u copied %u", | ||
1431 | inode->i_sb->s_id, inode->i_ino, | ||
1432 | (unsigned long long) pos, len, copied); | ||
1408 | ret = ext4_jbd2_file_inode(handle, inode); | 1433 | ret = ext4_jbd2_file_inode(handle, inode); |
1409 | 1434 | ||
1410 | if (ret == 0) { | 1435 | if (ret == 0) { |
@@ -1443,6 +1468,10 @@ static int ext4_writeback_write_end(struct file *file, | |||
1443 | int ret = 0, ret2; | 1468 | int ret = 0, ret2; |
1444 | loff_t new_i_size; | 1469 | loff_t new_i_size; |
1445 | 1470 | ||
1471 | trace_mark(ext4_writeback_write_end, | ||
1472 | "dev %s ino %lu pos %llu len %u copied %u", | ||
1473 | inode->i_sb->s_id, inode->i_ino, | ||
1474 | (unsigned long long) pos, len, copied); | ||
1446 | new_i_size = pos + copied; | 1475 | new_i_size = pos + copied; |
1447 | if (new_i_size > EXT4_I(inode)->i_disksize) { | 1476 | if (new_i_size > EXT4_I(inode)->i_disksize) { |
1448 | ext4_update_i_disksize(inode, new_i_size); | 1477 | ext4_update_i_disksize(inode, new_i_size); |
@@ -1478,6 +1507,10 @@ static int ext4_journalled_write_end(struct file *file, | |||
1478 | unsigned from, to; | 1507 | unsigned from, to; |
1479 | loff_t new_i_size; | 1508 | loff_t new_i_size; |
1480 | 1509 | ||
1510 | trace_mark(ext4_journalled_write_end, | ||
1511 | "dev %s ino %lu pos %llu len %u copied %u", | ||
1512 | inode->i_sb->s_id, inode->i_ino, | ||
1513 | (unsigned long long) pos, len, copied); | ||
1481 | from = pos & (PAGE_CACHE_SIZE - 1); | 1514 | from = pos & (PAGE_CACHE_SIZE - 1); |
1482 | to = from + len; | 1515 | to = from + len; |
1483 | 1516 | ||
@@ -1624,7 +1657,7 @@ struct mpage_da_data { | |||
1624 | get_block_t *get_block; | 1657 | get_block_t *get_block; |
1625 | struct writeback_control *wbc; | 1658 | struct writeback_control *wbc; |
1626 | int io_done; | 1659 | int io_done; |
1627 | long pages_written; | 1660 | int pages_written; |
1628 | int retval; | 1661 | int retval; |
1629 | }; | 1662 | }; |
1630 | 1663 | ||
@@ -1644,35 +1677,39 @@ struct mpage_da_data { | |||
1644 | */ | 1677 | */ |
1645 | static int mpage_da_submit_io(struct mpage_da_data *mpd) | 1678 | static int mpage_da_submit_io(struct mpage_da_data *mpd) |
1646 | { | 1679 | { |
1647 | struct address_space *mapping = mpd->inode->i_mapping; | ||
1648 | int ret = 0, err, nr_pages, i; | ||
1649 | unsigned long index, end; | ||
1650 | struct pagevec pvec; | ||
1651 | long pages_skipped; | 1680 | long pages_skipped; |
1681 | struct pagevec pvec; | ||
1682 | unsigned long index, end; | ||
1683 | int ret = 0, err, nr_pages, i; | ||
1684 | struct inode *inode = mpd->inode; | ||
1685 | struct address_space *mapping = inode->i_mapping; | ||
1652 | 1686 | ||
1653 | BUG_ON(mpd->next_page <= mpd->first_page); | 1687 | BUG_ON(mpd->next_page <= mpd->first_page); |
1654 | pagevec_init(&pvec, 0); | 1688 | /* |
1689 | * We need to start from the first_page to the next_page - 1 | ||
1690 | * to make sure we also write the mapped dirty buffer_heads. | ||
1691 | * If we look at mpd->lbh.b_blocknr we would only be looking | ||
1692 | * at the currently mapped buffer_heads. | ||
1693 | */ | ||
1655 | index = mpd->first_page; | 1694 | index = mpd->first_page; |
1656 | end = mpd->next_page - 1; | 1695 | end = mpd->next_page - 1; |
1657 | 1696 | ||
1697 | pagevec_init(&pvec, 0); | ||
1658 | while (index <= end) { | 1698 | while (index <= end) { |
1659 | /* | 1699 | nr_pages = pagevec_lookup(&pvec, mapping, index, PAGEVEC_SIZE); |
1660 | * We can use PAGECACHE_TAG_DIRTY lookup here because | ||
1661 | * even though we have cleared the dirty flag on the page | ||
1662 | * We still keep the page in the radix tree with tag | ||
1663 | * PAGECACHE_TAG_DIRTY. See clear_page_dirty_for_io. | ||
1664 | * The PAGECACHE_TAG_DIRTY is cleared in set_page_writeback | ||
1665 | * which is called via the below writepage callback. | ||
1666 | */ | ||
1667 | nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, | ||
1668 | PAGECACHE_TAG_DIRTY, | ||
1669 | min(end - index, | ||
1670 | (pgoff_t)PAGEVEC_SIZE-1) + 1); | ||
1671 | if (nr_pages == 0) | 1700 | if (nr_pages == 0) |
1672 | break; | 1701 | break; |
1673 | for (i = 0; i < nr_pages; i++) { | 1702 | for (i = 0; i < nr_pages; i++) { |
1674 | struct page *page = pvec.pages[i]; | 1703 | struct page *page = pvec.pages[i]; |
1675 | 1704 | ||
1705 | index = page->index; | ||
1706 | if (index > end) | ||
1707 | break; | ||
1708 | index++; | ||
1709 | |||
1710 | BUG_ON(!PageLocked(page)); | ||
1711 | BUG_ON(PageWriteback(page)); | ||
1712 | |||
1676 | pages_skipped = mpd->wbc->pages_skipped; | 1713 | pages_skipped = mpd->wbc->pages_skipped; |
1677 | err = mapping->a_ops->writepage(page, mpd->wbc); | 1714 | err = mapping->a_ops->writepage(page, mpd->wbc); |
1678 | if (!err && (pages_skipped == mpd->wbc->pages_skipped)) | 1715 | if (!err && (pages_skipped == mpd->wbc->pages_skipped)) |
@@ -1830,13 +1867,13 @@ static void ext4_print_free_blocks(struct inode *inode) | |||
1830 | ext4_count_free_blocks(inode->i_sb)); | 1867 | ext4_count_free_blocks(inode->i_sb)); |
1831 | printk(KERN_EMERG "Free/Dirty block details\n"); | 1868 | printk(KERN_EMERG "Free/Dirty block details\n"); |
1832 | printk(KERN_EMERG "free_blocks=%lld\n", | 1869 | printk(KERN_EMERG "free_blocks=%lld\n", |
1833 | percpu_counter_sum(&sbi->s_freeblocks_counter)); | 1870 | (long long)percpu_counter_sum(&sbi->s_freeblocks_counter)); |
1834 | printk(KERN_EMERG "dirty_blocks=%lld\n", | 1871 | printk(KERN_EMERG "dirty_blocks=%lld\n", |
1835 | percpu_counter_sum(&sbi->s_dirtyblocks_counter)); | 1872 | (long long)percpu_counter_sum(&sbi->s_dirtyblocks_counter)); |
1836 | printk(KERN_EMERG "Block reservation details\n"); | 1873 | printk(KERN_EMERG "Block reservation details\n"); |
1837 | printk(KERN_EMERG "i_reserved_data_blocks=%lu\n", | 1874 | printk(KERN_EMERG "i_reserved_data_blocks=%u\n", |
1838 | EXT4_I(inode)->i_reserved_data_blocks); | 1875 | EXT4_I(inode)->i_reserved_data_blocks); |
1839 | printk(KERN_EMERG "i_reserved_meta_blocks=%lu\n", | 1876 | printk(KERN_EMERG "i_reserved_meta_blocks=%u\n", |
1840 | EXT4_I(inode)->i_reserved_meta_blocks); | 1877 | EXT4_I(inode)->i_reserved_meta_blocks); |
1841 | return; | 1878 | return; |
1842 | } | 1879 | } |
@@ -2086,11 +2123,29 @@ static int __mpage_da_writepage(struct page *page, | |||
2086 | bh = head; | 2123 | bh = head; |
2087 | do { | 2124 | do { |
2088 | BUG_ON(buffer_locked(bh)); | 2125 | BUG_ON(buffer_locked(bh)); |
2126 | /* | ||
2127 | * We need to try to allocate | ||
2128 | * unmapped blocks in the same page. | ||
2129 | * Otherwise we won't make progress | ||
2130 | * with the page in ext4_da_writepage | ||
2131 | */ | ||
2089 | if (buffer_dirty(bh) && | 2132 | if (buffer_dirty(bh) && |
2090 | (!buffer_mapped(bh) || buffer_delay(bh))) { | 2133 | (!buffer_mapped(bh) || buffer_delay(bh))) { |
2091 | mpage_add_bh_to_extent(mpd, logical, bh); | 2134 | mpage_add_bh_to_extent(mpd, logical, bh); |
2092 | if (mpd->io_done) | 2135 | if (mpd->io_done) |
2093 | return MPAGE_DA_EXTENT_TAIL; | 2136 | return MPAGE_DA_EXTENT_TAIL; |
2137 | } else if (buffer_dirty(bh) && (buffer_mapped(bh))) { | ||
2138 | /* | ||
2139 | * mapped dirty buffer. We need to update | ||
2140 | * the b_state because we look at | ||
2141 | * b_state in mpage_da_map_blocks. We don't | ||
2142 | * update b_size because if we find an | ||
2143 | * unmapped buffer_head later we need to | ||
2144 | * use the b_state flag of that buffer_head. | ||
2145 | */ | ||
2146 | if (mpd->lbh.b_size == 0) | ||
2147 | mpd->lbh.b_state = | ||
2148 | bh->b_state & BH_FLAGS; | ||
2094 | } | 2149 | } |
2095 | logical++; | 2150 | logical++; |
2096 | } while ((bh = bh->b_this_page) != head); | 2151 | } while ((bh = bh->b_this_page) != head); |
@@ -2268,10 +2323,13 @@ static int ext4_da_writepage(struct page *page, | |||
2268 | { | 2323 | { |
2269 | int ret = 0; | 2324 | int ret = 0; |
2270 | loff_t size; | 2325 | loff_t size; |
2271 | unsigned long len; | 2326 | unsigned int len; |
2272 | struct buffer_head *page_bufs; | 2327 | struct buffer_head *page_bufs; |
2273 | struct inode *inode = page->mapping->host; | 2328 | struct inode *inode = page->mapping->host; |
2274 | 2329 | ||
2330 | trace_mark(ext4_da_writepage, | ||
2331 | "dev %s ino %lu page_index %lu", | ||
2332 | inode->i_sb->s_id, inode->i_ino, page->index); | ||
2275 | size = i_size_read(inode); | 2333 | size = i_size_read(inode); |
2276 | if (page->index == size >> PAGE_CACHE_SHIFT) | 2334 | if (page->index == size >> PAGE_CACHE_SHIFT) |
2277 | len = size & ~PAGE_CACHE_MASK; | 2335 | len = size & ~PAGE_CACHE_MASK; |
@@ -2377,10 +2435,25 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2377 | struct mpage_da_data mpd; | 2435 | struct mpage_da_data mpd; |
2378 | struct inode *inode = mapping->host; | 2436 | struct inode *inode = mapping->host; |
2379 | int no_nrwrite_index_update; | 2437 | int no_nrwrite_index_update; |
2380 | long pages_written = 0, pages_skipped; | 2438 | int pages_written = 0; |
2439 | long pages_skipped; | ||
2381 | int needed_blocks, ret = 0, nr_to_writebump = 0; | 2440 | int needed_blocks, ret = 0, nr_to_writebump = 0; |
2382 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2441 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
2383 | 2442 | ||
2443 | trace_mark(ext4_da_writepages, | ||
2444 | "dev %s ino %lu nr_t_write %ld " | ||
2445 | "pages_skipped %ld range_start %llu " | ||
2446 | "range_end %llu nonblocking %d " | ||
2447 | "for_kupdate %d for_reclaim %d " | ||
2448 | "for_writepages %d range_cyclic %d", | ||
2449 | inode->i_sb->s_id, inode->i_ino, | ||
2450 | wbc->nr_to_write, wbc->pages_skipped, | ||
2451 | (unsigned long long) wbc->range_start, | ||
2452 | (unsigned long long) wbc->range_end, | ||
2453 | wbc->nonblocking, wbc->for_kupdate, | ||
2454 | wbc->for_reclaim, wbc->for_writepages, | ||
2455 | wbc->range_cyclic); | ||
2456 | |||
2384 | /* | 2457 | /* |
2385 | * No pages to write? This is mainly a kludge to avoid starting | 2458 | * No pages to write? This is mainly a kludge to avoid starting |
2386 | * a transaction for special inodes like journal inode on last iput() | 2459 | * a transaction for special inodes like journal inode on last iput() |
@@ -2388,6 +2461,20 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2388 | */ | 2461 | */ |
2389 | if (!mapping->nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) | 2462 | if (!mapping->nrpages || !mapping_tagged(mapping, PAGECACHE_TAG_DIRTY)) |
2390 | return 0; | 2463 | return 0; |
2464 | |||
2465 | /* | ||
2466 | * If the filesystem has aborted, it is read-only, so return | ||
2467 | * right away instead of dumping stack traces later on that | ||
2468 | * will obscure the real source of the problem. We test | ||
2469 | * EXT4_MOUNT_ABORT instead of sb->s_flag's MS_RDONLY because | ||
2470 | * the latter could be true if the filesystem is mounted | ||
2471 | * read-only, and in that case, ext4_da_writepages should | ||
2472 | * *never* be called, so if that ever happens, we would want | ||
2473 | * the stack trace. | ||
2474 | */ | ||
2475 | if (unlikely(sbi->s_mount_opt & EXT4_MOUNT_ABORT)) | ||
2476 | return -EROFS; | ||
2477 | |||
2391 | /* | 2478 | /* |
2392 | * Make sure nr_to_write is >= sbi->s_mb_stream_request | 2479 | * Make sure nr_to_write is >= sbi->s_mb_stream_request |
2393 | * This make sure small files blocks are allocated in | 2480 | * This make sure small files blocks are allocated in |
@@ -2432,7 +2519,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2432 | handle = ext4_journal_start(inode, needed_blocks); | 2519 | handle = ext4_journal_start(inode, needed_blocks); |
2433 | if (IS_ERR(handle)) { | 2520 | if (IS_ERR(handle)) { |
2434 | ret = PTR_ERR(handle); | 2521 | ret = PTR_ERR(handle); |
2435 | printk(KERN_EMERG "%s: jbd2_start: " | 2522 | printk(KERN_CRIT "%s: jbd2_start: " |
2436 | "%ld pages, ino %lu; err %d\n", __func__, | 2523 | "%ld pages, ino %lu; err %d\n", __func__, |
2437 | wbc->nr_to_write, inode->i_ino, ret); | 2524 | wbc->nr_to_write, inode->i_ino, ret); |
2438 | dump_stack(); | 2525 | dump_stack(); |
@@ -2485,6 +2572,14 @@ out_writepages: | |||
2485 | if (!no_nrwrite_index_update) | 2572 | if (!no_nrwrite_index_update) |
2486 | wbc->no_nrwrite_index_update = 0; | 2573 | wbc->no_nrwrite_index_update = 0; |
2487 | wbc->nr_to_write -= nr_to_writebump; | 2574 | wbc->nr_to_write -= nr_to_writebump; |
2575 | trace_mark(ext4_da_writepage_result, | ||
2576 | "dev %s ino %lu ret %d pages_written %d " | ||
2577 | "pages_skipped %ld congestion %d " | ||
2578 | "more_io %d no_nrwrite_index_update %d", | ||
2579 | inode->i_sb->s_id, inode->i_ino, ret, | ||
2580 | pages_written, wbc->pages_skipped, | ||
2581 | wbc->encountered_congestion, wbc->more_io, | ||
2582 | wbc->no_nrwrite_index_update); | ||
2488 | return ret; | 2583 | return ret; |
2489 | } | 2584 | } |
2490 | 2585 | ||
@@ -2497,7 +2592,7 @@ static int ext4_nonda_switch(struct super_block *sb) | |||
2497 | /* | 2592 | /* |
2498 | * switch to non delalloc mode if we are running low | 2593 | * switch to non delalloc mode if we are running low |
2499 | * on free block. The free block accounting via percpu | 2594 | * on free block. The free block accounting via percpu |
2500 | * counters can get slightly wrong with FBC_BATCH getting | 2595 | * counters can get slightly wrong with percpu_counter_batch getting |
2501 | * accumulated on each CPU without updating global counters | 2596 | * accumulated on each CPU without updating global counters |
2502 | * Delalloc need an accurate free block accounting. So switch | 2597 | * Delalloc need an accurate free block accounting. So switch |
2503 | * to non delalloc when we are near to error range. | 2598 | * to non delalloc when we are near to error range. |
@@ -2536,6 +2631,11 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, | |||
2536 | len, flags, pagep, fsdata); | 2631 | len, flags, pagep, fsdata); |
2537 | } | 2632 | } |
2538 | *fsdata = (void *)0; | 2633 | *fsdata = (void *)0; |
2634 | |||
2635 | trace_mark(ext4_da_write_begin, | ||
2636 | "dev %s ino %lu pos %llu len %u flags %u", | ||
2637 | inode->i_sb->s_id, inode->i_ino, | ||
2638 | (unsigned long long) pos, len, flags); | ||
2539 | retry: | 2639 | retry: |
2540 | /* | 2640 | /* |
2541 | * With delayed allocation, we don't log the i_disksize update | 2641 | * With delayed allocation, we don't log the i_disksize update |
@@ -2549,7 +2649,7 @@ retry: | |||
2549 | goto out; | 2649 | goto out; |
2550 | } | 2650 | } |
2551 | 2651 | ||
2552 | page = __grab_cache_page(mapping, index); | 2652 | page = grab_cache_page_write_begin(mapping, index, flags); |
2553 | if (!page) { | 2653 | if (!page) { |
2554 | ext4_journal_stop(handle); | 2654 | ext4_journal_stop(handle); |
2555 | ret = -ENOMEM; | 2655 | ret = -ENOMEM; |
@@ -2625,6 +2725,10 @@ static int ext4_da_write_end(struct file *file, | |||
2625 | } | 2725 | } |
2626 | } | 2726 | } |
2627 | 2727 | ||
2728 | trace_mark(ext4_da_write_end, | ||
2729 | "dev %s ino %lu pos %llu len %u copied %u", | ||
2730 | inode->i_sb->s_id, inode->i_ino, | ||
2731 | (unsigned long long) pos, len, copied); | ||
2628 | start = pos & (PAGE_CACHE_SIZE - 1); | 2732 | start = pos & (PAGE_CACHE_SIZE - 1); |
2629 | end = start + copied - 1; | 2733 | end = start + copied - 1; |
2630 | 2734 | ||
@@ -2717,7 +2821,7 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) | |||
2717 | filemap_write_and_wait(mapping); | 2821 | filemap_write_and_wait(mapping); |
2718 | } | 2822 | } |
2719 | 2823 | ||
2720 | if (EXT4_I(inode)->i_state & EXT4_STATE_JDATA) { | 2824 | if (EXT4_JOURNAL(inode) && EXT4_I(inode)->i_state & EXT4_STATE_JDATA) { |
2721 | /* | 2825 | /* |
2722 | * This is a REALLY heavyweight approach, but the use of | 2826 | * This is a REALLY heavyweight approach, but the use of |
2723 | * bmap on dirty files is expected to be extremely rare: | 2827 | * bmap on dirty files is expected to be extremely rare: |
@@ -2835,6 +2939,9 @@ static int ext4_normal_writepage(struct page *page, | |||
2835 | loff_t size = i_size_read(inode); | 2939 | loff_t size = i_size_read(inode); |
2836 | loff_t len; | 2940 | loff_t len; |
2837 | 2941 | ||
2942 | trace_mark(ext4_normal_writepage, | ||
2943 | "dev %s ino %lu page_index %lu", | ||
2944 | inode->i_sb->s_id, inode->i_ino, page->index); | ||
2838 | J_ASSERT(PageLocked(page)); | 2945 | J_ASSERT(PageLocked(page)); |
2839 | if (page->index == size >> PAGE_CACHE_SHIFT) | 2946 | if (page->index == size >> PAGE_CACHE_SHIFT) |
2840 | len = size & ~PAGE_CACHE_MASK; | 2947 | len = size & ~PAGE_CACHE_MASK; |
@@ -2920,6 +3027,9 @@ static int ext4_journalled_writepage(struct page *page, | |||
2920 | loff_t size = i_size_read(inode); | 3027 | loff_t size = i_size_read(inode); |
2921 | loff_t len; | 3028 | loff_t len; |
2922 | 3029 | ||
3030 | trace_mark(ext4_journalled_writepage, | ||
3031 | "dev %s ino %lu page_index %lu", | ||
3032 | inode->i_sb->s_id, inode->i_ino, page->index); | ||
2923 | J_ASSERT(PageLocked(page)); | 3033 | J_ASSERT(PageLocked(page)); |
2924 | if (page->index == size >> PAGE_CACHE_SHIFT) | 3034 | if (page->index == size >> PAGE_CACHE_SHIFT) |
2925 | len = size & ~PAGE_CACHE_MASK; | 3035 | len = size & ~PAGE_CACHE_MASK; |
@@ -2988,7 +3098,10 @@ static void ext4_invalidatepage(struct page *page, unsigned long offset) | |||
2988 | if (offset == 0) | 3098 | if (offset == 0) |
2989 | ClearPageChecked(page); | 3099 | ClearPageChecked(page); |
2990 | 3100 | ||
2991 | jbd2_journal_invalidatepage(journal, page, offset); | 3101 | if (journal) |
3102 | jbd2_journal_invalidatepage(journal, page, offset); | ||
3103 | else | ||
3104 | block_invalidatepage(page, offset); | ||
2992 | } | 3105 | } |
2993 | 3106 | ||
2994 | static int ext4_releasepage(struct page *page, gfp_t wait) | 3107 | static int ext4_releasepage(struct page *page, gfp_t wait) |
@@ -2998,7 +3111,10 @@ static int ext4_releasepage(struct page *page, gfp_t wait) | |||
2998 | WARN_ON(PageChecked(page)); | 3111 | WARN_ON(PageChecked(page)); |
2999 | if (!page_has_buffers(page)) | 3112 | if (!page_has_buffers(page)) |
3000 | return 0; | 3113 | return 0; |
3001 | return jbd2_journal_try_to_free_buffers(journal, page, wait); | 3114 | if (journal) |
3115 | return jbd2_journal_try_to_free_buffers(journal, page, wait); | ||
3116 | else | ||
3117 | return try_to_free_buffers(page); | ||
3002 | } | 3118 | } |
3003 | 3119 | ||
3004 | /* | 3120 | /* |
@@ -3270,7 +3386,7 @@ int ext4_block_truncate_page(handle_t *handle, | |||
3270 | 3386 | ||
3271 | err = 0; | 3387 | err = 0; |
3272 | if (ext4_should_journal_data(inode)) { | 3388 | if (ext4_should_journal_data(inode)) { |
3273 | err = ext4_journal_dirty_metadata(handle, bh); | 3389 | err = ext4_handle_dirty_metadata(handle, inode, bh); |
3274 | } else { | 3390 | } else { |
3275 | if (ext4_should_order_data(inode)) | 3391 | if (ext4_should_order_data(inode)) |
3276 | err = ext4_jbd2_file_inode(handle, inode); | 3392 | err = ext4_jbd2_file_inode(handle, inode); |
@@ -3394,8 +3510,8 @@ static void ext4_clear_blocks(handle_t *handle, struct inode *inode, | |||
3394 | __le32 *p; | 3510 | __le32 *p; |
3395 | if (try_to_extend_transaction(handle, inode)) { | 3511 | if (try_to_extend_transaction(handle, inode)) { |
3396 | if (bh) { | 3512 | if (bh) { |
3397 | BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); | 3513 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
3398 | ext4_journal_dirty_metadata(handle, bh); | 3514 | ext4_handle_dirty_metadata(handle, inode, bh); |
3399 | } | 3515 | } |
3400 | ext4_mark_inode_dirty(handle, inode); | 3516 | ext4_mark_inode_dirty(handle, inode); |
3401 | ext4_journal_test_restart(handle, inode); | 3517 | ext4_journal_test_restart(handle, inode); |
@@ -3495,7 +3611,7 @@ static void ext4_free_data(handle_t *handle, struct inode *inode, | |||
3495 | count, block_to_free_p, p); | 3611 | count, block_to_free_p, p); |
3496 | 3612 | ||
3497 | if (this_bh) { | 3613 | if (this_bh) { |
3498 | BUFFER_TRACE(this_bh, "call ext4_journal_dirty_metadata"); | 3614 | BUFFER_TRACE(this_bh, "call ext4_handle_dirty_metadata"); |
3499 | 3615 | ||
3500 | /* | 3616 | /* |
3501 | * The buffer head should have an attached journal head at this | 3617 | * The buffer head should have an attached journal head at this |
@@ -3503,8 +3619,8 @@ static void ext4_free_data(handle_t *handle, struct inode *inode, | |||
3503 | * block pointed to itself, it would have been detached when | 3619 | * block pointed to itself, it would have been detached when |
3504 | * the block was cleared. Check for this instead of OOPSing. | 3620 | * the block was cleared. Check for this instead of OOPSing. |
3505 | */ | 3621 | */ |
3506 | if (bh2jh(this_bh)) | 3622 | if ((EXT4_JOURNAL(inode) == NULL) || bh2jh(this_bh)) |
3507 | ext4_journal_dirty_metadata(handle, this_bh); | 3623 | ext4_handle_dirty_metadata(handle, inode, this_bh); |
3508 | else | 3624 | else |
3509 | ext4_error(inode->i_sb, __func__, | 3625 | ext4_error(inode->i_sb, __func__, |
3510 | "circular indirect block detected, " | 3626 | "circular indirect block detected, " |
@@ -3534,7 +3650,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode, | |||
3534 | ext4_fsblk_t nr; | 3650 | ext4_fsblk_t nr; |
3535 | __le32 *p; | 3651 | __le32 *p; |
3536 | 3652 | ||
3537 | if (is_handle_aborted(handle)) | 3653 | if (ext4_handle_is_aborted(handle)) |
3538 | return; | 3654 | return; |
3539 | 3655 | ||
3540 | if (depth--) { | 3656 | if (depth--) { |
@@ -3604,7 +3720,7 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode, | |||
3604 | * will merely complain about releasing a free block, | 3720 | * will merely complain about releasing a free block, |
3605 | * rather than leaking blocks. | 3721 | * rather than leaking blocks. |
3606 | */ | 3722 | */ |
3607 | if (is_handle_aborted(handle)) | 3723 | if (ext4_handle_is_aborted(handle)) |
3608 | return; | 3724 | return; |
3609 | if (try_to_extend_transaction(handle, inode)) { | 3725 | if (try_to_extend_transaction(handle, inode)) { |
3610 | ext4_mark_inode_dirty(handle, inode); | 3726 | ext4_mark_inode_dirty(handle, inode); |
@@ -3623,9 +3739,10 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode, | |||
3623 | parent_bh)){ | 3739 | parent_bh)){ |
3624 | *p = 0; | 3740 | *p = 0; |
3625 | BUFFER_TRACE(parent_bh, | 3741 | BUFFER_TRACE(parent_bh, |
3626 | "call ext4_journal_dirty_metadata"); | 3742 | "call ext4_handle_dirty_metadata"); |
3627 | ext4_journal_dirty_metadata(handle, | 3743 | ext4_handle_dirty_metadata(handle, |
3628 | parent_bh); | 3744 | inode, |
3745 | parent_bh); | ||
3629 | } | 3746 | } |
3630 | } | 3747 | } |
3631 | } | 3748 | } |
@@ -3813,7 +3930,7 @@ do_indirects: | |||
3813 | * synchronous | 3930 | * synchronous |
3814 | */ | 3931 | */ |
3815 | if (IS_SYNC(inode)) | 3932 | if (IS_SYNC(inode)) |
3816 | handle->h_sync = 1; | 3933 | ext4_handle_sync(handle); |
3817 | out_stop: | 3934 | out_stop: |
3818 | /* | 3935 | /* |
3819 | * If this was a simple ftruncate(), and the file will remain alive | 3936 | * If this was a simple ftruncate(), and the file will remain alive |
@@ -3843,7 +3960,7 @@ static int __ext4_get_inode_loc(struct inode *inode, | |||
3843 | ext4_fsblk_t block; | 3960 | ext4_fsblk_t block; |
3844 | int inodes_per_block, inode_offset; | 3961 | int inodes_per_block, inode_offset; |
3845 | 3962 | ||
3846 | iloc->bh = 0; | 3963 | iloc->bh = NULL; |
3847 | if (!ext4_valid_inum(sb, inode->i_ino)) | 3964 | if (!ext4_valid_inum(sb, inode->i_ino)) |
3848 | return -EIO; | 3965 | return -EIO; |
3849 | 3966 | ||
@@ -3950,7 +4067,7 @@ make_io: | |||
3950 | num = EXT4_INODES_PER_GROUP(sb); | 4067 | num = EXT4_INODES_PER_GROUP(sb); |
3951 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, | 4068 | if (EXT4_HAS_RO_COMPAT_FEATURE(sb, |
3952 | EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) | 4069 | EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) |
3953 | num -= le16_to_cpu(gdp->bg_itable_unused); | 4070 | num -= ext4_itable_unused_count(sb, gdp); |
3954 | table += num / inodes_per_block; | 4071 | table += num / inodes_per_block; |
3955 | if (end > table) | 4072 | if (end > table) |
3956 | end = table; | 4073 | end = table; |
@@ -4164,9 +4281,11 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) | |||
4164 | inode->i_op = &ext4_dir_inode_operations; | 4281 | inode->i_op = &ext4_dir_inode_operations; |
4165 | inode->i_fop = &ext4_dir_operations; | 4282 | inode->i_fop = &ext4_dir_operations; |
4166 | } else if (S_ISLNK(inode->i_mode)) { | 4283 | } else if (S_ISLNK(inode->i_mode)) { |
4167 | if (ext4_inode_is_fast_symlink(inode)) | 4284 | if (ext4_inode_is_fast_symlink(inode)) { |
4168 | inode->i_op = &ext4_fast_symlink_inode_operations; | 4285 | inode->i_op = &ext4_fast_symlink_inode_operations; |
4169 | else { | 4286 | nd_terminate_link(ei->i_data, inode->i_size, |
4287 | sizeof(ei->i_data) - 1); | ||
4288 | } else { | ||
4170 | inode->i_op = &ext4_symlink_inode_operations; | 4289 | inode->i_op = &ext4_symlink_inode_operations; |
4171 | ext4_set_aops(inode); | 4290 | ext4_set_aops(inode); |
4172 | } | 4291 | } |
@@ -4310,8 +4429,8 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4310 | EXT4_SET_RO_COMPAT_FEATURE(sb, | 4429 | EXT4_SET_RO_COMPAT_FEATURE(sb, |
4311 | EXT4_FEATURE_RO_COMPAT_LARGE_FILE); | 4430 | EXT4_FEATURE_RO_COMPAT_LARGE_FILE); |
4312 | sb->s_dirt = 1; | 4431 | sb->s_dirt = 1; |
4313 | handle->h_sync = 1; | 4432 | ext4_handle_sync(handle); |
4314 | err = ext4_journal_dirty_metadata(handle, | 4433 | err = ext4_handle_dirty_metadata(handle, inode, |
4315 | EXT4_SB(sb)->s_sbh); | 4434 | EXT4_SB(sb)->s_sbh); |
4316 | } | 4435 | } |
4317 | } | 4436 | } |
@@ -4338,9 +4457,8 @@ static int ext4_do_update_inode(handle_t *handle, | |||
4338 | raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); | 4457 | raw_inode->i_extra_isize = cpu_to_le16(ei->i_extra_isize); |
4339 | } | 4458 | } |
4340 | 4459 | ||
4341 | 4460 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); | |
4342 | BUFFER_TRACE(bh, "call ext4_journal_dirty_metadata"); | 4461 | rc = ext4_handle_dirty_metadata(handle, inode, bh); |
4343 | rc = ext4_journal_dirty_metadata(handle, bh); | ||
4344 | if (!err) | 4462 | if (!err) |
4345 | err = rc; | 4463 | err = rc; |
4346 | ei->i_state &= ~EXT4_STATE_NEW; | 4464 | ei->i_state &= ~EXT4_STATE_NEW; |
@@ -4403,6 +4521,25 @@ int ext4_write_inode(struct inode *inode, int wait) | |||
4403 | return ext4_force_commit(inode->i_sb); | 4521 | return ext4_force_commit(inode->i_sb); |
4404 | } | 4522 | } |
4405 | 4523 | ||
4524 | int __ext4_write_dirty_metadata(struct inode *inode, struct buffer_head *bh) | ||
4525 | { | ||
4526 | int err = 0; | ||
4527 | |||
4528 | mark_buffer_dirty(bh); | ||
4529 | if (inode && inode_needs_sync(inode)) { | ||
4530 | sync_dirty_buffer(bh); | ||
4531 | if (buffer_req(bh) && !buffer_uptodate(bh)) { | ||
4532 | ext4_error(inode->i_sb, __func__, | ||
4533 | "IO error syncing inode, " | ||
4534 | "inode=%lu, block=%llu", | ||
4535 | inode->i_ino, | ||
4536 | (unsigned long long)bh->b_blocknr); | ||
4537 | err = -EIO; | ||
4538 | } | ||
4539 | } | ||
4540 | return err; | ||
4541 | } | ||
4542 | |||
4406 | /* | 4543 | /* |
4407 | * ext4_setattr() | 4544 | * ext4_setattr() |
4408 | * | 4545 | * |
@@ -4707,16 +4844,15 @@ int | |||
4707 | ext4_reserve_inode_write(handle_t *handle, struct inode *inode, | 4844 | ext4_reserve_inode_write(handle_t *handle, struct inode *inode, |
4708 | struct ext4_iloc *iloc) | 4845 | struct ext4_iloc *iloc) |
4709 | { | 4846 | { |
4710 | int err = 0; | 4847 | int err; |
4711 | if (handle) { | 4848 | |
4712 | err = ext4_get_inode_loc(inode, iloc); | 4849 | err = ext4_get_inode_loc(inode, iloc); |
4713 | if (!err) { | 4850 | if (!err) { |
4714 | BUFFER_TRACE(iloc->bh, "get_write_access"); | 4851 | BUFFER_TRACE(iloc->bh, "get_write_access"); |
4715 | err = ext4_journal_get_write_access(handle, iloc->bh); | 4852 | err = ext4_journal_get_write_access(handle, iloc->bh); |
4716 | if (err) { | 4853 | if (err) { |
4717 | brelse(iloc->bh); | 4854 | brelse(iloc->bh); |
4718 | iloc->bh = NULL; | 4855 | iloc->bh = NULL; |
4719 | } | ||
4720 | } | 4856 | } |
4721 | } | 4857 | } |
4722 | ext4_std_error(inode->i_sb, err); | 4858 | ext4_std_error(inode->i_sb, err); |
@@ -4788,7 +4924,8 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
4788 | 4924 | ||
4789 | might_sleep(); | 4925 | might_sleep(); |
4790 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 4926 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
4791 | if (EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && | 4927 | if (ext4_handle_valid(handle) && |
4928 | EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && | ||
4792 | !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) { | 4929 | !(EXT4_I(inode)->i_state & EXT4_STATE_NO_EXPAND)) { |
4793 | /* | 4930 | /* |
4794 | * We need extra buffer credits since we may write into EA block | 4931 | * We need extra buffer credits since we may write into EA block |
@@ -4840,6 +4977,11 @@ void ext4_dirty_inode(struct inode *inode) | |||
4840 | handle_t *current_handle = ext4_journal_current_handle(); | 4977 | handle_t *current_handle = ext4_journal_current_handle(); |
4841 | handle_t *handle; | 4978 | handle_t *handle; |
4842 | 4979 | ||
4980 | if (!ext4_handle_valid(current_handle)) { | ||
4981 | ext4_mark_inode_dirty(current_handle, inode); | ||
4982 | return; | ||
4983 | } | ||
4984 | |||
4843 | handle = ext4_journal_start(inode, 2); | 4985 | handle = ext4_journal_start(inode, 2); |
4844 | if (IS_ERR(handle)) | 4986 | if (IS_ERR(handle)) |
4845 | goto out; | 4987 | goto out; |
@@ -4877,8 +5019,9 @@ static int ext4_pin_inode(handle_t *handle, struct inode *inode) | |||
4877 | BUFFER_TRACE(iloc.bh, "get_write_access"); | 5019 | BUFFER_TRACE(iloc.bh, "get_write_access"); |
4878 | err = jbd2_journal_get_write_access(handle, iloc.bh); | 5020 | err = jbd2_journal_get_write_access(handle, iloc.bh); |
4879 | if (!err) | 5021 | if (!err) |
4880 | err = ext4_journal_dirty_metadata(handle, | 5022 | err = ext4_handle_dirty_metadata(handle, |
4881 | iloc.bh); | 5023 | inode, |
5024 | iloc.bh); | ||
4882 | brelse(iloc.bh); | 5025 | brelse(iloc.bh); |
4883 | } | 5026 | } |
4884 | } | 5027 | } |
@@ -4904,6 +5047,8 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val) | |||
4904 | */ | 5047 | */ |
4905 | 5048 | ||
4906 | journal = EXT4_JOURNAL(inode); | 5049 | journal = EXT4_JOURNAL(inode); |
5050 | if (!journal) | ||
5051 | return 0; | ||
4907 | if (is_journal_aborted(journal)) | 5052 | if (is_journal_aborted(journal)) |
4908 | return -EROFS; | 5053 | return -EROFS; |
4909 | 5054 | ||
@@ -4933,7 +5078,7 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val) | |||
4933 | return PTR_ERR(handle); | 5078 | return PTR_ERR(handle); |
4934 | 5079 | ||
4935 | err = ext4_mark_inode_dirty(handle, inode); | 5080 | err = ext4_mark_inode_dirty(handle, inode); |
4936 | handle->h_sync = 1; | 5081 | ext4_handle_sync(handle); |
4937 | ext4_journal_stop(handle); | 5082 | ext4_journal_stop(handle); |
4938 | ext4_std_error(inode->i_sb, err); | 5083 | ext4_std_error(inode->i_sb, err); |
4939 | 5084 | ||