diff options
Diffstat (limited to 'fs/ext2')
-rw-r--r-- | fs/ext2/balloc.c | 98 | ||||
-rw-r--r-- | fs/ext2/dir.c | 2 | ||||
-rw-r--r-- | fs/ext2/ext2.h | 6 | ||||
-rw-r--r-- | fs/ext2/file.c | 4 | ||||
-rw-r--r-- | fs/ext2/inode.c | 37 | ||||
-rw-r--r-- | fs/ext2/ioctl.c | 12 | ||||
-rw-r--r-- | fs/ext2/namei.c | 12 | ||||
-rw-r--r-- | fs/ext2/super.c | 66 |
8 files changed, 152 insertions, 85 deletions
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c index 377ad172d74b..e7b2bafa1dd9 100644 --- a/fs/ext2/balloc.c +++ b/fs/ext2/balloc.c | |||
@@ -69,9 +69,53 @@ struct ext2_group_desc * ext2_get_group_desc(struct super_block * sb, | |||
69 | return desc + offset; | 69 | return desc + offset; |
70 | } | 70 | } |
71 | 71 | ||
72 | static int ext2_valid_block_bitmap(struct super_block *sb, | ||
73 | struct ext2_group_desc *desc, | ||
74 | unsigned int block_group, | ||
75 | struct buffer_head *bh) | ||
76 | { | ||
77 | ext2_grpblk_t offset; | ||
78 | ext2_grpblk_t next_zero_bit; | ||
79 | ext2_fsblk_t bitmap_blk; | ||
80 | ext2_fsblk_t group_first_block; | ||
81 | |||
82 | group_first_block = ext2_group_first_block_no(sb, block_group); | ||
83 | |||
84 | /* check whether block bitmap block number is set */ | ||
85 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); | ||
86 | offset = bitmap_blk - group_first_block; | ||
87 | if (!ext2_test_bit(offset, bh->b_data)) | ||
88 | /* bad block bitmap */ | ||
89 | goto err_out; | ||
90 | |||
91 | /* check whether the inode bitmap block number is set */ | ||
92 | bitmap_blk = le32_to_cpu(desc->bg_inode_bitmap); | ||
93 | offset = bitmap_blk - group_first_block; | ||
94 | if (!ext2_test_bit(offset, bh->b_data)) | ||
95 | /* bad block bitmap */ | ||
96 | goto err_out; | ||
97 | |||
98 | /* check whether the inode table block number is set */ | ||
99 | bitmap_blk = le32_to_cpu(desc->bg_inode_table); | ||
100 | offset = bitmap_blk - group_first_block; | ||
101 | next_zero_bit = ext2_find_next_zero_bit(bh->b_data, | ||
102 | offset + EXT2_SB(sb)->s_itb_per_group, | ||
103 | offset); | ||
104 | if (next_zero_bit >= offset + EXT2_SB(sb)->s_itb_per_group) | ||
105 | /* good bitmap for inode tables */ | ||
106 | return 1; | ||
107 | |||
108 | err_out: | ||
109 | ext2_error(sb, __FUNCTION__, | ||
110 | "Invalid block bitmap - " | ||
111 | "block_group = %d, block = %lu", | ||
112 | block_group, bitmap_blk); | ||
113 | return 0; | ||
114 | } | ||
115 | |||
72 | /* | 116 | /* |
73 | * Read the bitmap for a given block_group, reading into the specified | 117 | * Read the bitmap for a given block_group,and validate the |
74 | * slot in the superblock's bitmap cache. | 118 | * bits for block/inode/inode tables are set in the bitmaps |
75 | * | 119 | * |
76 | * Return buffer_head on success or NULL in case of failure. | 120 | * Return buffer_head on success or NULL in case of failure. |
77 | */ | 121 | */ |
@@ -80,17 +124,36 @@ read_block_bitmap(struct super_block *sb, unsigned int block_group) | |||
80 | { | 124 | { |
81 | struct ext2_group_desc * desc; | 125 | struct ext2_group_desc * desc; |
82 | struct buffer_head * bh = NULL; | 126 | struct buffer_head * bh = NULL; |
83 | 127 | ext2_fsblk_t bitmap_blk; | |
84 | desc = ext2_get_group_desc (sb, block_group, NULL); | 128 | |
129 | desc = ext2_get_group_desc(sb, block_group, NULL); | ||
85 | if (!desc) | 130 | if (!desc) |
86 | goto error_out; | 131 | return NULL; |
87 | bh = sb_bread(sb, le32_to_cpu(desc->bg_block_bitmap)); | 132 | bitmap_blk = le32_to_cpu(desc->bg_block_bitmap); |
88 | if (!bh) | 133 | bh = sb_getblk(sb, bitmap_blk); |
89 | ext2_error (sb, "read_block_bitmap", | 134 | if (unlikely(!bh)) { |
135 | ext2_error(sb, __FUNCTION__, | ||
136 | "Cannot read block bitmap - " | ||
137 | "block_group = %d, block_bitmap = %u", | ||
138 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | ||
139 | return NULL; | ||
140 | } | ||
141 | if (likely(bh_uptodate_or_lock(bh))) | ||
142 | return bh; | ||
143 | |||
144 | if (bh_submit_read(bh) < 0) { | ||
145 | brelse(bh); | ||
146 | ext2_error(sb, __FUNCTION__, | ||
90 | "Cannot read block bitmap - " | 147 | "Cannot read block bitmap - " |
91 | "block_group = %d, block_bitmap = %u", | 148 | "block_group = %d, block_bitmap = %u", |
92 | block_group, le32_to_cpu(desc->bg_block_bitmap)); | 149 | block_group, le32_to_cpu(desc->bg_block_bitmap)); |
93 | error_out: | 150 | return NULL; |
151 | } | ||
152 | if (!ext2_valid_block_bitmap(sb, desc, block_group, bh)) { | ||
153 | brelse(bh); | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
94 | return bh; | 157 | return bh; |
95 | } | 158 | } |
96 | 159 | ||
@@ -474,11 +537,13 @@ do_more: | |||
474 | in_range (block, le32_to_cpu(desc->bg_inode_table), | 537 | in_range (block, le32_to_cpu(desc->bg_inode_table), |
475 | sbi->s_itb_per_group) || | 538 | sbi->s_itb_per_group) || |
476 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), | 539 | in_range (block + count - 1, le32_to_cpu(desc->bg_inode_table), |
477 | sbi->s_itb_per_group)) | 540 | sbi->s_itb_per_group)) { |
478 | ext2_error (sb, "ext2_free_blocks", | 541 | ext2_error (sb, "ext2_free_blocks", |
479 | "Freeing blocks in system zones - " | 542 | "Freeing blocks in system zones - " |
480 | "Block = %lu, count = %lu", | 543 | "Block = %lu, count = %lu", |
481 | block, count); | 544 | block, count); |
545 | goto error_return; | ||
546 | } | ||
482 | 547 | ||
483 | for (i = 0, group_freed = 0; i < count; i++) { | 548 | for (i = 0, group_freed = 0; i < count; i++) { |
484 | if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), | 549 | if (!ext2_clear_bit_atomic(sb_bgl_lock(sbi, block_group), |
@@ -1250,8 +1315,8 @@ retry_alloc: | |||
1250 | smp_rmb(); | 1315 | smp_rmb(); |
1251 | 1316 | ||
1252 | /* | 1317 | /* |
1253 | * Now search the rest of the groups. We assume that | 1318 | * Now search the rest of the groups. We assume that |
1254 | * i and gdp correctly point to the last group visited. | 1319 | * group_no and gdp correctly point to the last group visited. |
1255 | */ | 1320 | */ |
1256 | for (bgi = 0; bgi < ngroups; bgi++) { | 1321 | for (bgi = 0; bgi < ngroups; bgi++) { |
1257 | group_no++; | 1322 | group_no++; |
@@ -1311,11 +1376,13 @@ allocated: | |||
1311 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), | 1376 | in_range(ret_block, le32_to_cpu(gdp->bg_inode_table), |
1312 | EXT2_SB(sb)->s_itb_per_group) || | 1377 | EXT2_SB(sb)->s_itb_per_group) || |
1313 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), | 1378 | in_range(ret_block + num - 1, le32_to_cpu(gdp->bg_inode_table), |
1314 | EXT2_SB(sb)->s_itb_per_group)) | 1379 | EXT2_SB(sb)->s_itb_per_group)) { |
1315 | ext2_error(sb, "ext2_new_blocks", | 1380 | ext2_error(sb, "ext2_new_blocks", |
1316 | "Allocating block in system zone - " | 1381 | "Allocating block in system zone - " |
1317 | "blocks from "E2FSBLK", length %lu", | 1382 | "blocks from "E2FSBLK", length %lu", |
1318 | ret_block, num); | 1383 | ret_block, num); |
1384 | goto out; | ||
1385 | } | ||
1319 | 1386 | ||
1320 | performed_allocation = 1; | 1387 | performed_allocation = 1; |
1321 | 1388 | ||
@@ -1466,9 +1533,6 @@ int ext2_bg_has_super(struct super_block *sb, int group) | |||
1466 | */ | 1533 | */ |
1467 | unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) | 1534 | unsigned long ext2_bg_num_gdb(struct super_block *sb, int group) |
1468 | { | 1535 | { |
1469 | if (EXT2_HAS_RO_COMPAT_FEATURE(sb,EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)&& | 1536 | return ext2_bg_has_super(sb, group) ? EXT2_SB(sb)->s_gdb_count : 0; |
1470 | !ext2_group_sparse(group)) | ||
1471 | return 0; | ||
1472 | return EXT2_SB(sb)->s_gdb_count; | ||
1473 | } | 1537 | } |
1474 | 1538 | ||
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c index d868e26c15eb..8dededd80fe2 100644 --- a/fs/ext2/dir.c +++ b/fs/ext2/dir.c | |||
@@ -703,7 +703,7 @@ const struct file_operations ext2_dir_operations = { | |||
703 | .llseek = generic_file_llseek, | 703 | .llseek = generic_file_llseek, |
704 | .read = generic_read_dir, | 704 | .read = generic_read_dir, |
705 | .readdir = ext2_readdir, | 705 | .readdir = ext2_readdir, |
706 | .ioctl = ext2_ioctl, | 706 | .unlocked_ioctl = ext2_ioctl, |
707 | #ifdef CONFIG_COMPAT | 707 | #ifdef CONFIG_COMPAT |
708 | .compat_ioctl = ext2_compat_ioctl, | 708 | .compat_ioctl = ext2_compat_ioctl, |
709 | #endif | 709 | #endif |
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index c87ae29c19cb..47d88da2d33b 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h | |||
@@ -124,9 +124,8 @@ 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 *); | ||
130 | extern void ext2_delete_inode (struct inode *); | 129 | extern void ext2_delete_inode (struct inode *); |
131 | extern int ext2_sync_inode (struct inode *); | 130 | extern int ext2_sync_inode (struct inode *); |
132 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); | 131 | extern int ext2_get_block(struct inode *, sector_t, struct buffer_head *, int); |
@@ -139,8 +138,7 @@ int __ext2_write_begin(struct file *file, struct address_space *mapping, | |||
139 | struct page **pagep, void **fsdata); | 138 | struct page **pagep, void **fsdata); |
140 | 139 | ||
141 | /* ioctl.c */ | 140 | /* ioctl.c */ |
142 | extern int ext2_ioctl (struct inode *, struct file *, unsigned int, | 141 | extern long ext2_ioctl(struct file *, unsigned int, unsigned long); |
143 | unsigned long); | ||
144 | extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); | 142 | extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); |
145 | 143 | ||
146 | /* namei.c */ | 144 | /* namei.c */ |
diff --git a/fs/ext2/file.c b/fs/ext2/file.c index c051798459a1..5f2fa9c36293 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c | |||
@@ -48,7 +48,7 @@ const struct file_operations ext2_file_operations = { | |||
48 | .write = do_sync_write, | 48 | .write = do_sync_write, |
49 | .aio_read = generic_file_aio_read, | 49 | .aio_read = generic_file_aio_read, |
50 | .aio_write = generic_file_aio_write, | 50 | .aio_write = generic_file_aio_write, |
51 | .ioctl = ext2_ioctl, | 51 | .unlocked_ioctl = ext2_ioctl, |
52 | #ifdef CONFIG_COMPAT | 52 | #ifdef CONFIG_COMPAT |
53 | .compat_ioctl = ext2_compat_ioctl, | 53 | .compat_ioctl = ext2_compat_ioctl, |
54 | #endif | 54 | #endif |
@@ -65,7 +65,7 @@ const struct file_operations ext2_xip_file_operations = { | |||
65 | .llseek = generic_file_llseek, | 65 | .llseek = generic_file_llseek, |
66 | .read = xip_file_read, | 66 | .read = xip_file_read, |
67 | .write = xip_file_write, | 67 | .write = xip_file_write, |
68 | .ioctl = ext2_ioctl, | 68 | .unlocked_ioctl = ext2_ioctl, |
69 | #ifdef CONFIG_COMPAT | 69 | #ifdef CONFIG_COMPAT |
70 | .compat_ioctl = ext2_compat_ioctl, | 70 | .compat_ioctl = ext2_compat_ioctl, |
71 | #endif | 71 | #endif |
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index b1ab32ab5a77..c62006805427 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c | |||
@@ -286,15 +286,12 @@ static unsigned long ext2_find_near(struct inode *inode, Indirect *ind) | |||
286 | * ext2_find_goal - find a prefered place for allocation. | 286 | * ext2_find_goal - find a prefered place for allocation. |
287 | * @inode: owner | 287 | * @inode: owner |
288 | * @block: block we want | 288 | * @block: block we want |
289 | * @chain: chain of indirect blocks | ||
290 | * @partial: pointer to the last triple within a chain | 289 | * @partial: pointer to the last triple within a chain |
291 | * | 290 | * |
292 | * Returns preferred place for a block (the goal). | 291 | * Returns preferred place for a block (the goal). |
293 | */ | 292 | */ |
294 | 293 | ||
295 | static inline int ext2_find_goal(struct inode *inode, | 294 | static inline int ext2_find_goal(struct inode *inode, long block, |
296 | long block, | ||
297 | Indirect chain[4], | ||
298 | Indirect *partial) | 295 | Indirect *partial) |
299 | { | 296 | { |
300 | struct ext2_block_alloc_info *block_i; | 297 | struct ext2_block_alloc_info *block_i; |
@@ -569,7 +566,6 @@ static void ext2_splice_branch(struct inode *inode, | |||
569 | * | 566 | * |
570 | * `handle' can be NULL if create == 0. | 567 | * `handle' can be NULL if create == 0. |
571 | * | 568 | * |
572 | * The BKL may not be held on entry here. Be sure to take it early. | ||
573 | * return > 0, # of blocks mapped or allocated. | 569 | * return > 0, # of blocks mapped or allocated. |
574 | * return = 0, if plain lookup failed. | 570 | * return = 0, if plain lookup failed. |
575 | * return < 0, error case. | 571 | * return < 0, error case. |
@@ -639,7 +635,7 @@ reread: | |||
639 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) | 635 | if (S_ISREG(inode->i_mode) && (!ei->i_block_alloc_info)) |
640 | ext2_init_block_alloc_info(inode); | 636 | ext2_init_block_alloc_info(inode); |
641 | 637 | ||
642 | goal = ext2_find_goal(inode, iblock, chain, partial); | 638 | goal = ext2_find_goal(inode, iblock, partial); |
643 | 639 | ||
644 | /* the number of blocks need to allocate for [d,t]indirect blocks */ | 640 | /* the number of blocks need to allocate for [d,t]indirect blocks */ |
645 | indirect_blks = (chain + depth) - partial - 1; | 641 | indirect_blks = (chain + depth) - partial - 1; |
@@ -1185,22 +1181,33 @@ void ext2_get_inode_flags(struct ext2_inode_info *ei) | |||
1185 | ei->i_flags |= EXT2_DIRSYNC_FL; | 1181 | ei->i_flags |= EXT2_DIRSYNC_FL; |
1186 | } | 1182 | } |
1187 | 1183 | ||
1188 | void ext2_read_inode (struct inode * inode) | 1184 | struct inode *ext2_iget (struct super_block *sb, unsigned long ino) |
1189 | { | 1185 | { |
1190 | struct ext2_inode_info *ei = EXT2_I(inode); | 1186 | struct ext2_inode_info *ei; |
1191 | ino_t ino = inode->i_ino; | ||
1192 | struct buffer_head * bh; | 1187 | struct buffer_head * bh; |
1193 | 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; | ||
1194 | int n; | 1191 | int n; |
1195 | 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); | ||
1196 | #ifdef CONFIG_EXT2_FS_POSIX_ACL | 1200 | #ifdef CONFIG_EXT2_FS_POSIX_ACL |
1197 | ei->i_acl = EXT2_ACL_NOT_CACHED; | 1201 | ei->i_acl = EXT2_ACL_NOT_CACHED; |
1198 | ei->i_default_acl = EXT2_ACL_NOT_CACHED; | 1202 | ei->i_default_acl = EXT2_ACL_NOT_CACHED; |
1199 | #endif | 1203 | #endif |
1200 | ei->i_block_alloc_info = NULL; | 1204 | ei->i_block_alloc_info = NULL; |
1201 | 1205 | ||
1202 | 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); | ||
1203 | goto bad_inode; | 1209 | goto bad_inode; |
1210 | } | ||
1204 | 1211 | ||
1205 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); | 1212 | inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
1206 | 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); |
@@ -1224,6 +1231,7 @@ void ext2_read_inode (struct inode * inode) | |||
1224 | 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)) { |
1225 | /* this inode is deleted */ | 1232 | /* this inode is deleted */ |
1226 | brelse (bh); | 1233 | brelse (bh); |
1234 | ret = -ESTALE; | ||
1227 | goto bad_inode; | 1235 | goto bad_inode; |
1228 | } | 1236 | } |
1229 | inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); | 1237 | inode->i_blocks = le32_to_cpu(raw_inode->i_blocks); |
@@ -1290,11 +1298,12 @@ void ext2_read_inode (struct inode * inode) | |||
1290 | } | 1298 | } |
1291 | brelse (bh); | 1299 | brelse (bh); |
1292 | ext2_set_inode_flags(inode); | 1300 | ext2_set_inode_flags(inode); |
1293 | return; | 1301 | unlock_new_inode(inode); |
1302 | return inode; | ||
1294 | 1303 | ||
1295 | bad_inode: | 1304 | bad_inode: |
1296 | make_bad_inode(inode); | 1305 | iget_failed(inode); |
1297 | return; | 1306 | return ERR_PTR(ret); |
1298 | } | 1307 | } |
1299 | 1308 | ||
1300 | 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/ioctl.c b/fs/ext2/ioctl.c index 320b2cb3d4d2..b8ea11fee5c6 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
@@ -17,9 +17,9 @@ | |||
17 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
18 | 18 | ||
19 | 19 | ||
20 | int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | 20 | long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
21 | unsigned long arg) | ||
22 | { | 21 | { |
22 | struct inode *inode = filp->f_dentry->d_inode; | ||
23 | struct ext2_inode_info *ei = EXT2_I(inode); | 23 | struct ext2_inode_info *ei = EXT2_I(inode); |
24 | unsigned int flags; | 24 | unsigned int flags; |
25 | unsigned short rsv_window_size; | 25 | unsigned short rsv_window_size; |
@@ -141,9 +141,6 @@ int ext2_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
141 | #ifdef CONFIG_COMPAT | 141 | #ifdef CONFIG_COMPAT |
142 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 142 | long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
143 | { | 143 | { |
144 | struct inode *inode = file->f_path.dentry->d_inode; | ||
145 | int ret; | ||
146 | |||
147 | /* These are just misnamed, they actually get/put from/to user an int */ | 144 | /* These are just misnamed, they actually get/put from/to user an int */ |
148 | switch (cmd) { | 145 | switch (cmd) { |
149 | case EXT2_IOC32_GETFLAGS: | 146 | case EXT2_IOC32_GETFLAGS: |
@@ -161,9 +158,6 @@ long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
161 | default: | 158 | default: |
162 | return -ENOIOCTLCMD; | 159 | return -ENOIOCTLCMD; |
163 | } | 160 | } |
164 | lock_kernel(); | 161 | return ext2_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); |
165 | ret = ext2_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | ||
166 | unlock_kernel(); | ||
167 | return ret; | ||
168 | } | 162 | } |
169 | #endif | 163 | #endif |
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 6abaf75163f0..088b011bb97e 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c | |||
@@ -234,16 +234,16 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
234 | le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { | 234 | le16_to_cpu(es->s_def_resgid) != EXT2_DEF_RESGID) { |
235 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); | 235 | seq_printf(seq, ",resgid=%u", sbi->s_resgid); |
236 | } | 236 | } |
237 | if (test_opt(sb, ERRORS_CONT)) { | 237 | if (test_opt(sb, ERRORS_RO)) { |
238 | int def_errors = le16_to_cpu(es->s_errors); | 238 | int def_errors = le16_to_cpu(es->s_errors); |
239 | 239 | ||
240 | if (def_errors == EXT2_ERRORS_PANIC || | 240 | if (def_errors == EXT2_ERRORS_PANIC || |
241 | def_errors == EXT2_ERRORS_RO) { | 241 | def_errors == EXT2_ERRORS_CONTINUE) { |
242 | seq_puts(seq, ",errors=continue"); | 242 | seq_puts(seq, ",errors=remount-ro"); |
243 | } | 243 | } |
244 | } | 244 | } |
245 | if (test_opt(sb, ERRORS_RO)) | 245 | if (test_opt(sb, ERRORS_CONT)) |
246 | seq_puts(seq, ",errors=remount-ro"); | 246 | seq_puts(seq, ",errors=continue"); |
247 | if (test_opt(sb, ERRORS_PANIC)) | 247 | if (test_opt(sb, ERRORS_PANIC)) |
248 | seq_puts(seq, ",errors=panic"); | 248 | seq_puts(seq, ",errors=panic"); |
249 | if (test_opt(sb, NO_UID32)) | 249 | if (test_opt(sb, NO_UID32)) |
@@ -285,6 +285,9 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
285 | seq_puts(seq, ",xip"); | 285 | seq_puts(seq, ",xip"); |
286 | #endif | 286 | #endif |
287 | 287 | ||
288 | if (!test_opt(sb, RESERVATION)) | ||
289 | seq_puts(seq, ",noreservation"); | ||
290 | |||
288 | return 0; | 291 | return 0; |
289 | } | 292 | } |
290 | 293 | ||
@@ -296,7 +299,6 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type, const char *da | |||
296 | static const struct super_operations ext2_sops = { | 299 | static const struct super_operations ext2_sops = { |
297 | .alloc_inode = ext2_alloc_inode, | 300 | .alloc_inode = ext2_alloc_inode, |
298 | .destroy_inode = ext2_destroy_inode, | 301 | .destroy_inode = ext2_destroy_inode, |
299 | .read_inode = ext2_read_inode, | ||
300 | .write_inode = ext2_write_inode, | 302 | .write_inode = ext2_write_inode, |
301 | .delete_inode = ext2_delete_inode, | 303 | .delete_inode = ext2_delete_inode, |
302 | .put_super = ext2_put_super, | 304 | .put_super = ext2_put_super, |
@@ -326,11 +328,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 | 328 | * it might be "neater" to call ext2_get_inode first and check |
327 | * if the inode is valid..... | 329 | * if the inode is valid..... |
328 | */ | 330 | */ |
329 | inode = iget(sb, ino); | 331 | inode = ext2_iget(sb, ino); |
330 | if (inode == NULL) | 332 | if (IS_ERR(inode)) |
331 | return ERR_PTR(-ENOMEM); | 333 | return ERR_CAST(inode); |
332 | if (is_bad_inode(inode) || | 334 | if (generation && inode->i_generation != generation) { |
333 | (generation && inode->i_generation != generation)) { | ||
334 | /* we didn't find the right inode.. */ | 335 | /* we didn't find the right inode.. */ |
335 | iput(inode); | 336 | iput(inode); |
336 | return ERR_PTR(-ESTALE); | 337 | return ERR_PTR(-ESTALE); |
@@ -617,27 +618,24 @@ static int ext2_setup_super (struct super_block * sb, | |||
617 | return res; | 618 | return res; |
618 | } | 619 | } |
619 | 620 | ||
620 | static int ext2_check_descriptors (struct super_block * sb) | 621 | static int ext2_check_descriptors(struct super_block *sb) |
621 | { | 622 | { |
622 | int i; | 623 | int i; |
623 | int desc_block = 0; | ||
624 | struct ext2_sb_info *sbi = EXT2_SB(sb); | 624 | struct ext2_sb_info *sbi = EXT2_SB(sb); |
625 | unsigned long first_block = le32_to_cpu(sbi->s_es->s_first_data_block); | 625 | unsigned long first_block = le32_to_cpu(sbi->s_es->s_first_data_block); |
626 | unsigned long last_block; | 626 | unsigned long last_block; |
627 | struct ext2_group_desc * gdp = NULL; | ||
628 | 627 | ||
629 | ext2_debug ("Checking group descriptors"); | 628 | ext2_debug ("Checking group descriptors"); |
630 | 629 | ||
631 | for (i = 0; i < sbi->s_groups_count; i++) | 630 | for (i = 0; i < sbi->s_groups_count; i++) { |
632 | { | 631 | struct ext2_group_desc *gdp = ext2_get_group_desc(sb, i, NULL); |
632 | |||
633 | if (i == sbi->s_groups_count - 1) | 633 | if (i == sbi->s_groups_count - 1) |
634 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; | 634 | last_block = le32_to_cpu(sbi->s_es->s_blocks_count) - 1; |
635 | else | 635 | else |
636 | last_block = first_block + | 636 | last_block = first_block + |
637 | (EXT2_BLOCKS_PER_GROUP(sb) - 1); | 637 | (EXT2_BLOCKS_PER_GROUP(sb) - 1); |
638 | 638 | ||
639 | if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) | ||
640 | gdp = (struct ext2_group_desc *) sbi->s_group_desc[desc_block++]->b_data; | ||
641 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || | 639 | if (le32_to_cpu(gdp->bg_block_bitmap) < first_block || |
642 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) | 640 | le32_to_cpu(gdp->bg_block_bitmap) > last_block) |
643 | { | 641 | { |
@@ -667,7 +665,6 @@ static int ext2_check_descriptors (struct super_block * sb) | |||
667 | return 0; | 665 | return 0; |
668 | } | 666 | } |
669 | first_block += EXT2_BLOCKS_PER_GROUP(sb); | 667 | first_block += EXT2_BLOCKS_PER_GROUP(sb); |
670 | gdp++; | ||
671 | } | 668 | } |
672 | return 1; | 669 | return 1; |
673 | } | 670 | } |
@@ -750,6 +747,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
750 | unsigned long logic_sb_block; | 747 | unsigned long logic_sb_block; |
751 | unsigned long offset = 0; | 748 | unsigned long offset = 0; |
752 | unsigned long def_mount_opts; | 749 | unsigned long def_mount_opts; |
750 | long ret = -EINVAL; | ||
753 | int blocksize = BLOCK_SIZE; | 751 | int blocksize = BLOCK_SIZE; |
754 | int db_count; | 752 | int db_count; |
755 | int i, j; | 753 | int i, j; |
@@ -820,10 +818,10 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
820 | 818 | ||
821 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC) | 819 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC) |
822 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 820 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
823 | else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_RO) | 821 | else if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_CONTINUE) |
824 | set_opt(sbi->s_mount_opt, ERRORS_RO); | ||
825 | else | ||
826 | set_opt(sbi->s_mount_opt, ERRORS_CONT); | 822 | set_opt(sbi->s_mount_opt, ERRORS_CONT); |
823 | else | ||
824 | set_opt(sbi->s_mount_opt, ERRORS_RO); | ||
827 | 825 | ||
828 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); | 826 | sbi->s_resuid = le16_to_cpu(es->s_def_resuid); |
829 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); | 827 | sbi->s_resgid = le16_to_cpu(es->s_def_resgid); |
@@ -868,8 +866,7 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
868 | 866 | ||
869 | blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); | 867 | blocksize = BLOCK_SIZE << le32_to_cpu(sbi->s_es->s_log_block_size); |
870 | 868 | ||
871 | if ((ext2_use_xip(sb)) && ((blocksize != PAGE_SIZE) || | 869 | if (ext2_use_xip(sb) && blocksize != PAGE_SIZE) { |
872 | (sb->s_blocksize != blocksize))) { | ||
873 | if (!silent) | 870 | if (!silent) |
874 | printk("XIP: Unsupported blocksize\n"); | 871 | printk("XIP: Unsupported blocksize\n"); |
875 | goto failed_mount; | 872 | goto failed_mount; |
@@ -1046,19 +1043,24 @@ static int ext2_fill_super(struct super_block *sb, void *data, int silent) | |||
1046 | sb->s_op = &ext2_sops; | 1043 | sb->s_op = &ext2_sops; |
1047 | sb->s_export_op = &ext2_export_ops; | 1044 | sb->s_export_op = &ext2_export_ops; |
1048 | sb->s_xattr = ext2_xattr_handlers; | 1045 | sb->s_xattr = ext2_xattr_handlers; |
1049 | root = iget(sb, EXT2_ROOT_INO); | 1046 | root = ext2_iget(sb, EXT2_ROOT_INO); |
1050 | sb->s_root = d_alloc_root(root); | 1047 | if (IS_ERR(root)) { |
1051 | if (!sb->s_root) { | 1048 | ret = PTR_ERR(root); |
1052 | iput(root); | ||
1053 | printk(KERN_ERR "EXT2-fs: get root inode failed\n"); | ||
1054 | goto failed_mount3; | 1049 | goto failed_mount3; |
1055 | } | 1050 | } |
1056 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { | 1051 | if (!S_ISDIR(root->i_mode) || !root->i_blocks || !root->i_size) { |
1057 | dput(sb->s_root); | 1052 | iput(root); |
1058 | sb->s_root = NULL; | ||
1059 | printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); | 1053 | printk(KERN_ERR "EXT2-fs: corrupt root inode, run e2fsck\n"); |
1060 | goto failed_mount3; | 1054 | goto failed_mount3; |
1061 | } | 1055 | } |
1056 | |||
1057 | sb->s_root = d_alloc_root(root); | ||
1058 | if (!sb->s_root) { | ||
1059 | iput(root); | ||
1060 | printk(KERN_ERR "EXT2-fs: get root inode failed\n"); | ||
1061 | ret = -ENOMEM; | ||
1062 | goto failed_mount3; | ||
1063 | } | ||
1062 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) | 1064 | if (EXT2_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_HAS_JOURNAL)) |
1063 | ext2_warning(sb, __FUNCTION__, | 1065 | ext2_warning(sb, __FUNCTION__, |
1064 | "mounting ext3 filesystem as ext2"); | 1066 | "mounting ext3 filesystem as ext2"); |
@@ -1085,7 +1087,7 @@ failed_mount: | |||
1085 | failed_sbi: | 1087 | failed_sbi: |
1086 | sb->s_fs_info = NULL; | 1088 | sb->s_fs_info = NULL; |
1087 | kfree(sbi); | 1089 | kfree(sbi); |
1088 | return -EINVAL; | 1090 | return ret; |
1089 | } | 1091 | } |
1090 | 1092 | ||
1091 | static void ext2_commit_super (struct super_block * sb, | 1093 | static void ext2_commit_super (struct super_block * sb, |