Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Dan Carpenter
> But it is better to fix them in an independent patch. :)

Yah.  Of course.  This was completely unrelated.

regards,
dan carpenter
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Gao Xiang
Hi Dan,

On 2018/8/13 20:25, Dan Carpenter wrote:
> On Mon, Aug 13, 2018 at 08:17:27PM +0800, Gao Xiang wrote:
>>> /* we assume that ofs is aligned with 4 bytes */
>>> it->ofs = EROFS_XATTR_ALIGN(it->ofs);
>>> return err;
>>>
> This might be cleaner if we wrote:
> 
>   return (err < 0) ? error : 0;
> 
> The callers all treate zero and one the same so there isn't any reason
> to propogate the 1 back.
> 

Thanks, I will recheck all callers and fix as you suggested.
But it is better to fix them in an independent patch. :) I will send a new 
patch later.

Thanks,
Gao Xiang

> regards,
> dan carpenter
> 
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Gao Xiang
Hi Dan,

On 2018/8/13 20:40, Dan Carpenter wrote:
> On Mon, Aug 13, 2018 at 08:17:27PM +0800, Gao Xiang wrote:
 @@ -294,8 +322,11 @@ static int inline_getxattr(struct inode *inode, 
 struct getxattr_iter *it)
ret = xattr_foreach(>it, _xattr_handlers, );
if (ret >= 0)
break;
 +
 +  if (unlikely(ret != -ENOATTR))  /* -ENOMEM, -EIO, etc. */
>>> I have held off commenting on all the likely/unlikely annotations we
>>> are adding because I don't know what the fast paths are in this code.
>>> However, this is clearly an error path here, not on a fast path.
>>>
>>> Generally the rule on likely/unlikely is that they hurt readability so
>>> we should only add them if it makes a difference in benchmarking.
>>>
>> In my opinion, return values other than 0 and ENOATTR(ENODATA) rarely 
>> happens,
>> it should be in the slow path...
>>
> What I'm trying to say is please stop adding so many likely/unlikely
> annotations.  You should only add them if you have the benchmark data to
> show the it really is required.
> 
> 
OK, I'll follow your suggestion.

I could say it is my personal code tendency(style).
If you don't like it/think them useless, I will remove them all. 

Thanks for your suggestion.

Thanks,
Gao Xiang

> regards,
> dan carpenter
> 
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Chao Yu
On 2018/8/13 20:17, Gao Xiang wrote:
>> Generally the rule on likely/unlikely is that they hurt readability so
>> we should only add them if it makes a difference in benchmarking.
>>
> 
> In my opinion, return values other than 0 and ENOATTR(ENODATA) rarely happens,
> it should be in the slow path...

Hi Dan, thanks for the comments.

IMO, we should check and clean up all likely/unlikely in erofs, to make sure
they are used in the right place.

Thanks,
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Dan Carpenter
On Mon, Aug 13, 2018 at 08:17:27PM +0800, Gao Xiang wrote:
> >> @@ -294,8 +322,11 @@ static int inline_getxattr(struct inode *inode, 
> >> struct getxattr_iter *it)
> >>ret = xattr_foreach(>it, _xattr_handlers, );
> >>if (ret >= 0)
> >>break;
> >> +
> >> +  if (unlikely(ret != -ENOATTR))  /* -ENOMEM, -EIO, etc. */
> > 
> > I have held off commenting on all the likely/unlikely annotations we
> > are adding because I don't know what the fast paths are in this code.
> > However, this is clearly an error path here, not on a fast path.
> > 
> > Generally the rule on likely/unlikely is that they hurt readability so
> > we should only add them if it makes a difference in benchmarking.
> > 
> 
> In my opinion, return values other than 0 and ENOATTR(ENODATA) rarely happens,
> it should be in the slow path...
> 

What I'm trying to say is please stop adding so many likely/unlikely
annotations.  You should only add them if you have the benchmark data to
show the it really is required.


regards,
dan carpenter

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Dan Carpenter
On Mon, Aug 13, 2018 at 08:17:27PM +0800, Gao Xiang wrote:
> > /* we assume that ofs is aligned with 4 bytes */
> > it->ofs = EROFS_XATTR_ALIGN(it->ofs);
> > return err;
> > 

This might be cleaner if we wrote:

return (err < 0) ? error : 0;

