* [PATCH 1/1] ceph: Deletion of unnecessary checks before two function calls [not found] ` <5317A59D.4@users.sourceforge.net> @ 2014-11-02 14:20 ` SF Markus Elfring 2014-11-03 10:35 ` Ilya Dryomov 2014-12-01 10:23 ` [PATCH 1/1] block-rbd: Delete a check before ceph_put_snap_context() SF Markus Elfring 2015-11-23 19:40 ` [PATCH 0/2] block-rbd: Deletion of an unnecessary check SF Markus Elfring 2 siblings, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2014-11-02 14:20 UTC (permalink / raw) To: Sage Weil, ceph-devel; +Cc: linux-kernel, kernel-janitors, trivial, Coccinelle The functions ceph_put_snap_context() and iput() test whether their argument is NULL and then return immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> --- fs/ceph/caps.c | 3 +-- fs/ceph/mds_client.c | 6 ++---- fs/ceph/snap.c | 9 +++------ 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 6d1cd45..7d99fc8 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -3136,8 +3136,7 @@ flush_cap_releases: done: mutex_unlock(&session->s_mutex); done_unlocked: - if (inode) - iput(inode); + iput(inode); return; bad: diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index bad07c0..3b0ab05 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -523,8 +523,7 @@ void ceph_mdsc_release_request(struct kref *kref) } if (req->r_locked_dir) ceph_put_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN); - if (req->r_target_inode) - iput(req->r_target_inode); + iput(req->r_target_inode); if (req->r_dentry) dput(req->r_dentry); if (req->r_old_dentry) @@ -995,8 +994,7 @@ out: session->s_cap_iterator = NULL; spin_unlock(&session->s_cap_lock); - if (last_inode) - iput(last_inode); + iput(last_inode); if (old_cap) ceph_put_cap(session->s_mdsc, old_cap); diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c index f01645a..c1cc993 100644 --- a/fs/ceph/snap.c +++ b/fs/ceph/snap.c @@ -365,8 +365,7 @@ static int build_snap_context(struct ceph_snap_realm *realm) realm->ino, realm, snapc, snapc->seq, (unsigned int) snapc->num_snaps); - if (realm->cached_context) - ceph_put_snap_context(realm->cached_context); + ceph_put_snap_context(realm->cached_context); realm->cached_context = snapc; return 0; @@ -590,15 +589,13 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm *realm) if (!inode) continue; spin_unlock(&realm->inodes_with_caps_lock); - if (lastinode) - iput(lastinode); + iput(lastinode); lastinode = inode; ceph_queue_cap_snap(ci); spin_lock(&realm->inodes_with_caps_lock); } spin_unlock(&realm->inodes_with_caps_lock); - if (lastinode) - iput(lastinode); + iput(lastinode); list_for_each_entry(child, &realm->children, child_item) { dout("queue_realm_cap_snaps %p %llx queue child %p %llx\n", -- 2.1.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/1] ceph: Deletion of unnecessary checks before two function calls 2014-11-02 14:20 ` [PATCH 1/1] ceph: Deletion of unnecessary checks before two function calls SF Markus Elfring @ 2014-11-03 10:35 ` Ilya Dryomov 2014-11-03 13:27 ` SF Markus Elfring 0 siblings, 1 reply; 22+ messages in thread From: Ilya Dryomov @ 2014-11-03 10:35 UTC (permalink / raw) To: SF Markus Elfring Cc: Sage Weil, Ceph Development, Linux Kernel Mailing List, kernel-janitors, trivial, Coccinelle, Yan, Zheng On Sun, Nov 2, 2014 at 5:20 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: > The functions ceph_put_snap_context() and iput() test whether their argument > is NULL and then return immediately. Thus the test around the call > is not needed. > > This issue was detected by using the Coccinelle software. > > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> > --- > fs/ceph/caps.c | 3 +-- > fs/ceph/mds_client.c | 6 ++---- > fs/ceph/snap.c | 9 +++------ > 3 files changed, 6 insertions(+), 12 deletions(-) [CC'ed Zheng] Applied, but see below. > > diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c > index 6d1cd45..7d99fc8 100644 > --- a/fs/ceph/caps.c > +++ b/fs/ceph/caps.c > @@ -3136,8 +3136,7 @@ flush_cap_releases: > done: > mutex_unlock(&session->s_mutex); > done_unlocked: > - if (inode) > - iput(inode); > + iput(inode); > return; > > bad: > diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c > index bad07c0..3b0ab05 100644 > --- a/fs/ceph/mds_client.c > +++ b/fs/ceph/mds_client.c > @@ -523,8 +523,7 @@ void ceph_mdsc_release_request(struct kref *kref) > } > if (req->r_locked_dir) > ceph_put_cap_refs(ceph_inode(req->r_locked_dir), CEPH_CAP_PIN); > - if (req->r_target_inode) > - iput(req->r_target_inode); > + iput(req->r_target_inode); > if (req->r_dentry) > dput(req->r_dentry); dput() also checks for NULL argument, but the check is wrapped into unlikely(), which is why I presume it wasn't picked up. It would be great if you could improve your coccinelle script to handle {un,}likely() as well. > if (req->r_old_dentry) > @@ -995,8 +994,7 @@ out: > session->s_cap_iterator = NULL; > spin_unlock(&session->s_cap_lock); > > - if (last_inode) > - iput(last_inode); > + iput(last_inode); > if (old_cap) > ceph_put_cap(session->s_mdsc, old_cap); > > diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c > index f01645a..c1cc993 100644 > --- a/fs/ceph/snap.c > +++ b/fs/ceph/snap.c > @@ -365,8 +365,7 @@ static int build_snap_context(struct ceph_snap_realm *realm) > realm->ino, realm, snapc, snapc->seq, > (unsigned int) snapc->num_snaps); > > - if (realm->cached_context) > - ceph_put_snap_context(realm->cached_context); > + ceph_put_snap_context(realm->cached_context); > realm->cached_context = snapc; > return 0; > > @@ -590,15 +589,13 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm > *realm) The patch was corrupted, that should have been a single line. I fixed it up but you may want to look into your email client settings. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: ceph: Deletion of unnecessary checks before two function calls 2014-11-03 10:35 ` Ilya Dryomov @ 2014-11-03 13:27 ` SF Markus Elfring 2014-11-03 14:23 ` Ilya Dryomov 0 siblings, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2014-11-03 13:27 UTC (permalink / raw) To: Ilya Dryomov Cc: Sage Weil, Ceph Development, Linux Kernel Mailing List, kernel-janitors, trivial, Coccinelle, Yan, Zheng > dput() also checks for NULL argument, but the check is wrapped into > unlikely(), which is why I presume it wasn't picked up. It would be > great if you could improve your coccinelle script to handle > {un,}likely() as well. Thanks for your suggestion. Should I consider any more fine-tuning for the affected script "list_input_parameter_validation1.cocci" in the near future? https://lkml.org/lkml/2014/3/5/362 http://article.gmane.org/gmane.comp.version-control.coccinelle/3514 >> @@ -590,15 +589,13 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm >> *realm) > > The patch was corrupted, that should have been a single line. I fixed > it up but you may want to look into your email client settings. Thanks for your feedback. Does this example show a conflict between long comments after patch ranges and line length limitation for email eventually? Regards, Markus ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: ceph: Deletion of unnecessary checks before two function calls 2014-11-03 13:27 ` SF Markus Elfring @ 2014-11-03 14:23 ` Ilya Dryomov 0 siblings, 0 replies; 22+ messages in thread From: Ilya Dryomov @ 2014-11-03 14:23 UTC (permalink / raw) To: SF Markus Elfring Cc: Sage Weil, Ceph Development, Linux Kernel Mailing List, kernel-janitors, trivial, Coccinelle, Yan, Zheng On Mon, Nov 3, 2014 at 4:27 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: >> dput() also checks for NULL argument, but the check is wrapped into >> unlikely(), which is why I presume it wasn't picked up. It would be >> great if you could improve your coccinelle script to handle >> {un,}likely() as well. > > Thanks for your suggestion. > > Should I consider any more fine-tuning for the affected script > "list_input_parameter_validation1.cocci" in the near future? > https://lkml.org/lkml/2014/3/5/362 > http://article.gmane.org/gmane.comp.version-control.coccinelle/3514 Make sure it at least catches stuff like: { if (input) { } } { if (likely(input)) { } } { if (!input) return; ... } { if (unlikely(!input)) return; ... } And of course each match then has to be validated manually. > > >>> @@ -590,15 +589,13 @@ static void queue_realm_cap_snaps(struct ceph_snap_realm >>> *realm) >> >> The patch was corrupted, that should have been a single line. I fixed >> it up but you may want to look into your email client settings. > > Thanks for your feedback. > > Does this example show a conflict between long comments after patch ranges and > line length limitation for email eventually? There is no line length limitation for email, at least one that would be relevant here. Patches should be sent verbatim, no line wrapping, expandtab, etc or they won't apply. I'd recommend git-send-email, but if you want to make thunderbird work for patches (which is what you seem to be using) have a look at the "Thunderbird (GUI)" section of Documentation/email-clients.txt in the kernel tree. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/1] block-rbd: Delete a check before ceph_put_snap_context() [not found] ` <5317A59D.4@users.sourceforge.net> 2014-11-02 14:20 ` [PATCH 1/1] ceph: Deletion of unnecessary checks before two function calls SF Markus Elfring @ 2014-12-01 10:23 ` SF Markus Elfring 2014-12-01 11:57 ` Ilya Dryomov 2015-11-23 19:40 ` [PATCH 0/2] block-rbd: Deletion of an unnecessary check SF Markus Elfring 2 siblings, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2014-12-01 10:23 UTC (permalink / raw) To: Alex Elder, Sage Weil, Yehuda Sadeh, Ceph Cc: LKML, kernel-janitors, Julia Lawall From: Markus Elfring <elfring@users.sourceforge.net> Date: Mon, 1 Dec 2014 11:18:21 +0100 The ceph_put_snap_context() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> --- drivers/block/rbd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 27b71a0..3c34ab5 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -3405,8 +3405,7 @@ err_rq: if (result) rbd_warn(rbd_dev, "%s %llx at %llx result %d", obj_op_name(op_type), length, offset, result); - if (snapc) - ceph_put_snap_context(snapc); + ceph_put_snap_context(snapc); blk_end_request_all(rq, result); } -- 2.1.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/1] block-rbd: Delete a check before ceph_put_snap_context() 2014-12-01 10:23 ` [PATCH 1/1] block-rbd: Delete a check before ceph_put_snap_context() SF Markus Elfring @ 2014-12-01 11:57 ` Ilya Dryomov 0 siblings, 0 replies; 22+ messages in thread From: Ilya Dryomov @ 2014-12-01 11:57 UTC (permalink / raw) To: SF Markus Elfring Cc: Alex Elder, Sage Weil, Yehuda Sadeh, Ceph, LKML, kernel-janitors, Julia Lawall On Mon, Dec 1, 2014 at 1:23 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: > From: Markus Elfring <elfring@users.sourceforge.net> > Date: Mon, 1 Dec 2014 11:18:21 +0100 > > The ceph_put_snap_context() function tests whether its argument is NULL > and then returns immediately. Thus the test around the call is not needed. > > This issue was detected by using the Coccinelle software. > > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> > --- > drivers/block/rbd.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c > index 27b71a0..3c34ab5 100644 > --- a/drivers/block/rbd.c > +++ b/drivers/block/rbd.c > @@ -3405,8 +3405,7 @@ err_rq: > if (result) > rbd_warn(rbd_dev, "%s %llx at %llx result %d", > obj_op_name(op_type), length, offset, result); > - if (snapc) > - ceph_put_snap_context(snapc); > + ceph_put_snap_context(snapc); > blk_end_request_all(rq, result); > } > I squashed it into your "ceph: Deletion of unnecessary checks before two function calls", which deals with ceph_put_snap_context() in fs/ceph. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 0/2] block-rbd: Deletion of an unnecessary check [not found] ` <5317A59D.4@users.sourceforge.net> 2014-11-02 14:20 ` [PATCH 1/1] ceph: Deletion of unnecessary checks before two function calls SF Markus Elfring 2014-12-01 10:23 ` [PATCH 1/1] block-rbd: Delete a check before ceph_put_snap_context() SF Markus Elfring @ 2015-11-23 19:40 ` SF Markus Elfring 2015-11-23 19:44 ` [PATCH 1/2] block-rbd: Delete an unnecessary check before the function call "rbd_dev_destroy" SF Markus Elfring 2015-11-23 19:46 ` [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection SF Markus Elfring 2 siblings, 2 replies; 22+ messages in thread From: SF Markus Elfring @ 2015-11-23 19:40 UTC (permalink / raw) To: Alex Elder, Ilya Dryomov, Sage Weil, ceph-devel Cc: LKML, kernel-janitors, Julia Lawall From: Markus Elfring <elfring@users.sourceforge.net> Date: Mon, 23 Nov 2015 20:33:59 +0100 Another update suggestion was taken into account after a patch was applied from static source code analysis. Markus Elfring (2): Delete an unnecessary check before the function call "rbd_dev_destroy" One function call less in rbd_dev_probe_parent() after error detection drivers/block/rbd.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) -- 2.6.3 ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 1/2] block-rbd: Delete an unnecessary check before the function call "rbd_dev_destroy" 2015-11-23 19:40 ` [PATCH 0/2] block-rbd: Deletion of an unnecessary check SF Markus Elfring @ 2015-11-23 19:44 ` SF Markus Elfring 2015-11-24 13:20 ` Ilya Dryomov 2015-11-23 19:46 ` [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection SF Markus Elfring 1 sibling, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2015-11-23 19:44 UTC (permalink / raw) To: Alex Elder, Ilya Dryomov, Sage Weil, ceph-devel Cc: LKML, kernel-janitors, Julia Lawall From: Markus Elfring <elfring@users.sourceforge.net> Date: Mon, 23 Nov 2015 20:16:45 +0100 The rbd_dev_destroy() function tests whether its argument is NULL and then returns immediately. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> --- drivers/block/rbd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 235708c..24a757e 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -5184,8 +5184,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) out_err: rbd_dev_unparent(rbd_dev); - if (parent) - rbd_dev_destroy(parent); + rbd_dev_destroy(parent); return ret; } -- 2.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 1/2] block-rbd: Delete an unnecessary check before the function call "rbd_dev_destroy" 2015-11-23 19:44 ` [PATCH 1/2] block-rbd: Delete an unnecessary check before the function call "rbd_dev_destroy" SF Markus Elfring @ 2015-11-24 13:20 ` Ilya Dryomov 0 siblings, 0 replies; 22+ messages in thread From: Ilya Dryomov @ 2015-11-24 13:20 UTC (permalink / raw) To: SF Markus Elfring Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Mon, Nov 23, 2015 at 8:44 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: > From: Markus Elfring <elfring@users.sourceforge.net> > Date: Mon, 23 Nov 2015 20:16:45 +0100 > > The rbd_dev_destroy() function tests whether its argument is NULL > and then returns immediately. Thus the test around the call is not needed. > > This issue was detected by using the Coccinelle software. > > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> > --- > drivers/block/rbd.c | 3 +-- > 1 file changed, 1 insertion(+), 2 deletions(-) > > diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c > index 235708c..24a757e 100644 > --- a/drivers/block/rbd.c > +++ b/drivers/block/rbd.c > @@ -5184,8 +5184,7 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) > > out_err: > rbd_dev_unparent(rbd_dev); > - if (parent) > - rbd_dev_destroy(parent); > + rbd_dev_destroy(parent); > return ret; > } Applied, see https://github.com/ceph/ceph-client/commit/b0098c3eadd33fa212987dab0529e35c948aaff4. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-23 19:40 ` [PATCH 0/2] block-rbd: Deletion of an unnecessary check SF Markus Elfring 2015-11-23 19:44 ` [PATCH 1/2] block-rbd: Delete an unnecessary check before the function call "rbd_dev_destroy" SF Markus Elfring @ 2015-11-23 19:46 ` SF Markus Elfring 2015-11-24 13:21 ` Ilya Dryomov 1 sibling, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2015-11-23 19:46 UTC (permalink / raw) To: Alex Elder, Ilya Dryomov, Sage Weil, ceph-devel Cc: LKML, kernel-janitors, Julia Lawall From: Markus Elfring <elfring@users.sourceforge.net> Date: Mon, 23 Nov 2015 20:22:41 +0100 The rbd_dev_destroy() function was called in two cases by the rbd_dev_probe_parent() function during error handling even if the passed variable contained a null pointer. * This implementation detail could be improved by adjustments for jump targets according to the Linux coding style convention. * Drop an unnecessary initialisation for the variable "parent" then. Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> --- drivers/block/rbd.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 24a757e..2ad9092 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -5148,7 +5148,7 @@ out_err: */ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) { - struct rbd_device *parent = NULL; + struct rbd_device *parent; int ret; if (!rbd_dev->parent_spec) @@ -5157,14 +5157,14 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) if (++depth > RBD_MAX_PARENT_CHAIN_LEN) { pr_info("parent chain is too long (%d)\n", depth); ret = -EINVAL; - goto out_err; + goto unparent_device; } parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec, NULL); if (!parent) { ret = -ENOMEM; - goto out_err; + goto unparent_device; } /* @@ -5176,15 +5176,15 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) ret = rbd_dev_image_probe(parent, depth); if (ret < 0) - goto out_err; + goto destroy_device; rbd_dev->parent = parent; atomic_set(&rbd_dev->parent_ref, 1); return 0; - -out_err: - rbd_dev_unparent(rbd_dev); +destroy_device: rbd_dev_destroy(parent); +unparent_device: + rbd_dev_unparent(rbd_dev); return ret; } -- 2.6.3 ^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-23 19:46 ` [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection SF Markus Elfring @ 2015-11-24 13:21 ` Ilya Dryomov 2015-11-24 19:23 ` SF Markus Elfring 0 siblings, 1 reply; 22+ messages in thread From: Ilya Dryomov @ 2015-11-24 13:21 UTC (permalink / raw) To: SF Markus Elfring Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Mon, Nov 23, 2015 at 8:46 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: > From: Markus Elfring <elfring@users.sourceforge.net> > Date: Mon, 23 Nov 2015 20:22:41 +0100 > > The rbd_dev_destroy() function was called in two cases by the > rbd_dev_probe_parent() function during error handling even if > the passed variable contained a null pointer. > > * This implementation detail could be improved by adjustments > for jump targets according to the Linux coding style convention. > > * Drop an unnecessary initialisation for the variable "parent" then. > > Signed-off-by: Markus Elfring <elfring@users.sourceforge.net> > --- > drivers/block/rbd.c | 14 +++++++------- > 1 file changed, 7 insertions(+), 7 deletions(-) > > diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c > index 24a757e..2ad9092 100644 > --- a/drivers/block/rbd.c > +++ b/drivers/block/rbd.c > @@ -5148,7 +5148,7 @@ out_err: > */ > static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) > { > - struct rbd_device *parent = NULL; > + struct rbd_device *parent; > int ret; > > if (!rbd_dev->parent_spec) > @@ -5157,14 +5157,14 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) > if (++depth > RBD_MAX_PARENT_CHAIN_LEN) { > pr_info("parent chain is too long (%d)\n", depth); > ret = -EINVAL; > - goto out_err; > + goto unparent_device; > } > > parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec, > NULL); > if (!parent) { > ret = -ENOMEM; > - goto out_err; > + goto unparent_device; > } > > /* > @@ -5176,15 +5176,15 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) > > ret = rbd_dev_image_probe(parent, depth); > if (ret < 0) > - goto out_err; > + goto destroy_device; > > rbd_dev->parent = parent; > atomic_set(&rbd_dev->parent_ref, 1); > return 0; > - > -out_err: > - rbd_dev_unparent(rbd_dev); > +destroy_device: > rbd_dev_destroy(parent); > +unparent_device: > + rbd_dev_unparent(rbd_dev); > return ret; > } Cleanup here is (and should be) done in reverse order. We allocate parent rbd_device and then link it with what we already have, so the order in which we cleanup is unlink ("unparent"), destroy. Changing it is just asking for use-after-free bugs. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 13:21 ` Ilya Dryomov @ 2015-11-24 19:23 ` SF Markus Elfring 2015-11-24 20:21 ` Ilya Dryomov 0 siblings, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2015-11-24 19:23 UTC (permalink / raw) To: Ilya Dryomov Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall >> @@ -5157,14 +5157,14 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) >> if (++depth > RBD_MAX_PARENT_CHAIN_LEN) { >> pr_info("parent chain is too long (%d)\n", depth); >> ret = -EINVAL; >> - goto out_err; >> + goto unparent_device; >> } >> >> parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec, >> NULL); >> if (!parent) { >> ret = -ENOMEM; >> - goto out_err; >> + goto unparent_device; >> } >> >> /* >> @@ -5176,15 +5176,15 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) >> >> ret = rbd_dev_image_probe(parent, depth); >> if (ret < 0) >> - goto out_err; >> + goto destroy_device; >> >> rbd_dev->parent = parent; >> atomic_set(&rbd_dev->parent_ref, 1); >> return 0; >> - >> -out_err: >> - rbd_dev_unparent(rbd_dev); >> +destroy_device: >> rbd_dev_destroy(parent); >> +unparent_device: >> + rbd_dev_unparent(rbd_dev); >> return ret; >> } > > Cleanup here is (and should be) done in reverse order. I have got an other impression about the appropriate order for the corresponding clean-up function calls. > We allocate parent rbd_device and then link it with what we already have, I guess that we have got a different understanding about the relevant "linking". > so the order in which we cleanup is unlink ("unparent"), destroy. I interpreted the eventual passing of a null pointer to the rbd_dev_destroy() function as an indication for further source code adjustments. > Changing it is just asking for use-after-free bugs. Do the affected implementation details need a bit more clarification? Regards, Markus ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 19:23 ` SF Markus Elfring @ 2015-11-24 20:21 ` Ilya Dryomov 2015-11-24 20:34 ` SF Markus Elfring ` (2 more replies) 0 siblings, 3 replies; 22+ messages in thread From: Ilya Dryomov @ 2015-11-24 20:21 UTC (permalink / raw) To: SF Markus Elfring Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Tue, Nov 24, 2015 at 8:23 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: >>> @@ -5157,14 +5157,14 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) >>> if (++depth > RBD_MAX_PARENT_CHAIN_LEN) { >>> pr_info("parent chain is too long (%d)\n", depth); >>> ret = -EINVAL; >>> - goto out_err; >>> + goto unparent_device; >>> } >>> >>> parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec, >>> NULL); >>> if (!parent) { >>> ret = -ENOMEM; >>> - goto out_err; >>> + goto unparent_device; >>> } >>> >>> /* >>> @@ -5176,15 +5176,15 @@ static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) >>> >>> ret = rbd_dev_image_probe(parent, depth); >>> if (ret < 0) >>> - goto out_err; >>> + goto destroy_device; >>> >>> rbd_dev->parent = parent; >>> atomic_set(&rbd_dev->parent_ref, 1); >>> return 0; >>> - >>> -out_err: >>> - rbd_dev_unparent(rbd_dev); >>> +destroy_device: >>> rbd_dev_destroy(parent); >>> +unparent_device: >>> + rbd_dev_unparent(rbd_dev); >>> return ret; >>> } >> >> Cleanup here is (and should be) done in reverse order. > > I have got an other impression about the appropriate order for the corresponding > clean-up function calls. > > >> We allocate parent rbd_device and then link it with what we already have, > > I guess that we have got a different understanding about the relevant "linking". Well, there isn't any _literal_ linking (e.g. adding to a link list, etc) in this case. We just bump some refs and do probe to fill in the newly allocated parent. If probe fails, we put refs and free parent, reversing the "alloc parent, bump refs" order. The actual linking (rbd_dev->parent = parent) is done right before returning so we never have to undo it in rbd_dev_probe_parent() and that's the only reason your patch probably doesn't break anything. Think about what happens if, after your patch is applied, someone moves that assignment up or adds an extra step that can fail after it... > > >> so the order in which we cleanup is unlink ("unparent"), destroy. > > I interpreted the eventual passing of a null pointer to the rbd_dev_destroy() > function as an indication for further source code adjustments. If all error paths could be adjusted so that NULL pointers are never passed in, destroy functions wouldn't need to have a NULL check, would they? Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 20:21 ` Ilya Dryomov @ 2015-11-24 20:34 ` SF Markus Elfring 2015-11-24 21:54 ` Ilya Dryomov 2015-11-25 11:55 ` [PATCH 2/2] " Dan Carpenter 2015-11-26 7:54 ` SF Markus Elfring 2 siblings, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2015-11-24 20:34 UTC (permalink / raw) To: Ilya Dryomov Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall > Well, there isn't any _literal_ linking (e.g. adding to a link list, > etc) in this case. We just bump some refs and do probe to fill in the > newly allocated parent. Thanks for your clarification. > The actual linking (rbd_dev->parent = parent) is done right before > returning so we never have to undo it in rbd_dev_probe_parent() and > that's the only reason your patch probably doesn't break anything. Is this function implementation just also affected by an issue which is mentioned in the Linux document "CodingStyle" as "one err bugs"? > Think about what happens if, after your patch is applied, someone moves > that assignment up or adds an extra step that can fail after it... Is such a software maintenance concern really enough to delay (or reject) my second update suggestion in this small patch series? Regards, Markus ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 20:34 ` SF Markus Elfring @ 2015-11-24 21:54 ` Ilya Dryomov 2015-11-25 10:23 ` SF Markus Elfring 0 siblings, 1 reply; 22+ messages in thread From: Ilya Dryomov @ 2015-11-24 21:54 UTC (permalink / raw) To: SF Markus Elfring Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Tue, Nov 24, 2015 at 9:34 PM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: >> Well, there isn't any _literal_ linking (e.g. adding to a link list, >> etc) in this case. We just bump some refs and do probe to fill in the >> newly allocated parent. > > Thanks for your clarification. > > >> The actual linking (rbd_dev->parent = parent) is done right before >> returning so we never have to undo it in rbd_dev_probe_parent() and >> that's the only reason your patch probably doesn't break anything. > > Is this function implementation just also affected by an issue > which is mentioned in the Linux document "CodingStyle" as "one err bugs"? No, why? "one err bug" as per CodingStyle is a NULL deref on line 2 if foo is NULL. If it was just "err: kfree(foo); return ret;", a NULL foo would be perfectly OK. 1 err: 2 kfree(foo->bar); 3 kfree(foo); 4 return ret; If you can spot such a NULL deref in rbd_dev_probe_parent(), I'd gladly take a patch. > > >> Think about what happens if, after your patch is applied, someone moves >> that assignment up or adds an extra step that can fail after it... > > Is such a software maintenance concern really enough to delay (or reject) > my second update suggestion in this small patch series? Yes - it's rejected because it messes up the order of cleanup for no good reason. I realize why you think the patch is correct and it's not without merit, but it just doesn't fit the weird rbd_dev_probe_parent() contract. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 21:54 ` Ilya Dryomov @ 2015-11-25 10:23 ` SF Markus Elfring 0 siblings, 0 replies; 22+ messages in thread From: SF Markus Elfring @ 2015-11-25 10:23 UTC (permalink / raw) To: Ilya Dryomov Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall, Dan Carpenter > "one err bug" as per CodingStyle is a NULL deref on line 2 if foo is NULL. > If it was just "err: kfree(foo); return ret;", a NULL foo would be perfectly OK. Would it make sense to rename such an issue as the "one error jump label bug"? https://plus.google.com/106378716002406849458/posts/dnanfhQ4mHQ Regards, Markus ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 20:21 ` Ilya Dryomov 2015-11-24 20:34 ` SF Markus Elfring @ 2015-11-25 11:55 ` Dan Carpenter 2015-11-25 14:06 ` Ilya Dryomov 2015-11-26 7:54 ` SF Markus Elfring 2 siblings, 1 reply; 22+ messages in thread From: Dan Carpenter @ 2015-11-25 11:55 UTC (permalink / raw) To: Ilya Dryomov Cc: SF Markus Elfring, Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Tue, Nov 24, 2015 at 09:21:06PM +0100, Ilya Dryomov wrote: > >> Cleanup here is (and should be) done in reverse order. > > Yes. This is true. > > I have got an other impression about the appropriate order for the corresponding > > clean-up function calls. > > > > > >> We allocate parent rbd_device and then link it with what we already have, > > > > I guess that we have got a different understanding about the relevant "linking". > > Well, there isn't any _literal_ linking (e.g. adding to a link list, > etc) in this case. We just bump some refs and do probe to fill in the > newly allocated parent. If probe fails, we put refs and free parent, > reversing the "alloc parent, bump refs" order. > > The actual linking (rbd_dev->parent = parent) is done right before > returning so we never have to undo it in rbd_dev_probe_parent() and > that's the only reason your patch probably doesn't break anything. > Think about what happens if, after your patch is applied, someone moves > that assignment up or adds an extra step that can fail after it... > The problem is that the unwind code should be a mirror of the allocate code but rbd_dev_unparent() doesn't mirror anything. Generally, writing future proof stubs like this is a wrong thing because predicting the future is hard and in the mean time we are left stubs which confuse everyone. > If all error paths could be adjusted so that NULL pointers are never > passed in, destroy functions wouldn't need to have a NULL check, would > they? Yep. We agree on the right way to do it. I am probably the number one kernel developer for removing the most sanity checks. :P (As opposed to patch 1/1 where we now rely on the sanity check inside rbd_dev_destroy().) drivers/block/rbd.c 5149 static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) 5150 { 5151 struct rbd_device *parent = NULL; 5152 int ret; 5153 5154 if (!rbd_dev->parent_spec) 5155 return 0; 5156 5157 if (++depth > RBD_MAX_PARENT_CHAIN_LEN) { 5158 pr_info("parent chain is too long (%d)\n", depth); 5159 ret = -EINVAL; 5160 goto out_err; We haven't allocated anything so this should just be return -EINVAL; In the original code, we decrement the kref count on ->parent_spec on this error path so that is a classic One Err Bug. 5161 } 5162 5163 parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec, 5164 NULL); 5165 if (!parent) { 5166 ret = -ENOMEM; 5167 goto out_err; Still haven't allocated anything so return -ENOMEM, but if we fail after this point we will need to call rbd_dev_destroy(). 5168 } 5169 5170 /* 5171 * Images related by parent/child relationships always share 5172 * rbd_client and spec/parent_spec, so bump their refcounts. 5173 */ 5174 __rbd_get_client(rbd_dev->rbd_client); 5175 rbd_spec_get(rbd_dev->parent_spec); We will need to put these on any later error paths. 5176 5177 ret = rbd_dev_image_probe(parent, depth); 5178 if (ret < 0) 5179 goto out_err; Ok. We need to put the ->parent_spec, ->rbd_client and free the parent. 5180 5181 rbd_dev->parent = parent; 5182 atomic_set(&rbd_dev->parent_ref, 1); 5183 return 0; 5184 5185 out_err: 5186 rbd_dev_unparent(rbd_dev); This is a complicated way to say rbd_spec_put(rbd_dev->parent_spec); Also, is it really necessary to set ->parent_spec to NULL? If we didn't put the last reference then doesn't setting it to NULL mean we are leaking? Setting it to NULL is confusing and feels like a layering violation. 5187 if (parent) 5188 rbd_dev_destroy(parent); 5189 return ret; 5190 } I feel like we should be calling rbd_put_client() on this error path or else the code is buggy or has layer violations. So I *think* it should look like this: dec_ref_counts: rbd_spec_put(rbd_dev->parent_spec); rbd_put_client(rbd_dev->rbd_client); rbd_dev_destroy(parent); return ret; regards, dan carpenter ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-25 11:55 ` [PATCH 2/2] " Dan Carpenter @ 2015-11-25 14:06 ` Ilya Dryomov 2015-11-25 15:26 ` Dan Carpenter 0 siblings, 1 reply; 22+ messages in thread From: Ilya Dryomov @ 2015-11-25 14:06 UTC (permalink / raw) To: Dan Carpenter Cc: SF Markus Elfring, Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Wed, Nov 25, 2015 at 12:55 PM, Dan Carpenter <dan.carpenter@oracle.com> wrote: > On Tue, Nov 24, 2015 at 09:21:06PM +0100, Ilya Dryomov wrote: >> >> Cleanup here is (and should be) done in reverse order. >> > > > Yes. This is true. > >> > I have got an other impression about the appropriate order for the corresponding >> > clean-up function calls. >> > >> > >> >> We allocate parent rbd_device and then link it with what we already have, >> > >> > I guess that we have got a different understanding about the relevant "linking". >> >> Well, there isn't any _literal_ linking (e.g. adding to a link list, >> etc) in this case. We just bump some refs and do probe to fill in the >> newly allocated parent. If probe fails, we put refs and free parent, >> reversing the "alloc parent, bump refs" order. >> >> The actual linking (rbd_dev->parent = parent) is done right before >> returning so we never have to undo it in rbd_dev_probe_parent() and >> that's the only reason your patch probably doesn't break anything. >> Think about what happens if, after your patch is applied, someone moves >> that assignment up or adds an extra step that can fail after it... >> > > The problem is that the unwind code should be a mirror of the allocate > code but rbd_dev_unparent() doesn't mirror anything. Generally, writing > future proof stubs like this is a wrong thing because predicting the > future is hard and in the mean time we are left stubs which confuse > everyone. It's not a future proof stub. It's just some crufty code that was fixed over time to not leak things. I won't defend it - it is confusing and could definitely be improved - but that can't be done without refactoring a fair bunch of calling code. A patch changing rbd_dev_probe_parent() alone just won't do it. > >> If all error paths could be adjusted so that NULL pointers are never >> passed in, destroy functions wouldn't need to have a NULL check, would >> they? > > Yep. We agree on the right way to do it. I am probably the number one > kernel developer for removing the most sanity checks. :P (As opposed > to patch 1/1 where we now rely on the sanity check inside > rbd_dev_destroy().) > > drivers/block/rbd.c > 5149 static int rbd_dev_probe_parent(struct rbd_device *rbd_dev, int depth) > 5150 { > 5151 struct rbd_device *parent = NULL; > 5152 int ret; > 5153 > 5154 if (!rbd_dev->parent_spec) > 5155 return 0; > 5156 > 5157 if (++depth > RBD_MAX_PARENT_CHAIN_LEN) { > 5158 pr_info("parent chain is too long (%d)\n", depth); > 5159 ret = -EINVAL; > 5160 goto out_err; > > We haven't allocated anything so this should just be return -EINVAL; > In the original code, we decrement the kref count on ->parent_spec on > this error path so that is a classic One Err Bug. The caller expects rbd_dev->parent_spec to be put on any error. Notice that we return right away if !rbd_dev->parent_spec. > > 5161 } > 5162 > 5163 parent = rbd_dev_create(rbd_dev->rbd_client, rbd_dev->parent_spec, > 5164 NULL); > 5165 if (!parent) { > 5166 ret = -ENOMEM; > 5167 goto out_err; > > Still haven't allocated anything so return -ENOMEM, but if we fail after > this point we will need to call rbd_dev_destroy(). > > 5168 } > 5169 > 5170 /* > 5171 * Images related by parent/child relationships always share > 5172 * rbd_client and spec/parent_spec, so bump their refcounts. > 5173 */ > 5174 __rbd_get_client(rbd_dev->rbd_client); > 5175 rbd_spec_get(rbd_dev->parent_spec); > > We will need to put these on any later error paths. And we do, in rbd_dev_destroy(parent), since these are references for the parent. > > 5176 > 5177 ret = rbd_dev_image_probe(parent, depth); > 5178 if (ret < 0) > 5179 goto out_err; > > Ok. We need to put the ->parent_spec, ->rbd_client and free the parent. > > 5180 > 5181 rbd_dev->parent = parent; > 5182 atomic_set(&rbd_dev->parent_ref, 1); > 5183 return 0; > 5184 > 5185 out_err: > 5186 rbd_dev_unparent(rbd_dev); > > This is a complicated way to say rbd_spec_put(rbd_dev->parent_spec); > > Also, is it really necessary to set ->parent_spec to NULL? If we didn't > put the last reference then doesn't setting it to NULL mean we are > leaking? Setting it to NULL is confusing and feels like a layering > violation. Yes, because as it is, ->parent_spec is a determinant of whether or not the image has a parent. If we fail in rbd_dev_probe_parent(), it needs to be set to NULL to signify that the image doesn't have a parent. Even if the entire thing was refactored, we'd still have to do the same because not every image has a parent and the same error path has to work for all images. The layering violation is that we have to do in rbd_dev_probe_parent() even though we didn't allocate it there. > > 5187 if (parent) > 5188 rbd_dev_destroy(parent); > 5189 return ret; > 5190 } > > I feel like we should be calling rbd_put_client() on this error path or > else the code is buggy or has layer violations. So I *think* it should > look like this: > > dec_ref_counts: > rbd_spec_put(rbd_dev->parent_spec); > rbd_put_client(rbd_dev->rbd_client); > > rbd_dev_destroy(parent); > > return ret; We do, in rbd_dev_destroy(parent). Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-25 14:06 ` Ilya Dryomov @ 2015-11-25 15:26 ` Dan Carpenter 0 siblings, 0 replies; 22+ messages in thread From: Dan Carpenter @ 2015-11-25 15:26 UTC (permalink / raw) To: Ilya Dryomov Cc: SF Markus Elfring, Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall Ah... I see now. Thanks. regards, dan carpenter ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-24 20:21 ` Ilya Dryomov 2015-11-24 20:34 ` SF Markus Elfring 2015-11-25 11:55 ` [PATCH 2/2] " Dan Carpenter @ 2015-11-26 7:54 ` SF Markus Elfring 2015-11-26 11:37 ` Ilya Dryomov 2 siblings, 1 reply; 22+ messages in thread From: SF Markus Elfring @ 2015-11-26 7:54 UTC (permalink / raw) To: Ilya Dryomov Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall >> I interpreted the eventual passing of a null pointer to the rbd_dev_destroy() >> function as an indication for further source code adjustments. > > If all error paths could be adjusted so that NULL pointers are never passed in, > destroy functions wouldn't need to have a NULL check, would they? How do you think about to clarify corresponding implementation details a bit more? * Why was the function "rbd_dev_probe_parent" implemented in the way that it relies on a sanity check in the function "rbd_dev_destroy" then? * How are the chances to restructure the source code a bit (like changing a few jump labels) so that it should also work without an extra function call during error handling there? Regards, Markus ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-26 7:54 ` SF Markus Elfring @ 2015-11-26 11:37 ` Ilya Dryomov 2015-11-26 13:41 ` SF Markus Elfring 0 siblings, 1 reply; 22+ messages in thread From: Ilya Dryomov @ 2015-11-26 11:37 UTC (permalink / raw) To: SF Markus Elfring Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall On Thu, Nov 26, 2015 at 8:54 AM, SF Markus Elfring <elfring@users.sourceforge.net> wrote: >>> I interpreted the eventual passing of a null pointer to the rbd_dev_destroy() >>> function as an indication for further source code adjustments. >> >> If all error paths could be adjusted so that NULL pointers are never passed in, >> destroy functions wouldn't need to have a NULL check, would they? > > How do you think about to clarify corresponding implementation details a bit more? > > * Why was the function "rbd_dev_probe_parent" implemented in the way > that it relies on a sanity check in the function "rbd_dev_destroy" then? Because it's not a bad thing? What's wrong with an init to NULL, a possible assignment, in this case from rbd_dev_create(), and an unconditional rbd_dev_destroy()? The NULL check in rbd_dev_destroy() is not a sanity check, it's a feature. It's not there to "fixup" callers that pass NULL - it's there because it is _expected_ that some callers will pass NULL. > * How are the chances to restructure the source code a bit (like changing a few > jump labels) so that it should also work without an extra function call > during error handling there? As I said in my reply to Dan, the problem with rbd_dev_probe_parent() is the calling code which expects it to call unparent if ->parent_spec. This makes it stand out and confuses people, but can't be fixed without refactoring a bunch of other code. The extra function call is *not* a problem. Thanks, Ilya ^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: block-rbd: One function call less in rbd_dev_probe_parent() after error detection 2015-11-26 11:37 ` Ilya Dryomov @ 2015-11-26 13:41 ` SF Markus Elfring 0 siblings, 0 replies; 22+ messages in thread From: SF Markus Elfring @ 2015-11-26 13:41 UTC (permalink / raw) To: Ilya Dryomov Cc: Alex Elder, Sage Weil, Ceph Development, LKML, kernel-janitors, Julia Lawall >> * Why was the function "rbd_dev_probe_parent" implemented in the way >> that it relies on a sanity check in the function "rbd_dev_destroy" then? > > Because it's not a bad thing? There are different opinions about this implementation detail. > What's wrong with an init to NULL, a possible assignment, in this case > from rbd_dev_create(), and an unconditional rbd_dev_destroy()? Does this approach look like it is affected by a "one error jump label bug" symptom? > The NULL check in rbd_dev_destroy() is not a sanity check, > it's a feature. I have got an other impression here. > It's not there to "fixup" callers that pass NULL It seems that the explanations on the detail why a function tolerates passed null pointers can also be different. > - it's there because it is _expected_ that some callers will pass NULL. I find it still unnecessary to let a called function like "rbd_dev_destroy" to repeat the check when you know already that the passed variable contains a null pointer. > As I said in my reply to Dan, the problem with rbd_dev_probe_parent() > is the calling code which expects it to call unparent if ->parent_spec. > This makes it stand out and confuses people, but can't be fixed without > refactoring a bunch of other code. I would appreciate if the discussed function could be also improved by itself. More refactoring might follow at other source code places later. > The extra function call is *not* a problem. How many software developers and reviewers will care if corresponding error handling can also become a bit more efficient? Regards, Markus ^ permalink raw reply [flat|nested] 22+ messages in thread
end of thread, other threads:[~2015-11-26 13:41 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <5307CAA2.8060406@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1402212321410.2043@localhost6.localdomain6>
[not found] ` <530A086E.8010901@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1402231635510.1985@localhost6.localdomain6>
[not found] ` <530A72AA.3000601@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1402240658210.2090@localhost6.localdomain6>
[not found] ` <530B5FB6.6010207@users.sourceforge.net>
[not found] ` <alpine.DEB.2.10.1402241710370.2074@hadrien>
[not found] ` <530C5E18.1020800@users.sourceforge.net>
[not found] ` <alpine.DEB.2.10.1402251014170.2080@hadrien>
[not found] ` <530CD2C4.4050903@users.sourceforge.net>
[not found] ` <alpine.DEB.2.10.1402251840450.7035@hadrien>
[not found] ` <530CF8FF.8080600@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1402252117150.2047@localhost6.localdomain6>
[not found] ` <530DD06F.4090703@users.sourceforge.net>
[not found] ` <alpine.DEB.2.02.1402262129250.2221@localhost6.localdomain6>
[not found] ` <5317A59D.4@users.so urceforge.net>
[not found] ` <5317A59D.4@users.sourceforge.net>
2014-11-02 14:20 ` [PATCH 1/1] ceph: Deletion of unnecessary checks before two function calls SF Markus Elfring
2014-11-03 10:35 ` Ilya Dryomov
2014-11-03 13:27 ` SF Markus Elfring
2014-11-03 14:23 ` Ilya Dryomov
2014-12-01 10:23 ` [PATCH 1/1] block-rbd: Delete a check before ceph_put_snap_context() SF Markus Elfring
2014-12-01 11:57 ` Ilya Dryomov
2015-11-23 19:40 ` [PATCH 0/2] block-rbd: Deletion of an unnecessary check SF Markus Elfring
2015-11-23 19:44 ` [PATCH 1/2] block-rbd: Delete an unnecessary check before the function call "rbd_dev_destroy" SF Markus Elfring
2015-11-24 13:20 ` Ilya Dryomov
2015-11-23 19:46 ` [PATCH 2/2] block-rbd: One function call less in rbd_dev_probe_parent() after error detection SF Markus Elfring
2015-11-24 13:21 ` Ilya Dryomov
2015-11-24 19:23 ` SF Markus Elfring
2015-11-24 20:21 ` Ilya Dryomov
2015-11-24 20:34 ` SF Markus Elfring
2015-11-24 21:54 ` Ilya Dryomov
2015-11-25 10:23 ` SF Markus Elfring
2015-11-25 11:55 ` [PATCH 2/2] " Dan Carpenter
2015-11-25 14:06 ` Ilya Dryomov
2015-11-25 15:26 ` Dan Carpenter
2015-11-26 7:54 ` SF Markus Elfring
2015-11-26 11:37 ` Ilya Dryomov
2015-11-26 13:41 ` SF Markus Elfring
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox