aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4/inode.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2010-05-16 22:00:00 -0400
committerTheodore Ts'o <tytso@mit.edu>2010-05-16 22:00:00 -0400
commit12e9b892002d9af057655d35b44db8ee9243b0dc (patch)
treec5831b4bcf98eebdd39158d08dab97c198f5c683 /fs/ext4/inode.c
parent24676da469f50f433baa347845639662c561d1f6 (diff)
ext4: Use bitops to read/modify i_flags in struct ext4_inode_info
At several places we modify EXT4_I(inode)->i_flags without holding i_mutex (ext4_do_update_inode, ...). These modifications are racy and we can lose updates to i_flags. So convert handling of i_flags to use bitops which are atomic. https://bugzilla.kernel.org/show_bug.cgi?id=15792 Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r--fs/ext4/inode.c30
1 files changed, 15 insertions, 15 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 3b687725758..c2b0724e8ad 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -931,7 +931,7 @@ static int ext4_ind_map_blocks(handle_t *handle, struct inode *inode,
931 int count = 0; 931 int count = 0;
932 ext4_fsblk_t first_block = 0; 932 ext4_fsblk_t first_block = 0;
933 933
934 J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)); 934 J_ASSERT(!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)));
935 J_ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0); 935 J_ASSERT(handle != NULL || (flags & EXT4_GET_BLOCKS_CREATE) == 0);
936 depth = ext4_block_to_path(inode, map->m_lblk, offsets, 936 depth = ext4_block_to_path(inode, map->m_lblk, offsets,
937 &blocks_to_boundary); 937 &blocks_to_boundary);
@@ -1059,7 +1059,7 @@ static int ext4_indirect_calc_metadata_amount(struct inode *inode,
1059 */ 1059 */
1060static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock) 1060static int ext4_calc_metadata_amount(struct inode *inode, sector_t lblock)
1061{ 1061{
1062 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) 1062 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
1063 return ext4_ext_calc_metadata_amount(inode, lblock); 1063 return ext4_ext_calc_metadata_amount(inode, lblock);
1064 1064
1065 return ext4_indirect_calc_metadata_amount(inode, lblock); 1065 return ext4_indirect_calc_metadata_amount(inode, lblock);
@@ -1236,7 +1236,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
1236 * file system block. 1236 * file system block.
1237 */ 1237 */
1238 down_read((&EXT4_I(inode)->i_data_sem)); 1238 down_read((&EXT4_I(inode)->i_data_sem));
1239 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 1239 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
1240 retval = ext4_ext_map_blocks(handle, inode, map, 0); 1240 retval = ext4_ext_map_blocks(handle, inode, map, 0);
1241 } else { 1241 } else {
1242 retval = ext4_ind_map_blocks(handle, inode, map, 0); 1242 retval = ext4_ind_map_blocks(handle, inode, map, 0);
@@ -1295,7 +1295,7 @@ int ext4_map_blocks(handle_t *handle, struct inode *inode,
1295 * We need to check for EXT4 here because migrate 1295 * We need to check for EXT4 here because migrate
1296 * could have changed the inode type in between 1296 * could have changed the inode type in between
1297 */ 1297 */
1298 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 1298 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
1299 retval = ext4_ext_map_blocks(handle, inode, map, flags); 1299 retval = ext4_ext_map_blocks(handle, inode, map, flags);
1300 } else { 1300 } else {
1301 retval = ext4_ind_map_blocks(handle, inode, map, flags); 1301 retval = ext4_ind_map_blocks(handle, inode, map, flags);
@@ -2325,7 +2325,7 @@ static void mpage_add_bh_to_extent(struct mpage_da_data *mpd,
2325 goto flush_it; 2325 goto flush_it;
2326 2326
2327 /* check if thereserved journal credits might overflow */ 2327 /* check if thereserved journal credits might overflow */
2328 if (!(EXT4_I(mpd->inode)->i_flags & EXT4_EXTENTS_FL)) { 2328 if (!(ext4_test_inode_flag(mpd->inode, EXT4_INODE_EXTENTS))) {
2329 if (nrblocks >= EXT4_MAX_TRANS_DATA) { 2329 if (nrblocks >= EXT4_MAX_TRANS_DATA) {
2330 /* 2330 /*
2331 * With non-extent format we are limited by the journal 2331 * With non-extent format we are limited by the journal
@@ -2779,7 +2779,7 @@ static int ext4_da_writepages_trans_blocks(struct inode *inode)
2779 * number of contiguous block. So we will limit 2779 * number of contiguous block. So we will limit
2780 * number of contiguous block to a sane value 2780 * number of contiguous block to a sane value
2781 */ 2781 */
2782 if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) && 2782 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) &&
2783 (max_blocks > EXT4_MAX_TRANS_DATA)) 2783 (max_blocks > EXT4_MAX_TRANS_DATA))
2784 max_blocks = EXT4_MAX_TRANS_DATA; 2784 max_blocks = EXT4_MAX_TRANS_DATA;
2785 2785
@@ -3995,7 +3995,7 @@ static ssize_t ext4_direct_IO(int rw, struct kiocb *iocb,
3995 struct file *file = iocb->ki_filp; 3995 struct file *file = iocb->ki_filp;
3996 struct inode *inode = file->f_mapping->host; 3996 struct inode *inode = file->f_mapping->host;
3997 3997
3998 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) 3998 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))
3999 return ext4_ext_direct_IO(rw, iocb, iov, offset, nr_segs); 3999 return ext4_ext_direct_IO(rw, iocb, iov, offset, nr_segs);
4000 4000
4001 return ext4_ind_direct_IO(rw, iocb, iov, offset, nr_segs); 4001 return ext4_ind_direct_IO(rw, iocb, iov, offset, nr_segs);
@@ -4631,12 +4631,12 @@ void ext4_truncate(struct inode *inode)
4631 if (!ext4_can_truncate(inode)) 4631 if (!ext4_can_truncate(inode))
4632 return; 4632 return;
4633 4633
4634 EXT4_I(inode)->i_flags &= ~EXT4_EOFBLOCKS_FL; 4634 ext4_clear_inode_flag(inode, EXT4_INODE_EOFBLOCKS);
4635 4635
4636 if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC)) 4636 if (inode->i_size == 0 && !test_opt(inode->i_sb, NO_AUTO_DA_ALLOC))
4637 ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE); 4637 ext4_set_inode_state(inode, EXT4_STATE_DA_ALLOC_CLOSE);
4638 4638
4639 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 4639 if (ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)) {
4640 ext4_ext_truncate(inode); 4640 ext4_ext_truncate(inode);
4641 return; 4641 return;
4642 } 4642 }
@@ -5473,7 +5473,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
5473 } 5473 }
5474 5474
5475 if (attr->ia_valid & ATTR_SIZE) { 5475 if (attr->ia_valid & ATTR_SIZE) {
5476 if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) { 5476 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS))) {
5477 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 5477 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
5478 5478
5479 if (attr->ia_size > sbi->s_bitmap_maxbytes) { 5479 if (attr->ia_size > sbi->s_bitmap_maxbytes) {
@@ -5486,7 +5486,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
5486 if (S_ISREG(inode->i_mode) && 5486 if (S_ISREG(inode->i_mode) &&
5487 attr->ia_valid & ATTR_SIZE && 5487 attr->ia_valid & ATTR_SIZE &&
5488 (attr->ia_size < inode->i_size || 5488 (attr->ia_size < inode->i_size ||
5489 (EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL))) { 5489 (ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS)))) {
5490 handle_t *handle; 5490 handle_t *handle;
5491 5491
5492 handle = ext4_journal_start(inode, 3); 5492 handle = ext4_journal_start(inode, 3);
@@ -5518,7 +5518,7 @@ int ext4_setattr(struct dentry *dentry, struct iattr *attr)
5518 } 5518 }
5519 } 5519 }
5520 /* ext4_truncate will clear the flag */ 5520 /* ext4_truncate will clear the flag */
5521 if ((EXT4_I(inode)->i_flags & EXT4_EOFBLOCKS_FL)) 5521 if ((ext4_test_inode_flag(inode, EXT4_INODE_EOFBLOCKS)))
5522 ext4_truncate(inode); 5522 ext4_truncate(inode);
5523 } 5523 }
5524 5524
@@ -5594,7 +5594,7 @@ static int ext4_indirect_trans_blocks(struct inode *inode, int nrblocks,
5594 5594
5595static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk) 5595static int ext4_index_trans_blocks(struct inode *inode, int nrblocks, int chunk)
5596{ 5596{
5597 if (!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)) 5597 if (!(ext4_test_inode_flag(inode, EXT4_INODE_EXTENTS)))
5598 return ext4_indirect_trans_blocks(inode, nrblocks, chunk); 5598 return ext4_indirect_trans_blocks(inode, nrblocks, chunk);
5599 return ext4_ext_index_trans_blocks(inode, nrblocks, chunk); 5599 return ext4_ext_index_trans_blocks(inode, nrblocks, chunk);
5600} 5600}
@@ -5929,9 +5929,9 @@ int ext4_change_inode_journal_flag(struct inode *inode, int val)
5929 */ 5929 */
5930 5930
5931 if (val) 5931 if (val)
5932 EXT4_I(inode)->i_flags |= EXT4_JOURNAL_DATA_FL; 5932 ext4_set_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
5933 else 5933 else
5934 EXT4_I(inode)->i_flags &= ~EXT4_JOURNAL_DATA_FL; 5934 ext4_clear_inode_flag(inode, EXT4_INODE_JOURNAL_DATA);
5935 ext4_set_aops(inode); 5935 ext4_set_aops(inode);
5936 5936
5937 jbd2_journal_unlock_updates(journal); 5937 jbd2_journal_unlock_updates(journal);