From patchwork Sat Jan 10 20:28:02 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Cyrill Gorcunov X-Patchwork-Id: 17755 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id 3BEF0474C9 for ; Sun, 11 Jan 2009 07:28:15 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752235AbZAJU2L (ORCPT ); Sat, 10 Jan 2009 15:28:11 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751476AbZAJU2J (ORCPT ); Sat, 10 Jan 2009 15:28:09 -0500 Received: from fg-out-1718.google.com ([72.14.220.156]:47638 "EHLO fg-out-1718.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751005AbZAJU2G (ORCPT ); Sat, 10 Jan 2009 15:28:06 -0500 Received: by fg-out-1718.google.com with SMTP id 19so3668724fgg.17 for ; Sat, 10 Jan 2009 12:28:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:received:date:from:to:cc :subject:message-id:mime-version:content-type:content-disposition :user-agent; bh=hTw6JUJ/+CiMVPC6Sp0WWVLm+qVvm224ScI6+ZLwz64=; b=g2sm/lt9chROcHoIPoRjKMcOu2oqftxu9bIETvjFRRbrHTlDY8gxZJO1oWdvXtJeNl HhqPllCq5T7M1AelbAbxbepCblOuHsraO54eD38sjxjLeT5cQNcrrjAr1kvkaj+puDWq sIXeI+LsQFXo8vYYcWYUKm2mWTJntuzmL9j3E= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=date:from:to:cc:subject:message-id:mime-version:content-type :content-disposition:user-agent; b=q5epTpIOj8BYkhz7VeYfLQXbhp9QGpKz5Vx0AKnvA9T44Nc+hiCMYLNFUGm2HlTSn4 EzWyOg0JATQCWfQy6eAAJjvgisCzNLCo17waWfscOcU3d6zO/IWuenHHYusuMTEMF5PU N8ZWidx/84rV5ZUDWIIra+u0Gch5obSMhkMnA= Received: by 10.86.84.18 with SMTP id h18mr15624446fgb.22.1231619283606; Sat, 10 Jan 2009 12:28:03 -0800 (PST) Received: from gorcunov (ppp78-37-255-4.pppoe.avangarddsl.ru [78.37.255.4]) by mx.google.com with ESMTPS id e11sm24434559fga.2.2009.01.10.12.28.02 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 10 Jan 2009 12:28:03 -0800 (PST) Received: by gorcunov (Postfix, from userid 1000) id 3685251E; Sat, 10 Jan 2009 23:28:02 +0300 (MSK) Date: Sat, 10 Jan 2009 23:28:02 +0300 From: Cyrill Gorcunov To: David Miller , Andrew Morton , James Chapman Cc: LKML , NKML Subject: [PATCH] net: ppp_generic - fix broken userspace Message-ID: <20090110202802.GF29349@localhost> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.17+20080114 (2008-01-14) Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org The commits: 7a95d267fb62cd6b80ef73be0592bbbe1dbd5df7 ab5024ab23b78c86a0a1425defcdde48710fe449 introduced usage of IDR functionality but broke userspace side. Before this commits it was possible to allocate new ppp interface with specified number. Now it fails with EINVAL. Fix it by trying to allocate interface with specified unit number and return EEXIST if fail which allow pppd to ask us to allocate new unit number. And fix messages on memory allocation fails - add details that it's PPP module who is complaining. Signed-off-by: Cyrill Gorcunov --- If this is not a right way to fix this issue maybe better would be to just revert the commits mentioned. Please review carefully. Thanks! The patch is on top of current net-next-2.6 tree. drivers/net/ppp_generic.c | 43 +++++++++++++++++++++++++++++++++++++------ 1 file changed, 37 insertions(+), 6 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-2.6.git/drivers/net/ppp_generic.c =================================================================== --- linux-2.6.git.orig/drivers/net/ppp_generic.c +++ linux-2.6.git/drivers/net/ppp_generic.c @@ -250,6 +250,7 @@ static int ppp_connect_channel(struct ch static int ppp_disconnect_channel(struct channel *pch); static void ppp_destroy_channel(struct channel *pch); static int unit_get(struct idr *p, void *ptr); +static int unit_set(struct idr *p, void *ptr, int n); static void unit_put(struct idr *p, int n); static void *unit_find(struct idr *p, int n); @@ -2432,11 +2433,18 @@ ppp_create_interface(int unit, int *retp } else { if (unit_find(&ppp_units_idr, unit)) goto out2; /* unit already exists */ - else { - /* darn, someone is cheating us? */ - *retp = -EINVAL; + /* + * if caller need a specified unit number + * lets try to satisfy him, otherwise -- + * he should better ask us for new unit number + * + * NOTE: yes I know that returning EEXIST it's not + * fair but at least pppd will ask us to allocate + * new unit in this case so user is happy :) + */ + unit = unit_set(&ppp_units_idr, ppp, unit); + if (unit < 0) goto out2; - } } /* Initialize the new ppp unit */ @@ -2677,14 +2685,37 @@ static void __exit ppp_cleanup(void) * by holding all_ppp_mutex */ +/* associate pointer with specified number */ +static int unit_set(struct idr *p, void *ptr, int n) +{ + int unit, err; + +again: + if (!idr_pre_get(p, GFP_KERNEL)) { + printk(KERN_ERR "PPP: No free memory for idr\n"); + return -ENOMEM; + } + + err = idr_get_new_above(p, ptr, n, &unit); + if (err == -EAGAIN) + goto again; + + if (unit != n) { + idr_remove(p, unit); + return -EINVAL; + } + + return unit; +} + /* get new free unit number and associate pointer with it */ static int unit_get(struct idr *p, void *ptr) { int unit, err; again: - if (idr_pre_get(p, GFP_KERNEL) == 0) { - printk(KERN_ERR "Out of memory expanding drawable idr\n"); + if (!idr_pre_get(p, GFP_KERNEL)) { + printk(KERN_ERR "PPP: No free memory for idr\n"); return -ENOMEM; }