1 ext4: convert dx_probe() to use the ERR_PTR convention
3 From: Theodore Ts'o <tytso@mit.edu>
5 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
7 fs/ext4/namei.c | 89 +++++++++++++++++++++++----------------------------------
8 1 file changed, 35 insertions(+), 54 deletions(-)
10 diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
11 index af13c90..e6d5165 100644
14 @@ -253,8 +253,7 @@ static unsigned dx_node_limit(struct inode *dir);
15 static struct dx_frame *dx_probe(const struct qstr *d_name,
17 struct dx_hash_info *hinfo,
18 - struct dx_frame *frame,
20 + struct dx_frame *frame);
21 static void dx_release(struct dx_frame *frames);
22 static int dx_make_map(struct ext4_dir_entry_2 *de, unsigned blocksize,
23 struct dx_hash_info *hinfo, struct dx_map_entry map[]);
24 @@ -670,29 +669,25 @@ struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir,
26 static struct dx_frame *
27 dx_probe(const struct qstr *d_name, struct inode *dir,
28 - struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err)
29 + struct dx_hash_info *hinfo, struct dx_frame *frame_in)
31 unsigned count, indirect;
32 struct dx_entry *at, *entries, *p, *q, *m;
34 - struct buffer_head *bh;
35 struct dx_frame *frame = frame_in;
36 + struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR);
40 - bh = ext4_read_dirblock(dir, 0, INDEX);
45 - root = (struct dx_root *) bh->b_data;
46 + frame->bh = ext4_read_dirblock(dir, 0, INDEX);
47 + if (IS_ERR(frame->bh))
48 + return (struct dx_frame *) frame->bh;
50 + root = (struct dx_root *) frame->bh->b_data;
51 if (root->info.hash_version != DX_HASH_TEA &&
52 root->info.hash_version != DX_HASH_HALF_MD4 &&
53 root->info.hash_version != DX_HASH_LEGACY) {
54 ext4_warning(dir->i_sb, "Unrecognised inode hash code %d",
55 root->info.hash_version);
57 - *err = ERR_BAD_DX_DIR;
60 hinfo->hash_version = root->info.hash_version;
61 @@ -706,16 +701,12 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
62 if (root->info.unused_flags & 1) {
63 ext4_warning(dir->i_sb, "Unimplemented inode hash flags: %#06x",
64 root->info.unused_flags);
66 - *err = ERR_BAD_DX_DIR;
70 if ((indirect = root->info.indirect_levels) > 1) {
71 ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
72 root->info.indirect_levels);
74 - *err = ERR_BAD_DX_DIR;
78 @@ -725,27 +716,21 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
79 if (dx_get_limit(entries) != dx_root_limit(dir,
80 root->info.info_length)) {
81 ext4_warning(dir->i_sb, "dx entry: limit != root limit");
83 - *err = ERR_BAD_DX_DIR;
87 dxtrace(printk("Look up %x", hash));
91 count = dx_get_count(entries);
92 if (!count || count > dx_get_limit(entries)) {
93 ext4_warning(dir->i_sb,
94 "dx entry: no count or count > limit");
96 - *err = ERR_BAD_DX_DIR;
102 q = entries + count - 1;
107 dxtrace(printk("."));
108 if (dx_get_hash(m) > hash)
109 @@ -754,8 +739,7 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
113 - if (0) // linear search cross check
115 + if (0) { // linear search cross check
116 unsigned n = count - 1;
119 @@ -772,38 +756,35 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
122 dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
124 frame->entries = entries;
126 - if (!indirect--) return frame;
127 - bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX);
129 - *err = PTR_ERR(bh);
134 + frame->bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX);
135 + if (IS_ERR(frame->bh)) {
136 + ret_err = (struct dx_frame *) frame->bh;
140 - entries = ((struct dx_node *) bh->b_data)->entries;
141 + entries = ((struct dx_node *) frame->bh->b_data)->entries;
143 if (dx_get_limit(entries) != dx_node_limit (dir)) {
144 ext4_warning(dir->i_sb,
145 "dx entry: limit != node limit");
147 - *err = ERR_BAD_DX_DIR;
156 while (frame >= frame_in) {
161 - if (*err == ERR_BAD_DX_DIR)
162 + if (ret_err == ERR_PTR(ERR_BAD_DX_DIR))
163 ext4_warning(dir->i_sb,
164 "Corrupt dir inode %lu, running e2fsck is "
165 "recommended.", dir->i_ino);
170 static void dx_release (struct dx_frame *frames)
171 @@ -989,9 +970,9 @@ int ext4_htree_fill_tree(struct file *dir_file, __u32 start_hash,
173 hinfo.hash = start_hash;
174 hinfo.minor_hash = 0;
175 - frame = dx_probe(NULL, dir, &hinfo, frames, &err);
178 + frame = dx_probe(NULL, dir, &hinfo, frames);
180 + return PTR_ERR(frame);
182 /* Add '.' and '..' from the htree header */
183 if (!start_hash && !start_minor_hash) {
184 @@ -1369,11 +1350,11 @@ static struct buffer_head * ext4_dx_find_entry(struct inode *dir, const struct q
185 struct dx_frame frames[2], *frame;
186 struct buffer_head *bh;
188 - int err = 0, retval;
191 - frame = dx_probe(d_name, dir, &hinfo, frames, &err);
193 - return ERR_PTR(err);
194 + frame = dx_probe(d_name, dir, &hinfo, frames);
196 + return (struct buffer_head *) frame;
198 block = dx_get_block(frame->at);
199 bh = ext4_read_dirblock(dir, block, DIRENT);
200 @@ -1977,9 +1958,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct dentry *dentry,
201 struct ext4_dir_entry_2 *de;
204 - frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err);
207 + frame = dx_probe(&dentry->d_name, dir, &hinfo, frames);
209 + return PTR_ERR(frame);
210 entries = frame->entries;
212 bh = ext4_read_dirblock(dir, dx_get_block(frame->at), DIRENT);