Commit 2b7e5bcbd9e03f7236d2869f4261059074ea50a2
Committed by
Linus Torvalds
1 parent
a1d4aebbfa
Exists in
master
and in
4 other branches
iget: stop QNX4 from using iget() and read_inode()
Stop the QNX4 filesystem from using iget() and read_inode(). Replace qnx4_read_inode() with qnx4_iget(), and call that instead of iget(). qnx4_iget() then uses iget_locked() directly and returns a proper error code instead of an inode in the event of an error. qnx4_fill_super() returns any error incurred when getting the root inode instead of EINVAL. [akpm@linux-foundation.org: coding-style fixes] Signed-off-by: David Howells <dhowells@redhat.com> Cc: Anders Larsen <al@alarsen.net> Acked-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 3 changed files with 38 additions and 18 deletions Side-by-side Diff
fs/qnx4/inode.c
... | ... | @@ -125,7 +125,6 @@ |
125 | 125 | static void qnx4_put_super(struct super_block *sb); |
126 | 126 | static struct inode *qnx4_alloc_inode(struct super_block *sb); |
127 | 127 | static void qnx4_destroy_inode(struct inode *inode); |
128 | -static void qnx4_read_inode(struct inode *); | |
129 | 128 | static int qnx4_remount(struct super_block *sb, int *flags, char *data); |
130 | 129 | static int qnx4_statfs(struct dentry *, struct kstatfs *); |
131 | 130 | |
... | ... | @@ -133,7 +132,6 @@ |
133 | 132 | { |
134 | 133 | .alloc_inode = qnx4_alloc_inode, |
135 | 134 | .destroy_inode = qnx4_destroy_inode, |
136 | - .read_inode = qnx4_read_inode, | |
137 | 135 | .put_super = qnx4_put_super, |
138 | 136 | .statfs = qnx4_statfs, |
139 | 137 | .remount_fs = qnx4_remount, |
... | ... | @@ -357,6 +355,7 @@ |
357 | 355 | struct inode *root; |
358 | 356 | const char *errmsg; |
359 | 357 | struct qnx4_sb_info *qs; |
358 | + int ret = -EINVAL; | |
360 | 359 | |
361 | 360 | qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); |
362 | 361 | if (!qs) |
363 | 362 | |
364 | 363 | |
... | ... | @@ -396,12 +395,14 @@ |
396 | 395 | } |
397 | 396 | |
398 | 397 | /* does root not have inode number QNX4_ROOT_INO ?? */ |
399 | - root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); | |
400 | - if (!root) { | |
398 | + root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); | |
399 | + if (IS_ERR(root)) { | |
401 | 400 | printk("qnx4: get inode failed\n"); |
401 | + ret = PTR_ERR(root); | |
402 | 402 | goto out; |
403 | 403 | } |
404 | 404 | |
405 | + ret = -ENOMEM; | |
405 | 406 | s->s_root = d_alloc_root(root); |
406 | 407 | if (s->s_root == NULL) |
407 | 408 | goto outi; |
... | ... | @@ -417,7 +418,7 @@ |
417 | 418 | outnobh: |
418 | 419 | kfree(qs); |
419 | 420 | s->s_fs_info = NULL; |
420 | - return -EINVAL; | |
421 | + return ret; | |
421 | 422 | } |
422 | 423 | |
423 | 424 | static void qnx4_put_super(struct super_block *sb) |
424 | 425 | |
425 | 426 | |
426 | 427 | |
427 | 428 | |
428 | 429 | |
... | ... | @@ -462,29 +463,38 @@ |
462 | 463 | .bmap = qnx4_bmap |
463 | 464 | }; |
464 | 465 | |
465 | -static void qnx4_read_inode(struct inode *inode) | |
466 | +struct inode *qnx4_iget(struct super_block *sb, unsigned long ino) | |
466 | 467 | { |
467 | 468 | struct buffer_head *bh; |
468 | 469 | struct qnx4_inode_entry *raw_inode; |
469 | - int block, ino; | |
470 | - struct super_block *sb = inode->i_sb; | |
471 | - struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode); | |
470 | + int block; | |
471 | + struct qnx4_inode_entry *qnx4_inode; | |
472 | + struct inode *inode; | |
472 | 473 | |
473 | - ino = inode->i_ino; | |
474 | + inode = iget_locked(sb, ino); | |
475 | + if (!inode) | |
476 | + return ERR_PTR(-ENOMEM); | |
477 | + if (!(inode->i_state & I_NEW)) | |
478 | + return inode; | |
479 | + | |
480 | + qnx4_inode = qnx4_raw_inode(inode); | |
474 | 481 | inode->i_mode = 0; |
475 | 482 | |
476 | 483 | QNX4DEBUG(("Reading inode : [%d]\n", ino)); |
477 | 484 | if (!ino) { |
478 | - printk("qnx4: bad inode number on dev %s: %d is out of range\n", | |
485 | + printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is " | |
486 | + "out of range\n", | |
479 | 487 | sb->s_id, ino); |
480 | - return; | |
488 | + iget_failed(inode); | |
489 | + return ERR_PTR(-EIO); | |
481 | 490 | } |
482 | 491 | block = ino / QNX4_INODES_PER_BLOCK; |
483 | 492 | |
484 | 493 | if (!(bh = sb_bread(sb, block))) { |
485 | 494 | printk("qnx4: major problem: unable to read inode from dev " |
486 | 495 | "%s\n", sb->s_id); |
487 | - return; | |
496 | + iget_failed(inode); | |
497 | + return ERR_PTR(-EIO); | |
488 | 498 | } |
489 | 499 | raw_inode = ((struct qnx4_inode_entry *) bh->b_data) + |
490 | 500 | (ino % QNX4_INODES_PER_BLOCK); |
491 | 501 | |
... | ... | @@ -515,9 +525,16 @@ |
515 | 525 | inode->i_op = &page_symlink_inode_operations; |
516 | 526 | inode->i_mapping->a_ops = &qnx4_aops; |
517 | 527 | qnx4_i(inode)->mmu_private = inode->i_size; |
518 | - } else | |
519 | - printk("qnx4: bad inode %d on dev %s\n",ino,sb->s_id); | |
528 | + } else { | |
529 | + printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n", | |
530 | + ino, sb->s_id); | |
531 | + iget_failed(inode); | |
532 | + brelse(bh); | |
533 | + return ERR_PTR(-EIO); | |
534 | + } | |
520 | 535 | brelse(bh); |
536 | + unlock_new_inode(inode); | |
537 | + return inode; | |
521 | 538 | } |
522 | 539 | |
523 | 540 | static struct kmem_cache *qnx4_inode_cachep; |
fs/qnx4/namei.c
... | ... | @@ -128,10 +128,12 @@ |
128 | 128 | } |
129 | 129 | brelse(bh); |
130 | 130 | |
131 | - if ((foundinode = iget(dir->i_sb, ino)) == NULL) { | |
131 | + foundinode = qnx4_iget(dir->i_sb, ino); | |
132 | + if (IS_ERR(foundinode)) { | |
132 | 133 | unlock_kernel(); |
133 | - QNX4DEBUG(("qnx4: lookup->iget -> NULL\n")); | |
134 | - return ERR_PTR(-EACCES); | |
134 | + QNX4DEBUG(("qnx4: lookup->iget -> error %ld\n", | |
135 | + PTR_ERR(foundinode))); | |
136 | + return ERR_CAST(foundinode); | |
135 | 137 | } |
136 | 138 | out: |
137 | 139 | unlock_kernel(); |
include/linux/qnx4_fs.h
... | ... | @@ -110,6 +110,7 @@ |
110 | 110 | struct inode vfs_inode; |
111 | 111 | }; |
112 | 112 | |
113 | +extern struct inode *qnx4_iget(struct super_block *, unsigned long); | |
113 | 114 | extern struct dentry *qnx4_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd); |
114 | 115 | extern unsigned long qnx4_count_free_blocks(struct super_block *sb); |
115 | 116 | extern unsigned long qnx4_block_map(struct inode *inode, long iblock); |