diff options
author | Theodore Ts'o <tytso@mit.edu> | 2014-08-29 20:52:17 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2014-08-29 20:52:17 -0400 |
commit | dd73b5d5cb675e2aa3b1d4952e208af1546f91c1 (patch) | |
tree | 4f2f8f62f37fae15a6222ace8e19b82ce6fc9ef5 /fs/ext4/namei.c | |
parent | 1c2150283cae895526d0db3953d13d139f4e7a03 (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.c | 89 |
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); | |||
253 | static struct dx_frame *dx_probe(const struct qstr *d_name, | 253 | static 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); | ||
258 | static void dx_release(struct dx_frame *frames); | 257 | static void dx_release(struct dx_frame *frames); |
259 | static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize, | 258 | static 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 | */ |
671 | static struct dx_frame * | 670 | static struct dx_frame * |
672 | dx_probe(const struct qstr *d_name, struct inode *dir, | 671 | dx_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 | } |
796 | fail2: | 778 | fail: |
797 | while (frame >= frame_in) { | 779 | while (frame >= frame_in) { |
798 | brelse(frame->bh); | 780 | brelse(frame->bh); |
799 | frame--; | 781 | frame--; |
800 | } | 782 | } |
801 | fail: | 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 | ||
809 | static void dx_release (struct dx_frame *frames) | 790 | static 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); |