From: Andreas Dilger <adilger@dilger.ca>
To: Eric Biggers <ebiggers3@gmail.com>, Jan Kara <jack@suse.cz>
Cc: David Howells <dhowells@redhat.com>,
linux-ext4 <linux-ext4@vger.kernel.org>,
linux-fsdevel <linux-fsdevel@vger.kernel.org>,
LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] ext4: Add statx support
Date: Fri, 17 Mar 2017 14:19:22 -0600 [thread overview]
Message-ID: <1A035757-CBE2-40F1-9CD3-9554F56F63CB@dilger.ca> (raw)
In-Reply-To: <20170317054755.GA595@zzz>
[-- Attachment #1: Type: text/plain, Size: 4318 bytes --]
On Mar 16, 2017, at 11:47 PM, Eric Biggers <ebiggers3@gmail.com> wrote:
> On Thu, Mar 16, 2017 at 11:35:33AM +0000, David Howells wrote:
>> +
>> + ext4_get_inode_flags(ei);
>> + flags = ei->i_flags & EXT4_FL_USER_VISIBLE;
>> + if (flags & EXT4_APPEND_FL)
>> + stat->attributes |= STATX_ATTR_APPEND;
>> + if (flags & EXT4_COMPR_FL)
>> + stat->attributes |= STATX_ATTR_COMPRESSED;
>> + if (flags & EXT4_ENCRYPT_FL)
>> + stat->attributes |= STATX_ATTR_ENCRYPTED;
>> + if (flags & EXT4_IMMUTABLE_FL)
>> + stat->attributes |= STATX_ATTR_IMMUTABLE;
>> + if (flags & EXT4_NODUMP_FL)
>> + stat->attributes |= STATX_ATTR_NODUMP;
>>
>> - inode = d_inode(path->dentry);
>> generic_fillattr(inode, stat);
>> + return 0;
>> +}
>
> I think it's the wrong approach to be calling ext4_get_inode_flags() here to
> sync the generic inode flags (inode->i_flags) to the ext4-specific inode flags
> (ei->i_flags). I know the GETFLAGS and FSGETXATTR ioctls do it too, but I
> think it's a mistake --- at least, when done so without holding the inode lock.
> The issue is that flag syncs can occur in both directions concurrently and
> cause an update to be lost. For example, with thread 1 doing a stat() and
> thread 2 doing the SETFLAGS ioctl to set the APPEND flag:
>
> Thread 1, ext4_get_inode_flags() Thread 2, ext4_ioctl_setflags()
> ----------------------------------- ---------------------------
> Read inode->i_flags; S_APPEND clear
> Set EXT4_APPEND_FL in ei->i_flags
> Clear EXT4_APPEND_FL in ei->i_flags
> Read ei->i_flags; EXT4_APPEND_FL clear
> Clear S_APPEND in inode->i_flags
>
> So the flag set by SETFLAGS gets lost. This bug probably hasn't really been
> noticable with GETFLAGS and FSGETXATTR since they're rarely used, but stat() on
> the other hand is very common, and I'm worried that with this change people
> would start seeing this race more often.
>
> Ultimately this needs to be addressed in ext4 more fully, but how about for
> ->getattr() just skipping the call to ext4_get_inode_flags() and instead
> populating the generic attributes like STATX_ATTR_APPEND and
> STATX_ATTR_IMMUTABLE from the generic inode flags, rather than from the
> ext4-specific flags? Actually, it could even be done in generic_fillattr(), so
> that all filesystems benefit.
Wouldn't it make more sense to just extract the ext4 flags directly from
ei->i_flags? I think ext4_get_inode_flags() is only really useful when
the VFS inode flags are changed and they need to be propagated to the ext4
inode.
I guess the other more significant question is when/where are the VFS inode
flags changed that they need to be propagated into the ext4 disk inode?
The main avenue for changing these attribute flags that I know about is via
EXT4_IOC_SETFLAGS (FS_IOC_SETFLAGS), and there is one place that I could
find in fs/nsfs.c that sets S_IMMUTABLE but I don't think that propagates
down to an ext4 disk inode.
It seems like the use of ext4_get_inode_flags() is largely superfluous.
The original commit ff9ddf7e847 indicates this was for quota inodes only.
I think it can be removed from EXT4_IOC_FSGETXATTR, and EXT4_IOC_GETFLAGS
and made conditional in ext4_do_update_inode():
#ifdef CONFIG_QUOTA
for (i = 0; i < EXT4_MAXQUOTAS; i++) {
if (unlikely(sb_dqopt(sb)->files[i] == inode))
ext4_get_inode_flags(EXT4_I(inode));
}
#endif
Jan, what do you think?
Cheers, Andreas
>
>> diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c
>> index 73b184d161fc..4c6b23a0603e 100644
>> --- a/fs/ext4/symlink.c
>> +++ b/fs/ext4/symlink.c
>> @@ -91,11 +91,13 @@ const struct inode_operations ext4_encrypted_symlink_inode_operations = {
>> const struct inode_operations ext4_symlink_inode_operations = {
>> .get_link = page_get_link,
>> .setattr = ext4_setattr,
>> + .getattr = ext4_getattr,
>> .listxattr = ext4_listxattr,
>> };
>>
>> const struct inode_operations ext4_fast_symlink_inode_operations = {
>> .get_link = simple_get_link,
>> .setattr = ext4_setattr,
>> + .getattr = ext4_getattr,
>> .listxattr = ext4_listxattr,
>> };
>>
>
> getattr needs to be added to ext4_encrypted_symlink_inode_operations too.
>
> - Eric
Cheers, Andreas
[-- Attachment #2: Message signed with OpenPGP --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
next prev parent reply other threads:[~2017-03-17 20:19 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-03-16 11:35 David Howells
2017-03-16 21:46 ` Andreas Dilger
2017-03-17 5:47 ` Eric Biggers
2017-03-17 20:19 ` Andreas Dilger [this message]
2017-03-19 11:12 ` Jan Kara
2017-04-12 7:34 ` Jan Kara
2017-03-20 17:52 ` Christoph Hellwig
2017-03-31 8:06 ` David Howells
2017-03-31 15:28 David Howells
2017-03-31 21:06 ` Andreas Dilger
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=1A035757-CBE2-40F1-9CD3-9554F56F63CB@dilger.ca \
--to=adilger@dilger.ca \
--cc=dhowells@redhat.com \
--cc=ebiggers3@gmail.com \
--cc=jack@suse.cz \
--cc=linux-ext4@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®