aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2007-05-08 03:30:33 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:12 -0400
commit28be5abb400e5e082f5225105fdc69337ec0c0b4 (patch)
treee4bb3e527aac316004be68e28a25b2919e30afd4
parent9926e4c74300c4b31dee007298c6475d33369df0 (diff)
ext3: copy i_flags to inode flags on write
A patch that stores inode flags such as S_IMMUTABLE, S_APPEND, etc. from i_flags to EXT3_I(inode)->i_flags when inode is written to disk. The same thing is done on GETFLAGS ioctl. Quota code changes these flags on quota files (to make it harder for sysadmin to screw himself) and these changes were not correctly propagated into the filesystem (especially, lsattr did not show them and users were wondering...). Propagate flags such as S_APPEND, S_IMMUTABLE, etc. from i_flags into ext3-specific i_flags. Hence, when someone sets these flags via a different interface than ioctl, they are stored correctly. Signed-off-by: Jan Kara <jack@suse.cz> Cc: <linux-ext4@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/ext3/inode.c20
-rw-r--r--fs/ext3/ioctl.c1
-rw-r--r--include/linux/ext3_fs.h1
3 files changed, 22 insertions, 0 deletions
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index f9bcddbd2ef1..e1bb03171986 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -2580,6 +2580,25 @@ void ext3_set_inode_flags(struct inode *inode)
2580 inode->i_flags |= S_DIRSYNC; 2580 inode->i_flags |= S_DIRSYNC;
2581} 2581}
2582 2582
2583/* Propagate flags from i_flags to EXT3_I(inode)->i_flags */
2584void ext3_get_inode_flags(struct ext3_inode_info *ei)
2585{
2586 unsigned int flags = ei->vfs_inode.i_flags;
2587
2588 ei->i_flags &= ~(EXT3_SYNC_FL|EXT3_APPEND_FL|
2589 EXT3_IMMUTABLE_FL|EXT3_NOATIME_FL|EXT3_DIRSYNC_FL);
2590 if (flags & S_SYNC)
2591 ei->i_flags |= EXT3_SYNC_FL;
2592 if (flags & S_APPEND)
2593 ei->i_flags |= EXT3_APPEND_FL;
2594 if (flags & S_IMMUTABLE)
2595 ei->i_flags |= EXT3_IMMUTABLE_FL;
2596 if (flags & S_NOATIME)
2597 ei->i_flags |= EXT3_NOATIME_FL;
2598 if (flags & S_DIRSYNC)
2599 ei->i_flags |= EXT3_DIRSYNC_FL;
2600}
2601
2583void ext3_read_inode(struct inode * inode) 2602void ext3_read_inode(struct inode * inode)
2584{ 2603{
2585 struct ext3_iloc iloc; 2604 struct ext3_iloc iloc;
@@ -2735,6 +2754,7 @@ static int ext3_do_update_inode(handle_t *handle,
2735 if (ei->i_state & EXT3_STATE_NEW) 2754 if (ei->i_state & EXT3_STATE_NEW)
2736 memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size); 2755 memset(raw_inode, 0, EXT3_SB(inode->i_sb)->s_inode_size);
2737 2756
2757 ext3_get_inode_flags(ei);
2738 raw_inode->i_mode = cpu_to_le16(inode->i_mode); 2758 raw_inode->i_mode = cpu_to_le16(inode->i_mode);
2739 if(!(test_opt(inode->i_sb, NO_UID32))) { 2759 if(!(test_opt(inode->i_sb, NO_UID32))) {
2740 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); 2760 raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid));
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
index 9b8090d94e6c..965006dba6be 100644
--- a/fs/ext3/ioctl.c
+++ b/fs/ext3/ioctl.c
@@ -28,6 +28,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd,
28 28
29 switch (cmd) { 29 switch (cmd) {
30 case EXT3_IOC_GETFLAGS: 30 case EXT3_IOC_GETFLAGS:
31 ext3_get_inode_flags(ei);
31 flags = ei->i_flags & EXT3_FL_USER_VISIBLE; 32 flags = ei->i_flags & EXT3_FL_USER_VISIBLE;
32 return put_user(flags, (int __user *) arg); 33 return put_user(flags, (int __user *) arg);
33 case EXT3_IOC_SETFLAGS: { 34 case EXT3_IOC_SETFLAGS: {
diff --git a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
index 4eb18ac510ae..ece49a804fe1 100644
--- a/include/linux/ext3_fs.h
+++ b/include/linux/ext3_fs.h
@@ -824,6 +824,7 @@ extern int ext3_change_inode_journal_flag(struct inode *, int);
824extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *); 824extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *);
825extern void ext3_truncate (struct inode *); 825extern void ext3_truncate (struct inode *);
826extern void ext3_set_inode_flags(struct inode *); 826extern void ext3_set_inode_flags(struct inode *);
827extern void ext3_get_inode_flags(struct ext3_inode_info *);
827extern void ext3_set_aops(struct inode *inode); 828extern void ext3_set_aops(struct inode *inode);
828 829
829/* ioctl.c */ 830/* ioctl.c */