X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fqnx4%2Finode.c;h=2aad1044b84ccf1342578cd66407ef88e406cf1d;hb=d9ecdb282c91952796b7542c4f57fd6de6948d7b;hp=df8bd87e49b724f3014f65245aa48922792c58c8;hpb=ebc283118ee448dcb6e6cae74a8a43f17a1ccc3f;p=linux-2.6 diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c index df8bd87e49..2aad1044b8 100644 --- a/fs/qnx4/inode.c +++ b/fs/qnx4/inode.c @@ -125,7 +125,6 @@ static int qnx4_write_inode(struct inode *inode, int unused) static void qnx4_put_super(struct super_block *sb); static struct inode *qnx4_alloc_inode(struct super_block *sb); static void qnx4_destroy_inode(struct inode *inode); -static void qnx4_read_inode(struct inode *); static int qnx4_remount(struct super_block *sb, int *flags, char *data); static int qnx4_statfs(struct dentry *, struct kstatfs *); @@ -133,7 +132,6 @@ static const struct super_operations qnx4_sops = { .alloc_inode = qnx4_alloc_inode, .destroy_inode = qnx4_destroy_inode, - .read_inode = qnx4_read_inode, .put_super = qnx4_put_super, .statfs = qnx4_statfs, .remount_fs = qnx4_remount, @@ -357,6 +355,7 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent) struct inode *root; const char *errmsg; struct qnx4_sb_info *qs; + int ret = -EINVAL; qs = kzalloc(sizeof(struct qnx4_sb_info), GFP_KERNEL); if (!qs) @@ -396,12 +395,14 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent) } /* does root not have inode number QNX4_ROOT_INO ?? */ - root = iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); - if (!root) { + root = qnx4_iget(s, QNX4_ROOT_INO * QNX4_INODES_PER_BLOCK); + if (IS_ERR(root)) { printk("qnx4: get inode failed\n"); + ret = PTR_ERR(root); goto out; } + ret = -ENOMEM; s->s_root = d_alloc_root(root); if (s->s_root == NULL) goto outi; @@ -417,7 +418,7 @@ static int qnx4_fill_super(struct super_block *s, void *data, int silent) outnobh: kfree(qs); s->s_fs_info = NULL; - return -EINVAL; + return ret; } static void qnx4_put_super(struct super_block *sb) @@ -462,29 +463,38 @@ static const struct address_space_operations qnx4_aops = { .bmap = qnx4_bmap }; -static void qnx4_read_inode(struct inode *inode) +struct inode *qnx4_iget(struct super_block *sb, unsigned long ino) { struct buffer_head *bh; struct qnx4_inode_entry *raw_inode; - int block, ino; - struct super_block *sb = inode->i_sb; - struct qnx4_inode_entry *qnx4_inode = qnx4_raw_inode(inode); + int block; + struct qnx4_inode_entry *qnx4_inode; + struct inode *inode; - ino = inode->i_ino; + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); + if (!(inode->i_state & I_NEW)) + return inode; + + qnx4_inode = qnx4_raw_inode(inode); inode->i_mode = 0; QNX4DEBUG(("Reading inode : [%d]\n", ino)); if (!ino) { - printk("qnx4: bad inode number on dev %s: %d is out of range\n", + printk(KERN_ERR "qnx4: bad inode number on dev %s: %lu is " + "out of range\n", sb->s_id, ino); - return; + iget_failed(inode); + return ERR_PTR(-EIO); } block = ino / QNX4_INODES_PER_BLOCK; if (!(bh = sb_bread(sb, block))) { printk("qnx4: major problem: unable to read inode from dev " "%s\n", sb->s_id); - return; + iget_failed(inode); + return ERR_PTR(-EIO); } raw_inode = ((struct qnx4_inode_entry *) bh->b_data) + (ino % QNX4_INODES_PER_BLOCK); @@ -515,9 +525,16 @@ static void qnx4_read_inode(struct inode *inode) inode->i_op = &page_symlink_inode_operations; inode->i_mapping->a_ops = &qnx4_aops; qnx4_i(inode)->mmu_private = inode->i_size; - } else - printk("qnx4: bad inode %d on dev %s\n",ino,sb->s_id); + } else { + printk(KERN_ERR "qnx4: bad inode %lu on dev %s\n", + ino, sb->s_id); + iget_failed(inode); + brelse(bh); + return ERR_PTR(-EIO); + } brelse(bh); + unlock_new_inode(inode); + return inode; } static struct kmem_cache *qnx4_inode_cachep; @@ -536,8 +553,7 @@ static void qnx4_destroy_inode(struct inode *inode) kmem_cache_free(qnx4_inode_cachep, qnx4_i(inode)); } -static void init_once(void *foo, struct kmem_cache * cachep, - unsigned long flags) +static void init_once(void *foo) { struct qnx4_inode_info *ei = (struct qnx4_inode_info *) foo;