From patchwork Wed Oct 17 19:20:21 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Dryomov X-Patchwork-Id: 10646003 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id EA1AC157A for ; Wed, 17 Oct 2018 19:21:03 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D90DF286AA for ; Wed, 17 Oct 2018 19:21:03 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id CD7302882F; Wed, 17 Oct 2018 19:21:03 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B832B286AA for ; Wed, 17 Oct 2018 19:21:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728393AbeJRDSJ (ORCPT ); Wed, 17 Oct 2018 23:18:09 -0400 Received: from mail-wr1-f65.google.com ([209.85.221.65]:35483 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728095AbeJRDSI (ORCPT ); Wed, 17 Oct 2018 23:18:08 -0400 Received: by mail-wr1-f65.google.com with SMTP id w5-v6so30946248wrt.2 for ; Wed, 17 Oct 2018 12:21:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:in-reply-to:references; bh=Ucegoaui/t/cVko0YL36CMdautxTm28toBzmnT4/N8Y=; b=mNNTYsdpG2XP2e4C8k6885WQRXTzNzrDFPoDORCiOo9VQVZw5CIvYI3MZsYGeFZnpv X+eN08R6+DOdmSWCBgSiKvKpIvj0XvoglPCte/+DhU3a+Vc62KKba2MM+lKZz6w03Vej ZDNeg0rYnErwpl+74T6l7IYrREvaJG6cJKi3Bp/xM5Aq2HnW20fWzmELO5D87C0S3+mq EZ3NfaGzUt+Z47WyvJ3wNxrsdpzNkL1Q8vaCJckQ60UhaYq+hk16sDXI8Iq3m0xR5bXe laDtXJifyKdd3McCx+fzKf0iaJ7zn93lxROaWku4D837vzmhKiroOWCm7TC1qi2lDAt7 nzqw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=Ucegoaui/t/cVko0YL36CMdautxTm28toBzmnT4/N8Y=; b=Y30WZJw0nEQVAtkfeCz9o62ccriHjELAVelziAGL1vIBTWDgpdxpRKGaKvJ+zuQIQa JYGmKEOcw99dKk8+85Te9FHLWFLvX87Wwi3wkWJ9+G9XxfbxiyOHhU7yLMqYGmYNdruN afqG7pwdTjhGC90NuRcAdU/qQlZciRS4oDBJFuAp1lWpDxl9ZTPMvMSnxgME54IHV33W vapnuF5orXFXA9KOOHafP87wCEEwImXQfhrRc6RcaKDaFAY+IuKQkCitg6JLyrGk1Blw LVfCsdA8a+6SqxQRDrZOe8oyaIjxbVy1EYBd90S4gdfjNqebk9+oc4/5uA7HDMs4nssi gFVw== X-Gm-Message-State: ABuFfoi8XSeVFwhRcagq3vnHIFCTdXArQzV1fz8ynKSes6tKc23igUZw WiWmEYoVdB6gPzOSl9C2p+f5weWU X-Google-Smtp-Source: ACcGV62VUZvDWRb/iVL+D8BfgQMit0wvpeZvEB37kBBlK0opQ6uFnJbUrUBHfzNoxHGJCVZEIefhgA== X-Received: by 2002:adf:a1c7:: with SMTP id v7-v6mr15780929wrv.87.1539804059660; Wed, 17 Oct 2018 12:20:59 -0700 (PDT) Received: from orange.redhat.com ([213.175.37.12]) by smtp.gmail.com with ESMTPSA id f7-v6sm16059501wrr.68.2018.10.17.12.20.58 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Oct 2018 12:20:58 -0700 (PDT) From: Ilya Dryomov To: ceph-devel@vger.kernel.org Subject: [PATCH 02/10] libceph: don't consume a ref on pagelist in ceph_msg_data_add_pagelist() Date: Wed, 17 Oct 2018 21:20:21 +0200 Message-Id: <20181017192029.23294-3-idryomov@gmail.com> X-Mailer: git-send-email 2.14.4 In-Reply-To: <20181017192029.23294-1-idryomov@gmail.com> References: <20181017192029.23294-1-idryomov@gmail.com> Sender: ceph-devel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: ceph-devel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Because send_mds_reconnect() wants to send a message with a pagelist and pass the ownership to the messenger, ceph_msg_data_add_pagelist() consumes a ref which is then put in ceph_msg_data_destroy(). This makes managing pagelists in the OSD client (where they are wrapped in ceph_osd_data) unnecessarily hard because the handoff only happens in ceph_osdc_start_request() instead of when the pagelist is passed to ceph_osd_data_pagelist_init(). I counted several memory leaks on various error paths. Fix up ceph_msg_data_add_pagelist() and carry a pagelist ref in ceph_osd_data. Signed-off-by: Ilya Dryomov --- fs/ceph/mds_client.c | 2 +- net/ceph/messenger.c | 1 + net/ceph/osd_client.c | 8 ++++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 580a79b9a91f..97de674ea377 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c @@ -2136,7 +2136,6 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc, if (req->r_pagelist) { struct ceph_pagelist *pagelist = req->r_pagelist; - refcount_inc(&pagelist->refcnt); ceph_msg_data_add_pagelist(msg, pagelist); msg->hdr.data_len = cpu_to_le32(pagelist->length); } else { @@ -3240,6 +3239,7 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, mutex_unlock(&mdsc->mutex); up_read(&mdsc->snap_rwsem); + ceph_pagelist_release(pagelist); return; fail: diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c index 0a187196aeed..76684edc43ef 100644 --- a/net/ceph/messenger.c +++ b/net/ceph/messenger.c @@ -3313,6 +3313,7 @@ void ceph_msg_data_add_pagelist(struct ceph_msg *msg, data = ceph_msg_data_create(CEPH_MSG_DATA_PAGELIST); BUG_ON(!data); + refcount_inc(&pagelist->refcnt); data->pagelist = pagelist; list_add_tail(&data->links, &msg->data); diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index db2ebc9e5f1f..ad00495dbd39 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c @@ -126,6 +126,9 @@ static void ceph_osd_data_init(struct ceph_osd_data *osd_data) osd_data->type = CEPH_OSD_DATA_TYPE_NONE; } +/* + * Consumes @pages if @own_pages is true. + */ static void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data, struct page **pages, u64 length, u32 alignment, bool pages_from_pool, bool own_pages) @@ -138,6 +141,9 @@ static void ceph_osd_data_pages_init(struct ceph_osd_data *osd_data, osd_data->own_pages = own_pages; } +/* + * Consumes a ref on @pagelist. + */ static void ceph_osd_data_pagelist_init(struct ceph_osd_data *osd_data, struct ceph_pagelist *pagelist) { @@ -362,6 +368,8 @@ static void ceph_osd_data_release(struct ceph_osd_data *osd_data) num_pages = calc_pages_for((u64)osd_data->alignment, (u64)osd_data->length); ceph_release_page_vector(osd_data->pages, num_pages); + } else if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGELIST) { + ceph_pagelist_release(osd_data->pagelist); } ceph_osd_data_init(osd_data); }