The callers all treate zero and one the same so there isn't any reason
to propogate the 1 back.

regards,
dan carpenter

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Gao Xiang
Hi Dan,

On 2018/8/13 19:47, Dan Carpenter wrote:
>> -static void xattr_iter_fixup(struct xattr_iter *it)
>> +static inline int xattr_iter_fixup(struct xattr_iter *it)
>>  {
>> -if (unlikely(it->ofs >= EROFS_BLKSIZ)) {
>> -xattr_iter_end(it, true);
>> +if (likely(it->ofs < EROFS_BLKSIZ))
>> +return 0;
>>  
>> -it->blkaddr += erofs_blknr(it->ofs);
>> -it->page = erofs_get_meta_page_nofail(it->sb,
>> -it->blkaddr, false);
>> -BUG_ON(IS_ERR(it->page));
>> +xattr_iter_end(it, true);
>>  
>> -it->kaddr = kmap_atomic(it->page);
>> -it->ofs = erofs_blkoff(it->ofs);
>> +it->blkaddr += erofs_blknr(it->ofs);
>> +
>> +it->page = erofs_get_meta_page(it->sb, it->blkaddr, false);
>> +if (IS_ERR(it->page)) {
>> +it->page = NULL;
>> +return PTR_ERR(it->page);
> 
> This is returning PTR_ERR(NULL) which is success.  There is a smatch
> test for this and maybe other static checkers as well so it would have
> been caught very quickly.
> 

I am sorry about this. It has already fixed in patch v2.

>>  }
>> +
>> +it->kaddr = kmap_atomic(it->page);
>> +it->ofs = erofs_blkoff(it->ofs);
>> +return 0;
>>  }
>>  
>>  static int inline_xattr_iter_begin(struct xattr_iter *it,
>> @@ -134,22 +154,25 @@ static int inline_xattr_iter_begin(struct xattr_iter 
>> *it,
>>  it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs);
>>  it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
>>  
>> -it->page = erofs_get_inline_page_nofail(inode, it->blkaddr);
>> -BUG_ON(IS_ERR(it->page));
>> -it->kaddr = kmap_atomic(it->page);
>> +it->page = erofs_get_inline_page(inode, it->blkaddr);
>> +if (IS_ERR(it->page))
>> +return PTR_ERR(it->page);
>>  
>> +it->kaddr = kmap_atomic(it->page);
>>  return vi->xattr_isize - xattr_header_sz;
>>  }
>>  
>>  static int xattr_foreach(struct xattr_iter *it,
>> -struct xattr_iter_handlers *op, unsigned *tlimit)
>> +const struct xattr_iter_handlers *op, unsigned *tlimit)
>>  {
>>  struct erofs_xattr_entry entry;
>>  unsigned value_sz, processed, slice;
>>  int err;
>>  
>>  /* 0. fixup blkaddr, ofs, ipage */
>> -xattr_iter_fixup(it);
>> +err = xattr_iter_fixup(it);
>> +if (unlikely(err))
>> +return err;
>>  
>>  /*
>>   * 1. read xattr entry to the memory,
>> @@ -181,7 +204,9 @@ static int xattr_foreach(struct xattr_iter *it,
>>  if (it->ofs >= EROFS_BLKSIZ) {
>>  BUG_ON(it->ofs > EROFS_BLKSIZ);
>>  
>> -xattr_iter_fixup(it);
>> +err = xattr_iter_fixup(it);
>> +if (unlikely(err))
>> +goto out;
>>  it->ofs = 0;
>>  }
>>  
>> @@ -213,7 +238,10 @@ static int xattr_foreach(struct xattr_iter *it,
>>  while (processed < value_sz) {
>>  if (it->ofs >= EROFS_BLKSIZ) {
>>  BUG_ON(it->ofs > EROFS_BLKSIZ);
>> -xattr_iter_fixup(it);
>> +
>> +err = xattr_iter_fixup(it);
>> +if (unlikely(err))
>> +goto out;
>>  it->ofs = 0;
>>  }
>>  
>> @@ -273,7 +301,7 @@ static void xattr_copyvalue(struct xattr_iter *_it,
>>  memcpy(it->buffer + processed, buf, len);
>>  }
>>  
>> -static struct xattr_iter_handlers find_xattr_handlers = {
>> +static const struct xattr_iter_handlers find_xattr_handlers = {
>>  .entry = xattr_entrymatch,
>>  .name = xattr_namematch,
>>  .alloc_buffer = xattr_checkbuffer,
>> @@ -294,8 +322,11 @@ static int inline_getxattr(struct inode *inode, struct 
>> getxattr_iter *it)
>>  ret = xattr_foreach(>it, _xattr_handlers, );
>>  if (ret >= 0)
>>  break;
>> +
>> +if (unlikely(ret != -ENOATTR))  /* -ENOMEM, -EIO, etc. */
> 
> I have held off commenting on all the likely/unlikely annotations we
> are adding because I don't know what the fast paths are in this code.
> However, this is clearly an error path here, not on a fast path.
> 
> Generally the rule on likely/unlikely is that they hurt readability so
> we should only add them if it makes a difference in benchmarking.
> 

In my opinion, return values other than 0 and ENOATTR(ENODATA) rarely happens,
it should be in the slow path...

>> +break;
>>  }
>> -xattr_iter_end(>it, true);
>> +xattr_iter_end_final(>it);
>>  
>>  return ret < 0 ? ret : it->buffer_size;
>>  }
>> @@ -318,9 +349,10 @@ static int shared_getxattr(struct inode *inode, struct 
>> getxattr_iter *it)
>>  if (i)
>>  xattr_iter_end(>it, true);
>>  
>> -it->it.page = erofs_get_meta_page_nofail(sb,
>> -blkaddr, false);
>> 

Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Dan Carpenter
> -static void xattr_iter_fixup(struct xattr_iter *it)
> +static inline int xattr_iter_fixup(struct xattr_iter *it)
>  {
> - if (unlikely(it->ofs >= EROFS_BLKSIZ)) {
> - xattr_iter_end(it, true);
> + if (likely(it->ofs < EROFS_BLKSIZ))
> + return 0;
>  
> - it->blkaddr += erofs_blknr(it->ofs);
> - it->page = erofs_get_meta_page_nofail(it->sb,
> - it->blkaddr, false);
> - BUG_ON(IS_ERR(it->page));
> + xattr_iter_end(it, true);
>  
> - it->kaddr = kmap_atomic(it->page);
> - it->ofs = erofs_blkoff(it->ofs);
> + it->blkaddr += erofs_blknr(it->ofs);
> +
> + it->page = erofs_get_meta_page(it->sb, it->blkaddr, false);
> + if (IS_ERR(it->page)) {
> + it->page = NULL;
> + return PTR_ERR(it->page);

This is returning PTR_ERR(NULL) which is success.  There is a smatch
test for this and maybe other static checkers as well so it would have
been caught very quickly.

>   }
> +
> + it->kaddr = kmap_atomic(it->page);
> + it->ofs = erofs_blkoff(it->ofs);
> + return 0;
>  }
>  
>  static int inline_xattr_iter_begin(struct xattr_iter *it,
> @@ -134,22 +154,25 @@ static int inline_xattr_iter_begin(struct xattr_iter 
> *it,
>   it->blkaddr = erofs_blknr(iloc(sbi, vi->nid) + inline_xattr_ofs);
>   it->ofs = erofs_blkoff(iloc(sbi, vi->nid) + inline_xattr_ofs);
>  
> - it->page = erofs_get_inline_page_nofail(inode, it->blkaddr);
> - BUG_ON(IS_ERR(it->page));
> - it->kaddr = kmap_atomic(it->page);
> + it->page = erofs_get_inline_page(inode, it->blkaddr);
> + if (IS_ERR(it->page))
> + return PTR_ERR(it->page);
>  
> + it->kaddr = kmap_atomic(it->page);
>   return vi->xattr_isize - xattr_header_sz;
>  }
>  
>  static int xattr_foreach(struct xattr_iter *it,
> - struct xattr_iter_handlers *op, unsigned *tlimit)
> + const struct xattr_iter_handlers *op, unsigned *tlimit)
>  {
>   struct erofs_xattr_entry entry;
>   unsigned value_sz, processed, slice;
>   int err;
>  
>   /* 0. fixup blkaddr, ofs, ipage */
> - xattr_iter_fixup(it);
> + err = xattr_iter_fixup(it);
> + if (unlikely(err))
> + return err;
>  
>   /*
>* 1. read xattr entry to the memory,
> @@ -181,7 +204,9 @@ static int xattr_foreach(struct xattr_iter *it,
>   if (it->ofs >= EROFS_BLKSIZ) {
>   BUG_ON(it->ofs > EROFS_BLKSIZ);
>  
> - xattr_iter_fixup(it);
> + err = xattr_iter_fixup(it);
> + if (unlikely(err))
> + goto out;
>   it->ofs = 0;
>   }
>  
> @@ -213,7 +238,10 @@ static int xattr_foreach(struct xattr_iter *it,
>   while (processed < value_sz) {
>   if (it->ofs >= EROFS_BLKSIZ) {
>   BUG_ON(it->ofs > EROFS_BLKSIZ);
> - xattr_iter_fixup(it);
> +
> + err = xattr_iter_fixup(it);
> + if (unlikely(err))
> + goto out;
>   it->ofs = 0;
>   }
>  
> @@ -273,7 +301,7 @@ static void xattr_copyvalue(struct xattr_iter *_it,
>   memcpy(it->buffer + processed, buf, len);
>  }
>  
> -static struct xattr_iter_handlers find_xattr_handlers = {
> +static const struct xattr_iter_handlers find_xattr_handlers = {
>   .entry = xattr_entrymatch,
>   .name = xattr_namematch,
>   .alloc_buffer = xattr_checkbuffer,
> @@ -294,8 +322,11 @@ static int inline_getxattr(struct inode *inode, struct 
> getxattr_iter *it)
>   ret = xattr_foreach(>it, _xattr_handlers, );
>   if (ret >= 0)
>   break;
> +
> + if (unlikely(ret != -ENOATTR))  /* -ENOMEM, -EIO, etc. */

I have held off commenting on all the likely/unlikely annotations we
are adding because I don't know what the fast paths are in this code.
However, this is clearly an error path here, not on a fast path.

Generally the rule on likely/unlikely is that they hurt readability so
we should only add them if it makes a difference in benchmarking.

> + break;
>   }
> - xattr_iter_end(>it, true);
> + xattr_iter_end_final(>it);
>  
>   return ret < 0 ? ret : it->buffer_size;
>  }
> @@ -318,9 +349,10 @@ static int shared_getxattr(struct inode *inode, struct 
> getxattr_iter *it)
>   if (i)
>   xattr_iter_end(>it, true);
>  
> - it->it.page = erofs_get_meta_page_nofail(sb,
> - blkaddr, false);
> - BUG_ON(IS_ERR(it->it.page));
> + it->it.page = erofs_get_meta_page(sb, blkaddr, false);
> + if (IS_ERR(it->it.page))
> + return PTR_ERR(it->it.page);
> +
>   it->it.kaddr = 

Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-13 Thread Chao Yu
Hi Xiang,

