aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/namei.c
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2014-08-29 20:52:17 -0400
committerTheodore Ts'o <tytso@mit.edu>2014-08-29 20:52:17 -0400
commitdd73b5d5cb675e2aa3b1d4952e208af1546f91c1 (patch)
tree4f2f8f62f37fae15a6222ace8e19b82ce6fc9ef5 /fs/ext4/namei.c
parent1c2150283cae895526d0db3953d13d139f4e7a03 (diff)
ext4: convert dx_probe() to use the ERR_PTR convention
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/namei.c')
-rw-r--r--fs/ext4/namei.c89
1 files changed, 35 insertions, 54 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
index af13c908f617..e6d51655ffcd 100644
--- a/fs/ext4/namei.c
+++ b/fs/ext4/namei.c
@@ -253,8 +253,7 @@ static unsigned dx_node_limit(struct inode *dir);
253static struct dx_frame *dx_probe(const struct qstr *d_name, 253static struct dx_frame *dx_probe(const struct qstr *d_name,
254 struct inode *dir, 254 struct inode *dir,
255 struct dx_hash_info *hinfo, 255 struct dx_hash_info *hinfo,
256 struct dx_frame *frame, 256 struct dx_frame *frame);
257 int *err);
258static void dx_release(struct dx_frame *frames); 257static void dx_release(struct dx_frame *frames);
259static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize, 258static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize,
260 struct dx_hash_info *hinfo, struct dx_map_entry map[]); 259 struct dx_hash_info *hinfo, struct dx_map_entry map[]);
@@ -670,29 +669,25 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
670 */ 669 */
671static struct dx_frame * 670static struct dx_frame *
672dx_probe(const struct qstr *d_name, struct inode *dir, 671dx_probe(const struct qstr *d_name, struct inode *dir,
673 struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err) 672 struct dx_hash_info *hinfo, struct dx_frame *frame_in)
674{ 673{
675 unsigned count, indirect; 674 unsigned count, indirect;
676 struct dx_entry *at, *entries, *p, *q, *m; 675 struct dx_entry *at, *entries, *p, *q, *m;
677 struct dx_root *root; 676 struct dx_root *root;
678 struct buffer_head *bh;
679 struct dx_frame *frame = frame_in; 677 struct dx_frame *frame = frame_in;
678 struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR);
680 u32 hash; 679 u32 hash;
681 680
682 frame->bh = NULL; 681 frame->bh = ext4_read_dirblock(dir, 0, INDEX);
683 bh = ext4_read_dirblock(dir, 0, INDEX); 682 if (IS_ERR(frame->bh))
684 if (IS_ERR(bh)) { 683 return (struct dx_frame *) frame->bh;
685 *err = PTR_ERR(bh); 684
686 goto fail; 685 root = (struct dx_root *) frame->bh->b_data;
687 }
688 root = (struct dx_root *) bh->b_data;
689 if (root->info.hash_version != DX_HASH_TEA && 686 if (root->info.hash_version != DX_HASH_TEA &&
690 root->info.hash_version != DX_HASH_HALF_MD4 && 687 root->info.hash_version != DX_HASH_HALF_MD4 &&
691 root->info.hash_version != DX_HASH_LEGACY) { 688 root->info.hash_version != DX_HASH_LEGACY) {
692 ext4_warning(dir->i_sb, "Unrecognised inode hash code %d", 689 ext4_warning(dir->i_sb, "Unrecognised inode hash code %d",
693 root->info.hash_version); 690 root->info.hash_version);
694 brelse(bh);
695 *err = ERR_BAD_DX_DIR;
696 goto fail; 691 goto fail;
697 } 692 }
698 hinfo->hash_version = root->info.hash_version; 693 hinfo->hash_version = root->info.hash_version;
@@ -706,16 +701,12 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
706 if (root->info.unused_flags & 1) { 701 if (root->info.unused_flags & 1) {
707 ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x", 702 ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
708 root->info.unused_flags); 703 root->info.unused_flags);
709 brelse(bh);
710 *err = ERR_BAD_DX_DIR;
711 goto fail; 704 goto fail;
712 } 705 }
713 706
714 if ((indirect = root->info.indirect_levels) > 1) { 707 if ((indirect = root->info.indirect_levels) > 1) {
715 ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x", 708 ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
716 root->info.indirect_levels); 709 root->info.indirect_levels);
717 brelse(bh);
718 *err = ERR_BAD_DX_DIR;
719 goto fail; 710 goto fail;
720 } 711 }
721 712
@@ -725,27 +716,21 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
725 if (dx_get_limit(entries) != dx_root_limit(dir, 716 if (dx_get_limit(entries) != dx_root_limit(dir,
726 root->info.info_length)) { 717 root->info.info_length)) {
727 ext4_warning(dir->i_sb, "dx entry: limit != root limit"); 718 ext4_warning(dir->i_sb, "dx entry: limit != root limit");
728 brelse(bh);
729 *err = ERR_BAD_DX_DIR;
730 goto fail; 719 goto fail;
731 } 720 }
732 721
733 dxtrace(printk("Look up %x", hash)); 722 dxtrace(printk("Look up %x", hash));
734 while (1) 723 while (1) {
735 {
736 count = dx_get_count(entries); 724 count = dx_get_count(entries);
737 if (!count || count > dx_get_limit(entries)) { 725 if (!count || count > dx_get_limit(entries)) {
738 ext4_warning(dir->i_sb, 726 ext4_warning(dir->i_sb,
739 "dx entry: no count or count > limit"); 727 "dx entry: no count or count > limit");
740 brelse(bh); 728 goto fail;
741 *err = ERR_BAD_DX_DIR;
742 goto fail2;
743 } 729 }
744 730
745 p = entries + 1; 731 p = entries + 1;
746 q = entries + count - 1; 732 q = entries + count - 1;
747 while (p <= q) 733 while (p <= q) {
748 {
749 m = p + (q - p)/2; 734 m = p + (q - p)/2;
750 dxtrace(printk(".")); 735 dxtrace(printk("."));
751 if (dx_get_hash(m) > hash) 736 if (dx_get_hash(m) > hash)
@@ -754,8 +739,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
754 p = m + 1; 739 p = m + 1;
755 } 740 }
756 741
757 if (0) // linear search cross check 742 if (0) { // linear search cross check
758 {
759 unsigned n = count - 1; 743 unsigned n = count - 1;
760 at = entries; 744 at = entries;
761 while (n--) 745 while (n--)
@@ -772,38 +756,35 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
772 756
773 at = p - 1; 757 at = p - 1;
774 dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); 758 dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
775 frame->bh = bh;
776 frame->entries = entries; 759 frame->entries = entries;
777 frame->at = at; 760 frame->at = at;
778 if (!indirect--) return frame; 761 if (!indirect--)
779 bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX); 762 return frame;
780 if (IS_ERR(bh)) { 763 frame++;
781 *err = PTR_ERR(bh); 764 frame->bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX);
782 goto fail2; 765 if (IS_ERR(frame->bh)) {
766 ret_err = (struct dx_frame *) frame->bh;
767 frame->bh = NULL;
768 goto fail;
783 } 769 }
784 entries = ((struct dx_node *) bh->b_data)->entries; 770 entries = ((struct dx_node *) frame->bh->b_data)->entries;
785 771
786 if (dx_get_limit(entries) != dx_node_limit (dir)) { 772 if (dx_get_limit(entries) != dx_node_limit (dir)) {
787 ext4_warning(dir->i_sb, 773 ext4_warning(dir->i_sb,
788 "dx entry: limit != node limit"); 774 "dx entry: limit != node limit");
789 brelse(bh); 775 goto fail;
790 *err = ERR_BAD_DX_DIR;
791 goto fail2;
792 } 776 }
793 frame++;
794 frame->bh = NULL;
795 } 777 }
796fail2: 778fail:
797 while (frame >= frame_in) { 779 while (frame >= frame_in) {
798 brelse(frame->bh); 780 brelse(frame->bh);
799 frame--; 781 frame--;
800 } 782 }
801fail: 783 if (ret_err == ERR_PTR(ERR_BAD_DX_DIR))
802 if (*err == ERR_BAD_DX_DIR)
803 ext4_warning(dir->i_sb, 784 ext4_warning(dir->i_sb,
804 "Corrupt dir inode %lu, running e2fsck is " 785 "Corrupt dir inode %lu, running e2fsck is "
805 "recommended.", dir->i_ino); 786 "recommended.", dir->i_ino);
806 return NULL; 787 return ret_err;
807} 788}
808 789
809static void dx_release (struct dx_frame *frames) 790static void dx_release (struct dx_frame *frames)
@@ -989,9 +970,9 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
989 } 970 }
990 hinfo.hash = start_hash; 971 hinfo.hash = start_hash;
991 hinfo.minor_hash = 0; 972 hinfo.minor_hash = 0;
992 frame = dx_probe(NULL, dir, &hinfo, frames, &err); 973 frame = dx_probe(NULL, dir, &hinfo, frames);
993 if (!frame) 974 if (IS_ERR(frame))
994 return err; 975 return PTR_ERR(frame);
995 976
996 /* Add '.' and '..' from the htree header */ 977 /* Add '.' and '..' from the htree header */
997 if (!start_hash && !start_minor_hash) { 978 if (!start_hash && !start_minor_hash) {
@@ -1369,11 +1350,11 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
1369 struct dx_frame frames[2], *frame; 1350 struct dx_frame frames[2], *frame;
1370 struct buffer_head *bh; 1351 struct buffer_head *bh;
1371 ext4_lblk_t block; 1352 ext4_lblk_t block;
1372 int err = 0, retval; 1353 int retval;
1373 1354
1374 frame = dx_probe(d_name, dir, &hinfo, frames, &err); 1355 frame = dx_probe(d_name, dir, &hinfo, frames);
1375 if (err) 1356 if (IS_ERR(frame))
1376 return ERR_PTR(err); 1357 return (struct buffer_head *) frame;
1377 do { 1358 do {
1378 block = dx_get_block(frame->at); 1359 block = dx_get_block(frame->at);
1379 bh = ext4_read_dirblock(dir, block, DIRENT); 1360 bh = ext4_read_dirblock(dir, block, DIRENT);
@@ -1977,9 +1958,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
1977 struct ext4_dir_entry_2 *de; 1958 struct ext4_dir_entry_2 *de;
1978 int err; 1959 int err;
1979 1960
1980 frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err); 1961 frame = dx_probe(&dentry->d_name, dir, &hinfo, frames);
1981 if (!frame) 1962 if (IS_ERR(frame))
1982 return err; 1963 return PTR_ERR(frame);
1983 entries = frame->entries; 1964 entries = frame->entries;
1984 at = frame->at; 1965 at = frame->at;
1985 bh = ext4_read_dirblock(dir, dx_get_block(frame->at), DIRENT); 1966 bh = ext4_read_dirblock(dir, dx_get_block(frame->at), DIRENT);