From: Wang Sheng-Hui on
于 2010-7-12 22:29, crosslonelyover 写道:
> Hi,
> I walked through ext2_xattr_get, and felt that we can
> do some optimization on it. For name_len check, it's done
> after down xattr_sem and sb_read, both of which are time
> consuming operation compared with strlen:
> down_read(&EXT2_I(inode)->xattr_sem);
> ...
> bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
> ...
> /* find named attribute */
> name_len = strlen(name);
>
> error = -ERANGE;
> if (name_len> 255)
> goto cleanup;
>
> Most of the case, you'll get one valid block, but if the
> name len> 255, then the xattr_sem down and sb_bread operation
> can be seen as a waste of time. So I think we'd better do
> name len check as early as possible.
> Following is my patch, and it's against 2.6.35-rc4.
> Please check it.
>
> Signed-off-by: Wang Sheng-Hui<crosslonelyover(a)gmail.com>
> ---
> fs/ext2/xattr.c | 12 +++++++-----
> 1 files changed, 7 insertions(+), 5 deletions(-)
>
> diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
> index 7c39157..0b94d61 100644
> --- a/fs/ext2/xattr.c
> +++ b/fs/ext2/xattr.c
> @@ -161,6 +161,13 @@ ext2_xattr_get(struct inode *inode, int name_index, const char *name,
>
> if (name == NULL)
> return -EINVAL;
> +
> + /* find named attribute */
> + name_len = strlen(name);
> + error = -ERANGE;
> + if (name_len> 255)
> + goto cleanup;
> +
> down_read(&EXT2_I(inode)->xattr_sem);
> error = -ENODATA;
> if (!EXT2_I(inode)->i_file_acl)
> @@ -181,12 +188,7 @@ bad_block: ext2_error(inode->i_sb, "ext2_xattr_get",
> error = -EIO;
> goto cleanup;
> }
> - /* find named attribute */
> - name_len = strlen(name);
>
> - error = -ERANGE;
> - if (name_len> 255)
> - goto cleanup;
> entry = FIRST_ENTRY(bh);
> while (!IS_LAST_ENTRY(entry)) {
> struct ext2_xattr_entry *next =
Hi, I noticed in ext2_xattr_set, name_len check is done
before
down_write(&EXT2_I(inode)->xattr_sem);
So I think ext2_xattr_get should do in the same way.

Please check this patch.

--
Thanks and Regards,
shenghui

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Jan Kara on
On Thu 22-07-10 08:03:18, shenghui wrote:
> 2010/7/22 Jan Kara <jack(a)suse.cz>:
> >> Hi,
> >> � � � �I walked through ext2_xattr_get, and felt that we can
> >> do some optimization on it. For name_len check, it's done
> >> after down xattr_sem and sb_read, both of which are time
> >> consuming operation compared with strlen:
> >> � � � � �down_read(&EXT2_I(inode)->xattr_sem);
> >> �...
> >> � � � � �bh = sb_bread(inode->i_sb, EXT2_I(inode)->i_file_acl);
> >> �...
> >> � � � � �/* find named attribute */
> >> � � � � �name_len = strlen(name);
> >>
> >> � � � � �error = -ERANGE;
> >> � � � � �if (name_len > 255)
> >> � � � � � � � � �goto cleanup;
> >>
> >> � � � �Most of the case, you'll get one valid block, but if the
> >> name len > 255, then the xattr_sem down and sb_bread operation
> >> can be seen as a waste of time. So I think we'd better do
> >> name len check as early as possible.
> >> � � � �Following is my patch, and it's against 2.6.35-rc4.
> >> Please check it.
> >>
> >> Signed-off-by: Wang Sheng-Hui <crosslonelyover(a)gmail.com>
> >> ---
> >> �fs/ext2/xattr.c | � 12 +++++++-----
> >> �1 files changed, 7 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/fs/ext2/xattr.c b/fs/ext2/xattr.c
> >> index 7c39157..0b94d61 100644
> >> --- a/fs/ext2/xattr.c
> >> +++ b/fs/ext2/xattr.c
> >> @@ -161,6 +161,13 @@ ext2_xattr_get(struct inode *inode, int name_index, const char *name,
> >>
> >> � � � if (name == NULL)
> >> � � � � � � � return -EINVAL;
> >> +
> >> + � � /* find named attribute */
> >> + � � name_len = strlen(name);
> >> + � � error = -ERANGE;
> >> + � � if (name_len > 255)
> >> + � � � � � � goto cleanup;
> > �But you cannot go to cleanup here because you don't hold xattr_sem...
> >
>
> Sorry, I'm a little confused by your words.
> The patch just checks name_len, and it
> doesn't need xattr_sem.
Checking of name_len is fine as you did it. But I wanted to point out
that if name_len is greater than 255, you then go to 'cleanup' label which
tries to do up_read(&EXT2_I(inode)->xattr_sem). But that's a bug because
after you moved the code, we don't hold xattr_sem at the moment we check
name_len.

Honza
--
Jan Kara <jack(a)suse.cz>
SUSE Labs, CR
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
From: Ted Ts'o on
On Fri, Jul 23, 2010 at 10:37:59AM +0200, Jan Kara wrote:
> Checking of name_len is fine as you did it. But I wanted to point out
> that if name_len is greater than 255, you then go to 'cleanup' label which
> tries to do up_read(&EXT2_I(inode)->xattr_sem). But that's a bug because
> after you moved the code, we don't hold xattr_sem at the moment we check
> name_len.

Yup, you could just return -ERANGE right there.

The simpler fix though might be to just delete the check altogether.
Neither ext3 nor ext4 checks for the length of the xattr name in their
_xattr_get() function. Instead they'll just do the search, and then
return -ENODATA. That seems legit; there can be no entries larger
than 255, so saying the extended attribute doesn't exist is quite
correct. There is a check in the _xattr_set() functions for both ext3
and ext4, which is quite correct and proper.

Does that mean we'll end up doing a search before returning an error
--- yes, but I don't think that matters. Why should we care about
optimizing an error case? It's not like this is going to be in a
timing sensitive part of an application.... (of course the same
consideration could apply to your patch as well).

- Ted
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo(a)vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/