On 2018/8/13 10:36, Gao Xiang wrote:
> Hi Chao,
> 
> On 2018/8/13 10:00, Chao Yu wrote:
>> On 2018/8/12 22:01, Chao Yu wrote:
>>> From: Gao Xiang 
>>>
>>> This patch enhances the missing error handling code for
>>> xattr submodule, which improves the stability for the rare cases.
>>>
>>> Signed-off-by: Gao Xiang 
>>> Reviewed-by: Chao Yu 
>>> Signed-off-by: Chao Yu 
>>> ---
>>>  drivers/staging/erofs/internal.h |   6 +-
>>>  drivers/staging/erofs/xattr.c| 120 ---
>>>  2 files changed, 83 insertions(+), 43 deletions(-)
>>>
>>> diff --git a/drivers/staging/erofs/internal.h 
>>> b/drivers/staging/erofs/internal.h
>>> index a756abeff7e9..8951e01216e3 100644
>>> --- a/drivers/staging/erofs/internal.h
>>> +++ b/drivers/staging/erofs/internal.h
>>> @@ -485,10 +485,10 @@ struct erofs_map_blocks_iter {
>>>  
>>>  
>>>  static inline struct page *
>>> -erofs_get_inline_page_nofail(struct inode *inode,
>>> -erofs_blk_t blkaddr)
>>> +erofs_get_inline_page(struct inode *inode,
>>> + erofs_blk_t blkaddr)
>>>  {
>>> -   return erofs_get_meta_page_nofail(inode->i_sb,
>>> +   return erofs_get_meta_page(inode->i_sb,
>>> blkaddr, S_ISDIR(inode->i_mode));
>>>  }
>>>  
>>> diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c
>>> index 2593c856b079..1b5815fc70db 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);
>>> @@ -54,8 +63,9 @@ static void init_inode_xattrs(struct inode *inode)
>>> it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
>>> it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
>>>  
>>> -   it.page = erofs_get_inline_page_nofail(inode, it.blkaddr);
>>> -   BUG_ON(IS_ERR(it.page));
>>> +   it.page = erofs_get_inline_page(inode, it.blkaddr);
>>> +   if (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(, atomic_map);
>>> +   return -ENOMEM;
>>> +   }
>>>  
>>> /* let's skip ibody header */
>>> it.ofs += sizeof(struct erofs_xattr_ibody_header);
>>> @@ -77,9 +90,10 @@ static void init_inode_xattrs(struct inode *inode)
>>> BUG_ON(it.ofs != EROFS_BLKSIZ);
>>> xattr_iter_end(, atomic_map);
>>>  
>>> -   it.page = erofs_get_meta_page_nofail(sb,
>>> +   it.page = erofs_get_meta_page(sb,
>>> ++it.blkaddr, S_ISDIR(inode->i_mode));
>>> -   BUG_ON(IS_ERR(it.page));
>>> +   if (IS_ERR(it.page))
>>> +   return PTR_ERR(it.page);
>>>  
>>> it.kaddr = kmap_atomic(it.page);
>>> atomic_map = true;
>>> @@ -92,6 +106,7 @@ static void init_inode_xattrs(struct inode *inode)
>>> xattr_iter_end(, atomic_map);
>>>  
>>> inode_set_inited_xattr(inode);
>>> +   return 0;
>>>  }
>>>  
>>>  struct xattr_iter_handlers {
>>> @@ -101,19 +116,24 @@ struct xattr_iter_handlers {
>>> void (*value)(struct xattr_iter *, unsigned, char *, unsigned);
>>>  };
>>>  
>>> -static void xattr_iter_fixup(struct xattr_iter *it)
>>> +static inline int xattr_iter_fixup(struct xattr_iter 

Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-12 Thread Gao Xiang
Hi Chao,

On 2018/8/13 10:00, Chao Yu wrote:
> On 2018/8/12 22:01, Chao Yu wrote:
>> From: Gao Xiang 
>>
>> This patch enhances the missing error handling code for
>> xattr submodule, which improves the stability for the rare cases.
>>
>> Signed-off-by: Gao Xiang 
>> Reviewed-by: Chao Yu 
>> Signed-off-by: Chao Yu 
>> ---
>>  drivers/staging/erofs/internal.h |   6 +-
>>  drivers/staging/erofs/xattr.c| 120 ---
>>  2 files changed, 83 insertions(+), 43 deletions(-)
>>
>> diff --git a/drivers/staging/erofs/internal.h 
>> b/drivers/staging/erofs/internal.h
>> index a756abeff7e9..8951e01216e3 100644
>> --- a/drivers/staging/erofs/internal.h
>> +++ b/drivers/staging/erofs/internal.h
>> @@ -485,10 +485,10 @@ struct erofs_map_blocks_iter {
>>  
>>  
>>  static inline struct page *
>> -erofs_get_inline_page_nofail(struct inode *inode,
>> - erofs_blk_t blkaddr)
>> +erofs_get_inline_page(struct inode *inode,
>> +  erofs_blk_t blkaddr)
>>  {
>> -return erofs_get_meta_page_nofail(inode->i_sb,
>> +return erofs_get_meta_page(inode->i_sb,
>>  blkaddr, S_ISDIR(inode->i_mode));
>>  }
>>  
>> diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c
>> index 2593c856b079..1b5815fc70db 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);
>> @@ -54,8 +63,9 @@ static void init_inode_xattrs(struct inode *inode)
>>  it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
>>  it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
>>  
>> -it.page = erofs_get_inline_page_nofail(inode, it.blkaddr);
>> -BUG_ON(IS_ERR(it.page));
>> +it.page = erofs_get_inline_page(inode, it.blkaddr);
>> +if (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(, atomic_map);
>> +return -ENOMEM;
>> +}
>>  
>>  /* let's skip ibody header */
>>  it.ofs += sizeof(struct erofs_xattr_ibody_header);
>> @@ -77,9 +90,10 @@ static void init_inode_xattrs(struct inode *inode)
>>  BUG_ON(it.ofs != EROFS_BLKSIZ);
>>  xattr_iter_end(, atomic_map);
>>  
>> -it.page = erofs_get_meta_page_nofail(sb,
>> +it.page = erofs_get_meta_page(sb,
>>  ++it.blkaddr, S_ISDIR(inode->i_mode));
>> -BUG_ON(IS_ERR(it.page));
>> +if (IS_ERR(it.page))
>> +return PTR_ERR(it.page);
>>  
>>  it.kaddr = kmap_atomic(it.page);
>>  atomic_map = true;
>> @@ -92,6 +106,7 @@ static void init_inode_xattrs(struct inode *inode)
>>  xattr_iter_end(, atomic_map);
>>  
>>  inode_set_inited_xattr(inode);
>> +return 0;
>>  }
>>  
>>  struct xattr_iter_handlers {
>> @@ -101,19 +116,24 @@ struct xattr_iter_handlers {
>>  void (*value)(struct xattr_iter *, unsigned, char *, unsigned);
>>  };
>>  
>> -static void xattr_iter_fixup(struct xattr_iter *it)
>> +static inline int xattr_iter_fixup(struct xattr_iter *it)
>>  {
>> -if (unlikely(it->ofs >= EROFS_BLKSIZ)) {
>> -xattr_iter_end(it, true);
>> +if 

Re: [PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-12 Thread Chao Yu
On 2018/8/12 22:01, Chao Yu wrote:
> From: Gao Xiang 
> 
> This patch enhances the missing error handling code for
> xattr submodule, which improves the stability for the rare cases.
> 
> Signed-off-by: Gao Xiang 
> Reviewed-by: Chao Yu 
> Signed-off-by: Chao Yu 
> ---
>  drivers/staging/erofs/internal.h |   6 +-
>  drivers/staging/erofs/xattr.c| 120 ---
>  2 files changed, 83 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/staging/erofs/internal.h 
> b/drivers/staging/erofs/internal.h
> index a756abeff7e9..8951e01216e3 100644
> --- a/drivers/staging/erofs/internal.h
> +++ b/drivers/staging/erofs/internal.h
> @@ -485,10 +485,10 @@ struct erofs_map_blocks_iter {
>  
>  
>  static inline struct page *
> -erofs_get_inline_page_nofail(struct inode *inode,
> -  erofs_blk_t blkaddr)
> +erofs_get_inline_page(struct inode *inode,
> +   erofs_blk_t blkaddr)
>  {
> - return erofs_get_meta_page_nofail(inode->i_sb,
> + return erofs_get_meta_page(inode->i_sb,
>   blkaddr, S_ISDIR(inode->i_mode));
>  }
>  
> diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c
> index 2593c856b079..1b5815fc70db 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);
> @@ -54,8 +63,9 @@ static void init_inode_xattrs(struct inode *inode)
>   it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
>   it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
>  
> - it.page = erofs_get_inline_page_nofail(inode, it.blkaddr);
> - BUG_ON(IS_ERR(it.page));
> + it.page = erofs_get_inline_page(inode, it.blkaddr);
> + if (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(, atomic_map);
> + return -ENOMEM;
> + }
>  
>   /* let's skip ibody header */
>   it.ofs += sizeof(struct erofs_xattr_ibody_header);
> @@ -77,9 +90,10 @@ static void init_inode_xattrs(struct inode *inode)
>   BUG_ON(it.ofs != EROFS_BLKSIZ);
>   xattr_iter_end(, atomic_map);
>  
> - it.page = erofs_get_meta_page_nofail(sb,
> + it.page = erofs_get_meta_page(sb,
>   ++it.blkaddr, S_ISDIR(inode->i_mode));
> - BUG_ON(IS_ERR(it.page));
> + if (IS_ERR(it.page))
> + return PTR_ERR(it.page);
>  
>   it.kaddr = kmap_atomic(it.page);
>   atomic_map = true;
> @@ -92,6 +106,7 @@ static void init_inode_xattrs(struct inode *inode)
>   xattr_iter_end(, atomic_map);
>  
>   inode_set_inited_xattr(inode);
> + return 0;
>  }
>  
>  struct xattr_iter_handlers {
> @@ -101,19 +116,24 @@ struct xattr_iter_handlers {
>   void (*value)(struct xattr_iter *, unsigned, char *, unsigned);
>  };
>  
> -static void xattr_iter_fixup(struct xattr_iter *it)
> +static inline int xattr_iter_fixup(struct xattr_iter *it)
>  {
> - if (unlikely(it->ofs >= EROFS_BLKSIZ)) {
> - xattr_iter_end(it, true);
> + if (likely(it->ofs < EROFS_BLKSIZ))
> + return 0;
>  
> - it->blkaddr += erofs_blknr(it->ofs);
> -

[PATCH 3/8] staging: erofs: add error handling for xattr submodule

2018-08-12 Thread Chao Yu
From: Gao Xiang 

This patch enhances the missing error handling code for
xattr submodule, which improves the stability for the rare cases.

Signed-off-by: Gao Xiang 
Reviewed-by: Chao Yu 
Signed-off-by: Chao Yu 
---
 drivers/staging/erofs/internal.h |   6 +-
 drivers/staging/erofs/xattr.c| 120 ---
 2 files changed, 83 insertions(+), 43 deletions(-)

diff --git a/drivers/staging/erofs/internal.h b/drivers/staging/erofs/internal.h
index a756abeff7e9..8951e01216e3 100644
--- a/drivers/staging/erofs/internal.h
+++ b/drivers/staging/erofs/internal.h
@@ -485,10 +485,10 @@ struct erofs_map_blocks_iter {
 
 
 static inline struct page *
-erofs_get_inline_page_nofail(struct inode *inode,
-erofs_blk_t blkaddr)
+erofs_get_inline_page(struct inode *inode,
+ erofs_blk_t blkaddr)
 {
-   return erofs_get_meta_page_nofail(inode->i_sb,
+   return erofs_get_meta_page(inode->i_sb,
blkaddr, S_ISDIR(inode->i_mode));
 }
 
diff --git a/drivers/staging/erofs/xattr.c b/drivers/staging/erofs/xattr.c
index 2593c856b079..1b5815fc70db 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);
@@ -54,8 +63,9 @@ static void init_inode_xattrs(struct inode *inode)
it.blkaddr = erofs_blknr(iloc(sbi, vi->nid) + vi->inode_isize);
it.ofs = erofs_blkoff(iloc(sbi, vi->nid) + vi->inode_isize);
 
-   it.page = erofs_get_inline_page_nofail(inode, it.blkaddr);
-   BUG_ON(IS_ERR(it.page));
+   it.page = erofs_get_inline_page(inode, it.blkaddr);
+   if (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(, atomic_map);
+   return -ENOMEM;
+   }
 
/* let's skip ibody header */
it.ofs += sizeof(struct erofs_xattr_ibody_header);
@@ -77,9 +90,10 @@ static void init_inode_xattrs(struct inode *inode)
BUG_ON(it.ofs != EROFS_BLKSIZ);
xattr_iter_end(, atomic_map);
 
-   it.page = erofs_get_meta_page_nofail(sb,
+   it.page = erofs_get_meta_page(sb,
++it.blkaddr, S_ISDIR(inode->i_mode));
-   BUG_ON(IS_ERR(it.page));
+   if (IS_ERR(it.page))
+   return PTR_ERR(it.page);
 
it.kaddr = kmap_atomic(it.page);
atomic_map = true;
@@ -92,6 +106,7 @@ static void init_inode_xattrs(struct inode *inode)
xattr_iter_end(, atomic_map);
 
inode_set_inited_xattr(inode);
+   return 0;
 }
 
 struct xattr_iter_handlers {
@@ -101,19 +116,24 @@ struct xattr_iter_handlers {
void (*value)(struct xattr_iter *, unsigned, char *, unsigned);
 };
 
-static void xattr_iter_fixup(struct xattr_iter *it)
+static inline int xattr_iter_fixup(struct xattr_iter *it)
 {
-   if (unlikely(it->ofs >= EROFS_BLKSIZ)) {
-   xattr_iter_end(it, true);
+   if (likely(it->ofs < EROFS_BLKSIZ))
+   return 0;
 
-   it->blkaddr += erofs_blknr(it->ofs);
-   it->page = erofs_get_meta_page_nofail(it->sb,
-   it->blkaddr, false);
-   BUG_ON(IS_ERR(it->page));
+   xattr_iter_end(it, true);
 
-