aboutsummaryrefslogtreecommitdiffstats
path: root/fs/qnx4
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2013-12-10 19:48:58 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2014-01-25 03:13:03 -0500
commit208adb6403e079ceeb8e731696615d22db6f397b (patch)
treee2e2b778d320c89c73354b4e27e613b354a299be /fs/qnx4
parent5a9ed6f5e7b80c95b133818aa96b1fba8e1216a0 (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.c63
-rw-r--r--fs/qnx4/qnx4.h2
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
28static const struct super_operations qnx4_sops; 28static const struct super_operations qnx4_sops;
29 29
30static void qnx4_put_super(struct super_block *sb);
31static struct inode *qnx4_alloc_inode(struct super_block *sb); 30static struct inode *qnx4_alloc_inode(struct super_block *sb);
32static void qnx4_destroy_inode(struct inode *inode); 31static void qnx4_destroy_inode(struct inode *inode);
33static int qnx4_remount(struct super_block *sb, int *flags, char *data); 32static 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 */
151static const char *qnx4_checkroot(struct super_block *sb) 149static 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
255static void qnx4_put_super(struct super_block *sb) 235static 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
264static int qnx4_readpage(struct file *file, struct page *page) 245static 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};
415MODULE_ALIAS_FS("qnx4"); 396MODULE_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
12struct qnx4_sb_info { 12struct 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};