[PREVIEW] [PATCH 4/4] staging: erofs: add error handling for xattr submodule
Gao Xiang
gaoxiang25 at huawei.com
Fri Aug 10 16:15:03 AEST 2018
Hi Chao,
On 2018/8/10 14:08, Chao Yu wrote:
> Hi Xiang,
>
> On 2018/8/10 11:47, Gao Xiang wrote:
>> Hi Chao,
>>
>> On 2018/8/10 11:40, Chao Yu wrote:
>>> On 2018/8/1 14:01, Gao Xiang wrote:
>>>> This patch enhances the missing error handling code for
>>>> xattr submodule, which improves the stability for the rare cases.
>>>>
>>>> Signed-off-by: Gao Xiang <gaoxiang25 at huawei.com>
>>>> ---
>>>> drivers/staging/erofs/xattr.c | 114 ++++++++++++++++++++++++++++--------------
>>>> 1 file changed, 77 insertions(+), 37 deletions(-)
>>>>
>>>> diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c
>>>> index 702434b..bd911bb 100644
>>>> --- a/drivers/staging/erofs/xattr.c
>>>> +++ b/drivers/staging/erofs/xattr.c
>>>> @@ -24,16 +24,25 @@ struct xattr_iter {
>>>>
>>>> static inline void xattr_iter_end(struct xattr_iter *it, bool atomic)
>>>> {
>>>> - /* only init_inode_xattrs use non-atomic once */
>>>> + /* the only user of kunmap() is 'init_inode_xattrs' */
>>>> if (unlikely(!atomic))
>>>> kunmap(it->page);
>>>> else
>>>> kunmap_atomic(it->kaddr);
>>>> +
>>>> unlock_page(it->page);
>>>> put_page(it->page);
>>>> }
>>>>
>>>> -static void init_inode_xattrs(struct inode *inode)
>>>> +static inline void xattr_iter_end_final(struct xattr_iter *it)
>>>> +{
>>>> + if (unlikely(it->page == NULL))
>>>> + return;
>>>> +
>>>> + xattr_iter_end(it, true);
>>>> +}
>>>> +
>>>> +static int init_inode_xattrs(struct inode *inode)
>>>> {
>>>> struct xattr_iter it;
>>>> unsigned i;
>>>> @@ -44,7 +53,7 @@ static void init_inode_xattrs(struct inode *inode)
>>>> bool atomic_map;
>>>>
>>>> if (likely(inode_has_inited_xattr(inode)))
>>>> - return;
>>>> + return 0;
>>>>
>>>> vi = EROFS_V(inode);
>>>> BUG_ON(!vi->xattr_isize);
>>>> @@ -55,7 +64,8 @@ static void init_inode_xattrs(struct inode *inode)
>>>> it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
>>>>
>>>> it.page = erofs_get_inline_page_nofail(inode, it.blkaddr);
>>> Need to introduce and use erofs_get_inline_page()?
>>>
>>>> - BUG_ON(IS_ERR(it.page));
>>>> + if (unlikely(IS_ERR(it.page)))
>>>> + return PTR_ERR(it.page);
>>>>
>>>> /* read in shared xattr array (non-atomic, see kmalloc below) */
>>>> it.kaddr = kmap(it.page);
>>>> @@ -64,9 +74,12 @@ static void init_inode_xattrs(struct inode *inode)
>>>> ih = (struct erofs_xattr_ibody_header *)(it.kaddr + it.ofs);
>>>>
>>>> vi->xattr_shared_count = ih->h_shared_count;
>>>> - vi->xattr_shared_xattrs = (unsigned *)kmalloc_array(
>>>> - vi->xattr_shared_count, sizeof(unsigned),
>>>> - GFP_KERNEL | __GFP_NOFAIL);
>>>> + vi->xattr_shared_xattrs = kmalloc_array(vi->xattr_shared_count,
>>>> + sizeof(unsigned), GFP_KERNEL);
>>>> + if (unlikely(vi->xattr_shared_xattrs == NULL)) {
>>>> + xattr_iter_end(&it, atomic_map);
>>>> + return -ENOMEM;
>>>> + }
>>>>
>>>> /* let's skip ibody header */
>>>> it.ofs += sizeof(struct erofs_xattr_ibody_header);
>>>> @@ -79,7 +92,8 @@ static void init_inode_xattrs(struct inode *inode)
>>>>
>>>> it.page = erofs_get_meta_page_nofail(sb,
>>>> ++it.blkaddr, S_ISDIR(inode->i_mode));
>>> Need to use erofs_get_meta_page() instead?
>>>
>>> Thanks,
>> My consideration is for example,
>>
>> init_inode_xattrs itself can be seen as a part of inode initialization (other fs does it in
>> inode initialization, but erofs does it in the first xattr request), if it fail, the only way
>> is to retry again...but with more overhead to retry...
> I think we can easily return an error to user no matter we encounter -ENOMEM or
> -EIO, so erofs_get_meta_page() is enough here, thoughts?
>
OK, it depends on users (kernel / programs). I think they will simply retry again in the outer loop,
which will cause more overhead therefore for inode metadata (not xattrs), I personally tend to retry inside.
That is just my personal opinion, will fix it.
Thanks,
Gao Xiang
> Thanks,
>
More information about the Linux-erofs
mailing list