diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 4320782761ae875c54fc9f6a04592a3990ecfdc3..489f26bc26d9b4084b56b563761859186e1f9fd6 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c @@ -714,26 +714,30 @@ static int ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) return 0; } -void ufs_read_inode(struct inode * inode) +struct inode *ufs_iget(struct super_block *sb, unsigned long ino) { - struct ufs_inode_info *ufsi = UFS_I(inode); - struct super_block * sb; - struct ufs_sb_private_info * uspi; + struct ufs_inode_info *ufsi; + struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; struct buffer_head * bh; + struct inode *inode; int err; - UFSD("ENTER, ino %lu\n", inode->i_ino); - - sb = inode->i_sb; - uspi = UFS_SB(sb)->s_uspi; + UFSD("ENTER, ino %lu\n", ino); - if (inode->i_ino < UFS_ROOTINO || - inode->i_ino > (uspi->s_ncg * uspi->s_ipg)) { + if (ino < UFS_ROOTINO || ino > (uspi->s_ncg * uspi->s_ipg)) { ufs_warning(sb, "ufs_read_inode", "bad inode number (%lu)\n", - inode->i_ino); - goto bad_inode; + ino); + return ERR_PTR(-EIO); } + inode = iget_locked(sb, ino); + if (!inode) + return ERR_PTR(-ENOMEM); + if (!(inode->i_state & I_NEW)) + return inode; + + ufsi = UFS_I(inode); + bh = sb_bread(sb, uspi->s_sbbase + ufs_inotofsba(inode->i_ino)); if (!bh) { ufs_warning(sb, "ufs_read_inode", "unable to read inode %lu\n", @@ -765,10 +769,12 @@ void ufs_read_inode(struct inode * inode) brelse(bh); UFSD("EXIT\n"); - return; + unlock_new_inode(inode); + return inode; bad_inode: - make_bad_inode(inode); + iget_failed(inode); + return ERR_PTR(-EIO); } static void ufs1_update_inode(struct inode *inode, struct ufs_inode *ufs_inode) diff --git a/fs/ufs/namei.c b/fs/ufs/namei.c index d8bfbee2fe2ba9e9ced1bcc66dbfdebb4b9ced7c..747a4de6c69526d14eaff5b48a08031d21d10d5d 100644 --- a/fs/ufs/namei.c +++ b/fs/ufs/namei.c @@ -57,10 +57,10 @@ static struct dentry *ufs_lookup(struct inode * dir, struct dentry *dentry, stru lock_kernel(); ino = ufs_inode_by_name(dir, dentry); if (ino) { - inode = iget(dir->i_sb, ino); - if (!inode) { + inode = ufs_iget(dir->i_sb, ino); + if (IS_ERR(inode)) { unlock_kernel(); - return ERR_PTR(-EACCES); + return ERR_CAST(inode); } } unlock_kernel(); diff --git a/fs/ufs/super.c b/fs/ufs/super.c index 0072cb33ebec5da2f682574fbb36e809d0f1beb9..73deff475e6362326ab6e6785f89a93ad5b3f158 100644 --- a/fs/ufs/super.c +++ b/fs/ufs/super.c @@ -633,6 +633,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) unsigned block_size, super_block_size; unsigned flags; unsigned super_block_offset; + int ret = -EINVAL; uspi = NULL; ubh = NULL; @@ -1065,12 +1066,16 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) uspi->s_maxsymlinklen = fs32_to_cpu(sb, usb3->fs_un2.fs_44.fs_maxsymlinklen); - inode = iget(sb, UFS_ROOTINO); - if (!inode || is_bad_inode(inode)) + inode = ufs_iget(sb, UFS_ROOTINO); + if (IS_ERR(inode)) { + ret = PTR_ERR(inode); goto failed; + } sb->s_root = d_alloc_root(inode); - if (!sb->s_root) + if (!sb->s_root) { + ret = -ENOMEM; goto dalloc_failed; + } ufs_setup_cstotal(sb); /* @@ -1092,7 +1097,7 @@ static int ufs_fill_super(struct super_block *sb, void *data, int silent) kfree(sbi); sb->s_fs_info = NULL; UFSD("EXIT (FAILED)\n"); - return -EINVAL; + return ret; failed_nomem: UFSD("EXIT (NOMEM)\n"); @@ -1326,7 +1331,6 @@ static ssize_t ufs_quota_write(struct super_block *, int, const char *, size_t, static const struct super_operations ufs_super_ops = { .alloc_inode = ufs_alloc_inode, .destroy_inode = ufs_destroy_inode, - .read_inode = ufs_read_inode, .write_inode = ufs_write_inode, .delete_inode = ufs_delete_inode, .put_super = ufs_put_super, diff --git a/fs/ufs/ufs.h b/fs/ufs/ufs.h index 7faa4cd71a27537c9dac7ecf5e8c77aa1eb601c7..fcb9231bb9edac22b09593d8fa1d5e80624cde6a 100644 --- a/fs/ufs/ufs.h +++ b/fs/ufs/ufs.h @@ -106,7 +106,7 @@ extern void ufs_free_inode (struct inode *inode); extern struct inode * ufs_new_inode (struct inode *, int); /* inode.c */ -extern void ufs_read_inode (struct inode *); +extern struct inode *ufs_iget(struct super_block *, unsigned long); extern void ufs_put_inode (struct inode *); extern int ufs_write_inode (struct inode *, int); extern int ufs_sync_inode (struct inode *);