diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 14:34:40 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 14:34:40 -0400 |
commit | 2ac232f37fa0e8551856a575fe299c47b65b4d66 (patch) | |
tree | 58ff15ecdbc383415a82ea678e5191db16a479f3 /fs/ext3/inode.c | |
parent | fa8f53ace4af9470d8414427cb3dc3c0ffc4f182 (diff) | |
parent | 5cf49d763eb141d236e92be6d4a0dc94e31fa886 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs-2.6:
jbd: change the field "b_cow_tid" of struct journal_head from type unsigned to tid_t
ext3.txt: update the links in the section "useful links" to the latest ones
ext3: Fix data corruption in inodes with journalled data
ext2: check xattr name_len before acquiring xattr_sem in ext2_xattr_get
ext3: Fix compilation with -DDX_DEBUG
quota: Remove unused declaration
jbd: Use WRITE_SYNC in journal checkpoint.
jbd: Fix oops in journal_remove_journal_head()
ext3: Return -EINVAL when start is beyond the end of fs in ext3_trim_fs()
ext3/ioctl.c: silence sparse warnings about different address spaces
ext3/ext4 Documentation: remove bh/nobh since it has been deprecated
ext3: Improve truncate error handling
ext3: use proper little-endian bitops
ext2: include fs.h into ext2_fs.h
ext3: Fix oops in ext3_try_to_allocate_with_rsv()
jbd: fix a bug of leaking jh->b_jcount
jbd: remove dependency on __GFP_NOFAIL
ext3: Convert ext3 to new truncate calling convention
jbd: Add fixed tracepoints
ext3: Add fixed tracepoints
Resolve conflicts in fs/ext3/fsync.c due to fsync locking push-down and
new fixed tracepoints.
Diffstat (limited to 'fs/ext3/inode.c')
-rw-r--r-- | fs/ext3/inode.c | 193 |
1 files changed, 136 insertions, 57 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 2978a2a17a59..04da6acde85d 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -38,10 +38,12 @@ | |||
38 | #include <linux/bio.h> | 38 | #include <linux/bio.h> |
39 | #include <linux/fiemap.h> | 39 | #include <linux/fiemap.h> |
40 | #include <linux/namei.h> | 40 | #include <linux/namei.h> |
41 | #include <trace/events/ext3.h> | ||
41 | #include "xattr.h" | 42 | #include "xattr.h" |
42 | #include "acl.h" | 43 | #include "acl.h" |
43 | 44 | ||
44 | static int ext3_writepage_trans_blocks(struct inode *inode); | 45 | static int ext3_writepage_trans_blocks(struct inode *inode); |
46 | static int ext3_block_truncate_page(struct inode *inode, loff_t from); | ||
45 | 47 | ||
46 | /* | 48 | /* |
47 | * Test whether an inode is a fast symlink. | 49 | * Test whether an inode is a fast symlink. |
@@ -70,6 +72,7 @@ int ext3_forget(handle_t *handle, int is_metadata, struct inode *inode, | |||
70 | 72 | ||
71 | might_sleep(); | 73 | might_sleep(); |
72 | 74 | ||
75 | trace_ext3_forget(inode, is_metadata, blocknr); | ||
73 | BUFFER_TRACE(bh, "enter"); | 76 | BUFFER_TRACE(bh, "enter"); |
74 | 77 | ||
75 | jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " | 78 | jbd_debug(4, "forgetting bh %p: is_metadata = %d, mode %o, " |
@@ -194,20 +197,47 @@ static int truncate_restart_transaction(handle_t *handle, struct inode *inode) | |||
194 | */ | 197 | */ |
195 | void ext3_evict_inode (struct inode *inode) | 198 | void ext3_evict_inode (struct inode *inode) |
196 | { | 199 | { |
200 | struct ext3_inode_info *ei = EXT3_I(inode); | ||
197 | struct ext3_block_alloc_info *rsv; | 201 | struct ext3_block_alloc_info *rsv; |
198 | handle_t *handle; | 202 | handle_t *handle; |
199 | int want_delete = 0; | 203 | int want_delete = 0; |
200 | 204 | ||
205 | trace_ext3_evict_inode(inode); | ||
201 | if (!inode->i_nlink && !is_bad_inode(inode)) { | 206 | if (!inode->i_nlink && !is_bad_inode(inode)) { |
202 | dquot_initialize(inode); | 207 | dquot_initialize(inode); |
203 | want_delete = 1; | 208 | want_delete = 1; |
204 | } | 209 | } |
205 | 210 | ||
211 | /* | ||
212 | * When journalling data dirty buffers are tracked only in the journal. | ||
213 | * So although mm thinks everything is clean and ready for reaping the | ||
214 | * inode might still have some pages to write in the running | ||
215 | * transaction or waiting to be checkpointed. Thus calling | ||
216 | * journal_invalidatepage() (via truncate_inode_pages()) to discard | ||
217 | * these buffers can cause data loss. Also even if we did not discard | ||
218 | * these buffers, we would have no way to find them after the inode | ||
219 | * is reaped and thus user could see stale data if he tries to read | ||
220 | * them before the transaction is checkpointed. So be careful and | ||
221 | * force everything to disk here... We use ei->i_datasync_tid to | ||
222 | * store the newest transaction containing inode's data. | ||
223 | * | ||
224 | * Note that directories do not have this problem because they don't | ||
225 | * use page cache. | ||
226 | */ | ||
227 | if (inode->i_nlink && ext3_should_journal_data(inode) && | ||
228 | (S_ISLNK(inode->i_mode) || S_ISREG(inode->i_mode))) { | ||
229 | tid_t commit_tid = atomic_read(&ei->i_datasync_tid); | ||
230 | journal_t *journal = EXT3_SB(inode->i_sb)->s_journal; | ||
231 | |||
232 | log_start_commit(journal, commit_tid); | ||
233 | log_wait_commit(journal, commit_tid); | ||
234 | filemap_write_and_wait(&inode->i_data); | ||
235 | } | ||
206 | truncate_inode_pages(&inode->i_data, 0); | 236 | truncate_inode_pages(&inode->i_data, 0); |
207 | 237 | ||
208 | ext3_discard_reservation(inode); | 238 | ext3_discard_reservation(inode); |
209 | rsv = EXT3_I(inode)->i_block_alloc_info; | 239 | rsv = ei->i_block_alloc_info; |
210 | EXT3_I(inode)->i_block_alloc_info = NULL; | 240 | ei->i_block_alloc_info = NULL; |
211 | if (unlikely(rsv)) | 241 | if (unlikely(rsv)) |
212 | kfree(rsv); | 242 | kfree(rsv); |
213 | 243 | ||
@@ -231,15 +261,13 @@ void ext3_evict_inode (struct inode *inode) | |||
231 | if (inode->i_blocks) | 261 | if (inode->i_blocks) |
232 | ext3_truncate(inode); | 262 | ext3_truncate(inode); |
233 | /* | 263 | /* |
234 | * Kill off the orphan record which ext3_truncate created. | 264 | * Kill off the orphan record created when the inode lost the last |
235 | * AKPM: I think this can be inside the above `if'. | 265 | * link. Note that ext3_orphan_del() has to be able to cope with the |
236 | * Note that ext3_orphan_del() has to be able to cope with the | 266 | * deletion of a non-existent orphan - ext3_truncate() could |
237 | * deletion of a non-existent orphan - this is because we don't | 267 | * have removed the record. |
238 | * know if ext3_truncate() actually created an orphan record. | ||
239 | * (Well, we could do this if we need to, but heck - it works) | ||
240 | */ | 268 | */ |
241 | ext3_orphan_del(handle, inode); | 269 | ext3_orphan_del(handle, inode); |
242 | EXT3_I(inode)->i_dtime = get_seconds(); | 270 | ei->i_dtime = get_seconds(); |
243 | 271 | ||
244 | /* | 272 | /* |
245 | * One subtle ordering requirement: if anything has gone wrong | 273 | * One subtle ordering requirement: if anything has gone wrong |
@@ -842,6 +870,7 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
842 | ext3_fsblk_t first_block = 0; | 870 | ext3_fsblk_t first_block = 0; |
843 | 871 | ||
844 | 872 | ||
873 | trace_ext3_get_blocks_enter(inode, iblock, maxblocks, create); | ||
845 | J_ASSERT(handle != NULL || create == 0); | 874 | J_ASSERT(handle != NULL || create == 0); |
846 | depth = ext3_block_to_path(inode,iblock,offsets,&blocks_to_boundary); | 875 | depth = ext3_block_to_path(inode,iblock,offsets,&blocks_to_boundary); |
847 | 876 | ||
@@ -886,6 +915,9 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
886 | if (!create || err == -EIO) | 915 | if (!create || err == -EIO) |
887 | goto cleanup; | 916 | goto cleanup; |
888 | 917 | ||
918 | /* | ||
919 | * Block out ext3_truncate while we alter the tree | ||
920 | */ | ||
889 | mutex_lock(&ei->truncate_mutex); | 921 | mutex_lock(&ei->truncate_mutex); |
890 | 922 | ||
891 | /* | 923 | /* |
@@ -934,9 +966,6 @@ int ext3_get_blocks_handle(handle_t *handle, struct inode *inode, | |||
934 | */ | 966 | */ |
935 | count = ext3_blks_to_allocate(partial, indirect_blks, | 967 | count = ext3_blks_to_allocate(partial, indirect_blks, |
936 | maxblocks, blocks_to_boundary); | 968 | maxblocks, blocks_to_boundary); |
937 | /* | ||
938 | * Block out ext3_truncate while we alter the tree | ||
939 | */ | ||
940 | err = ext3_alloc_branch(handle, inode, indirect_blks, &count, goal, | 969 | err = ext3_alloc_branch(handle, inode, indirect_blks, &count, goal, |
941 | offsets + (partial - chain), partial); | 970 | offsets + (partial - chain), partial); |
942 | 971 | ||
@@ -970,6 +999,9 @@ cleanup: | |||
970 | } | 999 | } |
971 | BUFFER_TRACE(bh_result, "returned"); | 1000 | BUFFER_TRACE(bh_result, "returned"); |
972 | out: | 1001 | out: |
1002 | trace_ext3_get_blocks_exit(inode, iblock, | ||
1003 | depth ? le32_to_cpu(chain[depth-1].key) : 0, | ||
1004 | count, err); | ||
973 | return err; | 1005 | return err; |
974 | } | 1006 | } |
975 | 1007 | ||
@@ -1202,6 +1234,16 @@ static void ext3_truncate_failed_write(struct inode *inode) | |||
1202 | ext3_truncate(inode); | 1234 | ext3_truncate(inode); |
1203 | } | 1235 | } |
1204 | 1236 | ||
1237 | /* | ||
1238 | * Truncate blocks that were not used by direct IO write. We have to zero out | ||
1239 | * the last file block as well because direct IO might have written to it. | ||
1240 | */ | ||
1241 | static void ext3_truncate_failed_direct_write(struct inode *inode) | ||
1242 | { | ||
1243 | ext3_block_truncate_page(inode, inode->i_size); | ||
1244 | ext3_truncate(inode); | ||
1245 | } | ||
1246 | |||
1205 | static int ext3_write_begin(struct file *file, struct address_space *mapping, | 1247 | static int ext3_write_begin(struct file *file, struct address_space *mapping, |
1206 | loff_t pos, unsigned len, unsigned flags, | 1248 | loff_t pos, unsigned len, unsigned flags, |
1207 | struct page **pagep, void **fsdata) | 1249 | struct page **pagep, void **fsdata) |
@@ -1217,6 +1259,8 @@ static int ext3_write_begin(struct file *file, struct address_space *mapping, | |||
1217 | * we allocate blocks but write fails for some reason */ | 1259 | * we allocate blocks but write fails for some reason */ |
1218 | int needed_blocks = ext3_writepage_trans_blocks(inode) + 1; | 1260 | int needed_blocks = ext3_writepage_trans_blocks(inode) + 1; |
1219 | 1261 | ||
1262 | trace_ext3_write_begin(inode, pos, len, flags); | ||
1263 | |||
1220 | index = pos >> PAGE_CACHE_SHIFT; | 1264 | index = pos >> PAGE_CACHE_SHIFT; |
1221 | from = pos & (PAGE_CACHE_SIZE - 1); | 1265 | from = pos & (PAGE_CACHE_SIZE - 1); |
1222 | to = from + len; | 1266 | to = from + len; |
@@ -1332,6 +1376,7 @@ static int ext3_ordered_write_end(struct file *file, | |||
1332 | unsigned from, to; | 1376 | unsigned from, to; |
1333 | int ret = 0, ret2; | 1377 | int ret = 0, ret2; |
1334 | 1378 | ||
1379 | trace_ext3_ordered_write_end(inode, pos, len, copied); | ||
1335 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); | 1380 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); |
1336 | 1381 | ||
1337 | from = pos & (PAGE_CACHE_SIZE - 1); | 1382 | from = pos & (PAGE_CACHE_SIZE - 1); |
@@ -1367,6 +1412,7 @@ static int ext3_writeback_write_end(struct file *file, | |||
1367 | struct inode *inode = file->f_mapping->host; | 1412 | struct inode *inode = file->f_mapping->host; |
1368 | int ret; | 1413 | int ret; |
1369 | 1414 | ||
1415 | trace_ext3_writeback_write_end(inode, pos, len, copied); | ||
1370 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); | 1416 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); |
1371 | update_file_sizes(inode, pos, copied); | 1417 | update_file_sizes(inode, pos, copied); |
1372 | /* | 1418 | /* |
@@ -1391,10 +1437,12 @@ static int ext3_journalled_write_end(struct file *file, | |||
1391 | { | 1437 | { |
1392 | handle_t *handle = ext3_journal_current_handle(); | 1438 | handle_t *handle = ext3_journal_current_handle(); |
1393 | struct inode *inode = mapping->host; | 1439 | struct inode *inode = mapping->host; |
1440 | struct ext3_inode_info *ei = EXT3_I(inode); | ||
1394 | int ret = 0, ret2; | 1441 | int ret = 0, ret2; |
1395 | int partial = 0; | 1442 | int partial = 0; |
1396 | unsigned from, to; | 1443 | unsigned from, to; |
1397 | 1444 | ||
1445 | trace_ext3_journalled_write_end(inode, pos, len, copied); | ||
1398 | from = pos & (PAGE_CACHE_SIZE - 1); | 1446 | from = pos & (PAGE_CACHE_SIZE - 1); |
1399 | to = from + len; | 1447 | to = from + len; |
1400 | 1448 | ||
@@ -1419,8 +1467,9 @@ static int ext3_journalled_write_end(struct file *file, | |||
1419 | if (pos + len > inode->i_size && ext3_can_truncate(inode)) | 1467 | if (pos + len > inode->i_size && ext3_can_truncate(inode)) |
1420 | ext3_orphan_add(handle, inode); | 1468 | ext3_orphan_add(handle, inode); |
1421 | ext3_set_inode_state(inode, EXT3_STATE_JDATA); | 1469 | ext3_set_inode_state(inode, EXT3_STATE_JDATA); |
1422 | if (inode->i_size > EXT3_I(inode)->i_disksize) { | 1470 | atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid); |
1423 | EXT3_I(inode)->i_disksize = inode->i_size; | 1471 | if (inode->i_size > ei->i_disksize) { |
1472 | ei->i_disksize = inode->i_size; | ||
1424 | ret2 = ext3_mark_inode_dirty(handle, inode); | 1473 | ret2 = ext3_mark_inode_dirty(handle, inode); |
1425 | if (!ret) | 1474 | if (!ret) |
1426 | ret = ret2; | 1475 | ret = ret2; |
@@ -1577,6 +1626,7 @@ static int ext3_ordered_writepage(struct page *page, | |||
1577 | if (ext3_journal_current_handle()) | 1626 | if (ext3_journal_current_handle()) |
1578 | goto out_fail; | 1627 | goto out_fail; |
1579 | 1628 | ||
1629 | trace_ext3_ordered_writepage(page); | ||
1580 | if (!page_has_buffers(page)) { | 1630 | if (!page_has_buffers(page)) { |
1581 | create_empty_buffers(page, inode->i_sb->s_blocksize, | 1631 | create_empty_buffers(page, inode->i_sb->s_blocksize, |
1582 | (1 << BH_Dirty)|(1 << BH_Uptodate)); | 1632 | (1 << BH_Dirty)|(1 << BH_Uptodate)); |
@@ -1647,6 +1697,7 @@ static int ext3_writeback_writepage(struct page *page, | |||
1647 | if (ext3_journal_current_handle()) | 1697 | if (ext3_journal_current_handle()) |
1648 | goto out_fail; | 1698 | goto out_fail; |
1649 | 1699 | ||
1700 | trace_ext3_writeback_writepage(page); | ||
1650 | if (page_has_buffers(page)) { | 1701 | if (page_has_buffers(page)) { |
1651 | if (!walk_page_buffers(NULL, page_buffers(page), 0, | 1702 | if (!walk_page_buffers(NULL, page_buffers(page), 0, |
1652 | PAGE_CACHE_SIZE, NULL, buffer_unmapped)) { | 1703 | PAGE_CACHE_SIZE, NULL, buffer_unmapped)) { |
@@ -1689,6 +1740,7 @@ static int ext3_journalled_writepage(struct page *page, | |||
1689 | if (ext3_journal_current_handle()) | 1740 | if (ext3_journal_current_handle()) |
1690 | goto no_write; | 1741 | goto no_write; |
1691 | 1742 | ||
1743 | trace_ext3_journalled_writepage(page); | ||
1692 | handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); | 1744 | handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); |
1693 | if (IS_ERR(handle)) { | 1745 | if (IS_ERR(handle)) { |
1694 | ret = PTR_ERR(handle); | 1746 | ret = PTR_ERR(handle); |
@@ -1715,6 +1767,8 @@ static int ext3_journalled_writepage(struct page *page, | |||
1715 | if (ret == 0) | 1767 | if (ret == 0) |
1716 | ret = err; | 1768 | ret = err; |
1717 | ext3_set_inode_state(inode, EXT3_STATE_JDATA); | 1769 | ext3_set_inode_state(inode, EXT3_STATE_JDATA); |
1770 | atomic_set(&EXT3_I(inode)->i_datasync_tid, | ||
1771 | handle->h_transaction->t_tid); | ||
1718 | unlock_page(page); | 1772 | unlock_page(page); |
1719 | } else { | 1773 | } else { |
1720 | /* | 1774 | /* |
@@ -1739,6 +1793,7 @@ out_unlock: | |||
1739 | 1793 | ||
1740 | static int ext3_readpage(struct file *file, struct page *page) | 1794 | static int ext3_readpage(struct file *file, struct page *page) |
1741 | { | 1795 | { |
1796 | trace_ext3_readpage(page); | ||
1742 | return mpage_readpage(page, ext3_get_block); | 1797 | return mpage_readpage(page, ext3_get_block); |
1743 | } | 1798 | } |
1744 | 1799 | ||
@@ -1753,6 +1808,8 @@ static void ext3_invalidatepage(struct page *page, unsigned long offset) | |||
1753 | { | 1808 | { |
1754 | journal_t *journal = EXT3_JOURNAL(page->mapping->host); | 1809 | journal_t *journal = EXT3_JOURNAL(page->mapping->host); |
1755 | 1810 | ||
1811 | trace_ext3_invalidatepage(page, offset); | ||
1812 | |||
1756 | /* | 1813 | /* |
1757 | * If it's a full truncate we just forget about the pending dirtying | 1814 | * If it's a full truncate we just forget about the pending dirtying |
1758 | */ | 1815 | */ |
@@ -1766,6 +1823,7 @@ static int ext3_releasepage(struct page *page, gfp_t wait) | |||
1766 | { | 1823 | { |
1767 | journal_t *journal = EXT3_JOURNAL(page->mapping->host); | 1824 | journal_t *journal = EXT3_JOURNAL(page->mapping->host); |
1768 | 1825 | ||
1826 | trace_ext3_releasepage(page); | ||
1769 | WARN_ON(PageChecked(page)); | 1827 | WARN_ON(PageChecked(page)); |
1770 | if (!page_has_buffers(page)) | 1828 | if (!page_has_buffers(page)) |
1771 | return 0; | 1829 | return 0; |
@@ -1794,6 +1852,8 @@ static ssize_t ext3_direct_IO(int rw, struct kiocb *iocb, | |||
1794 | size_t count = iov_length(iov, nr_segs); | 1852 | size_t count = iov_length(iov, nr_segs); |
1795 | int retries = 0; | 1853 | int retries = 0; |
1796 | 1854 | ||
1855 | trace_ext3_direct_IO_enter(inode, offset, iov_length(iov, nr_segs), rw); | ||
1856 | |||
1797 | if (rw == WRITE) { | 1857 | if (rw == WRITE) { |
1798 | loff_t final_size = offset + count; | 1858 | loff_t final_size = offset + count; |
1799 | 1859 | ||
@@ -1827,7 +1887,7 @@ retry: | |||
1827 | loff_t end = offset + iov_length(iov, nr_segs); | 1887 | loff_t end = offset + iov_length(iov, nr_segs); |
1828 | 1888 | ||
1829 | if (end > isize) | 1889 | if (end > isize) |
1830 | vmtruncate(inode, isize); | 1890 | ext3_truncate_failed_direct_write(inode); |
1831 | } | 1891 | } |
1832 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1892 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
1833 | goto retry; | 1893 | goto retry; |
@@ -1841,7 +1901,7 @@ retry: | |||
1841 | /* This is really bad luck. We've written the data | 1901 | /* This is really bad luck. We've written the data |
1842 | * but cannot extend i_size. Truncate allocated blocks | 1902 | * but cannot extend i_size. Truncate allocated blocks |
1843 | * and pretend the write failed... */ | 1903 | * and pretend the write failed... */ |
1844 | ext3_truncate(inode); | 1904 | ext3_truncate_failed_direct_write(inode); |
1845 | ret = PTR_ERR(handle); | 1905 | ret = PTR_ERR(handle); |
1846 | goto out; | 1906 | goto out; |
1847 | } | 1907 | } |
@@ -1867,6 +1927,8 @@ retry: | |||
1867 | ret = err; | 1927 | ret = err; |
1868 | } | 1928 | } |
1869 | out: | 1929 | out: |
1930 | trace_ext3_direct_IO_exit(inode, offset, | ||
1931 | iov_length(iov, nr_segs), rw, ret); | ||
1870 | return ret; | 1932 | return ret; |
1871 | } | 1933 | } |
1872 | 1934 | ||
@@ -1949,17 +2011,24 @@ void ext3_set_aops(struct inode *inode) | |||
1949 | * This required during truncate. We need to physically zero the tail end | 2011 | * This required during truncate. We need to physically zero the tail end |
1950 | * of that block so it doesn't yield old data if the file is later grown. | 2012 | * of that block so it doesn't yield old data if the file is later grown. |
1951 | */ | 2013 | */ |
1952 | static int ext3_block_truncate_page(handle_t *handle, struct page *page, | 2014 | static int ext3_block_truncate_page(struct inode *inode, loff_t from) |
1953 | struct address_space *mapping, loff_t from) | ||
1954 | { | 2015 | { |
1955 | ext3_fsblk_t index = from >> PAGE_CACHE_SHIFT; | 2016 | ext3_fsblk_t index = from >> PAGE_CACHE_SHIFT; |
1956 | unsigned offset = from & (PAGE_CACHE_SIZE-1); | 2017 | unsigned offset = from & (PAGE_CACHE_SIZE - 1); |
1957 | unsigned blocksize, iblock, length, pos; | 2018 | unsigned blocksize, iblock, length, pos; |
1958 | struct inode *inode = mapping->host; | 2019 | struct page *page; |
2020 | handle_t *handle = NULL; | ||
1959 | struct buffer_head *bh; | 2021 | struct buffer_head *bh; |
1960 | int err = 0; | 2022 | int err = 0; |
1961 | 2023 | ||
2024 | /* Truncated on block boundary - nothing to do */ | ||
1962 | blocksize = inode->i_sb->s_blocksize; | 2025 | blocksize = inode->i_sb->s_blocksize; |
2026 | if ((from & (blocksize - 1)) == 0) | ||
2027 | return 0; | ||
2028 | |||
2029 | page = grab_cache_page(inode->i_mapping, index); | ||
2030 | if (!page) | ||
2031 | return -ENOMEM; | ||
1963 | length = blocksize - (offset & (blocksize - 1)); | 2032 | length = blocksize - (offset & (blocksize - 1)); |
1964 | iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); | 2033 | iblock = index << (PAGE_CACHE_SHIFT - inode->i_sb->s_blocksize_bits); |
1965 | 2034 | ||
@@ -2004,11 +2073,23 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page, | |||
2004 | goto unlock; | 2073 | goto unlock; |
2005 | } | 2074 | } |
2006 | 2075 | ||
2076 | /* data=writeback mode doesn't need transaction to zero-out data */ | ||
2077 | if (!ext3_should_writeback_data(inode)) { | ||
2078 | /* We journal at most one block */ | ||
2079 | handle = ext3_journal_start(inode, 1); | ||
2080 | if (IS_ERR(handle)) { | ||
2081 | clear_highpage(page); | ||
2082 | flush_dcache_page(page); | ||
2083 | err = PTR_ERR(handle); | ||
2084 | goto unlock; | ||
2085 | } | ||
2086 | } | ||
2087 | |||
2007 | if (ext3_should_journal_data(inode)) { | 2088 | if (ext3_should_journal_data(inode)) { |
2008 | BUFFER_TRACE(bh, "get write access"); | 2089 | BUFFER_TRACE(bh, "get write access"); |
2009 | err = ext3_journal_get_write_access(handle, bh); | 2090 | err = ext3_journal_get_write_access(handle, bh); |
2010 | if (err) | 2091 | if (err) |
2011 | goto unlock; | 2092 | goto stop; |
2012 | } | 2093 | } |
2013 | 2094 | ||
2014 | zero_user(page, offset, length); | 2095 | zero_user(page, offset, length); |
@@ -2022,6 +2103,9 @@ static int ext3_block_truncate_page(handle_t *handle, struct page *page, | |||
2022 | err = ext3_journal_dirty_data(handle, bh); | 2103 | err = ext3_journal_dirty_data(handle, bh); |
2023 | mark_buffer_dirty(bh); | 2104 | mark_buffer_dirty(bh); |
2024 | } | 2105 | } |
2106 | stop: | ||
2107 | if (handle) | ||
2108 | ext3_journal_stop(handle); | ||
2025 | 2109 | ||
2026 | unlock: | 2110 | unlock: |
2027 | unlock_page(page); | 2111 | unlock_page(page); |
@@ -2390,8 +2474,6 @@ static void ext3_free_branches(handle_t *handle, struct inode *inode, | |||
2390 | 2474 | ||
2391 | int ext3_can_truncate(struct inode *inode) | 2475 | int ext3_can_truncate(struct inode *inode) |
2392 | { | 2476 | { |
2393 | if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) | ||
2394 | return 0; | ||
2395 | if (S_ISREG(inode->i_mode)) | 2477 | if (S_ISREG(inode->i_mode)) |
2396 | return 1; | 2478 | return 1; |
2397 | if (S_ISDIR(inode->i_mode)) | 2479 | if (S_ISDIR(inode->i_mode)) |
@@ -2435,7 +2517,6 @@ void ext3_truncate(struct inode *inode) | |||
2435 | struct ext3_inode_info *ei = EXT3_I(inode); | 2517 | struct ext3_inode_info *ei = EXT3_I(inode); |
2436 | __le32 *i_data = ei->i_data; | 2518 | __le32 *i_data = ei->i_data; |
2437 | int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb); | 2519 | int addr_per_block = EXT3_ADDR_PER_BLOCK(inode->i_sb); |
2438 | struct address_space *mapping = inode->i_mapping; | ||
2439 | int offsets[4]; | 2520 | int offsets[4]; |
2440 | Indirect chain[4]; | 2521 | Indirect chain[4]; |
2441 | Indirect *partial; | 2522 | Indirect *partial; |
@@ -2443,7 +2524,8 @@ void ext3_truncate(struct inode *inode) | |||
2443 | int n; | 2524 | int n; |
2444 | long last_block; | 2525 | long last_block; |
2445 | unsigned blocksize = inode->i_sb->s_blocksize; | 2526 | unsigned blocksize = inode->i_sb->s_blocksize; |
2446 | struct page *page; | 2527 | |
2528 | trace_ext3_truncate_enter(inode); | ||
2447 | 2529 | ||
2448 | if (!ext3_can_truncate(inode)) | 2530 | if (!ext3_can_truncate(inode)) |
2449 | goto out_notrans; | 2531 | goto out_notrans; |
@@ -2451,37 +2533,12 @@ void ext3_truncate(struct inode *inode) | |||
2451 | if (inode->i_size == 0 && ext3_should_writeback_data(inode)) | 2533 | if (inode->i_size == 0 && ext3_should_writeback_data(inode)) |
2452 | ext3_set_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE); | 2534 | ext3_set_inode_state(inode, EXT3_STATE_FLUSH_ON_CLOSE); |
2453 | 2535 | ||
2454 | /* | ||
2455 | * We have to lock the EOF page here, because lock_page() nests | ||
2456 | * outside journal_start(). | ||
2457 | */ | ||
2458 | if ((inode->i_size & (blocksize - 1)) == 0) { | ||
2459 | /* Block boundary? Nothing to do */ | ||
2460 | page = NULL; | ||
2461 | } else { | ||
2462 | page = grab_cache_page(mapping, | ||
2463 | inode->i_size >> PAGE_CACHE_SHIFT); | ||
2464 | if (!page) | ||
2465 | goto out_notrans; | ||
2466 | } | ||
2467 | |||
2468 | handle = start_transaction(inode); | 2536 | handle = start_transaction(inode); |
2469 | if (IS_ERR(handle)) { | 2537 | if (IS_ERR(handle)) |
2470 | if (page) { | ||
2471 | clear_highpage(page); | ||
2472 | flush_dcache_page(page); | ||
2473 | unlock_page(page); | ||
2474 | page_cache_release(page); | ||
2475 | } | ||
2476 | goto out_notrans; | 2538 | goto out_notrans; |
2477 | } | ||
2478 | 2539 | ||
2479 | last_block = (inode->i_size + blocksize-1) | 2540 | last_block = (inode->i_size + blocksize-1) |
2480 | >> EXT3_BLOCK_SIZE_BITS(inode->i_sb); | 2541 | >> EXT3_BLOCK_SIZE_BITS(inode->i_sb); |
2481 | |||
2482 | if (page) | ||
2483 | ext3_block_truncate_page(handle, page, mapping, inode->i_size); | ||
2484 | |||
2485 | n = ext3_block_to_path(inode, last_block, offsets, NULL); | 2542 | n = ext3_block_to_path(inode, last_block, offsets, NULL); |
2486 | if (n == 0) | 2543 | if (n == 0) |
2487 | goto out_stop; /* error */ | 2544 | goto out_stop; /* error */ |
@@ -2596,6 +2653,7 @@ out_stop: | |||
2596 | ext3_orphan_del(handle, inode); | 2653 | ext3_orphan_del(handle, inode); |
2597 | 2654 | ||
2598 | ext3_journal_stop(handle); | 2655 | ext3_journal_stop(handle); |
2656 | trace_ext3_truncate_exit(inode); | ||
2599 | return; | 2657 | return; |
2600 | out_notrans: | 2658 | out_notrans: |
2601 | /* | 2659 | /* |
@@ -2604,6 +2662,7 @@ out_notrans: | |||
2604 | */ | 2662 | */ |
2605 | if (inode->i_nlink) | 2663 | if (inode->i_nlink) |
2606 | ext3_orphan_del(NULL, inode); | 2664 | ext3_orphan_del(NULL, inode); |
2665 | trace_ext3_truncate_exit(inode); | ||
2607 | } | 2666 | } |
2608 | 2667 | ||
2609 | static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, | 2668 | static ext3_fsblk_t ext3_get_inode_block(struct super_block *sb, |
@@ -2745,6 +2804,7 @@ make_io: | |||
2745 | * has in-inode xattrs, or we don't have this inode in memory. | 2804 | * has in-inode xattrs, or we don't have this inode in memory. |
2746 | * Read the block from disk. | 2805 | * Read the block from disk. |
2747 | */ | 2806 | */ |
2807 | trace_ext3_load_inode(inode); | ||
2748 | get_bh(bh); | 2808 | get_bh(bh); |
2749 | bh->b_end_io = end_buffer_read_sync; | 2809 | bh->b_end_io = end_buffer_read_sync; |
2750 | submit_bh(READ_META, bh); | 2810 | submit_bh(READ_META, bh); |
@@ -3229,18 +3289,36 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3229 | } | 3289 | } |
3230 | 3290 | ||
3231 | error = ext3_orphan_add(handle, inode); | 3291 | error = ext3_orphan_add(handle, inode); |
3292 | if (error) { | ||
3293 | ext3_journal_stop(handle); | ||
3294 | goto err_out; | ||
3295 | } | ||
3232 | EXT3_I(inode)->i_disksize = attr->ia_size; | 3296 | EXT3_I(inode)->i_disksize = attr->ia_size; |
3233 | rc = ext3_mark_inode_dirty(handle, inode); | 3297 | error = ext3_mark_inode_dirty(handle, inode); |
3234 | if (!error) | ||
3235 | error = rc; | ||
3236 | ext3_journal_stop(handle); | 3298 | ext3_journal_stop(handle); |
3299 | if (error) { | ||
3300 | /* Some hard fs error must have happened. Bail out. */ | ||
3301 | ext3_orphan_del(NULL, inode); | ||
3302 | goto err_out; | ||
3303 | } | ||
3304 | rc = ext3_block_truncate_page(inode, attr->ia_size); | ||
3305 | if (rc) { | ||
3306 | /* Cleanup orphan list and exit */ | ||
3307 | handle = ext3_journal_start(inode, 3); | ||
3308 | if (IS_ERR(handle)) { | ||
3309 | ext3_orphan_del(NULL, inode); | ||
3310 | goto err_out; | ||
3311 | } | ||
3312 | ext3_orphan_del(handle, inode); | ||
3313 | ext3_journal_stop(handle); | ||
3314 | goto err_out; | ||
3315 | } | ||
3237 | } | 3316 | } |
3238 | 3317 | ||
3239 | if ((attr->ia_valid & ATTR_SIZE) && | 3318 | if ((attr->ia_valid & ATTR_SIZE) && |
3240 | attr->ia_size != i_size_read(inode)) { | 3319 | attr->ia_size != i_size_read(inode)) { |
3241 | rc = vmtruncate(inode, attr->ia_size); | 3320 | truncate_setsize(inode, attr->ia_size); |
3242 | if (rc) | 3321 | ext3_truncate(inode); |
3243 | goto err_out; | ||
3244 | } | 3322 | } |
3245 | 3323 | ||
3246 | setattr_copy(inode, attr); | 3324 | setattr_copy(inode, attr); |
@@ -3374,6 +3452,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
3374 | int err; | 3452 | int err; |
3375 | 3453 | ||
3376 | might_sleep(); | 3454 | might_sleep(); |
3455 | trace_ext3_mark_inode_dirty(inode, _RET_IP_); | ||
3377 | err = ext3_reserve_inode_write(handle, inode, &iloc); | 3456 | err = ext3_reserve_inode_write(handle, inode, &iloc); |
3378 | if (!err) | 3457 | if (!err) |
3379 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | 3458 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); |