diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 8fab233cb05f..8d9707746413 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -25,7 +25,6 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/fs.h> | 26 | #include <linux/fs.h> |
27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
28 | #include <linux/ext4_jbd2.h> | ||
29 | #include <linux/jbd2.h> | 28 | #include <linux/jbd2.h> |
30 | #include <linux/highuid.h> | 29 | #include <linux/highuid.h> |
31 | #include <linux/pagemap.h> | 30 | #include <linux/pagemap.h> |
@@ -36,6 +35,7 @@ | |||
36 | #include <linux/mpage.h> | 35 | #include <linux/mpage.h> |
37 | #include <linux/uio.h> | 36 | #include <linux/uio.h> |
38 | #include <linux/bio.h> | 37 | #include <linux/bio.h> |
38 | #include "ext4_jbd2.h" | ||
39 | #include "xattr.h" | 39 | #include "xattr.h" |
40 | #include "acl.h" | 40 | #include "acl.h" |
41 | 41 | ||
@@ -93,7 +93,7 @@ int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | |||
93 | BUFFER_TRACE(bh, "call ext4_journal_revoke"); | 93 | BUFFER_TRACE(bh, "call ext4_journal_revoke"); |
94 | err = ext4_journal_revoke(handle, blocknr, bh); | 94 | err = ext4_journal_revoke(handle, blocknr, bh); |
95 | if (err) | 95 | if (err) |
96 | ext4_abort(inode->i_sb, __FUNCTION__, | 96 | ext4_abort(inode->i_sb, __func__, |
97 | "error %d when attempting revoke", err); | 97 | "error %d when attempting revoke", err); |
98 | BUFFER_TRACE(bh, "exit"); | 98 | BUFFER_TRACE(bh, "exit"); |
99 | return err; | 99 | return err; |
@@ -985,6 +985,16 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | |||
985 | } else { | 985 | } else { |
986 | retval = ext4_get_blocks_handle(handle, inode, block, | 986 | retval = ext4_get_blocks_handle(handle, inode, block, |
987 | max_blocks, bh, create, extend_disksize); | 987 | max_blocks, bh, create, extend_disksize); |
988 | |||
989 | if (retval > 0 && buffer_new(bh)) { | ||
990 | /* | ||
991 | * We allocated new blocks which will result in | ||
992 | * i_data's format changing. Force the migrate | ||
993 | * to fail by clearing migrate flags | ||
994 | */ | ||
995 | EXT4_I(inode)->i_flags = EXT4_I(inode)->i_flags & | ||
996 | ~EXT4_EXT_MIGRATE; | ||
997 | } | ||
988 | } | 998 | } |
989 | up_write((&EXT4_I(inode)->i_data_sem)); | 999 | up_write((&EXT4_I(inode)->i_data_sem)); |
990 | return retval; | 1000 | return retval; |
@@ -1230,7 +1240,7 @@ int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh) | |||
1230 | { | 1240 | { |
1231 | int err = jbd2_journal_dirty_data(handle, bh); | 1241 | int err = jbd2_journal_dirty_data(handle, bh); |
1232 | if (err) | 1242 | if (err) |
1233 | ext4_journal_abort_handle(__FUNCTION__, __FUNCTION__, | 1243 | ext4_journal_abort_handle(__func__, __func__, |
1234 | bh, handle, err); | 1244 | bh, handle, err); |
1235 | return err; | 1245 | return err; |
1236 | } | 1246 | } |
@@ -1301,10 +1311,11 @@ static int ext4_ordered_write_end(struct file *file, | |||
1301 | new_i_size = pos + copied; | 1311 | new_i_size = pos + copied; |
1302 | if (new_i_size > EXT4_I(inode)->i_disksize) | 1312 | if (new_i_size > EXT4_I(inode)->i_disksize) |
1303 | EXT4_I(inode)->i_disksize = new_i_size; | 1313 | EXT4_I(inode)->i_disksize = new_i_size; |
1304 | copied = ext4_generic_write_end(file, mapping, pos, len, copied, | 1314 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
1305 | page, fsdata); | 1315 | page, fsdata); |
1306 | if (copied < 0) | 1316 | copied = ret2; |
1307 | ret = copied; | 1317 | if (ret2 < 0) |
1318 | ret = ret2; | ||
1308 | } | 1319 | } |
1309 | ret2 = ext4_journal_stop(handle); | 1320 | ret2 = ext4_journal_stop(handle); |
1310 | if (!ret) | 1321 | if (!ret) |
@@ -1329,10 +1340,11 @@ static int ext4_writeback_write_end(struct file *file, | |||
1329 | if (new_i_size > EXT4_I(inode)->i_disksize) | 1340 | if (new_i_size > EXT4_I(inode)->i_disksize) |
1330 | EXT4_I(inode)->i_disksize = new_i_size; | 1341 | EXT4_I(inode)->i_disksize = new_i_size; |
1331 | 1342 | ||
1332 | copied = ext4_generic_write_end(file, mapping, pos, len, copied, | 1343 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
1333 | page, fsdata); | 1344 | page, fsdata); |
1334 | if (copied < 0) | 1345 | copied = ret2; |
1335 | ret = copied; | 1346 | if (ret2 < 0) |
1347 | ret = ret2; | ||
1336 | 1348 | ||
1337 | ret2 = ext4_journal_stop(handle); | 1349 | ret2 = ext4_journal_stop(handle); |
1338 | if (!ret) | 1350 | if (!ret) |
@@ -2501,12 +2513,10 @@ out_stop: | |||
2501 | static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, | 2513 | static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, |
2502 | unsigned long ino, struct ext4_iloc *iloc) | 2514 | unsigned long ino, struct ext4_iloc *iloc) |
2503 | { | 2515 | { |
2504 | unsigned long desc, group_desc; | ||
2505 | ext4_group_t block_group; | 2516 | ext4_group_t block_group; |
2506 | unsigned long offset; | 2517 | unsigned long offset; |
2507 | ext4_fsblk_t block; | 2518 | ext4_fsblk_t block; |
2508 | struct buffer_head *bh; | 2519 | struct ext4_group_desc *gdp; |
2509 | struct ext4_group_desc * gdp; | ||
2510 | 2520 | ||
2511 | if (!ext4_valid_inum(sb, ino)) { | 2521 | if (!ext4_valid_inum(sb, ino)) { |
2512 | /* | 2522 | /* |
@@ -2518,22 +2528,10 @@ static ext4_fsblk_t ext4_get_inode_block(struct super_block *sb, | |||
2518 | } | 2528 | } |
2519 | 2529 | ||
2520 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); | 2530 | block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb); |
2521 | if (block_group >= EXT4_SB(sb)->s_groups_count) { | 2531 | gdp = ext4_get_group_desc(sb, block_group, NULL); |
2522 | ext4_error(sb,"ext4_get_inode_block","group >= groups count"); | 2532 | if (!gdp) |
2523 | return 0; | 2533 | return 0; |
2524 | } | ||
2525 | smp_rmb(); | ||
2526 | group_desc = block_group >> EXT4_DESC_PER_BLOCK_BITS(sb); | ||
2527 | desc = block_group & (EXT4_DESC_PER_BLOCK(sb) - 1); | ||
2528 | bh = EXT4_SB(sb)->s_group_desc[group_desc]; | ||
2529 | if (!bh) { | ||
2530 | ext4_error (sb, "ext4_get_inode_block", | ||
2531 | "Descriptor not loaded"); | ||
2532 | return 0; | ||
2533 | } | ||
2534 | 2534 | ||
2535 | gdp = (struct ext4_group_desc *)((__u8 *)bh->b_data + | ||
2536 | desc * EXT4_DESC_SIZE(sb)); | ||
2537 | /* | 2535 | /* |
2538 | * Figure out the offset within the block group inode table | 2536 | * Figure out the offset within the block group inode table |
2539 | */ | 2537 | */ |
@@ -2976,7 +2974,8 @@ static int ext4_do_update_inode(handle_t *handle, | |||
2976 | if (ext4_inode_blocks_set(handle, raw_inode, ei)) | 2974 | if (ext4_inode_blocks_set(handle, raw_inode, ei)) |
2977 | goto out_brelse; | 2975 | goto out_brelse; |
2978 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); | 2976 | raw_inode->i_dtime = cpu_to_le32(ei->i_dtime); |
2979 | raw_inode->i_flags = cpu_to_le32(ei->i_flags); | 2977 | /* clear the migrate flag in the raw_inode */ |
2978 | raw_inode->i_flags = cpu_to_le32(ei->i_flags & ~EXT4_EXT_MIGRATE); | ||
2980 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != | 2979 | if (EXT4_SB(inode->i_sb)->s_es->s_creator_os != |
2981 | cpu_to_le32(EXT4_OS_HURD)) | 2980 | cpu_to_le32(EXT4_OS_HURD)) |
2982 | raw_inode->i_file_acl_high = | 2981 | raw_inode->i_file_acl_high = |
@@ -3374,7 +3373,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
3374 | EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; | 3373 | EXT4_I(inode)->i_state |= EXT4_STATE_NO_EXPAND; |
3375 | if (mnt_count != | 3374 | if (mnt_count != |
3376 | le16_to_cpu(sbi->s_es->s_mnt_count)) { | 3375 | le16_to_cpu(sbi->s_es->s_mnt_count)) { |
3377 | ext4_warning(inode->i_sb, __FUNCTION__, | 3376 | ext4_warning(inode->i_sb, __func__, |
3378 | "Unable to expand inode %lu. Delete" | 3377 | "Unable to expand inode %lu. Delete" |
3379 | " some EAs or run e2fsck.", | 3378 | " some EAs or run e2fsck.", |
3380 | inode->i_ino); | 3379 | inode->i_ino); |
@@ -3415,7 +3414,7 @@ void ext4_dirty_inode(struct inode *inode) | |||
3415 | current_handle->h_transaction != handle->h_transaction) { | 3414 | current_handle->h_transaction != handle->h_transaction) { |
3416 | /* This task has a transaction open against a different fs */ | 3415 | /* This task has a transaction open against a different fs */ |
3417 | printk(KERN_EMERG "%s: transactions do not match!\n", | 3416 | printk(KERN_EMERG "%s: transactions do not match!\n", |
3418 | __FUNCTION__); | 3417 | __func__); |
3419 | } else { | 3418 | } else { |
3420 | jbd_debug(5, "marking dirty. outer handle=%p\n", | 3419 | jbd_debug(5, "marking dirty. outer handle=%p\n", |
3421 | current_handle); | 3420 | current_handle); |