diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 17:37:31 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-11 17:37:31 -0500 |
commit | e9688f6acad8cb1f2e8d7abb2de06a6a5c9cbcf2 (patch) | |
tree | 2f9b89987c57e3395e53d3ca354f9674c0bef369 /fs/ext4/namei.c | |
parent | 40c73abbb37e399eba274fe49e520ffa3dd65bdb (diff) | |
parent | 0f0a25bf516843adae479636dc1cf75fd0bd003c (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (44 commits)
ext4: fix trimming starting with block 0 with small blocksize
ext4: revert buggy trim overflow patch
ext4: don't pass entire map to check_eofblocks_fl
ext4: fix memory leak in ext4_free_branches
ext4: remove ext4_mb_return_to_preallocation()
ext4: flush the i_completed_io_list during ext4_truncate
ext4: add error checking to calls to ext4_handle_dirty_metadata()
ext4: fix trimming of a single group
ext4: fix uninitialized variable in ext4_register_li_request
ext4: dynamically allocate the jbd2_inode in ext4_inode_info as necessary
ext4: drop i_state_flags on architectures with 64-bit longs
ext4: reorder ext4_inode_info structure elements to remove unneeded padding
ext4: drop ec_type from the ext4_ext_cache structure
ext4: use ext4_lblk_t instead of sector_t for logical blocks
ext4: replace i_delalloc_reserved_flag with EXT4_STATE_DELALLOC_RESERVED
ext4: fix 32bit overflow in ext4_ext_find_goal()
ext4: add more error checks to ext4_mkdir()
ext4: ext4_ext_migrate should use NULL not 0
ext4: Use ext4_error_file() to print the pathname to the corrupted inode
ext4: use IS_ERR() to check for errors in ext4_error_file
...
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r-- | fs/ext4/namei.c | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index dc40e75cba88..5485390d32c5 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -581,9 +581,9 @@ static int htree_dirblock_to_tree(struct file *dir_file, | |||
581 | dir->i_sb->s_blocksize - | 581 | dir->i_sb->s_blocksize - |
582 | EXT4_DIR_REC_LEN(0)); | 582 | EXT4_DIR_REC_LEN(0)); |
583 | for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) { | 583 | for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) { |
584 | if (!ext4_check_dir_entry(dir, de, bh, | 584 | if (ext4_check_dir_entry(dir, NULL, de, bh, |
585 | (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) | 585 | (block<<EXT4_BLOCK_SIZE_BITS(dir->i_sb)) |
586 | +((char *)de - bh->b_data))) { | 586 | + ((char *)de - bh->b_data))) { |
587 | /* On error, skip the f_pos to the next block. */ | 587 | /* On error, skip the f_pos to the next block. */ |
588 | dir_file->f_pos = (dir_file->f_pos | | 588 | dir_file->f_pos = (dir_file->f_pos | |
589 | (dir->i_sb->s_blocksize - 1)) + 1; | 589 | (dir->i_sb->s_blocksize - 1)) + 1; |
@@ -820,7 +820,7 @@ static inline int search_dirblock(struct buffer_head *bh, | |||
820 | if ((char *) de + namelen <= dlimit && | 820 | if ((char *) de + namelen <= dlimit && |
821 | ext4_match (namelen, name, de)) { | 821 | ext4_match (namelen, name, de)) { |
822 | /* found a match - just to be sure, do a full check */ | 822 | /* found a match - just to be sure, do a full check */ |
823 | if (!ext4_check_dir_entry(dir, de, bh, offset)) | 823 | if (ext4_check_dir_entry(dir, NULL, de, bh, offset)) |
824 | return -1; | 824 | return -1; |
825 | *res_dir = de; | 825 | *res_dir = de; |
826 | return 1; | 826 | return 1; |
@@ -1036,7 +1036,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru | |||
1036 | return ERR_PTR(-EIO); | 1036 | return ERR_PTR(-EIO); |
1037 | } | 1037 | } |
1038 | inode = ext4_iget(dir->i_sb, ino); | 1038 | inode = ext4_iget(dir->i_sb, ino); |
1039 | if (unlikely(IS_ERR(inode))) { | 1039 | if (IS_ERR(inode)) { |
1040 | if (PTR_ERR(inode) == -ESTALE) { | 1040 | if (PTR_ERR(inode) == -ESTALE) { |
1041 | EXT4_ERROR_INODE(dir, | 1041 | EXT4_ERROR_INODE(dir, |
1042 | "deleted inode referenced: %u", | 1042 | "deleted inode referenced: %u", |
@@ -1269,7 +1269,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, | |||
1269 | de = (struct ext4_dir_entry_2 *)bh->b_data; | 1269 | de = (struct ext4_dir_entry_2 *)bh->b_data; |
1270 | top = bh->b_data + blocksize - reclen; | 1270 | top = bh->b_data + blocksize - reclen; |
1271 | while ((char *) de <= top) { | 1271 | while ((char *) de <= top) { |
1272 | if (!ext4_check_dir_entry(dir, de, bh, offset)) | 1272 | if (ext4_check_dir_entry(dir, NULL, de, bh, offset)) |
1273 | return -EIO; | 1273 | return -EIO; |
1274 | if (ext4_match(namelen, name, de)) | 1274 | if (ext4_match(namelen, name, de)) |
1275 | return -EEXIST; | 1275 | return -EEXIST; |
@@ -1602,7 +1602,11 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry, | |||
1602 | if (err) | 1602 | if (err) |
1603 | goto journal_error; | 1603 | goto journal_error; |
1604 | } | 1604 | } |
1605 | ext4_handle_dirty_metadata(handle, inode, frames[0].bh); | 1605 | err = ext4_handle_dirty_metadata(handle, inode, frames[0].bh); |
1606 | if (err) { | ||
1607 | ext4_std_error(inode->i_sb, err); | ||
1608 | goto cleanup; | ||
1609 | } | ||
1606 | } | 1610 | } |
1607 | de = do_split(handle, dir, &bh, frame, &hinfo, &err); | 1611 | de = do_split(handle, dir, &bh, frame, &hinfo, &err); |
1608 | if (!de) | 1612 | if (!de) |
@@ -1630,17 +1634,21 @@ static int ext4_delete_entry(handle_t *handle, | |||
1630 | { | 1634 | { |
1631 | struct ext4_dir_entry_2 *de, *pde; | 1635 | struct ext4_dir_entry_2 *de, *pde; |
1632 | unsigned int blocksize = dir->i_sb->s_blocksize; | 1636 | unsigned int blocksize = dir->i_sb->s_blocksize; |
1633 | int i; | 1637 | int i, err; |
1634 | 1638 | ||
1635 | i = 0; | 1639 | i = 0; |
1636 | pde = NULL; | 1640 | pde = NULL; |
1637 | de = (struct ext4_dir_entry_2 *) bh->b_data; | 1641 | de = (struct ext4_dir_entry_2 *) bh->b_data; |
1638 | while (i < bh->b_size) { | 1642 | while (i < bh->b_size) { |
1639 | if (!ext4_check_dir_entry(dir, de, bh, i)) | 1643 | if (ext4_check_dir_entry(dir, NULL, de, bh, i)) |
1640 | return -EIO; | 1644 | return -EIO; |
1641 | if (de == de_del) { | 1645 | if (de == de_del) { |
1642 | BUFFER_TRACE(bh, "get_write_access"); | 1646 | BUFFER_TRACE(bh, "get_write_access"); |
1643 | ext4_journal_get_write_access(handle, bh); | 1647 | err = ext4_journal_get_write_access(handle, bh); |
1648 | if (unlikely(err)) { | ||
1649 | ext4_std_error(dir->i_sb, err); | ||
1650 | return err; | ||
1651 | } | ||
1644 | if (pde) | 1652 | if (pde) |
1645 | pde->rec_len = ext4_rec_len_to_disk( | 1653 | pde->rec_len = ext4_rec_len_to_disk( |
1646 | ext4_rec_len_from_disk(pde->rec_len, | 1654 | ext4_rec_len_from_disk(pde->rec_len, |
@@ -1652,7 +1660,11 @@ static int ext4_delete_entry(handle_t *handle, | |||
1652 | de->inode = 0; | 1660 | de->inode = 0; |
1653 | dir->i_version++; | 1661 | dir->i_version++; |
1654 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); | 1662 | BUFFER_TRACE(bh, "call ext4_handle_dirty_metadata"); |
1655 | ext4_handle_dirty_metadata(handle, dir, bh); | 1663 | err = ext4_handle_dirty_metadata(handle, dir, bh); |
1664 | if (unlikely(err)) { | ||
1665 | ext4_std_error(dir->i_sb, err); | ||
1666 | return err; | ||
1667 | } | ||
1656 | return 0; | 1668 | return 0; |
1657 | } | 1669 | } |
1658 | i += ext4_rec_len_from_disk(de->rec_len, blocksize); | 1670 | i += ext4_rec_len_from_disk(de->rec_len, blocksize); |
@@ -1789,7 +1801,7 @@ static int ext4_mkdir(struct inode *dir, struct dentry *dentry, int mode) | |||
1789 | { | 1801 | { |
1790 | handle_t *handle; | 1802 | handle_t *handle; |
1791 | struct inode *inode; | 1803 | struct inode *inode; |
1792 | struct buffer_head *dir_block; | 1804 | struct buffer_head *dir_block = NULL; |
1793 | struct ext4_dir_entry_2 *de; | 1805 | struct ext4_dir_entry_2 *de; |
1794 | unsigned int blocksize = dir->i_sb->s_blocksize; | 1806 | unsigned int blocksize = dir->i_sb->s_blocksize; |
1795 | int err, retries = 0; | 1807 | int err, retries = 0; |
@@ -1822,7 +1834,9 @@ retry: | |||
1822 | if (!dir_block) | 1834 | if (!dir_block) |
1823 | goto out_clear_inode; | 1835 | goto out_clear_inode; |
1824 | BUFFER_TRACE(dir_block, "get_write_access"); | 1836 | BUFFER_TRACE(dir_block, "get_write_access"); |
1825 | ext4_journal_get_write_access(handle, dir_block); | 1837 | err = ext4_journal_get_write_access(handle, dir_block); |
1838 | if (err) | ||
1839 | goto out_clear_inode; | ||
1826 | de = (struct ext4_dir_entry_2 *) dir_block->b_data; | 1840 | de = (struct ext4_dir_entry_2 *) dir_block->b_data; |
1827 | de->inode = cpu_to_le32(inode->i_ino); | 1841 | de->inode = cpu_to_le32(inode->i_ino); |
1828 | de->name_len = 1; | 1842 | de->name_len = 1; |
@@ -1839,10 +1853,12 @@ retry: | |||
1839 | ext4_set_de_type(dir->i_sb, de, S_IFDIR); | 1853 | ext4_set_de_type(dir->i_sb, de, S_IFDIR); |
1840 | inode->i_nlink = 2; | 1854 | inode->i_nlink = 2; |
1841 | BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata"); | 1855 | BUFFER_TRACE(dir_block, "call ext4_handle_dirty_metadata"); |
1842 | ext4_handle_dirty_metadata(handle, dir, dir_block); | 1856 | err = ext4_handle_dirty_metadata(handle, dir, dir_block); |
1843 | brelse(dir_block); | 1857 | if (err) |
1844 | ext4_mark_inode_dirty(handle, inode); | 1858 | goto out_clear_inode; |
1845 | err = ext4_add_entry(handle, dentry, inode); | 1859 | err = ext4_mark_inode_dirty(handle, inode); |
1860 | if (!err) | ||
1861 | err = ext4_add_entry(handle, dentry, inode); | ||
1846 | if (err) { | 1862 | if (err) { |
1847 | out_clear_inode: | 1863 | out_clear_inode: |
1848 | clear_nlink(inode); | 1864 | clear_nlink(inode); |
@@ -1853,10 +1869,13 @@ out_clear_inode: | |||
1853 | } | 1869 | } |
1854 | ext4_inc_count(handle, dir); | 1870 | ext4_inc_count(handle, dir); |
1855 | ext4_update_dx_flag(dir); | 1871 | ext4_update_dx_flag(dir); |
1856 | ext4_mark_inode_dirty(handle, dir); | 1872 | err = ext4_mark_inode_dirty(handle, dir); |
1873 | if (err) | ||
1874 | goto out_clear_inode; | ||
1857 | d_instantiate(dentry, inode); | 1875 | d_instantiate(dentry, inode); |
1858 | unlock_new_inode(inode); | 1876 | unlock_new_inode(inode); |
1859 | out_stop: | 1877 | out_stop: |
1878 | brelse(dir_block); | ||
1860 | ext4_journal_stop(handle); | 1879 | ext4_journal_stop(handle); |
1861 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) | 1880 | if (err == -ENOSPC && ext4_should_retry_alloc(dir->i_sb, &retries)) |
1862 | goto retry; | 1881 | goto retry; |
@@ -1919,7 +1938,7 @@ static int empty_dir(struct inode *inode) | |||
1919 | } | 1938 | } |
1920 | de = (struct ext4_dir_entry_2 *) bh->b_data; | 1939 | de = (struct ext4_dir_entry_2 *) bh->b_data; |
1921 | } | 1940 | } |
1922 | if (!ext4_check_dir_entry(inode, de, bh, offset)) { | 1941 | if (ext4_check_dir_entry(inode, NULL, de, bh, offset)) { |
1923 | de = (struct ext4_dir_entry_2 *)(bh->b_data + | 1942 | de = (struct ext4_dir_entry_2 *)(bh->b_data + |
1924 | sb->s_blocksize); | 1943 | sb->s_blocksize); |
1925 | offset = (offset | (sb->s_blocksize - 1)) + 1; | 1944 | offset = (offset | (sb->s_blocksize - 1)) + 1; |
@@ -2407,7 +2426,11 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2407 | ext4_current_time(new_dir); | 2426 | ext4_current_time(new_dir); |
2408 | ext4_mark_inode_dirty(handle, new_dir); | 2427 | ext4_mark_inode_dirty(handle, new_dir); |
2409 | BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata"); | 2428 | BUFFER_TRACE(new_bh, "call ext4_handle_dirty_metadata"); |
2410 | ext4_handle_dirty_metadata(handle, new_dir, new_bh); | 2429 | retval = ext4_handle_dirty_metadata(handle, new_dir, new_bh); |
2430 | if (unlikely(retval)) { | ||
2431 | ext4_std_error(new_dir->i_sb, retval); | ||
2432 | goto end_rename; | ||
2433 | } | ||
2411 | brelse(new_bh); | 2434 | brelse(new_bh); |
2412 | new_bh = NULL; | 2435 | new_bh = NULL; |
2413 | } | 2436 | } |
@@ -2459,7 +2482,11 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
2459 | PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) = | 2482 | PARENT_INO(dir_bh->b_data, new_dir->i_sb->s_blocksize) = |
2460 | cpu_to_le32(new_dir->i_ino); | 2483 | cpu_to_le32(new_dir->i_ino); |
2461 | BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata"); | 2484 | BUFFER_TRACE(dir_bh, "call ext4_handle_dirty_metadata"); |
2462 | ext4_handle_dirty_metadata(handle, old_dir, dir_bh); | 2485 | retval = ext4_handle_dirty_metadata(handle, old_dir, dir_bh); |
2486 | if (retval) { | ||
2487 | ext4_std_error(old_dir->i_sb, retval); | ||
2488 | goto end_rename; | ||
2489 | } | ||
2463 | ext4_dec_count(handle, old_dir); | 2490 | ext4_dec_count(handle, old_dir); |
2464 | if (new_inode) { | 2491 | if (new_inode) { |
2465 | /* checked empty_dir above, can't have another parent, | 2492 | /* checked empty_dir above, can't have another parent, |