Commit de329820e920cd9cfbc2127cad26a37026260cce

Authored by Linus Torvalds
1 parent ad4ba05900

ext3: fix broken handling of EXT3_STATE_NEW

In commit 9df93939b735 ("ext3: Use bitops to read/modify
EXT3_I(inode)->i_state") ext3 changed its internal 'i_state' variable to
use bitops for its state handling.  However, unline the same ext4
change, it didn't actually change the name of the field when it changed
the semantics of it.

As a result, an old use of 'i_state' remained in fs/ext3/ialloc.c that
initialized the field to EXT3_STATE_NEW.  And that does not work
_at_all_ when we're now working with individually named bits rather than
values that get masked.  So the code tried to mark the state to be new,
but in actual fact set the field to EXT3_STATE_JDATA.  Which makes no
sense at all, and screws up all the code that checks whether the inode
was newly allocated.

In particular, it made the xattr code unhappy, and caused various random
behavior, like apparently

	https://bugzilla.redhat.com/show_bug.cgi?id=577911

So fix the initialization, and rename the field to match ext4 so that we
don't have this happen again.

Cc: James Morris <jmorris@namei.org>
Cc: Stephen Smalley <sds@tycho.nsa.gov>
Cc: Daniel J Walsh <dwalsh@redhat.com>
Cc: Eric Paris <eparis@redhat.com>
Cc: Jan Kara <jack@suse.cz>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

Showing 4 changed files with 8 additions and 6 deletions Side-by-side Diff

... ... @@ -582,7 +582,9 @@
582 582 inode->i_generation = sbi->s_next_generation++;
583 583 spin_unlock(&sbi->s_next_gen_lock);
584 584  
585   - ei->i_state = EXT3_STATE_NEW;
  585 + ei->i_state_flags = 0;
  586 + ext3_set_inode_state(inode, EXT3_STATE_NEW);
  587 +
586 588 ei->i_extra_isize =
587 589 (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) ?
588 590 sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0;
... ... @@ -2811,7 +2811,7 @@
2811 2811 inode->i_mtime.tv_sec = (signed)le32_to_cpu(raw_inode->i_mtime);
2812 2812 inode->i_atime.tv_nsec = inode->i_ctime.tv_nsec = inode->i_mtime.tv_nsec = 0;
2813 2813  
2814   - ei->i_state = 0;
  2814 + ei->i_state_flags = 0;
2815 2815 ei->i_dir_start_lookup = 0;
2816 2816 ei->i_dtime = le32_to_cpu(raw_inode->i_dtime);
2817 2817 /* We now have enough fields to check if the inode was active or not.
include/linux/ext3_fs.h
... ... @@ -565,17 +565,17 @@
565 565  
566 566 static inline int ext3_test_inode_state(struct inode *inode, int bit)
567 567 {
568   - return test_bit(bit, &EXT3_I(inode)->i_state);
  568 + return test_bit(bit, &EXT3_I(inode)->i_state_flags);
569 569 }
570 570  
571 571 static inline void ext3_set_inode_state(struct inode *inode, int bit)
572 572 {
573   - set_bit(bit, &EXT3_I(inode)->i_state);
  573 + set_bit(bit, &EXT3_I(inode)->i_state_flags);
574 574 }
575 575  
576 576 static inline void ext3_clear_inode_state(struct inode *inode, int bit)
577 577 {
578   - clear_bit(bit, &EXT3_I(inode)->i_state);
  578 + clear_bit(bit, &EXT3_I(inode)->i_state_flags);
579 579 }
580 580 #else
581 581 /* Assume that user mode programs are passing in an ext3fs superblock, not
include/linux/ext3_fs_i.h
... ... @@ -87,7 +87,7 @@
87 87 * near to their parent directory's inode.
88 88 */
89 89 __u32 i_block_group;
90   - unsigned long i_state; /* Dynamic state flags for ext3 */
  90 + unsigned long i_state_flags; /* Dynamic state flags for ext3 */
91 91  
92 92 /* block reservation info */
93 93 struct ext3_block_alloc_info *i_block_alloc_info;