add patch jbd2_log_wait_for_space-improve-error-detection
[ext4-patch-queue.git] / convert-dx_probe-to-use-the-ERR_PTR-convention
blob4705db3eee42dbcf641e7e78280518eedd6b76b6
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>
6 ---
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
12 --- a/fs/ext4/namei.c
13 +++ b/fs/ext4/namei.c
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,
16                                  struct inode *dir,
17                                  struct dx_hash_info *hinfo,
18 -                                struct dx_frame *frame,
19 -                                int *err);
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,
25   */
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)
30  {
31         unsigned count, indirect;
32         struct dx_entry *at, *entries, *p, *q, *m;
33         struct dx_root *root;
34 -       struct buffer_head *bh;
35         struct dx_frame *frame = frame_in;
36 +       struct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR);
37         u32 hash;
39 -       frame->bh = NULL;
40 -       bh = ext4_read_dirblock(dir, 0, INDEX);
41 -       if (IS_ERR(bh)) {
42 -               *err = PTR_ERR(bh);
43 -               goto fail;
44 -       }
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);
56 -               brelse(bh);
57 -               *err = ERR_BAD_DX_DIR;
58                 goto fail;
59         }
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);
65 -               brelse(bh);
66 -               *err = ERR_BAD_DX_DIR;
67                 goto fail;
68         }
70         if ((indirect = root->info.indirect_levels) > 1) {
71                 ext4_warning(dir->i_sb, "Unimplemented inode hash depth: %#06x",
72                              root->info.indirect_levels);
73 -               brelse(bh);
74 -               *err = ERR_BAD_DX_DIR;
75                 goto fail;
76         }
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");
82 -               brelse(bh);
83 -               *err = ERR_BAD_DX_DIR;
84                 goto fail;
85         }
87         dxtrace(printk("Look up %x", hash));
88 -       while (1)
89 -       {
90 +       while (1) {
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");
95 -                       brelse(bh);
96 -                       *err = ERR_BAD_DX_DIR;
97 -                       goto fail2;
98 +                       goto fail;
99                 }
101                 p = entries + 1;
102                 q = entries + count - 1;
103 -               while (p <= q)
104 -               {
105 +               while (p <= q) {
106                         m = p + (q - p)/2;
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,
110                                 p = m + 1;
111                 }
113 -               if (0) // linear search cross check
114 -               {
115 +               if (0) { // linear search cross check
116                         unsigned n = count - 1;
117                         at = entries;
118                         while (n--)
119 @@ -772,38 +756,35 @@ dx_probe(const struct qstr *d_name, struct inode *dir,
121                 at = p - 1;
122                 dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at)));
123 -               frame->bh = bh;
124                 frame->entries = entries;
125                 frame->at = at;
126 -               if (!indirect--) return frame;
127 -               bh = ext4_read_dirblock(dir, dx_get_block(at), INDEX);
128 -               if (IS_ERR(bh)) {
129 -                       *err = PTR_ERR(bh);
130 -                       goto fail2;
131 +               if (!indirect--)
132 +                       return frame;
133 +               frame++;
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;
137 +                       frame->bh = NULL;
138 +                       goto fail;
139                 }
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");
146 -                       brelse(bh);
147 -                       *err = ERR_BAD_DX_DIR;
148 -                       goto fail2;
149 +                       goto fail;
150                 }
151 -               frame++;
152 -               frame->bh = NULL;
153         }
154 -fail2:
155 +fail:
156         while (frame >= frame_in) {
157                 brelse(frame->bh);
158                 frame--;
159         }
160 -fail:
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);
166 -       return NULL;
167 +       return ret_err;
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,
172         }
173         hinfo.hash = start_hash;
174         hinfo.minor_hash = 0;
175 -       frame = dx_probe(NULL, dir, &hinfo, frames, &err);
176 -       if (!frame)
177 -               return err;
178 +       frame = dx_probe(NULL, dir, &hinfo, frames);
179 +       if (IS_ERR(frame))
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;
187         ext4_lblk_t block;
188 -       int err = 0, retval;
189 +       int retval;
191 -       frame = dx_probe(d_name, dir, &hinfo, frames, &err);
192 -       if (err)
193 -               return ERR_PTR(err);
194 +       frame = dx_probe(d_name, dir, &hinfo, frames);
195 +       if (IS_ERR(frame))
196 +               return (struct buffer_head *) frame;
197         do {
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;
202         int err;
204 -       frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err);
205 -       if (!frame)
206 -               return err;
207 +       frame = dx_probe(&dentry->d_name, dir, &hinfo, frames);
208 +       if (IS_ERR(frame))
209 +               return PTR_ERR(frame);
210         entries = frame->entries;
211         at = frame->at;
212         bh = ext4_read_dirblock(dir, dx_get_block(frame->at), DIRENT);
213 -- 
214 2.1.0