diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2013-12-10 19:48:58 -0500 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-01-25 03:13:03 -0500 |
commit | 208adb6403e079ceeb8e731696615d22db6f397b (patch) | |
tree | e2e2b778d320c89c73354b4e27e613b354a299be /fs/qnx4 | |
parent | 5a9ed6f5e7b80c95b133818aa96b1fba8e1216a0 (diff) |
qnx4: clean qnx4_fill_super() up
* pass on-disk superblock to qnx4_chkroot() explicitly
* don't leave stale (and unused) pointers in qnx4_super_block
* free stuff in ->kill_sb(); ->put_super() becomes empty and dies
* simplify failure exits
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/qnx4')
-rw-r--r-- | fs/qnx4/inode.c | 63 | ||||
-rw-r--r-- | fs/qnx4/qnx4.h | 2 |
2 files changed, 22 insertions, 43 deletions
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index 2e8caa62da78..89558810381c 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c | |||
@@ -27,7 +27,6 @@ | |||
27 | 27 | ||
28 | static const struct super_operations qnx4_sops; | 28 | static const struct super_operations qnx4_sops; |
29 | 29 | ||
30 | static void qnx4_put_super(struct super_block *sb); | ||
31 | static struct inode *qnx4_alloc_inode(struct super_block *sb); | 30 | static struct inode *qnx4_alloc_inode(struct super_block *sb); |
32 | static void qnx4_destroy_inode(struct inode *inode); | 31 | static void qnx4_destroy_inode(struct inode *inode); |
33 | static int qnx4_remount(struct super_block *sb, int *flags, char *data); | 32 | static int qnx4_remount(struct super_block *sb, int *flags, char *data); |
@@ -37,7 +36,6 @@ static const struct super_operations qnx4_sops = | |||
37 | { | 36 | { |
38 | .alloc_inode = qnx4_alloc_inode, | 37 | .alloc_inode = qnx4_alloc_inode, |
39 | .destroy_inode = qnx4_destroy_inode, | 38 | .destroy_inode = qnx4_destroy_inode, |
40 | .put_super = qnx4_put_super, | ||
41 | .statfs = qnx4_statfs, | 39 | .statfs = qnx4_statfs, |
42 | .remount_fs = qnx4_remount, | 40 | .remount_fs = qnx4_remount, |
43 | }; | 41 | }; |
@@ -148,18 +146,19 @@ static int qnx4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
148 | * it really _is_ a qnx4 filesystem, and to check the size | 146 | * it really _is_ a qnx4 filesystem, and to check the size |
149 | * of the directory entry. | 147 | * of the directory entry. |
150 | */ | 148 | */ |
151 | static const char *qnx4_checkroot(struct super_block *sb) | 149 | static const char *qnx4_checkroot(struct super_block *sb, |
150 | struct qnx4_super_block *s) | ||
152 | { | 151 | { |
153 | struct buffer_head *bh; | 152 | struct buffer_head *bh; |
154 | struct qnx4_inode_entry *rootdir; | 153 | struct qnx4_inode_entry *rootdir; |
155 | int rd, rl; | 154 | int rd, rl; |
156 | int i, j; | 155 | int i, j; |
157 | 156 | ||
158 | if (*(qnx4_sb(sb)->sb->RootDir.di_fname) != '/') | 157 | if (s->RootDir.di_fname[0] != '/' || s->RootDir.di_fname[1] != '\0') |
159 | return "no qnx4 filesystem (no root dir)."; | 158 | return "no qnx4 filesystem (no root dir)."; |
160 | QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id)); | 159 | QNX4DEBUG((KERN_NOTICE "QNX4 filesystem found on dev %s.\n", sb->s_id)); |
161 | rd = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_blk) - 1; | 160 | rd = le32_to_cpu(s->RootDir.di_first_xtnt.xtnt_blk) - 1; |
162 | rl = le32_to_cpu(qnx4_sb(sb)->sb->RootDir.di_first_xtnt.xtnt_size); | 161 | rl = le32_to_cpu(s->RootDir.di_first_xtnt.xtnt_size); |
163 | for (j = 0; j < rl; j++) { | 162 | for (j = 0; j < rl; j++) { |
164 | bh = sb_bread(sb, rd + j); /* root dir, first block */ | 163 | bh = sb_bread(sb, rd + j); /* root dir, first block */ |
165 | if (bh == NULL) | 164 | if (bh == NULL) |
@@ -189,7 +188,6 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent) | |||
189 | struct inode *root; | 188 | struct inode *root; |
190 | const char *errmsg; | 189 | const char *errmsg; |
191 | struct qnx4_sb_info *qs; | 190 | struct qnx4_sb_info *qs; |
192 | int ret = -EINVAL; | ||
193 | 191 | ||
194 | qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); | 192 | qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); |
195 | if (!qs) | 193 | if (!qs) |
@@ -198,67 +196,50 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent) | |||
198 | 196 | ||
199 | sb_set_blocksize(s, QNX4_BLOCK_SIZE); | 197 | sb_set_blocksize(s, QNX4_BLOCK_SIZE); |
200 | 198 | ||
199 | s->s_op = &qnx4_sops; | ||
200 | s->s_magic = QNX4_SUPER_MAGIC; | ||
201 | s->s_flags |= MS_RDONLY; /* Yup, read-only yet */ | ||
202 | |||
201 | /* Check the superblock signature. Since the qnx4 code is | 203 | /* Check the superblock signature. Since the qnx4 code is |
202 | dangerous, we should leave as quickly as possible | 204 | dangerous, we should leave as quickly as possible |
203 | if we don't belong here... */ | 205 | if we don't belong here... */ |
204 | bh = sb_bread(s, 1); | 206 | bh = sb_bread(s, 1); |
205 | if (!bh) { | 207 | if (!bh) { |
206 | printk(KERN_ERR "qnx4: unable to read the superblock\n"); | 208 | printk(KERN_ERR "qnx4: unable to read the superblock\n"); |
207 | goto outnobh; | 209 | return -EINVAL; |
208 | } | 210 | } |
209 | if ( le32_to_cpup((__le32*) bh->b_data) != QNX4_SUPER_MAGIC ) { | ||
210 | if (!silent) | ||
211 | printk(KERN_ERR "qnx4: wrong fsid in superblock.\n"); | ||
212 | goto out; | ||
213 | } | ||
214 | s->s_op = &qnx4_sops; | ||
215 | s->s_magic = QNX4_SUPER_MAGIC; | ||
216 | s->s_flags |= MS_RDONLY; /* Yup, read-only yet */ | ||
217 | qnx4_sb(s)->sb_buf = bh; | ||
218 | qnx4_sb(s)->sb = (struct qnx4_super_block *) bh->b_data; | ||
219 | |||
220 | 211 | ||
221 | /* check before allocating dentries, inodes, .. */ | 212 | /* check before allocating dentries, inodes, .. */ |
222 | errmsg = qnx4_checkroot(s); | 213 | errmsg = qnx4_checkroot(s, (struct qnx4_super_block *) bh->b_data); |
214 | brelse(bh); | ||
223 | if (errmsg != NULL) { | 215 | if (errmsg != NULL) { |
224 | if (!silent) | 216 | if (!silent) |
225 | printk(KERN_ERR "qnx4: %s\n", errmsg); | 217 | printk(KERN_ERR "qnx4: %s\n", errmsg); |
226 | goto out; | 218 | return -EINVAL; |
227 | } | 219 | } |
228 | 220 | ||
229 | /* does root not have inode number QNX4_ROOT_INO ?? */ | 221 | /* does root not have inode number QNX4_ROOT_INO ?? */ |
230 | root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); | 222 | root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); |
231 | if (IS_ERR(root)) { | 223 | if (IS_ERR(root)) { |
232 | printk(KERN_ERR "qnx4: get inode failed\n"); | 224 | printk(KERN_ERR "qnx4: get inode failed\n"); |
233 | ret = PTR_ERR(root); | 225 | return PTR_ERR(root); |
234 | goto outb; | ||
235 | } | 226 | } |
236 | 227 | ||
237 | ret = -ENOMEM; | ||
238 | s->s_root = d_make_root(root); | 228 | s->s_root = d_make_root(root); |
239 | if (s->s_root == NULL) | 229 | if (s->s_root == NULL) |
240 | goto outb; | 230 | return -ENOMEM; |
241 | 231 | ||
242 | brelse(bh); | ||
243 | return 0; | 232 | return 0; |
244 | |||
245 | outb: | ||
246 | kfree(qs->BitMap); | ||
247 | out: | ||
248 | brelse(bh); | ||
249 | outnobh: | ||
250 | kfree(qs); | ||
251 | s->s_fs_info = NULL; | ||
252 | return ret; | ||
253 | } | 233 | } |
254 | 234 | ||
255 | static void qnx4_put_super(struct super_block *sb) | 235 | static void qnx4_kill_sb(struct super_block *sb) |
256 | { | 236 | { |
257 | struct qnx4_sb_info *qs = qnx4_sb(sb); | 237 | struct qnx4_sb_info *qs = qnx4_sb(sb); |
258 | kfree( qs->BitMap ); | 238 | kill_block_super(sb); |
259 | kfree( qs ); | 239 | if (qs) { |
260 | sb->s_fs_info = NULL; | 240 | kfree(qs->BitMap); |
261 | return; | 241 | kfree(qs); |
242 | } | ||
262 | } | 243 | } |
263 | 244 | ||
264 | static int qnx4_readpage(struct file *file, struct page *page) | 245 | static int qnx4_readpage(struct file *file, struct page *page) |
@@ -409,7 +390,7 @@ static struct file_system_type qnx4_fs_type = { | |||
409 | .owner = THIS_MODULE, | 390 | .owner = THIS_MODULE, |
410 | .name = "qnx4", | 391 | .name = "qnx4", |
411 | .mount = qnx4_mount, | 392 | .mount = qnx4_mount, |
412 | .kill_sb = kill_block_super, | 393 | .kill_sb = qnx4_kill_sb, |
413 | .fs_flags = FS_REQUIRES_DEV, | 394 | .fs_flags = FS_REQUIRES_DEV, |
414 | }; | 395 | }; |
415 | MODULE_ALIAS_FS("qnx4"); | 396 | MODULE_ALIAS_FS("qnx4"); |
diff --git a/fs/qnx4/qnx4.h b/fs/qnx4/qnx4.h index 34e2d329c97e..c9b1be2c164d 100644 --- a/fs/qnx4/qnx4.h +++ b/fs/qnx4/qnx4.h | |||
@@ -10,8 +10,6 @@ | |||
10 | #endif | 10 | #endif |
11 | 11 | ||
12 | struct qnx4_sb_info { | 12 | struct qnx4_sb_info { |
13 | struct buffer_head *sb_buf; /* superblock buffer */ | ||
14 | struct qnx4_super_block *sb; /* our superblock */ | ||
15 | unsigned int Version; /* may be useful */ | 13 | unsigned int Version; /* may be useful */ |
16 | struct qnx4_inode_entry *BitMap; /* useful */ | 14 | struct qnx4_inode_entry *BitMap; /* useful */ |
17 | }; | 15 | }; |