Message ID | 20231114153108.1932884-1-haowenchao2@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | ceph: quota: Fix invalid pointer access in | expand |
On 11/14/23 23:31, Wenchao Hao wrote: > This issue is reported by smatch, get_quota_realm() might return > ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return > value. > > Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> > --- > fs/ceph/quota.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > index 9d36c3532de1..c4b2929c6a83 100644 > --- a/fs/ceph/quota.c > +++ b/fs/ceph/quota.c > @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) > realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), > QUOTA_GET_MAX_BYTES, true); > up_read(&mdsc->snap_rwsem); > - if (!realm) > + if (IS_ERR_OR_NULL(realm)) > return false; > > spin_lock(&realm->inodes_with_caps_lock); Good catch. Reviewed-by: Xiubo Li <xiubli@redhat.com> We should CC the stable mail list. Thanks - Xiubo
Wenchao Hao <haowenchao2@huawei.com> writes: > This issue is reported by smatch, get_quota_realm() might return > ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return > value. > > Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> > --- > fs/ceph/quota.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > index 9d36c3532de1..c4b2929c6a83 100644 > --- a/fs/ceph/quota.c > +++ b/fs/ceph/quota.c > @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) > realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), > QUOTA_GET_MAX_BYTES, true); > up_read(&mdsc->snap_rwsem); > - if (!realm) > + if (IS_ERR_OR_NULL(realm)) > return false; > > spin_lock(&realm->inodes_with_caps_lock); > -- > > 2.32.0 > This looks right to me, the issue was introduced by commit 0c44a8e0fc55 ("ceph: quota: fix quota subdir mounts"). FWIW: Reviewed-by: Luis Henriques <lhenriques@suse.de> Cheers,
On 11/15/23 19:19, Luis Henriques wrote: > Wenchao Hao <haowenchao2@huawei.com> writes: > >> This issue is reported by smatch, get_quota_realm() might return >> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >> value. >> >> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >> --- >> fs/ceph/quota.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >> index 9d36c3532de1..c4b2929c6a83 100644 >> --- a/fs/ceph/quota.c >> +++ b/fs/ceph/quota.c >> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) >> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >> QUOTA_GET_MAX_BYTES, true); >> up_read(&mdsc->snap_rwsem); >> - if (!realm) >> + if (IS_ERR_OR_NULL(realm)) >> return false; >> >> spin_lock(&realm->inodes_with_caps_lock); >> -- >> >> 2.32.0 >> > This looks right to me, the issue was introduced by commit 0c44a8e0fc55 > ("ceph: quota: fix quota subdir mounts"). FWIW: > > Reviewed-by: Luis Henriques <lhenriques@suse.de> Thanks Luis. I have updated the testing branch. - Xiubo > Cheers,
On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: > > > On 11/14/23 23:31, Wenchao Hao wrote: > > This issue is reported by smatch, get_quota_realm() might return > > ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return > > value. > > > > Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> > > --- > > fs/ceph/quota.c | 2 +- > > 1 file changed, 1 insertion(+), 1 deletion(-) > > > > diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > > index 9d36c3532de1..c4b2929c6a83 100644 > > --- a/fs/ceph/quota.c > > +++ b/fs/ceph/quota.c > > @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) > > realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), > > QUOTA_GET_MAX_BYTES, true); > > up_read(&mdsc->snap_rwsem); > > - if (!realm) > > + if (IS_ERR_OR_NULL(realm)) > > return false; > > > > spin_lock(&realm->inodes_with_caps_lock); > > Good catch. > > Reviewed-by: Xiubo Li <xiubli@redhat.com> > > We should CC the stable mail list. Hi Xiubo, What exactly is being fixed here? get_quota_realm() is called with retry=true, which means that no errors can be returned -- EAGAIN, the only error that get_quota_realm() can otherwise generate, would be handled internally by retrying. Am I missing something that makes this qualify for stable? Thanks, Ilya
On 11/15/23 20:32, Ilya Dryomov wrote: > On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >> >> On 11/14/23 23:31, Wenchao Hao wrote: >>> This issue is reported by smatch, get_quota_realm() might return >>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >>> value. >>> >>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>> --- >>> fs/ceph/quota.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>> index 9d36c3532de1..c4b2929c6a83 100644 >>> --- a/fs/ceph/quota.c >>> +++ b/fs/ceph/quota.c >>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) >>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>> QUOTA_GET_MAX_BYTES, true); >>> up_read(&mdsc->snap_rwsem); >>> - if (!realm) >>> + if (IS_ERR_OR_NULL(realm)) >>> return false; >>> >>> spin_lock(&realm->inodes_with_caps_lock); >> Good catch. >> >> Reviewed-by: Xiubo Li <xiubli@redhat.com> >> >> We should CC the stable mail list. > Hi Xiubo, > > What exactly is being fixed here? get_quota_realm() is called with > retry=true, which means that no errors can be returned -- EAGAIN, the > only error that get_quota_realm() can otherwise generate, would be > handled internally by retrying. Yeah, that's true. > Am I missing something that makes this qualify for stable? Actually it's just for the smatch check for now. IMO we shouldn't depend on the 'retry', just potentially for new changes in future could return a ERR_PTR and cause potential bugs. If that's not worth to make it for stable, let's remove it. Thanks - Xiubo > > Thanks, > > Ilya >
On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: > > > On 11/15/23 20:32, Ilya Dryomov wrote: > > On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: > >> > >> On 11/14/23 23:31, Wenchao Hao wrote: > >>> This issue is reported by smatch, get_quota_realm() might return > >>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return > >>> value. > >>> > >>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> > >>> --- > >>> fs/ceph/quota.c | 2 +- > >>> 1 file changed, 1 insertion(+), 1 deletion(-) > >>> > >>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > >>> index 9d36c3532de1..c4b2929c6a83 100644 > >>> --- a/fs/ceph/quota.c > >>> +++ b/fs/ceph/quota.c > >>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) > >>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), > >>> QUOTA_GET_MAX_BYTES, true); > >>> up_read(&mdsc->snap_rwsem); > >>> - if (!realm) > >>> + if (IS_ERR_OR_NULL(realm)) > >>> return false; > >>> > >>> spin_lock(&realm->inodes_with_caps_lock); > >> Good catch. > >> > >> Reviewed-by: Xiubo Li <xiubli@redhat.com> > >> > >> We should CC the stable mail list. > > Hi Xiubo, > > > > What exactly is being fixed here? get_quota_realm() is called with > > retry=true, which means that no errors can be returned -- EAGAIN, the > > only error that get_quota_realm() can otherwise generate, would be > > handled internally by retrying. > > Yeah, that's true. > > > Am I missing something that makes this qualify for stable? > > Actually it's just for the smatch check for now. > > IMO we shouldn't depend on the 'retry', just potentially for new changes > in future could return a ERR_PTR and cause potential bugs. At present, ceph_quota_is_same_realm() also depends on it -- note how old_realm isn't checked for errors at all and new_realm is only checked for EAGAIN there. > > If that's not worth to make it for stable, let's remove it. Yes, let's remove it. Please update the commit message as well, so that it's clear that this is squashing a static checker warning and doesn't actually fix any immediate bug. Thanks, Ilya
On 11/15/23 21:25, Ilya Dryomov wrote: > On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >> >> On 11/15/23 20:32, Ilya Dryomov wrote: >>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>> This issue is reported by smatch, get_quota_realm() might return >>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >>>>> value. >>>>> >>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>> --- >>>>> fs/ceph/quota.c | 2 +- >>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>> >>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>> --- a/fs/ceph/quota.c >>>>> +++ b/fs/ceph/quota.c >>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) >>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>> QUOTA_GET_MAX_BYTES, true); >>>>> up_read(&mdsc->snap_rwsem); >>>>> - if (!realm) >>>>> + if (IS_ERR_OR_NULL(realm)) >>>>> return false; >>>>> >>>>> spin_lock(&realm->inodes_with_caps_lock); >>>> Good catch. >>>> >>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>> >>>> We should CC the stable mail list. >>> Hi Xiubo, >>> >>> What exactly is being fixed here? get_quota_realm() is called with >>> retry=true, which means that no errors can be returned -- EAGAIN, the >>> only error that get_quota_realm() can otherwise generate, would be >>> handled internally by retrying. >> Yeah, that's true. >> >>> Am I missing something that makes this qualify for stable? >> Actually it's just for the smatch check for now. >> >> IMO we shouldn't depend on the 'retry', just potentially for new changes >> in future could return a ERR_PTR and cause potential bugs. > At present, ceph_quota_is_same_realm() also depends on it -- note how > old_realm isn't checked for errors at all and new_realm is only checked > for EAGAIN there. > >> If that's not worth to make it for stable, let's remove it. > Yes, let's remove it. Please update the commit message as well, so > that it's clear that this is squashing a static checker warning and > doesn't actually fix any immediate bug. WenChao, Could update the commit comment and send the V2 ? Thanks - Xiubo > Thanks, > > Ilya >
On 2023/11/15 21:34, Xiubo Li wrote: > > On 11/15/23 21:25, Ilya Dryomov wrote: >> On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >>> >>> On 11/15/23 20:32, Ilya Dryomov wrote: >>>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >>>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>>> This issue is reported by smatch, get_quota_realm() might return >>>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >>>>>> value. >>>>>> >>>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>>> --- >>>>>> fs/ceph/quota.c | 2 +- >>>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>>> >>>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>>> --- a/fs/ceph/quota.c >>>>>> +++ b/fs/ceph/quota.c >>>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) >>>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>>> QUOTA_GET_MAX_BYTES, true); >>>>>> up_read(&mdsc->snap_rwsem); >>>>>> - if (!realm) >>>>>> + if (IS_ERR_OR_NULL(realm)) >>>>>> return false; >>>>>> >>>>>> spin_lock(&realm->inodes_with_caps_lock); >>>>> Good catch. >>>>> >>>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>>> >>>>> We should CC the stable mail list. >>>> Hi Xiubo, >>>> >>>> What exactly is being fixed here? get_quota_realm() is called with >>>> retry=true, which means that no errors can be returned -- EAGAIN, the >>>> only error that get_quota_realm() can otherwise generate, would be >>>> handled internally by retrying. >>> Yeah, that's true. >>> >>>> Am I missing something that makes this qualify for stable? >>> Actually it's just for the smatch check for now. >>> >>> IMO we shouldn't depend on the 'retry', just potentially for new changes >>> in future could return a ERR_PTR and cause potential bugs. >> At present, ceph_quota_is_same_realm() also depends on it -- note how >> old_realm isn't checked for errors at all and new_realm is only checked >> for EAGAIN there. >> >>> If that's not worth to make it for stable, let's remove it. >> Yes, let's remove it. Please update the commit message as well, so >> that it's clear that this is squashing a static checker warning and >> doesn't actually fix any immediate bug. > > WenChao, > > Could update the commit comment and send the V2 ? > OK, I would update the commit comment as following: This issue is reported by smatch, get_quota_realm() might return ERR_PTR. It's not a immediate bug because get_quota_realm() is called with 'retry=true', no errors can be returned. While we still should check the return value of get_quota_realm() with IS_ERR_OR_NULL to avoid potential bugs if get_quota_realm() is changed to return other ERR_PTR in future. What's more, should I change the ceph_quota_is_same_realm() too? Thanks > Thanks > > - Xiubo > > >> Thanks, >> >> Ilya >> >
On 11/16/23 10:54, Wenchao Hao wrote: > On 2023/11/15 21:34, Xiubo Li wrote: >> >> On 11/15/23 21:25, Ilya Dryomov wrote: >>> On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >>>> >>>> On 11/15/23 20:32, Ilya Dryomov wrote: >>>>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >>>>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>>>> This issue is reported by smatch, get_quota_realm() might return >>>>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >>>>>>> value. >>>>>>> >>>>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>>>> --- >>>>>>> fs/ceph/quota.c | 2 +- >>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>>>> >>>>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>>>> --- a/fs/ceph/quota.c >>>>>>> +++ b/fs/ceph/quota.c >>>>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct >>>>>>> ceph_fs_client *fsc, struct kstatfs *buf) >>>>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>>>> QUOTA_GET_MAX_BYTES, true); >>>>>>> up_read(&mdsc->snap_rwsem); >>>>>>> - if (!realm) >>>>>>> + if (IS_ERR_OR_NULL(realm)) >>>>>>> return false; >>>>>>> >>>>>>> spin_lock(&realm->inodes_with_caps_lock); >>>>>> Good catch. >>>>>> >>>>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>>>> >>>>>> We should CC the stable mail list. >>>>> Hi Xiubo, >>>>> >>>>> What exactly is being fixed here? get_quota_realm() is called with >>>>> retry=true, which means that no errors can be returned -- EAGAIN, the >>>>> only error that get_quota_realm() can otherwise generate, would be >>>>> handled internally by retrying. >>>> Yeah, that's true. >>>> >>>>> Am I missing something that makes this qualify for stable? >>>> Actually it's just for the smatch check for now. >>>> >>>> IMO we shouldn't depend on the 'retry', just potentially for new >>>> changes >>>> in future could return a ERR_PTR and cause potential bugs. >>> At present, ceph_quota_is_same_realm() also depends on it -- note how >>> old_realm isn't checked for errors at all and new_realm is only checked >>> for EAGAIN there. >>> >>>> If that's not worth to make it for stable, let's remove it. >>> Yes, let's remove it. Please update the commit message as well, so >>> that it's clear that this is squashing a static checker warning and >>> doesn't actually fix any immediate bug. >> >> WenChao, >> >> Could update the commit comment and send the V2 ? >> > > OK, I would update the commit comment as following: > > This issue is reported by smatch, get_quota_realm() might return > ERR_PTR. It's not a immediate bug because get_quota_realm() is called > with 'retry=true', no errors can be returned. > > While we still should check the return value of get_quota_realm() with > IS_ERR_OR_NULL to avoid potential bugs if get_quota_realm() is changed > to return other ERR_PTR in future. > > What's more, should I change the ceph_quota_is_same_realm() too? > Yeah, please. Let's fix them all. Thanks - Xiubo > Thanks > >> Thanks >> >> - Xiubo >> >> >>> Thanks, >>> >>> Ilya >>> >> >
On 2023/11/16 11:06, Xiubo Li wrote: > > On 11/16/23 10:54, Wenchao Hao wrote: >> On 2023/11/15 21:34, Xiubo Li wrote: >>> >>> On 11/15/23 21:25, Ilya Dryomov wrote: >>>> On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >>>>> >>>>> On 11/15/23 20:32, Ilya Dryomov wrote: >>>>>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >>>>>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>>>>> This issue is reported by smatch, get_quota_realm() might return >>>>>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >>>>>>>> value. >>>>>>>> >>>>>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>>>>> --- >>>>>>>> fs/ceph/quota.c | 2 +- >>>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>>>>> >>>>>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>>>>> --- a/fs/ceph/quota.c >>>>>>>> +++ b/fs/ceph/quota.c >>>>>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) >>>>>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>>>>> QUOTA_GET_MAX_BYTES, true); >>>>>>>> up_read(&mdsc->snap_rwsem); >>>>>>>> - if (!realm) >>>>>>>> + if (IS_ERR_OR_NULL(realm)) >>>>>>>> return false; >>>>>>>> >>>>>>>> spin_lock(&realm->inodes_with_caps_lock); >>>>>>> Good catch. >>>>>>> >>>>>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>>>>> >>>>>>> We should CC the stable mail list. >>>>>> Hi Xiubo, >>>>>> >>>>>> What exactly is being fixed here? get_quota_realm() is called with >>>>>> retry=true, which means that no errors can be returned -- EAGAIN, the >>>>>> only error that get_quota_realm() can otherwise generate, would be >>>>>> handled internally by retrying. >>>>> Yeah, that's true. >>>>> >>>>>> Am I missing something that makes this qualify for stable? >>>>> Actually it's just for the smatch check for now. >>>>> >>>>> IMO we shouldn't depend on the 'retry', just potentially for new changes >>>>> in future could return a ERR_PTR and cause potential bugs. >>>> At present, ceph_quota_is_same_realm() also depends on it -- note how >>>> old_realm isn't checked for errors at all and new_realm is only checked >>>> for EAGAIN there. >>>> >>>>> If that's not worth to make it for stable, let's remove it. >>>> Yes, let's remove it. Please update the commit message as well, so >>>> that it's clear that this is squashing a static checker warning and >>>> doesn't actually fix any immediate bug. >>> >>> WenChao, >>> >>> Could update the commit comment and send the V2 ? >>> >> >> OK, I would update the commit comment as following: >> >> This issue is reported by smatch, get_quota_realm() might return >> ERR_PTR. It's not a immediate bug because get_quota_realm() is called >> with 'retry=true', no errors can be returned. >> >> While we still should check the return value of get_quota_realm() with >> IS_ERR_OR_NULL to avoid potential bugs if get_quota_realm() is changed >> to return other ERR_PTR in future. >> >> What's more, should I change the ceph_quota_is_same_realm() too? >> > Yeah, please. Let's fix them all. > is_same is return as true if both old_realm and new_realm are NULL, I do not want to change the origin logic except add check for ERR_PTR, so following is my change: 1. make sure xxx_realm is valid before calling ceph_put_snap_realm. 2. return false if new_realm or old_realm is ERR_PTR, this is newly added and now we would always run with the else branch. diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c index c4b2929c6a83..8da9ffb05395 100644 --- a/fs/ceph/quota.c +++ b/fs/ceph/quota.c @@ -290,16 +290,20 @@ bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); if (PTR_ERR(new_realm) == -EAGAIN) { up_read(&mdsc->snap_rwsem); - if (old_realm) + if (!IS_ERR_OR_NULL(old_realm)) ceph_put_snap_realm(mdsc, old_realm); goto restart; } - is_same = (old_realm == new_realm); up_read(&mdsc->snap_rwsem); - if (old_realm) + if (IS_ERR(new_realm)) + is_same = false; + else + is_same = (old_realm == new_realm); + + if (!IS_ERR_OR_NULL(old_realm)) ceph_put_snap_realm(mdsc, old_realm); - if (new_realm) + if (!IS_ERR_OR_NULL(new_realm)) ceph_put_snap_realm(mdsc, new_realm); return is_same; > Thanks > > - Xiubo > > >> Thanks >> >>> Thanks >>> >>> - Xiubo >>> >>> >>>> Thanks, >>>> >>>> Ilya >>>> >>> >> > >
On 11/16/23 15:09, Wenchao Hao wrote: > On 2023/11/16 11:06, Xiubo Li wrote: >> >> On 11/16/23 10:54, Wenchao Hao wrote: >>> On 2023/11/15 21:34, Xiubo Li wrote: >>>> >>>> On 11/15/23 21:25, Ilya Dryomov wrote: >>>>> On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >>>>>> >>>>>> On 11/15/23 20:32, Ilya Dryomov wrote: >>>>>>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >>>>>>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>>>>>> This issue is reported by smatch, get_quota_realm() might return >>>>>>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the >>>>>>>>> return >>>>>>>>> value. >>>>>>>>> >>>>>>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>>>>>> --- >>>>>>>>> fs/ceph/quota.c | 2 +- >>>>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>>>>>> >>>>>>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>>>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>>>>>> --- a/fs/ceph/quota.c >>>>>>>>> +++ b/fs/ceph/quota.c >>>>>>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct >>>>>>>>> ceph_fs_client *fsc, struct kstatfs *buf) >>>>>>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>>>>>> QUOTA_GET_MAX_BYTES, true); >>>>>>>>> up_read(&mdsc->snap_rwsem); >>>>>>>>> - if (!realm) >>>>>>>>> + if (IS_ERR_OR_NULL(realm)) >>>>>>>>> return false; >>>>>>>>> >>>>>>>>> spin_lock(&realm->inodes_with_caps_lock); >>>>>>>> Good catch. >>>>>>>> >>>>>>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>>>>>> >>>>>>>> We should CC the stable mail list. >>>>>>> Hi Xiubo, >>>>>>> >>>>>>> What exactly is being fixed here? get_quota_realm() is called with >>>>>>> retry=true, which means that no errors can be returned -- >>>>>>> EAGAIN, the >>>>>>> only error that get_quota_realm() can otherwise generate, would be >>>>>>> handled internally by retrying. >>>>>> Yeah, that's true. >>>>>> >>>>>>> Am I missing something that makes this qualify for stable? >>>>>> Actually it's just for the smatch check for now. >>>>>> >>>>>> IMO we shouldn't depend on the 'retry', just potentially for new >>>>>> changes >>>>>> in future could return a ERR_PTR and cause potential bugs. >>>>> At present, ceph_quota_is_same_realm() also depends on it -- note how >>>>> old_realm isn't checked for errors at all and new_realm is only >>>>> checked >>>>> for EAGAIN there. >>>>> >>>>>> If that's not worth to make it for stable, let's remove it. >>>>> Yes, let's remove it. Please update the commit message as well, so >>>>> that it's clear that this is squashing a static checker warning and >>>>> doesn't actually fix any immediate bug. >>>> >>>> WenChao, >>>> >>>> Could update the commit comment and send the V2 ? >>>> >>> >>> OK, I would update the commit comment as following: >>> >>> This issue is reported by smatch, get_quota_realm() might return >>> ERR_PTR. It's not a immediate bug because get_quota_realm() is called >>> with 'retry=true', no errors can be returned. >>> >>> While we still should check the return value of get_quota_realm() with >>> IS_ERR_OR_NULL to avoid potential bugs if get_quota_realm() is changed >>> to return other ERR_PTR in future. >>> >>> What's more, should I change the ceph_quota_is_same_realm() too? >>> >> Yeah, please. Let's fix them all. >> > > is_same is return as true if both old_realm and new_realm are NULL, I > do not > want to change the origin logic except add check for ERR_PTR, so > following > is my change: > > 1. make sure xxx_realm is valid before calling ceph_put_snap_realm. > 2. return false if new_realm or old_realm is ERR_PTR, this is newly added > and now we would always run with the else branch. > > diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > index c4b2929c6a83..8da9ffb05395 100644 > --- a/fs/ceph/quota.c > +++ b/fs/ceph/quota.c > @@ -290,16 +290,20 @@ bool ceph_quota_is_same_realm(struct inode *old, > struct inode *new) > new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); > if (PTR_ERR(new_realm) == -EAGAIN) { > up_read(&mdsc->snap_rwsem); > - if (old_realm) > + if (!IS_ERR_OR_NULL(old_realm)) > ceph_put_snap_realm(mdsc, old_realm); > goto restart; > } > - is_same = (old_realm == new_realm); > up_read(&mdsc->snap_rwsem); > > - if (old_realm) > + if (IS_ERR(new_realm)) > + is_same = false; > + else > + is_same = (old_realm == new_realm); > + > + if (!IS_ERR_OR_NULL(old_realm)) > ceph_put_snap_realm(mdsc, old_realm); > - if (new_realm) > + if (!IS_ERR_OR_NULL(new_realm)) > ceph_put_snap_realm(mdsc, new_realm); > > return is_same; > If we just to fix the smatch check, how about make get_quota_realm() to return a 'int' type value and at the same time add a 'realmp' parameter ? And just return '-EAGAIN' or '0' always. Then it will be something likes: diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c index c4b2929c6a83..f37f5324b6a1 100644 --- a/fs/ceph/quota.c +++ b/fs/ceph/quota.c @@ -211,10 +211,9 @@ void ceph_cleanup_quotarealms_inodes(struct ceph_mds_client *mdsc) * this function will return -EAGAIN; otherwise, the snaprealms walk-through * will be restarted. */ -static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, - struct inode *inode, - enum quota_get_realm which_quota, - bool retry) +static int get_quota_realm(struct ceph_mds_client *mdsc, struct inode *inode, + enum quota_get_realm which_quota, + struct ceph_snap_realm **realmp, bool retry) { struct ceph_client *cl = mdsc->fsc->client; struct ceph_inode_info *ci = NULL; @@ -222,8 +221,10 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, struct inode *in; bool has_quota; + if (realmp) + *realmp = NULL; if (ceph_snap(inode) != CEPH_NOSNAP) - return NULL; + return 0; restart: realm = ceph_inode(inode)->i_snap_realm; @@ -250,7 +251,7 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, break; ceph_put_snap_realm(mdsc, realm); if (!retry) - return ERR_PTR(-EAGAIN); + return -EAGAIN; goto restart; } @@ -259,8 +260,11 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, iput(in); next = realm->parent; - if (has_quota || !next) - return realm; + if (has_quota || !next) { + if (realmp) + *realmp = realm; + return 0; + } ceph_get_snap_realm(mdsc, next); ceph_put_snap_realm(mdsc, realm); @@ -269,14 +273,15 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, if (realm) ceph_put_snap_realm(mdsc, realm); - return NULL; + return 0; } bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) { struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old->i_sb); - struct ceph_snap_realm *old_realm, *new_realm; + struct ceph_snap_realm *old_realm = NULL, *new_realm = NULL; bool is_same; + int ret; restart: /* @@ -286,9 +291,9 @@ bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) * dropped and we can then restart the whole operation. */ down_read(&mdsc->snap_rwsem); - old_realm = get_quota_realm(mdsc, old, QUOTA_GET_ANY, true); - new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); - if (PTR_ERR(new_realm) == -EAGAIN) { + get_quota_realm(mdsc, old, QUOTA_GET_ANY, &old_relam, true); + ret = get_quota_realm(mdsc, new, QUOTA_GET_ANY, &new_realm, false); + if (ret == -EAGAIN) { up_read(&mdsc->snap_rwsem); if (old_realm) ceph_put_snap_realm(mdsc, old_realm); Won't be this better ? Thanks - Xiubo > >> Thanks >> >> - Xiubo >> >> >>> Thanks >>> >>>> Thanks >>>> >>>> - Xiubo >>>> >>>> >>>>> Thanks, >>>>> >>>>> Ilya >>>>> >>>> >>> >> >> >
On 2023/11/17 14:14, Xiubo Li wrote: > > On 11/16/23 15:09, Wenchao Hao wrote: >> On 2023/11/16 11:06, Xiubo Li wrote: >>> >>> On 11/16/23 10:54, Wenchao Hao wrote: >>>> On 2023/11/15 21:34, Xiubo Li wrote: >>>>> >>>>> On 11/15/23 21:25, Ilya Dryomov wrote: >>>>>> On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >>>>>>> >>>>>>> On 11/15/23 20:32, Ilya Dryomov wrote: >>>>>>>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> wrote: >>>>>>>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>>>>>>> This issue is reported by smatch, get_quota_realm() might return >>>>>>>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return >>>>>>>>>> value. >>>>>>>>>> >>>>>>>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>>>>>>> --- >>>>>>>>>> fs/ceph/quota.c | 2 +- >>>>>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>>>>>>> >>>>>>>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>>>>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>>>>>>> --- a/fs/ceph/quota.c >>>>>>>>>> +++ b/fs/ceph/quota.c >>>>>>>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) >>>>>>>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>>>>>>> QUOTA_GET_MAX_BYTES, true); >>>>>>>>>> up_read(&mdsc->snap_rwsem); >>>>>>>>>> - if (!realm) >>>>>>>>>> + if (IS_ERR_OR_NULL(realm)) >>>>>>>>>> return false; >>>>>>>>>> >>>>>>>>>> spin_lock(&realm->inodes_with_caps_lock); >>>>>>>>> Good catch. >>>>>>>>> >>>>>>>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>>>>>>> >>>>>>>>> We should CC the stable mail list. >>>>>>>> Hi Xiubo, >>>>>>>> >>>>>>>> What exactly is being fixed here? get_quota_realm() is called with >>>>>>>> retry=true, which means that no errors can be returned -- EAGAIN, the >>>>>>>> only error that get_quota_realm() can otherwise generate, would be >>>>>>>> handled internally by retrying. >>>>>>> Yeah, that's true. >>>>>>> >>>>>>>> Am I missing something that makes this qualify for stable? >>>>>>> Actually it's just for the smatch check for now. >>>>>>> >>>>>>> IMO we shouldn't depend on the 'retry', just potentially for new changes >>>>>>> in future could return a ERR_PTR and cause potential bugs. >>>>>> At present, ceph_quota_is_same_realm() also depends on it -- note how >>>>>> old_realm isn't checked for errors at all and new_realm is only checked >>>>>> for EAGAIN there. >>>>>> >>>>>>> If that's not worth to make it for stable, let's remove it. >>>>>> Yes, let's remove it. Please update the commit message as well, so >>>>>> that it's clear that this is squashing a static checker warning and >>>>>> doesn't actually fix any immediate bug. >>>>> >>>>> WenChao, >>>>> >>>>> Could update the commit comment and send the V2 ? >>>>> >>>> >>>> OK, I would update the commit comment as following: >>>> >>>> This issue is reported by smatch, get_quota_realm() might return >>>> ERR_PTR. It's not a immediate bug because get_quota_realm() is called >>>> with 'retry=true', no errors can be returned. >>>> >>>> While we still should check the return value of get_quota_realm() with >>>> IS_ERR_OR_NULL to avoid potential bugs if get_quota_realm() is changed >>>> to return other ERR_PTR in future. >>>> >>>> What's more, should I change the ceph_quota_is_same_realm() too? >>>> >>> Yeah, please. Let's fix them all. >>> >> >> is_same is return as true if both old_realm and new_realm are NULL, I do not >> want to change the origin logic except add check for ERR_PTR, so following >> is my change: >> >> 1. make sure xxx_realm is valid before calling ceph_put_snap_realm. >> 2. return false if new_realm or old_realm is ERR_PTR, this is newly added >> and now we would always run with the else branch. >> >> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >> index c4b2929c6a83..8da9ffb05395 100644 >> --- a/fs/ceph/quota.c >> +++ b/fs/ceph/quota.c >> @@ -290,16 +290,20 @@ bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) >> new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); >> if (PTR_ERR(new_realm) == -EAGAIN) { >> up_read(&mdsc->snap_rwsem); >> - if (old_realm) >> + if (!IS_ERR_OR_NULL(old_realm)) >> ceph_put_snap_realm(mdsc, old_realm); >> goto restart; >> } >> - is_same = (old_realm == new_realm); >> up_read(&mdsc->snap_rwsem); >> >> - if (old_realm) >> + if (IS_ERR(new_realm)) >> + is_same = false; >> + else >> + is_same = (old_realm == new_realm); >> + >> + if (!IS_ERR_OR_NULL(old_realm)) >> ceph_put_snap_realm(mdsc, old_realm); >> - if (new_realm) >> + if (!IS_ERR_OR_NULL(new_realm)) >> ceph_put_snap_realm(mdsc, new_realm); >> >> return is_same; >> > If we just to fix the smatch check, how about make get_quota_realm() to return a 'int' type value and at the same time add a 'realmp' parameter ? And just return '-EAGAIN' or '0' always. > > Then it will be something likes: > > > diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c > index c4b2929c6a83..f37f5324b6a1 100644 > --- a/fs/ceph/quota.c > +++ b/fs/ceph/quota.c > @@ -211,10 +211,9 @@ void ceph_cleanup_quotarealms_inodes(struct ceph_mds_client *mdsc) > * this function will return -EAGAIN; otherwise, the snaprealms walk-through > * will be restarted. > */ > -static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, > - struct inode *inode, > - enum quota_get_realm which_quota, > - bool retry) > +static int get_quota_realm(struct ceph_mds_client *mdsc, struct inode *inode, > + enum quota_get_realm which_quota, > + struct ceph_snap_realm **realmp, bool retry) > { > struct ceph_client *cl = mdsc->fsc->client; > struct ceph_inode_info *ci = NULL; > @@ -222,8 +221,10 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, > struct inode *in; > bool has_quota; > > + if (realmp) > + *realmp = NULL; > if (ceph_snap(inode) != CEPH_NOSNAP) > - return NULL; > + return 0; > > restart: > realm = ceph_inode(inode)->i_snap_realm; > @@ -250,7 +251,7 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, > break; > ceph_put_snap_realm(mdsc, realm); > if (!retry) > - return ERR_PTR(-EAGAIN); > + return -EAGAIN; > goto restart; > } > > @@ -259,8 +260,11 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, > iput(in); > > next = realm->parent; > - if (has_quota || !next) > - return realm; > + if (has_quota || !next) { > + if (realmp) > + *realmp = realm; > + return 0; > + } > > ceph_get_snap_realm(mdsc, next); > ceph_put_snap_realm(mdsc, realm); > @@ -269,14 +273,15 @@ static struct ceph_snap_realm *get_quota_realm(struct ceph_mds_client *mdsc, > if (realm) > ceph_put_snap_realm(mdsc, realm); > > - return NULL; > + return 0; > } > > bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) > { > struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old->i_sb); > - struct ceph_snap_realm *old_realm, *new_realm; > + struct ceph_snap_realm *old_realm = NULL, *new_realm = NULL; > bool is_same; > + int ret; > > restart: > /* > @@ -286,9 +291,9 @@ bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) > * dropped and we can then restart the whole operation. > */ > down_read(&mdsc->snap_rwsem); > - old_realm = get_quota_realm(mdsc, old, QUOTA_GET_ANY, true); > - new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); > - if (PTR_ERR(new_realm) == -EAGAIN) { > + get_quota_realm(mdsc, old, QUOTA_GET_ANY, &old_relam, true); > + ret = get_quota_realm(mdsc, new, QUOTA_GET_ANY, &new_realm, false); > + if (ret == -EAGAIN) { > up_read(&mdsc->snap_rwsem); > if (old_realm) > ceph_put_snap_realm(mdsc, old_realm); > > > Won't be this better ? > Yes, it looks better. Would you post a patch to address it? Or should I apply your changes and send a V2? > Thanks > > - Xiubo > > > > >> >>> Thanks >>> >>> - Xiubo >>> >>> >>>> Thanks >>>> >>>>> Thanks >>>>> >>>>> - Xiubo >>>>> >>>>> >>>>>> Thanks, >>>>>> >>>>>> Ilya >>>>>> >>>>> >>>> >>> >>> >> >
On 11/17/23 16:53, Wenchao Hao wrote: > On 2023/11/17 14:14, Xiubo Li wrote: >> >> On 11/16/23 15:09, Wenchao Hao wrote: >>> On 2023/11/16 11:06, Xiubo Li wrote: >>>> >>>> On 11/16/23 10:54, Wenchao Hao wrote: >>>>> On 2023/11/15 21:34, Xiubo Li wrote: >>>>>> >>>>>> On 11/15/23 21:25, Ilya Dryomov wrote: >>>>>>> On Wed, Nov 15, 2023 at 2:17 PM Xiubo Li <xiubli@redhat.com> wrote: >>>>>>>> >>>>>>>> On 11/15/23 20:32, Ilya Dryomov wrote: >>>>>>>>> On Wed, Nov 15, 2023 at 1:35 AM Xiubo Li <xiubli@redhat.com> >>>>>>>>> wrote: >>>>>>>>>> On 11/14/23 23:31, Wenchao Hao wrote: >>>>>>>>>>> This issue is reported by smatch, get_quota_realm() might >>>>>>>>>>> return >>>>>>>>>>> ERR_PTR, so we should using IS_ERR_OR_NULL here to check the >>>>>>>>>>> return >>>>>>>>>>> value. >>>>>>>>>>> >>>>>>>>>>> Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> >>>>>>>>>>> --- >>>>>>>>>>> fs/ceph/quota.c | 2 +- >>>>>>>>>>> 1 file changed, 1 insertion(+), 1 deletion(-) >>>>>>>>>>> >>>>>>>>>>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>>>>>>>>>> index 9d36c3532de1..c4b2929c6a83 100644 >>>>>>>>>>> --- a/fs/ceph/quota.c >>>>>>>>>>> +++ b/fs/ceph/quota.c >>>>>>>>>>> @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct >>>>>>>>>>> ceph_fs_client *fsc, struct kstatfs *buf) >>>>>>>>>>> realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), >>>>>>>>>>> QUOTA_GET_MAX_BYTES, true); >>>>>>>>>>> up_read(&mdsc->snap_rwsem); >>>>>>>>>>> - if (!realm) >>>>>>>>>>> + if (IS_ERR_OR_NULL(realm)) >>>>>>>>>>> return false; >>>>>>>>>>> >>>>>>>>>>> spin_lock(&realm->inodes_with_caps_lock); >>>>>>>>>> Good catch. >>>>>>>>>> >>>>>>>>>> Reviewed-by: Xiubo Li <xiubli@redhat.com> >>>>>>>>>> >>>>>>>>>> We should CC the stable mail list. >>>>>>>>> Hi Xiubo, >>>>>>>>> >>>>>>>>> What exactly is being fixed here? get_quota_realm() is called >>>>>>>>> with >>>>>>>>> retry=true, which means that no errors can be returned -- >>>>>>>>> EAGAIN, the >>>>>>>>> only error that get_quota_realm() can otherwise generate, >>>>>>>>> would be >>>>>>>>> handled internally by retrying. >>>>>>>> Yeah, that's true. >>>>>>>> >>>>>>>>> Am I missing something that makes this qualify for stable? >>>>>>>> Actually it's just for the smatch check for now. >>>>>>>> >>>>>>>> IMO we shouldn't depend on the 'retry', just potentially for >>>>>>>> new changes >>>>>>>> in future could return a ERR_PTR and cause potential bugs. >>>>>>> At present, ceph_quota_is_same_realm() also depends on it -- >>>>>>> note how >>>>>>> old_realm isn't checked for errors at all and new_realm is only >>>>>>> checked >>>>>>> for EAGAIN there. >>>>>>> >>>>>>>> If that's not worth to make it for stable, let's remove it. >>>>>>> Yes, let's remove it. Please update the commit message as well, so >>>>>>> that it's clear that this is squashing a static checker warning and >>>>>>> doesn't actually fix any immediate bug. >>>>>> >>>>>> WenChao, >>>>>> >>>>>> Could update the commit comment and send the V2 ? >>>>>> >>>>> >>>>> OK, I would update the commit comment as following: >>>>> >>>>> This issue is reported by smatch, get_quota_realm() might return >>>>> ERR_PTR. It's not a immediate bug because get_quota_realm() is called >>>>> with 'retry=true', no errors can be returned. >>>>> >>>>> While we still should check the return value of get_quota_realm() >>>>> with >>>>> IS_ERR_OR_NULL to avoid potential bugs if get_quota_realm() is >>>>> changed >>>>> to return other ERR_PTR in future. >>>>> >>>>> What's more, should I change the ceph_quota_is_same_realm() too? >>>>> >>>> Yeah, please. Let's fix them all. >>>> >>> >>> is_same is return as true if both old_realm and new_realm are NULL, >>> I do not >>> want to change the origin logic except add check for ERR_PTR, so >>> following >>> is my change: >>> >>> 1. make sure xxx_realm is valid before calling ceph_put_snap_realm. >>> 2. return false if new_realm or old_realm is ERR_PTR, this is newly >>> added >>> and now we would always run with the else branch. >>> >>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >>> index c4b2929c6a83..8da9ffb05395 100644 >>> --- a/fs/ceph/quota.c >>> +++ b/fs/ceph/quota.c >>> @@ -290,16 +290,20 @@ bool ceph_quota_is_same_realm(struct inode >>> *old, struct inode *new) >>> new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); >>> if (PTR_ERR(new_realm) == -EAGAIN) { >>> up_read(&mdsc->snap_rwsem); >>> - if (old_realm) >>> + if (!IS_ERR_OR_NULL(old_realm)) >>> ceph_put_snap_realm(mdsc, old_realm); >>> goto restart; >>> } >>> - is_same = (old_realm == new_realm); >>> up_read(&mdsc->snap_rwsem); >>> >>> - if (old_realm) >>> + if (IS_ERR(new_realm)) >>> + is_same = false; >>> + else >>> + is_same = (old_realm == new_realm); >>> + >>> + if (!IS_ERR_OR_NULL(old_realm)) >>> ceph_put_snap_realm(mdsc, old_realm); >>> - if (new_realm) >>> + if (!IS_ERR_OR_NULL(new_realm)) >>> ceph_put_snap_realm(mdsc, new_realm); >>> >>> return is_same; >>> >> If we just to fix the smatch check, how about make get_quota_realm() >> to return a 'int' type value and at the same time add a 'realmp' >> parameter ? And just return '-EAGAIN' or '0' always. >> >> Then it will be something likes: >> >> >> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c >> index c4b2929c6a83..f37f5324b6a1 100644 >> --- a/fs/ceph/quota.c >> +++ b/fs/ceph/quota.c >> @@ -211,10 +211,9 @@ void ceph_cleanup_quotarealms_inodes(struct >> ceph_mds_client *mdsc) >> * this function will return -EAGAIN; otherwise, the snaprealms >> walk-through >> * will be restarted. >> */ >> -static struct ceph_snap_realm *get_quota_realm(struct >> ceph_mds_client *mdsc, >> - struct inode *inode, >> - enum quota_get_realm >> which_quota, >> - bool retry) >> +static int get_quota_realm(struct ceph_mds_client *mdsc, struct >> inode *inode, >> + enum quota_get_realm which_quota, >> + struct ceph_snap_realm **realmp, bool retry) >> { >> struct ceph_client *cl = mdsc->fsc->client; >> struct ceph_inode_info *ci = NULL; >> @@ -222,8 +221,10 @@ static struct ceph_snap_realm >> *get_quota_realm(struct ceph_mds_client *mdsc, >> struct inode *in; >> bool has_quota; >> >> + if (realmp) >> + *realmp = NULL; >> if (ceph_snap(inode) != CEPH_NOSNAP) >> - return NULL; >> + return 0; >> >> restart: >> realm = ceph_inode(inode)->i_snap_realm; >> @@ -250,7 +251,7 @@ static struct ceph_snap_realm >> *get_quota_realm(struct ceph_mds_client *mdsc, >> break; >> ceph_put_snap_realm(mdsc, realm); >> if (!retry) >> - return ERR_PTR(-EAGAIN); >> + return -EAGAIN; >> goto restart; >> } >> >> @@ -259,8 +260,11 @@ static struct ceph_snap_realm >> *get_quota_realm(struct ceph_mds_client *mdsc, >> iput(in); >> >> next = realm->parent; >> - if (has_quota || !next) >> - return realm; >> + if (has_quota || !next) { >> + if (realmp) >> + *realmp = realm; >> + return 0; >> + } >> >> ceph_get_snap_realm(mdsc, next); >> ceph_put_snap_realm(mdsc, realm); >> @@ -269,14 +273,15 @@ static struct ceph_snap_realm >> *get_quota_realm(struct ceph_mds_client *mdsc, >> if (realm) >> ceph_put_snap_realm(mdsc, realm); >> >> - return NULL; >> + return 0; >> } >> >> bool ceph_quota_is_same_realm(struct inode *old, struct inode *new) >> { >> struct ceph_mds_client *mdsc = ceph_sb_to_mdsc(old->i_sb); >> - struct ceph_snap_realm *old_realm, *new_realm; >> + struct ceph_snap_realm *old_realm = NULL, *new_realm = NULL; >> bool is_same; >> + int ret; >> >> restart: >> /* >> @@ -286,9 +291,9 @@ bool ceph_quota_is_same_realm(struct inode *old, >> struct inode *new) >> * dropped and we can then restart the whole operation. >> */ >> down_read(&mdsc->snap_rwsem); >> - old_realm = get_quota_realm(mdsc, old, QUOTA_GET_ANY, true); >> - new_realm = get_quota_realm(mdsc, new, QUOTA_GET_ANY, false); >> - if (PTR_ERR(new_realm) == -EAGAIN) { >> + get_quota_realm(mdsc, old, QUOTA_GET_ANY, &old_relam, true); >> + ret = get_quota_realm(mdsc, new, QUOTA_GET_ANY, &new_realm, >> false); >> + if (ret == -EAGAIN) { >> up_read(&mdsc->snap_rwsem); >> if (old_realm) >> ceph_put_snap_realm(mdsc, old_realm); >> >> >> Won't be this better ? >> > > Yes, it looks better. > > Would you post a patch to address it? Or should I apply your changes and > send a V2? > The above just a draft patch. Please send a V2 for it and I will review and test it. Thanks - Xiubo >> Thanks >> >> - Xiubo >> >> >> >> >>> >>>> Thanks >>>> >>>> - Xiubo >>>> >>>> >>>>> Thanks >>>>> >>>>>> Thanks >>>>>> >>>>>> - Xiubo >>>>>> >>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> Ilya >>>>>>> >>>>>> >>>>> >>>> >>>> >>> >> >
diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c index 9d36c3532de1..c4b2929c6a83 100644 --- a/fs/ceph/quota.c +++ b/fs/ceph/quota.c @@ -495,7 +495,7 @@ bool ceph_quota_update_statfs(struct ceph_fs_client *fsc, struct kstatfs *buf) realm = get_quota_realm(mdsc, d_inode(fsc->sb->s_root), QUOTA_GET_MAX_BYTES, true); up_read(&mdsc->snap_rwsem); - if (!realm) + if (IS_ERR_OR_NULL(realm)) return false; spin_lock(&realm->inodes_with_caps_lock);
This issue is reported by smatch, get_quota_realm() might return ERR_PTR, so we should using IS_ERR_OR_NULL here to check the return value. Signed-off-by: Wenchao Hao <haowenchao2@huawei.com> --- fs/ceph/quota.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)