aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/namei.c87
1 files changed, 75 insertions, 12 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index bd87b7a66afb..6d600a69fc9d 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -74,6 +74,12 @@ static struct buffer_head *ext4_append(handle_t *handle,
74 bh = NULL; 74 bh = NULL;
75 } 75 }
76 } 76 }
77 if (!bh && !(*err)) {
78 *err = -EIO;
79 ext4_error(inode->i_sb,
80 "Directory hole detected on inode %lu\n",
81 inode->i_ino);
82 }
77 return bh; 83 return bh;
78} 84}
79 85
@@ -601,8 +607,11 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
601 u32 hash; 607 u32 hash;
602 608
603 frame->bh = NULL; 609 frame->bh = NULL;
604 if (!(bh = ext4_bread (NULL,dir, 0, 0, err))) 610 if (!(bh = ext4_bread(NULL, dir, 0, 0, err))) {
611 if (*err == 0)
612 *err = ERR_BAD_DX_DIR;
605 goto fail; 613 goto fail;
614 }
606 root = (struct dx_root *) bh->b_data; 615 root = (struct dx_root *) bh->b_data;
607 if (root->info.hash_version != DX_HASH_TEA && 616 if (root->info.hash_version != DX_HASH_TEA &&
608 root->info.hash_version != DX_HASH_HALF_MD4 && 617 root->info.hash_version != DX_HASH_HALF_MD4 &&
@@ -703,8 +712,11 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
703 frame->entries = entries; 712 frame->entries = entries;
704 frame->at = at; 713 frame->at = at;
705 if (!indirect--) return frame; 714 if (!indirect--) return frame;
706 if (!(bh = ext4_bread (NULL,dir, dx_get_block(at), 0, err))) 715 if (!(bh = ext4_bread(NULL, dir, dx_get_block(at), 0, err))) {
716 if (!(*err))
717 *err = ERR_BAD_DX_DIR;
707 goto fail2; 718 goto fail2;
719 }
708 at = entries = ((struct dx_node *) bh->b_data)->entries; 720 at = entries = ((struct dx_node *) bh->b_data)->entries;
709 721
710 if (!buffer_verified(bh) && 722 if (!buffer_verified(bh) &&
@@ -814,8 +826,15 @@ static int ext4_htree_next_block(struct inode *dir, __u32 hash,
814 */ 826 */
815 while (num_frames--) { 827 while (num_frames--) {
816 if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at), 828 if (!(bh = ext4_bread(NULL, dir, dx_get_block(p->at),
817 0, &err))) 829 0, &err))) {
830 if (!err) {
831 ext4_error(dir->i_sb,
832 "Directory hole detected on inode %lu\n",
833 dir->i_ino);
834 return -EIO;
835 }
818 return err; /* Failure */ 836 return err; /* Failure */
837 }
819 838
820 if (!buffer_verified(bh) && 839 if (!buffer_verified(bh) &&
821 !ext4_dx_csum_verify(dir, 840 !ext4_dx_csum_verify(dir,
@@ -850,8 +869,15 @@ static int htree_dirblock_to_tree(struct file *dir_file,
850 869
851 dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n", 870 dxtrace(printk(KERN_INFO "In htree dirblock_to_tree: block %lu\n",
852 (unsigned long)block)); 871 (unsigned long)block));
853 if (!(bh = ext4_bread (NULL, dir, block, 0, &err))) 872 if (!(bh = ext4_bread(NULL, dir, block, 0, &err))) {
873 if (!err) {
874 err = -EIO;
875 ext4_error(dir->i_sb,
876 "Directory hole detected on inode %lu\n",
877 dir->i_ino);
878 }
854 return err; 879 return err;
880 }
855 881
856 if (!buffer_verified(bh) && 882 if (!buffer_verified(bh) &&
857 !ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data)) 883 !ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data))
@@ -1274,8 +1300,15 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
1274 return NULL; 1300 return NULL;
1275 do { 1301 do {
1276 block = dx_get_block(frame->at); 1302 block = dx_get_block(frame->at);
1277 if (!(bh = ext4_bread(NULL, dir, block, 0, err))) 1303 if (!(bh = ext4_bread(NULL, dir, block, 0, err))) {
1304 if (!(*err)) {
1305 *err = -EIO;
1306 ext4_error(dir->i_sb,
1307 "Directory hole detected on inode %lu\n",
1308 dir->i_ino);
1309 }
1278 goto errout; 1310 goto errout;
1311 }
1279 1312
1280 if (!buffer_verified(bh) && 1313 if (!buffer_verified(bh) &&
1281 !ext4_dirent_csum_verify(dir, 1314 !ext4_dirent_csum_verify(dir,
@@ -1808,9 +1841,15 @@ static int ext4_add_entry(handle_t *handle, struct dentry *dentry,
1808 } 1841 }
1809 blocks = dir->i_size >> sb->s_blocksize_bits; 1842 blocks = dir->i_size >> sb->s_blocksize_bits;
1810 for (block = 0; block < blocks; block++) { 1843 for (block = 0; block < blocks; block++) {
1811 bh = ext4_bread(handle, dir, block, 0, &retval); 1844 if (!(bh = ext4_bread(handle, dir, block, 0, &retval))) {
1812 if(!bh) 1845 if (!retval) {
1846 retval = -EIO;
1847 ext4_error(inode->i_sb,
1848 "Directory hole detected on inode %lu\n",
1849 inode->i_ino);
1850 }
1813 return retval; 1851 return retval;
1852 }
1814 if (!buffer_verified(bh) && 1853 if (!buffer_verified(bh) &&
1815 !ext4_dirent_csum_verify(dir, 1854 !ext4_dirent_csum_verify(dir,
1816 (struct ext4_dir_entry *)bh->b_data)) 1855 (struct ext4_dir_entry *)bh->b_data))
@@ -1867,8 +1906,15 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1867 entries = frame->entries; 1906 entries = frame->entries;
1868 at = frame->at; 1907 at = frame->at;
1869 1908
1870 if (!(bh = ext4_bread(handle,dir, dx_get_block(frame->at), 0, &err))) 1909 if (!(bh = ext4_bread(handle, dir, dx_get_block(frame->at), 0, &err))) {
1910 if (!err) {
1911 err = -EIO;
1912 ext4_error(dir->i_sb,
1913 "Directory hole detected on inode %lu\n",
1914 dir->i_ino);
1915 }
1871 goto cleanup; 1916 goto cleanup;
1917 }
1872 1918
1873 if (!buffer_verified(bh) && 1919 if (!buffer_verified(bh) &&
1874 !ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data)) 1920 !ext4_dirent_csum_verify(dir, (struct ext4_dir_entry *)bh->b_data))
@@ -2204,9 +2250,15 @@ retry:
2204 inode->i_op = &ext4_dir_inode_operations; 2250 inode->i_op = &ext4_dir_inode_operations;
2205 inode->i_fop = &ext4_dir_operations; 2251 inode->i_fop = &ext4_dir_operations;
2206 inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize; 2252 inode->i_size = EXT4_I(inode)->i_disksize = inode->i_sb->s_blocksize;
2207 dir_block = ext4_bread(handle, inode, 0, 1, &err); 2253 if (!(dir_block = ext4_bread(handle, inode, 0, 1, &err))) {
2208 if (!dir_block) 2254 if (!err) {
2255 err = -EIO;
2256 ext4_error(inode->i_sb,
2257 "Directory hole detected on inode %lu\n",
2258 inode->i_ino);
2259 }
2209 goto out_clear_inode; 2260 goto out_clear_inode;
2261 }
2210 BUFFER_TRACE(dir_block, "get_write_access"); 2262 BUFFER_TRACE(dir_block, "get_write_access");
2211 err = ext4_journal_get_write_access(handle, dir_block); 2263 err = ext4_journal_get_write_access(handle, dir_block);
2212 if (err) 2264 if (err)
@@ -2323,6 +2375,11 @@ static int empty_dir(struct inode *inode)
2323 EXT4_ERROR_INODE(inode, 2375 EXT4_ERROR_INODE(inode,
2324 "error %d reading directory " 2376 "error %d reading directory "
2325 "lblock %u", err, lblock); 2377 "lblock %u", err, lblock);
2378 else
2379 ext4_warning(inode->i_sb,
2380 "bad directory (dir #%lu) - no data block",
2381 inode->i_ino);
2382
2326 offset += sb->s_blocksize; 2383 offset += sb->s_blocksize;
2327 continue; 2384 continue;
2328 } 2385 }
@@ -2830,9 +2887,15 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
2830 goto end_rename; 2887 goto end_rename;
2831 } 2888 }
2832 retval = -EIO; 2889 retval = -EIO;
2833 dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval); 2890 if (!(dir_bh = ext4_bread(handle, old_inode, 0, 0, &retval))) {
2834 if (!dir_bh) 2891 if (!retval) {
2892 retval = -EIO;
2893 ext4_error(old_inode->i_sb,
2894 "Directory hole detected on inode %lu\n",
2895 old_inode->i_ino);
2896 }
2835 goto end_rename; 2897 goto end_rename;
2898 }
2836 if (!buffer_verified(dir_bh) && 2899 if (!buffer_verified(dir_bh) &&
2837 !ext4_dirent_csum_verify(old_inode, 2900 !ext4_dirent_csum_verify(old_inode,
2838 (struct ext4_dir_entry *)dir_bh->b_data)) 2901 (struct ext4_dir_entry *)dir_bh->b_data))