diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2/ext2.h | 2 | ||||
-rw-r--r-- | fs/ext2/inode.c | 29 | ||||
-rw-r--r-- | fs/ext2/namei.c | 12 | ||||
-rw-r--r-- | fs/ext2/super.c | 32 |
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 *); | |||
124 | extern unsigned long ext2_count_free (struct buffer_head *, unsigned); | 124 | extern unsigned long ext2_count_free (struct buffer_head *, unsigned); |
125 | 125 | ||
126 | /* inode.c */ | 126 | /* inode.c */ |
127 | extern void ext2_read_inode (struct inode *); | 127 | extern struct inode *ext2_iget (struct super_block *, unsigned long); |
128 | extern int ext2_write_inode (struct inode *, int); | 128 | extern int ext2_write_inode (struct inode *, int); |
129 | extern void ext2_put_inode (struct inode *); | 129 | extern void ext2_put_inode (struct inode *); |
130 | extern void ext2_delete_inode (struct inode *); | 130 | extern 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 | ||
1184 | void ext2_read_inode (struct inode * inode) | 1184 | struct 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 | ||
1291 | bad_inode: | 1304 | bad_inode: |
1292 | make_bad_inode(inode); | 1305 | iget_failed(inode); |
1293 | return; | 1306 | return ERR_PTR(ret); |
1294 | } | 1307 | } |
1295 | 1308 | ||
1296 | static int ext2_update_inode(struct inode * inode, int do_sync) | 1309 | static 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 | |||
296 | static const struct super_operations ext2_sops = { | 296 | static 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: | |||
1080 | failed_sbi: | 1084 | failed_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 | ||
1086 | static void ext2_commit_super (struct super_block * sb, | 1090 | static void ext2_commit_super (struct super_block * sb, |