aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext2/ext2.h2
-rw-r--r--fs/ext2/inode.c29
-rw-r--r--fs/ext2/namei.c12
-rw-r--r--fs/ext2/super.c32
4 files changed, 46 insertions, 29 deletions
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index bb9948cdd50f..f1e5705e75f1 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -124,7 +124,7 @@ extern void ext2_check_inodes_bitmap (struct super_block *);
124extern unsigned long ext2_count_free (struct buffer_head *, unsigned); 124extern unsigned long ext2_count_free (struct buffer_head *, unsigned);
125 125
126/* inode.c */ 126/* inode.c */
127extern void ext2_read_inode (struct inode *); 127extern struct inode *ext2_iget (struct super_block *, unsigned long);
128extern int ext2_write_inode (struct inode *, int); 128extern int ext2_write_inode (struct inode *, int);
129extern void ext2_put_inode (struct inode *); 129extern void ext2_put_inode (struct inode *);
130extern void ext2_delete_inode (struct inode *); 130extern void ext2_delete_inode (struct inode *);
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 03978ec2a91c..c62006805427 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -1181,22 +1181,33 @@ void ext2_get_inode_flags(struct ext2_inode_info *ei)
1181 ei->i_flags |= EXT2_DIRSYNC_FL; 1181 ei->i_flags |= EXT2_DIRSYNC_FL;
1182} 1182}
1183 1183
1184void ext2_read_inode (struct inode * inode) 1184struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
1185{ 1185{
1186 struct ext2_inode_info *ei = EXT2_I(inode); 1186 struct ext2_inode_info *ei;
1187 ino_t ino = inode->i_ino;
1188 struct buffer_head * bh; 1187 struct buffer_head * bh;
1189 struct ext2_inode * raw_inode = ext2_get_inode(inode->i_sb, ino, &bh); 1188 struct ext2_inode *raw_inode;
1189 struct inode *inode;
1190 long ret = -EIO;
1190 int n; 1191 int n;
1191 1192
1193 inode = iget_locked(sb, ino);
1194 if (!inode)
1195 return ERR_PTR(-ENOMEM);
1196 if (!(inode->i_state & I_NEW))
1197 return inode;
1198
1199 ei = EXT2_I(inode);
1192#ifdef CONFIG_EXT2_FS_POSIX_ACL 1200#ifdef CONFIG_EXT2_FS_POSIX_ACL
1193 ei->i_acl = EXT2_ACL_NOT_CACHED; 1201 ei->i_acl = EXT2_ACL_NOT_CACHED;
1194 ei->i_default_acl = EXT2_ACL_NOT_CACHED; 1202 ei->i_default_acl = EXT2_ACL_NOT_CACHED;
1195#endif 1203#endif
1196 ei->i_block_alloc_info = NULL; 1204 ei->i_block_alloc_info = NULL;
1197 1205
1198 if (IS_ERR(raw_inode)) 1206 raw_inode = ext2_get_inode(inode->i_sb, ino, &bh);
1207 if (IS_ERR(raw_inode)) {
1208 ret = PTR_ERR(raw_inode);
1199 goto bad_inode; 1209 goto bad_inode;
1210 }
1200 1211
1201 inode->i_mode = le16_to_cpu(raw_inode->i_mode); 1212 inode->i_mode = le16_to_cpu(raw_inode->i_mode);
1202 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); 1213 inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low);
@@ -1220,6 +1231,7 @@ void ext2_read_inode (struct inode * inode)
1220 if (inode->i_nlink == 0 && (inode->i_mode == 0 || ei->i_dtime)) { 1231 if (inode->i_nlink == 0 && (inode->i_mode == 0 || ei->i_dtime)) {
1221 /* this inode is deleted */ 1232 /* this inode is deleted */
1222 brelse (bh); 1233 brelse (bh);
1234 ret = -ESTALE;
1223 goto bad_inode; 1235 goto bad_inode;
1224 } 1236 }
1225 inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); 1237 inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
@@ -1286,11 +1298,12 @@ void ext2_read_inode (struct inode * inode)
1286 } 1298 }
1287 brelse (bh); 1299 brelse (bh);
1288 ext2_set_inode_flags(inode); 1300 ext2_set_inode_flags(inode);
1289 return; 1301 unlock_new_inode(inode);
1302 return inode;
1290 1303
1291bad_inode: 1304bad_inode:
1292 make_bad_inode(inode); 1305 iget_failed(inode);
1293 return; 1306 return ERR_PTR(ret);
1294} 1307}
1295 1308
1296static int ext2_update_inode(struct inode * inode, int do_sync) 1309static int ext2_update_inode(struct inode * inode, int do_sync)
diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c
index e69beed839ac..80c97fd8c571 100644
--- a/fs/ext2/namei.c
+++ b/fs/ext2/namei.c
@@ -63,9 +63,9 @@ static struct dentry *ext2_lookup(struct inode * dir, struct dentry *dentry, str
63 ino = ext2_inode_by_name(dir, dentry); 63 ino = ext2_inode_by_name(dir, dentry);
64 inode = NULL; 64 inode = NULL;
65 if (ino) { 65 if (ino) {
66 inode = iget(dir->i_sb, ino); 66 inode = ext2_iget(dir->i_sb, ino);
67 if (!inode) 67 if (IS_ERR(inode))
68 return ERR_PTR(-EACCES); 68 return ERR_CAST(inode);
69 } 69 }
70 return d_splice_alias(inode, dentry); 70 return d_splice_alias(inode, dentry);
71} 71}
@@ -83,10 +83,10 @@ struct dentry *ext2_get_parent(struct dentry *child)
83 ino = ext2_inode_by_name(child->d_inode, &dotdot); 83 ino = ext2_inode_by_name(child->d_inode, &dotdot);
84 if (!ino) 84 if (!ino)
85 return ERR_PTR(-ENOENT); 85 return ERR_PTR(-ENOENT);
86 inode = iget(child->d_inode->i_sb, ino); 86 inode = ext2_iget(child->d_inode->i_sb, ino);
87 87
88 if (!inode) 88 if (IS_ERR(inode))
89 return ERR_PTR(-EACCES); 89 return ERR_CAST(inode);
90 parent = d_alloc_anon(inode); 90 parent = d_alloc_anon(inode);
91 if (!parent) { 91 if (!parent) {
92 iput(inode); 92 iput(inode);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 1ba18b72d43a..22f1010bf79f 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -296,7 +296,6 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *da
296static const struct super_operations ext2_sops = { 296static const struct super_operations ext2_sops = {
297 .alloc_inode = ext2_alloc_inode, 297 .alloc_inode = ext2_alloc_inode,
298 .destroy_inode = ext2_destroy_inode, 298 .destroy_inode = ext2_destroy_inode,
299 .read_inode = ext2_read_inode,
300 .write_inode = ext2_write_inode, 299 .write_inode = ext2_write_inode,
301 .delete_inode = ext2_delete_inode, 300 .delete_inode = ext2_delete_inode,
302 .put_super = ext2_put_super, 301 .put_super = ext2_put_super,
@@ -326,11 +325,10 @@ static struct inode *ext2_nfs_get_inode(struct super_block *sb,
326 * it might be "neater" to call ext2_get_inode first and check 325 * it might be "neater" to call ext2_get_inode first and check
327 * if the inode is valid..... 326 * if the inode is valid.....
328 */ 327 */
329 inode = iget(sb, ino); 328 inode = ext2_iget(sb, ino);
330 if (inode == NULL) 329 if (IS_ERR(inode))
331 return ERR_PTR(-ENOMEM); 330 return ERR_CAST(inode);
332 if (is_bad_inode(inode) || 331 if (generation && inode->i_generation != generation) {
333 (generation && inode->i_generation != generation)) {
334 /* we didn't find the right inode.. */ 332 /* we didn't find the right inode.. */
335 iput(inode); 333 iput(inode);
336 return ERR_PTR(-ESTALE); 334 return ERR_PTR(-ESTALE);
@@ -746,6 +744,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
746 unsigned long logic_sb_block; 744 unsigned long logic_sb_block;
747 unsigned long offset = 0; 745 unsigned long offset = 0;
748 unsigned long def_mount_opts; 746 unsigned long def_mount_opts;
747 long ret = -EINVAL;
749 int blocksize = BLOCK_SIZE; 748 int blocksize = BLOCK_SIZE;
750 int db_count; 749 int db_count;
751 int i, j; 750 int i, j;
@@ -1041,19 +1040,24 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent)
1041 sb->s_op = &ext2_sops; 1040 sb->s_op = &ext2_sops;
1042 sb->s_export_op = &ext2_export_ops; 1041 sb->s_export_op = &ext2_export_ops;
1043 sb->s_xattr = ext2_xattr_handlers; 1042 sb->s_xattr = ext2_xattr_handlers;
1044 root = iget(sb, EXT2_ROOT_INO); 1043 root = ext2_iget(sb, EXT2_ROOT_INO);
1045 sb->s_root = d_alloc_root(root); 1044 if (IS_ERR(root)) {
1046 if (!sb->s_root) { 1045 ret = PTR_ERR(root);
1047 iput(root);
1048 printk(KERN_ERR "EXT2-fs: get root inode failed\n");
1049 goto failed_mount3; 1046 goto failed_mount3;
1050 } 1047 }
1051 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { 1048 if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) {
1052 dput(sb->s_root); 1049 iput(root);
1053 sb->s_root = NULL;
1054 printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); 1050 printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n");
1055 goto failed_mount3; 1051 goto failed_mount3;
1056 } 1052 }
1053
1054 sb->s_root = d_alloc_root(root);
1055 if (!sb->s_root) {
1056 iput(root);
1057 printk(KERN_ERR "EXT2-fs: get root inode failed\n");
1058 ret = -ENOMEM;
1059 goto failed_mount3;
1060 }
1057 if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) 1061 if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL))
1058 ext2_warning(sb, __FUNCTION__, 1062 ext2_warning(sb, __FUNCTION__,
1059 "mounting ext3 filesystem as ext2"); 1063 "mounting ext3 filesystem as ext2");
@@ -1080,7 +1084,7 @@ failed_mount:
1080failed_sbi: 1084failed_sbi:
1081 sb->s_fs_info = NULL; 1085 sb->s_fs_info = NULL;
1082 kfree(sbi); 1086 kfree(sbi);
1083 return -EINVAL; 1087 return ret;
1084} 1088}
1085 1089
1086static void ext2_commit_super (struct super_block * sb, 1090static void ext2_commit_super (struct super_block * sb,