From: Ted Ts'o <tytso@mit.edu>
To: Tao Ma <tm@tao.ma>
Cc: linux-ext4@vger.kernel.org, stable <stable@vger.kernel.org>
Subject: Re: [PATCH] ext4: Save and restore state flags in EXT4_IOC_SETFLAGS.
Date: Thu, 31 May 2012 23:48:20 -0400 [thread overview]
Message-ID: <20120601034820.GC7897@thunk.org> (raw)
In-Reply-To: <1336145869-4120-1-git-send-email-tm@tao.ma>
On Fri, May 04, 2012 at 11:37:49PM +0800, Tao Ma wrote:
> From: Tao Ma <boyu.mt@taobao.com>
>
> In commit 353eb83c we removes i_state_flags with 64-bit longs,
> But in case we call EXT4_IOC_SETFLAGS, we fail to save the
> high 32-bit state flags and only stores the low 32-bit back
> to ei->i_flags. So the state flags are missing now in 64-bit
> long architecture.
The problem with this approach is that we are still editing i_flags
and then replacing it with the new value. So we're vulnerable to
races where some other process is modifies the i_state_flags between
when we sample it using ext4_save_state_flags() and when we restore
them.
This is a better way to fix the problem, and what I plan to commit
into the ext4 tree:
commit 79906964a187c405db72a3abc60eb9b50d804fbc
Author: Theodore Ts'o <tytso@mit.edu>
Date: Thu May 31 23:46:01 2012 -0400
ext4: don't trash state flags in EXT4_IOC_SETFLAGS
In commit 353eb83c we removed i_state_flags with 64-bit longs, But
when handling the EXT4_IOC_SETFLAGS ioctl, we replace i_flags
directly, which trashes the state flags which are stored in the high
32-bits of i_flags on 64-bit platforms. So use the the
ext4_{set,clear}_inode_flags() functions which use atomic bit
manipulation functions instead.
Reported-by: Tao Ma <boyu.mt@taobao.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Cc: stable@kernel.org
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c
index feba55a..8ad112a 100644
--- a/fs/ext4/ioctl.c
+++ b/fs/ext4/ioctl.c
@@ -38,7 +38,7 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
handle_t *handle = NULL;
int err, migrate = 0;
struct ext4_iloc iloc;
- unsigned int oldflags;
+ unsigned int oldflags, mask, i;
unsigned int jflag;
if (!inode_owner_or_capable(inode))
@@ -115,8 +115,14 @@ long ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
if (err)
goto flags_err;
- flags = flags & EXT4_FL_USER_MODIFIABLE;
- flags |= oldflags & ~EXT4_FL_USER_MODIFIABLE;
+ for (i = 0, mask = 1; i < 32; i++, mask <<= 1) {
+ if (!(mask & EXT4_FL_USER_MODIFIABLE))
+ continue;
+ if (mask & flags)
+ ext4_set_inode_flag(inode, i);
+ else
+ ext4_clear_inode_flag(inode, i);
+ }
ei->i_flags = flags;
ext4_set_inode_flags(inode);
next prev parent reply other threads:[~2012-06-01 3:48 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-04 15:37 [PATCH] ext4: Save and restore state flags in EXT4_IOC_SETFLAGS Tao Ma
2012-05-30 1:59 ` Tao Ma
2012-06-01 3:48 ` Ted Ts'o [this message]
2012-06-04 3:22 ` Tao Ma
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120601034820.GC7897@thunk.org \
--to=tytso@mit.edu \
--cc=linux-ext4@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=tm@tao.ma \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.