Netdev List
 help / color / mirror / Atom feed
* Re: dst->obsolete has become pointless
From: Steffen Klassert @ 2011-11-08  9:34 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, timo.teras
In-Reply-To: <20111104.230910.520924516201406800.davem@davemloft.net>

On Fri, Nov 04, 2011 at 11:09:10PM -0400, David Miller wrote:
> 
> While researching the things unearthed by Steffen Klassert wrt. PMTU
> handling in the current tree I went to do some research on what the
> real story is wrt. dst->obsolete.
> 
> And sure enough EVERY SINGLE ipv4 and ipv6 route is created with
> obsolete set to -1, so we unconditionally always invoke ->dst_check().
> 
> This makes it completely pointless as an optimization to avoid calling
> the dst_ops->dst_check() method.  It never triggers.
> 
> This stems from Timo's change to make route expiry properly visible
> to IPSEC stacked routes:
> 
> --
> commit d11a4dc18bf41719c9f0d7ed494d295dd2973b92
> Author: Timo Teräs <timo.teras@iki.fi>
> Date:   Thu Mar 18 23:20:20 2010 +0000
> 
>     ipv4: check rt_genid in dst_check
> ...
> --
> 
> Only DecNET creates routes with obsolete initially set to zero, and
> therefore only hits ->dst_check() when dst_free is invoked on the route
> during a flush of the decnet routing tables.
> 
> And actually this is how ipv4 operated before we started using
> generation counts instead of flushing the entire table.  IPV6 seems to
> always have used the FIB6 tree serial numbers for expiration checking
> and therefore always set obsolete to -1 on new routes.
> 
> So we can't just get rid of the dst->obsolete check in dst_check() and
> __sk_dst_check() because that will break DecNET because DecNET's
> ->dst_check() handler assumes that if it was called then the route
> is obsolete and it just plainly returns NULL to tell the caller the
> route is in fact invalid.
> 

I don't know what to do with DecNET, but we probaply need to decide
about the future of dst->obsolete before we can fix the ipv4 PMTU
problems. Possible fixes might depend on whether ->dst_check() is
always invoked or not.

^ permalink raw reply

* [PATCH] net/ll_temac: FIX : Wait for indirect wait to end
From: Ricardo Ribalda Delgado @ 2011-11-08  9:39 UTC (permalink / raw)
  To: davem, ian.campbell, eric.dumazet, jeffrey.t.kirsher, jpirko,
	netdev, linux-kernel
  Cc: Ricardo Ribalda Delgado

While tracing down a connectivity problem on the temac I connected a
probe to the Cross bar irq, and it was triggered when doing
ifdown->ifup.

This is fixed once waiting for the indirect write to end. Since it is
not on the hot path there is no performance loss.

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/net/ethernet/xilinx/ll_temac_main.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 4d1658e..cf59dac 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -114,6 +114,7 @@ void temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
 		return;
 	temac_iow(lp, XTE_LSW0_OFFSET, value);
 	temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
+	temac_indirect_busywait(lp);
 }
 
 /**
-- 
1.7.7.1

^ permalink raw reply related

* [RESEND] ll_temac: Add support for phy_mii_ioctl
From: Ricardo Ribalda Delgado @ 2011-11-08  9:47 UTC (permalink / raw)
  To: davem, ian.campbell, eric.dumazet, jeffrey.t.kirsher, jpirko,
	netdev, linux-kernel
  Cc: Ricardo Ribalda Delgado

This patch enables the ioctl support for the driver. So userspace
programs like mii-tool can work.

Resend in merge window

Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
---
 drivers/net/ethernet/xilinx/ll_temac_main.c |   14 ++++++++++++++
 1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/xilinx/ll_temac_main.c b/drivers/net/ethernet/xilinx/ll_temac_main.c
index 4d1658e..b26e5ee 100644
--- a/drivers/net/ethernet/xilinx/ll_temac_main.c
+++ b/drivers/net/ethernet/xilinx/ll_temac_main.c
@@ -915,12 +915,26 @@ temac_poll_controller(struct net_device *ndev)
 }
 #endif
 
+static int temac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
+{
+	struct temac_local *lp = netdev_priv(ndev);
+
+	if (!netif_running(ndev))
+		return -EINVAL;
+
+	if (!lp->phy_dev)
+		return -EINVAL;
+
+	return phy_mii_ioctl(lp->phy_dev, rq, cmd);
+}
+
 static const struct net_device_ops temac_netdev_ops = {
 	.ndo_open = temac_open,
 	.ndo_stop = temac_stop,
 	.ndo_start_xmit = temac_start_xmit,
 	.ndo_set_mac_address = netdev_set_mac_address,
 	.ndo_validate_addr = eth_validate_addr,
+	.ndo_do_ioctl = temac_ioctl,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = temac_poll_controller,
 #endif
-- 
1.7.7.1

^ permalink raw reply related

* Re: Bug? GRE tunnel periodically won't transmit some packets
From: Eric Dumazet @ 2011-11-08 10:25 UTC (permalink / raw)
  To: Chris Siebenmann; +Cc: netdev
In-Reply-To: <1320737641.8976.4.camel@edumazet-laptop>

Le mardi 08 novembre 2011 à 08:34 +0100, Eric Dumazet a écrit :
> Le mardi 08 novembre 2011 à 02:08 -0500, Chris Siebenmann a écrit :
> 
> >  Let me know if you want a full dump of 'ip link show' (with or
> > without verbosity).
> > 
> > 	- cks
> 
> Oh yes, I meant "ip -s -s link show dev extun"
> 
> to get detailed infos :
> 
> # ip -s -s link show dev ppp0
> 8: ppp0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc
> pfifo_fast state UNKNOWN qlen 3
>     link/ppp 
>     RX: bytes  packets  errors  dropped overrun mcast   
>     21120910   21103    0       0       0       0      
>     RX errors: length  crc     frame   fifo    missed
>                0        0       0       0       0      
>     TX: bytes  packets  errors  dropped carrier collsns 
>     1310652    13736    0       0       0       0      
>     TX errors: aborted fifo    window  heartbeat
>                0        0       0       0      
> 


Hmm, by the way, I see the default device queue length of ppp is 3

You might have packet drops at the ppp0 device itself

ip -s -s link show dev ppp0 ; tc -s -d qdisc show dev ppp0

You could try to increase ppp0 queue length or install a classifier with
128 packet limit.

ifconfig ppp0 txqueuelen 32

or :

tc qdisc add dev ppp0 root sfq

^ permalink raw reply

* Re: [PATCH 1/2] net/smsc911x: Always wait for the chip to be ready
From: Linus Walleij @ 2011-11-08 10:34 UTC (permalink / raw)
  To: netdev, Steve Glendinning, David S. Miller
  Cc: Mathieu Poirer, Robert Marklund, Linus Walleij
In-Reply-To: <1319616343-6357-1-git-send-email-linus.walleij@stericsson.com>

2011/10/26 Linus Walleij <linus.walleij@stericsson.com>:

> From: Robert Marklund <robert.marklund@stericsson.com>
>
> Wait for the chip to be ready before any access to it. On the
> Snowball platform we need to enable an external regulator before
> the chip comes online, and then it happens that the device is
> not yet ready at probe time, so let's wait for it.
>
> Signed-off-by: Robert Marklund <robert.marklund@stericsson.com>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

Since there doesn't seem to be any consternation concerning
this first patch, can it be applied?

Yours,
Linus Walleij

^ permalink raw reply

* Re: [v2 PATCH 1/2] NETFILTER module xt_hmark new target for HASH based fw
From: Pablo Neira Ayuso @ 2011-11-08 10:51 UTC (permalink / raw)
  To: Hans Schillstrom
  Cc: Hans Schillstrom, kaber, jengelh, netfilter-devel, netdev
In-Reply-To: <0hivdsb.f18682ec9367f08c76301d993553f1b8@obelix.schillstrom.com>

On Tue, Nov 08, 2011 at 12:29:53AM +0100, Hans Schillstrom wrote:
> >We prefer skb_header_pointer instead. If conntrack is enabled, we can
> >benefit from defragmention. 
> 
> In  our case conntrack will not be there

Yes, but if conntrack is there, we benefit from fragment reassembly if
you use skb_header_pointer.

> >Please, replace all pskb_may_pull by skb_header_pointer in this code.
> >
> >We can assume that the IP header is linear (not fragmented).
> 
> I ran in to this issue in IPv6 testing so I got a little bit "paranoid".
> Are you sure that the embedded IP and L4 header in the ICMP msg also is unfragmented.  
> Is this true for both IPv6 & IPv4 ?

No sorry. I was refering to normal IP header in one packet.

> From what I remember  when I was testing IPv6  icmp and digged into the original header (on a 2.6.32 kernel)  
> pskb_may_pull was needed.

Yes, it is indeed needed.

> [snip]
> 
> >> +/*
> >> + * Calc hash value, special casre is taken on icmp and fragmented messages
> >> + * i.e. fragmented messages don't use ports.
> >> + */
> >> +static __u32 get_hash(struct sk_buff *skb, struct xt_hmark_info *info)
> >
> >This function seems to big to me, please, split it into smaller
> >chunks, like get_hash_ipv4, get_hash_ipv6 and get_hash_ports.
> >
> 
> Good catch I'll do that,
> 
> >> +{
> >> +	int nhoff, hash = 0, poff, proto, frag = 0;
> >> +	struct iphdr *ip;
> >> +	u8 ip_proto;
> >> +	u32 addr1, addr2, ihl;
> >> +	u16 snatport = 0, dnatport = 0;
> >> +	union {
> >> +		u32 v32;
> >> +		u16 v16[2];
> >> +	} ports;
> >> +
> >> +	nhoff = skb_network_offset(skb);
> >> +	proto = skb->protocol;
> >> +
> >> +	if (!proto && skb->sk) {
> >> +		if (skb->sk->sk_family == AF_INET)
> >> +			proto = __constant_htons(ETH_P_IP);
> >> +		else if (skb->sk->sk_family == AF_INET6)
> >> +			proto = __constant_htons(ETH_P_IPV6);
> >
> >You already have the layer3 protocol number in xt_action_param. No
> >need to use the socket information then.
> 
> When splitting get_hash()  above  will  be removed,  xt_action_param ->family will be used for selection.
> 
> [snip]
> >> +
> >> +		if (!ct || !nf_ct_is_confirmed(ct))
> >
> >You seem to (ab)use nf_ct_is_confirmed to make sure you're not in the
> >original direction. Better use the direction that you get by means of
> >nf_ct_get.
> >
> I'm not sure I follow you here ?

OK, why are you using nf_ct_is_confirmed here? :-)

> >> +			break;
> >> +		otuple = &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple;
> >> +		/* On the "return flow", to get the original address
> >> +		 * i,e, replace the source address.
> >> +		 */
> >> +		if (ct->status & IPS_DST_NAT &&
> >> +		    info->flags & XT_HMARK_USE_DNAT) {
> >> +			rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
> >> +			addr1 = (__force u32) otuple->dst.u3.in.s_addr;
> >> +			dnatport = otuple->dst.u.udp.port;
> >> +		}
> >> +		/* On the "return flow", to get the original address
> >> +		 * i,e, replace the destination address.
> >> +		 */
> >> +		if (ct->status & IPS_SRC_NAT &&
> >> +		    info->flags & XT_HMARK_USE_SNAT) {
> >> +			rtuple = &ct->tuplehash[IP_CT_DIR_REPLY].tuple;
> >> +			addr2 = (__force u32) otuple->src.u3.in.s_addr;
> >> +			snatport = otuple->src.u.udp.port;
> >> +		}
> >> +		break;
> >> +	}
> 
> [snip]
> 
> >> +			case NEXTHDR_NONE:
> >> +				nhoff += hdrlen;
> >> +				goto hdr_rdy;
> >> +			default:
> >> +				goto done;
> >
> >This goto doesn't make too much sense to me, better return 0.
> 
> hmmm 
> kind of left overs,  Actually all "goto done" can be replaced by return 0

no problem, just comestic change ;-)

> [snip]
> 
> >> +done:
> >> +	return 0;
> >> +}
> >
> >I'll try to find more time to look into this. Specifically, I want to
> >review the IPv6 bits more carefully.
> 
> The IPv6 header recursion is not obvious, and it's hard to test all cases :-)
> 
> I really appreciate you review

Welcome, let's see if we can get this into 3.3 since we cannot make it
for 3.2.

BTW, do you have some number of this running with and without
conntrack? It would be interesting to have.

^ permalink raw reply

* Re: Add IPSec IP Range in Linux kernel
From: Daniil Stolnikov @ 2011-11-08 10:51 UTC (permalink / raw)
  To: Peter P Waskiewicz Jr
  Cc: linux-kernel, netdev, linux-crypto, linux-security-module, davem
In-Reply-To: <1320733465.21617.4.camel@ppwaskie-mobl2>

> On Mon, 2011-11-07 at 19:10 -0800, Daniil Stolnikov wrote:
>> Hello!
>> 
>> Found that the stack IPSec in Linux does not support any IP range. Many people ask this question. The archives say strongswan said that their daemon supports a range, but the Linux IPSec stack supports only the subnets. I am writing to you to implement support for IP range in Linux. I think that a lot more people will appreciate this innovation.

> It'd be even better if you could write a patch for us to review.

> Cheers,
> -PJ

I was a little not so put it:) I'd certainly be happy and he would write a patch, but I'm afraid do not have the necessary knowledge to implement IPSec Linux. I turned to you, the developers, but rather to urge you to implement this feature using IP range. I hope very much for your help and support. This is especially beneficial for all - the Linux kernel will be more flexible and more compatible with different devices and software.

Regards
Daniil Stolnikov

^ permalink raw reply

* RE: [PATCH 7/7] gianfar: add support for wake-on-packet
From: Li Yang-R58472 @ 2011-11-08 11:07 UTC (permalink / raw)
  To: Wood Scott-B07421, Zhao Chenhui-B35336
  Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	Fleming Andy-AFLEMING
In-Reply-To: <4EB4558A.8070105@freescale.com>



>-----Original Message-----
>From: linuxppc-dev-bounces+leoli=freescale.com@lists.ozlabs.org
>[mailto:linuxppc-dev-bounces+leoli=freescale.com@lists.ozlabs.org] On
>Behalf Of Scott Wood
>Sent: Saturday, November 05, 2011 5:14 AM
>To: Zhao Chenhui-B35336
>Cc: netdev@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; Fleming Andy-
>AFLEMING
>Subject: Re: [PATCH 7/7] gianfar: add support for wake-on-packet
>
>On 11/04/2011 04:11 PM, Scott Wood wrote:
>> On 11/04/2011 07:40 AM, Zhao Chenhui wrote:
>>>  static int gfar_suspend(struct device *dev)  { @@ -1268,9 +1443,17
>>> @@ static int gfar_suspend(struct device *dev)
>>>  	struct gfar __iomem *regs = priv->gfargrp[0].regs;
>>>  	unsigned long flags;
>>>  	u32 tempval;
>>> -
>>>  	int magic_packet = priv->wol_en &&
>>> -		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
>>> +		(priv->wol_opts & GIANFAR_WOL_MAGIC);
>>> +	int arp_packet = priv->wol_en &&
>>> +		(priv->wol_opts & GIANFAR_WOL_ARP);
>>> +
>>> +	if (arp_packet) {
>>> +		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 1);
>>> +		pmc_enable_lossless(1);
>>> +		gfar_arp_suspend(ndev);
>>> +		return 0;
>>> +	}
>>
>> How do we know this isn't standby?
>
>Or suspend to disk, for that matter?

There is nothing we can do for hibernation.  The whole system is literally off.

- Leo

^ permalink raw reply

* RE: [PATCH 6/7] fsl_pmc: Add API to enable device as wakeup event source
From: Li Yang-R58472 @ 2011-11-08 11:12 UTC (permalink / raw)
  To: Wood Scott-B07421, Zhao Chenhui-B35336
  Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4EB455B1.8030009@freescale.com>



>-----Original Message-----
>From: linuxppc-dev-bounces+leoli=freescale.com@lists.ozlabs.org
>[mailto:linuxppc-dev-bounces+leoli=freescale.com@lists.ozlabs.org] On
>Behalf Of Scott Wood
>Sent: Saturday, November 05, 2011 5:14 AM
>To: Zhao Chenhui-B35336
>Cc: netdev@vger.kernel.org; linuxppc-dev@lists.ozlabs.org
>Subject: Re: [PATCH 6/7] fsl_pmc: Add API to enable device as wakeup event
>source
>
>On 11/04/2011 07:39 AM, Zhao Chenhui wrote:
>> @@ -45,6 +46,72 @@ static int has_lossless;
>>   * code can be compatible with both 32-bit & 36-bit */  extern void
>> mpc85xx_enter_deep_sleep(u64 ccsrbar, u32 powmgtreq);
>>
>> +#ifdef CONFIG_FSL_PMC
>> +/**
>> + * pmc_enable_wake - enable OF device as wakeup event source
>> + * @pdev: platform device affected
>> + * @state: PM state from which device will issue wakeup events
>> + * @enable: True to enable event generation; false to disable
>> + *
>> + * This enables the device as a wakeup event source, or disables it.
>> + *
>> + * RETURN VALUE:
>> + * 0 is returned on success
>> + * -EINVAL is returned if device is not supposed to wake up the
>> +system
>> + * Error code depending on the platform is returned if both the
>> +platform and
>> + * the native mechanism fail to enable the generation of wake-up
>> +events  */ int pmc_enable_wake(struct platform_device *pdev,
>> +				suspend_state_t state, bool enable)
>
>"pmc" is too generic for a global function.  If this can be either enable
>or disable, perhaps it should be something like mpc85xx_pmc_set_wake().
>
>> +{
>> +	int ret = 0;
>> +	struct device_node *clk_np;
>> +	u32 *pmcdr_mask;
>> +
>> +	if (!pmc_regs) {
>> +		printk(KERN_WARNING "PMC is unavailable\n");
>> +		return -ENOMEM;
>> +	}
>
>-ENOMEM is not appropriate here, maybe -ENODEV?
>
>Should print __func__ so the user knows what's complaining.
>
>> +	if (enable && !device_may_wakeup(&pdev->dev))
>> +		return -EINVAL;
>> +
>> +	clk_np = of_parse_phandle(pdev->dev.of_node, "clk-handle", 0);
>> +	if (!clk_np)
>> +		return -EINVAL;
>> +
>> +	pmcdr_mask = (u32 *)of_get_property(clk_np, "fsl,pmcdr-mask", NULL);
>> +	if (!pmcdr_mask) {
>> +		ret = -EINVAL;
>> +		goto out;
>> +	}
>> +
>> +	/* clear to enable clock in low power mode */
>> +	if (enable)
>> +		clrbits32(&pmc_regs->pmcdr, *pmcdr_mask);
>> +	else
>> +		setbits32(&pmc_regs->pmcdr, *pmcdr_mask);
>
>We should probably initialize PMCDR to all bits set (or at least all ones
>we know are valid) -- the default should be "not a wakeup source".

Ideally I agree with you.  But currently we only have the UI of changing wake-up source for Ethernet device.  Will do when we can change all of the devices.

>
>> +/**
>> + * pmc_enable_lossless - enable lossless ethernet in low power mode
>> + * @enable: True to enable event generation; false to disable  */
>> +void pmc_enable_lossless(int enable) {
>> +	if (enable && has_lossless)
>> +		setbits32(&pmc_regs->pmcsr, PMCSR_LOSSLESS);
>> +	else
>> +		clrbits32(&pmc_regs->pmcsr, PMCSR_LOSSLESS); }
>> +EXPORT_SYMBOL_GPL(pmc_enable_lossless);
>> +#endif
>
>Won't we overwrite this later?

You are right.  Will remove the code that overwrite this.

- Leo

^ permalink raw reply

* RE: [PATCH 7/7] gianfar: add support for wake-on-packet
From: Li Yang-R58472 @ 2011-11-08 11:20 UTC (permalink / raw)
  To: Wood Scott-B07421, Zhao Chenhui-B35336
  Cc: netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
	Fleming Andy-AFLEMING
In-Reply-To: <4EB45515.6060405@freescale.com>



>-----Original Message-----
>From: linuxppc-dev-bounces+leoli=freescale.com@lists.ozlabs.org
>[mailto:linuxppc-dev-bounces+leoli=freescale.com@lists.ozlabs.org] On
>Behalf Of Scott Wood
>Sent: Saturday, November 05, 2011 5:12 AM
>To: Zhao Chenhui-B35336
>Cc: netdev@vger.kernel.org; linuxppc-dev@lists.ozlabs.org; Fleming Andy-
>AFLEMING
>Subject: Re: [PATCH 7/7] gianfar: add support for wake-on-packet
>
>On 11/04/2011 07:40 AM, Zhao Chenhui wrote:
>> diff --git a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
>b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
>> index 2c6be03..543e36c 100644
>> --- a/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
>> +++ b/Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
>> @@ -56,6 +56,9 @@ Properties:
>>      hardware.
>>    - fsl,magic-packet : If present, indicates that the hardware supports
>>      waking up via magic packet.
>> +  - fsl,wake-on-filer : If present, indicates that the hardware
>supports
>> +    waking up via arp request to local ip address or unicast packet to
>> +    local mac address.
>
>Is there any way to determine this at runtime via the device's registers?
>
>I think TSEC_ID2[TSEC_CFG] can be used.  The manual describes it
>awkwardly, but it looks like 0x20 is the bit for the filer.

That bit only defines the filer feature but not wakeup on it.  Another solution is to get the capability from the fsl_pmc driver, but will make the driver a lot more complex.

>
>> @@ -751,7 +764,6 @@ static int gfar_of_init(struct platform_device
>*ofdev, struct net_device **pdev)
>>  			FSL_GIANFAR_DEV_HAS_PADDING |
>>  			FSL_GIANFAR_DEV_HAS_CSUM |
>>  			FSL_GIANFAR_DEV_HAS_VLAN |
>> -			FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
>>  			FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
>>  			FSL_GIANFAR_DEV_HAS_TIMER;
>
>This is an unrelated change.  Are there any eTSECs that don't support
>magic packet?

I'm not sure.  But as we have the property for it in device tree, we use it.

>
>> +static int gfar_get_ip(struct net_device *dev)
>> +{
>> +	struct gfar_private *priv = netdev_priv(dev);
>> +	struct in_device *in_dev = (struct in_device *)dev->ip_ptr;
>> +	struct in_ifaddr *ifa;
>> +
>> +	if (in_dev != NULL) {
>> +		ifa = (struct in_ifaddr *)in_dev->ifa_list;
>> +		if (ifa != NULL) {
>> +			memcpy(priv->ip_addr, &ifa->ifa_address, 4);
>> +			return 0;
>> +		}
>> +	}
>> +	return -ENOENT;
>> +}
>
>Unnecessary cast, ifa_list is already struct in_ifaddr *.
>
>Better, use for_primary_ifa(), and document that you won't wake on ARP
>packets for secondary IP addresses.
>
>>  static int gfar_suspend(struct device *dev)
>>  {
>> @@ -1268,9 +1443,17 @@ static int gfar_suspend(struct device *dev)
>>  	struct gfar __iomem *regs = priv->gfargrp[0].regs;
>>  	unsigned long flags;
>>  	u32 tempval;
>> -
>>  	int magic_packet = priv->wol_en &&
>> -		(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
>> +		(priv->wol_opts & GIANFAR_WOL_MAGIC);
>> +	int arp_packet = priv->wol_en &&
>> +		(priv->wol_opts & GIANFAR_WOL_ARP);
>> +
>> +	if (arp_packet) {
>> +		pmc_enable_wake(priv->ofdev, PM_SUSPEND_MEM, 1);
>> +		pmc_enable_lossless(1);
>> +		gfar_arp_suspend(ndev);
>> +		return 0;
>> +	}
>
>How do we know this isn't standby?

Maybe we can remove the PM state parameter from the API.

- Leo

^ permalink raw reply

* netem: Gilbert, Simple Gilbert, Bernouli loss model broken
From: Marcus Wermuth @ 2011-11-08 11:40 UTC (permalink / raw)
  To: netdev

Hey,

I wanted to try the netem extension to setup a loss via Gilbert,
Simple Gilbert, Bernouli loss model[1]. Kernel support is included
since several releases. But configuration as demonstrated in [1] does
not work at all. It seems that the userspace part in iproute is
missing, the original patch from the authors does not work.

Does anybody know about that?

Bye, Marcus

(I'm not subscribed to netdev-list)

[1] http://netgroup.uniroma2.it/twiki/bin/view.cgi/Main/NetemCLG

^ permalink raw reply

* [PATCH v4 0/3] SUNRPC: rcbind clients virtualization
From: Stanislav Kinsbursky @ 2011-11-08 11:41 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel

This patch-set was created in context of clone of git branch:
git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git.

v4:
1) Rebased of current repo state (i.e. all commits pulled before apply)

v3:
1) First two patches from previous version were squashed.

I feel it is ready for inclusion when the next merge window opens if no
objections wil appear.

This patch-set virtualizes rpcbind clients per network namespace context. IOW,
each network namespace will have its own pair of rpcbind clients (if they would
be created by request).

Note:
init_net pointer is still used instead of current->nsproxy->net_ns, because I'm
not sure yet about how to virtualize services. I.e. NFS callback services will
be per netns. NFSd service will be per netns too from my pow. But Lockd can be
per netns or one for all. And also we have NFSd file system, which is not
virtualized yet.

The following series consists of:

---

Stanislav Kinsbursky (3):
      SUNRPC: move rpcbind internals to sunrpc part of network namespace context
      SUNRPC: optimize net_ns dereferencing in rpcbind creation calls
      SUNRPC: optimize net_ns dereferencing in rpcbind registering calls


 net/sunrpc/netns.h     |    5 ++
 net/sunrpc/rpcb_clnt.c |  103 ++++++++++++++++++++++++++----------------------
 2 files changed, 61 insertions(+), 47 deletions(-)

-- 
Signature

^ permalink raw reply

* [PATCH v4 1/3] SUNRPC: move rpcbind internals to sunrpc part of network namespace context
From: Stanislav Kinsbursky @ 2011-11-08 11:41 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108104023.1714.87978.stgit@localhost6.localdomain6>

This patch makes rpcbind logic works in network namespace context. IOW each
network namespace will have it's own unique rpcbind internals (clients and
friends) which is required for registering svc services per network namespace.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/netns.h     |    5 ++++
 net/sunrpc/rpcb_clnt.c |   64 ++++++++++++++++++++++++++----------------------
 2 files changed, 40 insertions(+), 29 deletions(-)

diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index d013bf2..83eede3 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -9,6 +9,11 @@ struct cache_detail;
 struct sunrpc_net {
 	struct proc_dir_entry *proc_net_rpc;
 	struct cache_detail *ip_map_cache;
+
+	struct rpc_clnt *rpcb_local_clnt;
+	struct rpc_clnt *rpcb_local_clnt4;
+	spinlock_t rpcb_clnt_lock;
+	unsigned int rpcb_users;
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 8761bf8..7d32f19 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -23,12 +23,15 @@
 #include <linux/errno.h>
 #include <linux/mutex.h>
 #include <linux/slab.h>
+#include <linux/nsproxy.h>
 #include <net/ipv6.h>
 
 #include <linux/sunrpc/clnt.h>
 #include <linux/sunrpc/sched.h>
 #include <linux/sunrpc/xprtsock.h>
 
+#include "netns.h"
+
 #ifdef RPC_DEBUG
 # define RPCDBG_FACILITY	RPCDBG_BIND
 #endif
@@ -111,12 +114,6 @@ static void			rpcb_getport_done(struct rpc_task *, void *);
 static void			rpcb_map_release(void *data);
 static struct rpc_program	rpcb_program;
 
-static struct rpc_clnt *	rpcb_local_clnt;
-static struct rpc_clnt *	rpcb_local_clnt4;
-
-DEFINE_SPINLOCK(rpcb_clnt_lock);
-unsigned int			rpcb_users;
-
 struct rpcbind_args {
 	struct rpc_xprt *	r_xprt;
 
@@ -167,29 +164,31 @@ static void rpcb_map_release(void *data)
 static int rpcb_get_local(void)
 {
 	int cnt;
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
-	spin_lock(&rpcb_clnt_lock);
-	if (rpcb_users)
-		rpcb_users++;
-	cnt = rpcb_users;
-	spin_unlock(&rpcb_clnt_lock);
+	spin_lock(&sn->rpcb_clnt_lock);
+	if (sn->rpcb_users)
+		sn->rpcb_users++;
+	cnt = sn->rpcb_users;
+	spin_unlock(&sn->rpcb_clnt_lock);
 
 	return cnt;
 }
 
 void rpcb_put_local(void)
 {
-	struct rpc_clnt *clnt = rpcb_local_clnt;
-	struct rpc_clnt *clnt4 = rpcb_local_clnt4;
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+	struct rpc_clnt *clnt = sn->rpcb_local_clnt;
+	struct rpc_clnt *clnt4 = sn->rpcb_local_clnt4;
 	int shutdown;
 
-	spin_lock(&rpcb_clnt_lock);
-	if (--rpcb_users == 0) {
-		rpcb_local_clnt = NULL;
-		rpcb_local_clnt4 = NULL;
+	spin_lock(&sn->rpcb_clnt_lock);
+	if (--sn->rpcb_users == 0) {
+		sn->rpcb_local_clnt = NULL;
+		sn->rpcb_local_clnt4 = NULL;
 	}
-	shutdown = !rpcb_users;
-	spin_unlock(&rpcb_clnt_lock);
+	shutdown = !sn->rpcb_users;
+	spin_unlock(&sn->rpcb_clnt_lock);
 
 	if (shutdown) {
 		/*
@@ -204,14 +203,16 @@ void rpcb_put_local(void)
 
 static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
 {
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+
 	/* Protected by rpcb_create_local_mutex */
-	rpcb_local_clnt = clnt;
-	rpcb_local_clnt4 = clnt4;
+	sn->rpcb_local_clnt = clnt;
+	sn->rpcb_local_clnt4 = clnt4;
 	smp_wmb(); 
-	rpcb_users = 1;
+	sn->rpcb_users = 1;
 	dprintk("RPC:       created new rpcb local clients (rpcb_local_clnt: "
-			"%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
-			rpcb_local_clnt4);
+			"%p, rpcb_local_clnt4: %p)\n", sn->rpcb_local_clnt,
+			sn->rpcb_local_clnt4);
 }
 
 /*
@@ -431,6 +432,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	struct rpc_message msg = {
 		.rpc_argp	= &map,
 	};
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	dprintk("RPC:       %sregistering (%u, %u, %d, %u) with local "
 			"rpcbind\n", (port ? "" : "un"),
@@ -440,7 +442,7 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 	if (port)
 		msg.rpc_proc = &rpcb_procedures2[RPCBPROC_SET];
 
-	return rpcb_register_call(rpcb_local_clnt, &msg);
+	return rpcb_register_call(sn->rpcb_local_clnt, &msg);
 }
 
 /*
@@ -453,6 +455,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
 	struct rpcbind_args *map = msg->rpc_argp;
 	unsigned short port = ntohs(sin->sin_port);
 	int result;
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
 
@@ -465,7 +468,7 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
 	if (port)
 		msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 
-	result = rpcb_register_call(rpcb_local_clnt4, msg);
+	result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
 	kfree(map->r_addr);
 	return result;
 }
@@ -480,6 +483,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
 	struct rpcbind_args *map = msg->rpc_argp;
 	unsigned short port = ntohs(sin6->sin6_port);
 	int result;
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
 
@@ -492,7 +496,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
 	if (port)
 		msg->rpc_proc = &rpcb_procedures4[RPCBPROC_SET];
 
-	result = rpcb_register_call(rpcb_local_clnt4, msg);
+	result = rpcb_register_call(sn->rpcb_local_clnt4, msg);
 	kfree(map->r_addr);
 	return result;
 }
@@ -500,6 +504,7 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
 static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
 {
 	struct rpcbind_args *map = msg->rpc_argp;
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	dprintk("RPC:       unregistering [%u, %u, '%s'] with "
 		"local rpcbind\n",
@@ -508,7 +513,7 @@ static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
 	map->r_addr = "";
 	msg->rpc_proc = &rpcb_procedures4[RPCBPROC_UNSET];
 
-	return rpcb_register_call(rpcb_local_clnt4, msg);
+	return rpcb_register_call(sn->rpcb_local_clnt4, msg);
 }
 
 /**
@@ -566,8 +571,9 @@ int rpcb_v4_register(const u32 program, const u32 version,
 	struct rpc_message msg = {
 		.rpc_argp	= &map,
 	};
+	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
-	if (rpcb_local_clnt4 == NULL)
+	if (sn->rpcb_local_clnt4 == NULL)
 		return -EPROTONOSUPPORT;
 
 	if (address == NULL)

^ permalink raw reply related

* [PATCH v4 2/3] SUNRPC: optimize net_ns dereferencing in rpcbind creation calls
From: Stanislav Kinsbursky @ 2011-11-08 11:41 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108104023.1714.87978.stgit@localhost6.localdomain6>

Static rpcbind creation functions can be parametrized by network namespace
pointer, calculated only once, instead of using init_net pointer (or taking it
from current when virtualization will be comleted) in many places.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/rpcb_clnt.c |   35 +++++++++++++++++++----------------
 1 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 7d32f19..3df276a 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -161,10 +161,10 @@ static void rpcb_map_release(void *data)
 	kfree(map);
 }
 
-static int rpcb_get_local(void)
+static int rpcb_get_local(struct net *net)
 {
 	int cnt;
-	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
 	spin_lock(&sn->rpcb_clnt_lock);
 	if (sn->rpcb_users)
@@ -201,9 +201,10 @@ void rpcb_put_local(void)
 	}
 }
 
-static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
+static void rpcb_set_local(struct net *net, struct rpc_clnt *clnt,
+			struct rpc_clnt *clnt4)
 {
-	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
 	/* Protected by rpcb_create_local_mutex */
 	sn->rpcb_local_clnt = clnt;
@@ -211,22 +212,23 @@ static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
 	smp_wmb(); 
 	sn->rpcb_users = 1;
 	dprintk("RPC:       created new rpcb local clients (rpcb_local_clnt: "
-			"%p, rpcb_local_clnt4: %p)\n", sn->rpcb_local_clnt,
-			sn->rpcb_local_clnt4);
+			"%p, rpcb_local_clnt4: %p) for net %p%s\n",
+			sn->rpcb_local_clnt, sn->rpcb_local_clnt4,
+			net, (net == &init_net) ? " (init_net)" : "");
 }
 
 /*
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local_unix(void)
+static int rpcb_create_local_unix(struct net *net)
 {
 	static const struct sockaddr_un rpcb_localaddr_rpcbind = {
 		.sun_family		= AF_LOCAL,
 		.sun_path		= RPCBIND_SOCK_PATHNAME,
 	};
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= net,
 		.protocol	= XPRT_TRANSPORT_LOCAL,
 		.address	= (struct sockaddr *)&rpcb_localaddr_rpcbind,
 		.addrsize	= sizeof(rpcb_localaddr_rpcbind),
@@ -259,7 +261,7 @@ static int rpcb_create_local_unix(void)
 		clnt4 = NULL;
 	}
 
-	rpcb_set_local(clnt, clnt4);
+	rpcb_set_local(net, clnt, clnt4);
 
 out:
 	return result;
@@ -269,7 +271,7 @@ out:
  * Returns zero on success, otherwise a negative errno value
  * is returned.
  */
-static int rpcb_create_local_net(void)
+static int rpcb_create_local_net(struct net *net)
 {
 	static const struct sockaddr_in rpcb_inaddr_loopback = {
 		.sin_family		= AF_INET,
@@ -277,7 +279,7 @@ static int rpcb_create_local_net(void)
 		.sin_port		= htons(RPCBIND_PORT),
 	};
 	struct rpc_create_args args = {
-		.net		= &init_net,
+		.net		= net,
 		.protocol	= XPRT_TRANSPORT_TCP,
 		.address	= (struct sockaddr *)&rpcb_inaddr_loopback,
 		.addrsize	= sizeof(rpcb_inaddr_loopback),
@@ -311,7 +313,7 @@ static int rpcb_create_local_net(void)
 		clnt4 = NULL;
 	}
 
-	rpcb_set_local(clnt, clnt4);
+	rpcb_set_local(net, clnt, clnt4);
 
 out:
 	return result;
@@ -325,16 +327,17 @@ int rpcb_create_local(void)
 {
 	static DEFINE_MUTEX(rpcb_create_local_mutex);
 	int result = 0;
+	struct net *net = &init_net;
 
-	if (rpcb_get_local())
+	if (rpcb_get_local(net))
 		return result;
 
 	mutex_lock(&rpcb_create_local_mutex);
-	if (rpcb_get_local())
+	if (rpcb_get_local(net))
 		goto out;
 
-	if (rpcb_create_local_unix() != 0)
-		result = rpcb_create_local_net();
+	if (rpcb_create_local_unix(net) != 0)
+		result = rpcb_create_local_net(net);
 
 out:
 	mutex_unlock(&rpcb_create_local_mutex);

^ permalink raw reply related

* [PATCH v4 3/3] SUNRPC: optimize net_ns dereferencing in rpcbind registering calls
From: Stanislav Kinsbursky @ 2011-11-08 11:41 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108104023.1714.87978.stgit@localhost6.localdomain6>

Static rpcbind registering functions can be parametrized by network namespace
pointer, calculated only once, instead of using init_net pointer (or taking it
from current when virtualization will be comleted) in many places.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/rpcb_clnt.c |   18 +++++++++---------
 1 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
index 3df276a..371d229 100644
--- a/net/sunrpc/rpcb_clnt.c
+++ b/net/sunrpc/rpcb_clnt.c
@@ -451,14 +451,14 @@ int rpcb_register(u32 prog, u32 vers, int prot, unsigned short port)
 /*
  * Fill in AF_INET family-specific arguments to register
  */
-static int rpcb_register_inet4(const struct sockaddr *sap,
+static int rpcb_register_inet4(struct sunrpc_net *sn,
+			       const struct sockaddr *sap,
 			       struct rpc_message *msg)
 {
 	const struct sockaddr_in *sin = (const struct sockaddr_in *)sap;
 	struct rpcbind_args *map = msg->rpc_argp;
 	unsigned short port = ntohs(sin->sin_port);
 	int result;
-	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
 
@@ -479,14 +479,14 @@ static int rpcb_register_inet4(const struct sockaddr *sap,
 /*
  * Fill in AF_INET6 family-specific arguments to register
  */
-static int rpcb_register_inet6(const struct sockaddr *sap,
+static int rpcb_register_inet6(struct sunrpc_net *sn,
+			       const struct sockaddr *sap,
 			       struct rpc_message *msg)
 {
 	const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)sap;
 	struct rpcbind_args *map = msg->rpc_argp;
 	unsigned short port = ntohs(sin6->sin6_port);
 	int result;
-	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	map->r_addr = rpc_sockaddr2uaddr(sap, GFP_KERNEL);
 
@@ -504,10 +504,10 @@ static int rpcb_register_inet6(const struct sockaddr *sap,
 	return result;
 }
 
-static int rpcb_unregister_all_protofamilies(struct rpc_message *msg)
+static int rpcb_unregister_all_protofamilies(struct sunrpc_net *sn,
+					     struct rpc_message *msg)
 {
 	struct rpcbind_args *map = msg->rpc_argp;
-	struct sunrpc_net *sn = net_generic(&init_net, sunrpc_net_id);
 
 	dprintk("RPC:       unregistering [%u, %u, '%s'] with "
 		"local rpcbind\n",
@@ -580,13 +580,13 @@ int rpcb_v4_register(const u32 program, const u32 version,
 		return -EPROTONOSUPPORT;
 
 	if (address == NULL)
-		return rpcb_unregister_all_protofamilies(&msg);
+		return rpcb_unregister_all_protofamilies(sn, &msg);
 
 	switch (address->sa_family) {
 	case AF_INET:
-		return rpcb_register_inet4(address, &msg);
+		return rpcb_register_inet4(sn, address, &msg);
 	case AF_INET6:
-		return rpcb_register_inet6(address, &msg);
+		return rpcb_register_inet6(sn, address, &msg);
 	}
 
 	return -EAFNOSUPPORT;

^ permalink raw reply related

* Re: Add IPSec IP Range in Linux kernel
From: Alexey Dobriyan @ 2011-11-08 12:08 UTC (permalink / raw)
  To: Peter P Waskiewicz Jr
  Cc: Daniil Stolnikov, linux-kernel@vger.kernel.org,
	netdev@vger.kernel.org, linux-crypto@vger.kernel.org,
	linux-security-module@vger.kernel.org, davem@davemloft.net
In-Reply-To: <1320733465.21617.4.camel@ppwaskie-mobl2>

On Tue, Nov 8, 2011 at 8:24 AM, Peter P Waskiewicz Jr
<peter.p.waskiewicz.jr@intel.com> wrote:
> On Mon, 2011-11-07 at 19:10 -0800, Daniil Stolnikov wrote:
>> Hello!
>>
>> Found that the stack IPSec in Linux does not support any IP range. Many people ask this question. The archives say strongswan said that their daemon supports a range, but the Linux IPSec stack supports only the subnets. I am writing to you to implement support for IP range in Linux. I think that a lot more people will appreciate this innovation.
>
> It'd be even better if you could write a patch for us to review.

oh, come on!
changing addr_match() is trivial for ipv4 and easy for ipv6. :-)

^ permalink raw reply

* [PATCH v2] SUNRPC: remove non-exclusive pipe creation from RPC pipefs
From: Stanislav Kinsbursky @ 2011-11-08 12:09 UTC (permalink / raw)
  To: Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA
  Cc: linux-nfs-u79uwXL29TY76Z2rM5mHXA, xemul-bzQdu9zFT3WakBO8gow8eQ,
	neilb-l3A5Bk7waGM, netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	jbottomley-bzQdu9zFT3WakBO8gow8eQ, bfields-uC3wQj2KruNg9hUCZPvPmw,
	davem-fT/PcQaiUtIeIZ0/mPfg9Q, devel-GEFAQzZX7r8dnm+yROfE0A

This patch-set was created in context of clone of git branch:
git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git.

v2:
1) Rebased of current repo state (i.e. all commits were pulled before apply)

I feel it is ready for inclusion if no objections will appear.

SUNRPC pipefs non-exclusive pipe creation code looks obsolete. IOW, as I see
it, all pipes are creating with unique full path and only once.

Signed-off-by: Stanislav Kinsbursky <skinsbursky-bzQdu9zFT3WakBO8gow8eQ@public.gmane.org>

---
 include/linux/sunrpc/rpc_pipe_fs.h |    1 -
 net/sunrpc/rpc_pipe.c              |   44 +++++-------------------------------
 2 files changed, 6 insertions(+), 39 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index e4ea430..08aae01 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -30,7 +30,6 @@ struct rpc_inode {
 	int pipelen;
 	int nreaders;
 	int nwriters;
-	int nkern_readwriters;
 	wait_queue_head_t waitq;
 #define RPC_PIPE_WAIT_FOR_OPEN	1
 	int flags;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index bfddd68..e2f7b7f 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -555,7 +555,6 @@ static int __rpc_mkpipe(struct inode *dir, struct dentry *dentry,
 	if (err)
 		return err;
 	rpci = RPC_I(dentry->d_inode);
-	rpci->nkern_readwriters = 1;
 	rpci->private = private;
 	rpci->flags = flags;
 	rpci->ops = ops;
@@ -588,16 +587,12 @@ static int __rpc_unlink(struct inode *dir, struct dentry *dentry)
 static int __rpc_rmpipe(struct inode *dir, struct dentry *dentry)
 {
 	struct inode *inode = dentry->d_inode;
-	struct rpc_inode *rpci = RPC_I(inode);
 
-	rpci->nkern_readwriters--;
-	if (rpci->nkern_readwriters != 0)
-		return 0;
 	rpc_close_pipes(inode);
 	return __rpc_unlink(dir, dentry);
 }
 
-static struct dentry *__rpc_lookup_create(struct dentry *parent,
+static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
 					  struct qstr *name)
 {
 	struct dentry *dentry;
@@ -605,27 +600,13 @@ static struct dentry *__rpc_lookup_create(struct dentry *parent,
 	dentry = d_lookup(parent, name);
 	if (!dentry) {
 		dentry = d_alloc(parent, name);
-		if (!dentry) {
-			dentry = ERR_PTR(-ENOMEM);
-			goto out_err;
-		}
+		if (!dentry)
+			return ERR_PTR(-ENOMEM);
 	}
-	if (!dentry->d_inode)
+	if (dentry->d_inode == NULL) {
 		d_set_d_op(dentry, &rpc_dentry_operations);
-out_err:
-	return dentry;
-}
-
-static struct dentry *__rpc_lookup_create_exclusive(struct dentry *parent,
-					  struct qstr *name)
-{
-	struct dentry *dentry;
-
-	dentry = __rpc_lookup_create(parent, name);
-	if (IS_ERR(dentry))
-		return dentry;
-	if (dentry->d_inode == NULL)
 		return dentry;
+	}
 	dput(dentry);
 	return ERR_PTR(-EEXIST);
 }
@@ -813,22 +794,9 @@ struct dentry *rpc_mkpipe(struct dentry *parent, const char *name,
 	q.hash = full_name_hash(q.name, q.len),
 
 	mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT);
-	dentry = __rpc_lookup_create(parent, &q);
+	dentry = __rpc_lookup_create_exclusive(parent, &q);
 	if (IS_ERR(dentry))
 		goto out;
-	if (dentry->d_inode) {
-		struct rpc_inode *rpci = RPC_I(dentry->d_inode);
-		if (rpci->private != private ||
-				rpci->ops != ops ||
-				rpci->flags != flags) {
-			dput (dentry);
-			err = -EBUSY;
-			goto out_err;
-		}
-		rpci->nkern_readwriters++;
-		goto out;
-	}
-
 	err = __rpc_mkpipe(dir, dentry, umode, &rpc_pipe_fops,
 			   private, ops, flags);
 	if (err)

--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related

* [PATCH v2 0/7] SUNRPC: initial part of making pipefs work in net ns
From: Stanislav Kinsbursky @ 2011-11-08 12:12 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel

This patch-set was created in context of clone of git branch:
git://git.linux-nfs.org/projects/trondmy/nfs-2.6.git.

v2:
1) Rebased of current repo state (i.e. all commits were pulled before apply)

This patch-set implements pipefs superblock creation per network namespace
context instead of using single one for all possible contexts. Also, it
provides pipefs dentries creation and destruction helpers for kernel routines.

Additional description of the idea about how to make RPC pipefs work per
network namespace context can be found in the letter titled "SUNRPC: "RPC
pipefs per network namespace" preparations", which has been sent already to
linux-nfs@vger.kernel.org.

The following series consists of:

---

Stanislav Kinsbursky (7):
      SUNRPC: create RPC pipefs superblock per network namespace context
      SUNRPC: hold current network namespace while pipefs superblock is active
      SUNRPC: send notification events on pipefs sb creation and destruction
      SUNRPC: pipefs dentry lookup helper introduced
      SUNRPC: put pipefs superblock link on network namespace
      SUNRPC: pipefs per-net operations helper introduced
      SUNRPC: added debug messages to RPC pipefs


 include/linux/sunrpc/rpc_pipe_fs.h |   14 ++++
 net/sunrpc/netns.h                 |    3 +
 net/sunrpc/rpc_pipe.c              |  113 +++++++++++++++++++++++++++++++++++-
 net/sunrpc/sunrpc_syms.c           |    1 
 4 files changed, 129 insertions(+), 2 deletions(-)

-- 
Signature

^ permalink raw reply

* [PATCH v2 1/7] SUNRPC: create RPC pipefs superblock per network namespace context
From: Stanislav Kinsbursky @ 2011-11-08 12:12 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

This is the initial step of RPC pipefs virtualization. It changes nothing to
current pipefs behaviour except that mount of pipefs in other than init_net
network namespace context will provide only root tree. No other dentries will
be visible.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/rpc_pipe.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e2f7b7f..bb8a40b 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -994,6 +994,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 {
 	struct inode *inode;
 	struct dentry *root;
+	struct net *net = data;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1018,7 +1019,7 @@ static struct dentry *
 rpc_mount(struct file_system_type *fs_type,
 		int flags, const char *dev_name, void *data)
 {
-	return mount_single(fs_type, flags, data, rpc_fill_super);
+	return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super);
 }
 
 static struct file_system_type rpc_pipe_fs_type = {

^ permalink raw reply related

* [PATCH v2 2/7] SUNRPC: hold current network namespace while pipefs superblock is active
From: Stanislav Kinsbursky @ 2011-11-08 12:12 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

We want to be sure that network namespace is still alive while we have pipefs
mounted.
This will be required later, when RPC pipefs will be mounting only from
user-space context.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/rpc_pipe.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index bb8a40b..ff41fef 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -27,6 +27,9 @@
 #include <linux/workqueue.h>
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/cache.h>
+#include <linux/nsproxy.h>
+
+#include "netns.h"
 
 static struct vfsmount *rpc_mnt __read_mostly;
 static int rpc_mount_count;
@@ -1012,6 +1015,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
+	sb->s_fs_info = get_net(net);
 	return 0;
 }
 
@@ -1022,11 +1026,19 @@ rpc_mount(struct file_system_type *fs_type,
 	return mount_ns(fs_type, flags, current->nsproxy->net_ns, rpc_fill_super);
 }
 
+void rpc_kill_sb(struct super_block *sb)
+{
+	struct net *net = sb->s_fs_info;
+
+	put_net(net);
+	kill_litter_super(sb);
+}
+
 static struct file_system_type rpc_pipe_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= "rpc_pipefs",
 	.mount		= rpc_mount,
-	.kill_sb	= kill_litter_super,
+	.kill_sb	= rpc_kill_sb,
 };
 
 static void

^ permalink raw reply related

* [PATCH v2 3/7] SUNRPC: send notification events on pipefs sb creation and destruction
From: Stanislav Kinsbursky @ 2011-11-08 12:12 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

They will be used to notify subscribers about pipefs superblock creation and
destruction.
Subcribers will have to create their dentries on passed superblock on mount
event and destroy otherwise.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/rpc_pipe_fs.h |    8 ++++++++
 net/sunrpc/rpc_pipe.c              |   32 ++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 08aae01..733ef50 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -43,6 +43,14 @@ RPC_I(struct inode *inode)
 	return container_of(inode, struct rpc_inode, vfs_inode);
 }
 
+extern int rpc_pipefs_notifier_register(struct notifier_block *);
+extern void rpc_pipefs_notifier_unregister(struct notifier_block *);
+
+enum {
+	RPC_PIPEFS_MOUNT,
+	RPC_PIPEFS_UMOUNT,
+};
+
 extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
 				       char __user *, size_t);
 extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index ff41fef..07fb7dd 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -28,8 +28,10 @@
 #include <linux/sunrpc/rpc_pipe_fs.h>
 #include <linux/sunrpc/cache.h>
 #include <linux/nsproxy.h>
+#include <linux/notifier.h>
 
 #include "netns.h"
+#include "sunrpc.h"
 
 static struct vfsmount *rpc_mnt __read_mostly;
 static int rpc_mount_count;
@@ -41,6 +43,20 @@ static struct kmem_cache *rpc_inode_cachep __read_mostly;
 
 #define RPC_UPCALL_TIMEOUT (30*HZ)
 
+static BLOCKING_NOTIFIER_HEAD(rpc_pipefs_notifier_list);
+
+int rpc_pipefs_notifier_register(struct notifier_block *nb)
+{
+	return blocking_notifier_chain_cond_register(&rpc_pipefs_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_register);
+
+void rpc_pipefs_notifier_unregister(struct notifier_block *nb)
+{
+	blocking_notifier_chain_unregister(&rpc_pipefs_notifier_list, nb);
+}
+EXPORT_SYMBOL_GPL(rpc_pipefs_notifier_unregister);
+
 static void rpc_purge_list(struct rpc_inode *rpci, struct list_head *head,
 		void (*destroy_msg)(struct rpc_pipe_msg *), int err)
 {
@@ -998,6 +1014,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	struct inode *inode;
 	struct dentry *root;
 	struct net *net = data;
+	int err;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
 	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
@@ -1015,8 +1032,20 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
+	err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_MOUNT,
+					   sb);
+	if (err)
+		goto err_depopulate;
 	sb->s_fs_info = get_net(net);
 	return 0;
+
+err_depopulate:
+	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_UMOUNT,
+					   sb);
+	__rpc_depopulate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF);
+	return err;
 }
 
 static struct dentry *
@@ -1031,6 +1060,9 @@ void rpc_kill_sb(struct super_block *sb)
 	struct net *net = sb->s_fs_info;
 
 	put_net(net);
+	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
+					   RPC_PIPEFS_UMOUNT,
+					   sb);
 	kill_litter_super(sb);
 }
 

^ permalink raw reply related

* [PATCH v2 4/7] SUNRPC: pipefs dentry lookup helper introduced
From: Stanislav Kinsbursky @ 2011-11-08 12:12 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

In all places, where pipefs dentries are created, only directory inode is
actually required to create new dentry. And all this directories has root
pipefs dentry as their parent. So we actually don't need this pipefs mount
point at all if some pipefs lookup method will be provided.
IOW, all we really need is just superblock and simple lookup method to find
root's child dentry with appropriate name. And this patch introduces this
method.
Note, that no locking implemented in rpc_d_lookup_sb(). So it can be used only
in case of assurance, that pipefs superblock still exist. IOW, we can use this
method only in pipefs mount-umount notification subscribers callbacks.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/rpc_pipe_fs.h |    3 +++
 net/sunrpc/rpc_pipe.c              |   16 ++++++++++++++++
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 733ef50..4585985 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -51,6 +51,9 @@ enum {
 	RPC_PIPEFS_UMOUNT,
 };
 
+extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+				      const unsigned char *dir_name);
+
 extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
 				       char __user *, size_t);
 extern int rpc_queue_upcall(struct inode *, struct rpc_pipe_msg *);
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 07fb7dd..1de840d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1008,6 +1008,22 @@ static const struct rpc_filelist files[] = {
 	},
 };
 
+/*
+ * This call can be used only in RPC pipefs mount notification hooks.
+ */
+struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
+			       const unsigned char *dir_name)
+{
+	struct qstr dir = {
+		.name = dir_name,
+		.len = strlen(dir_name),
+		.hash = full_name_hash(dir_name, strlen(dir_name)),
+	};
+
+	return d_lookup(sb->s_root, &dir);
+}
+EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
+
 static int
 rpc_fill_super(struct super_block *sb, void *data, int silent)
 {

^ permalink raw reply related

* [PATCH v2 5/7] SUNRPC: put pipefs superblock link on network namespace
From: Stanislav Kinsbursky @ 2011-11-08 12:12 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

We have modules (like, pNFS blocklayout module) which creates pipes on
rpc_pipefs. Thus we need per-net operations for them. To make it possible we
require appropriate super block. So we have to put sb link on network namespace
context. Note, that it's not strongly required to create pipes in per-net
operations. IOW, if pipefs wasn't mounted yet, that no sb link reference will
present on network namespace and in this case we need just need to pass through
pipe creation. Pipe dentry will be created during pipefs mount notification.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/netns.h    |    2 ++
 net/sunrpc/rpc_pipe.c |    4 ++++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index d013bf2..b384252 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -9,6 +9,8 @@ struct cache_detail;
 struct sunrpc_net {
 	struct proc_dir_entry *proc_net_rpc;
 	struct cache_detail *ip_map_cache;
+
+	struct super_block *pipefs_sb;
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 1de840d..831e81d 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1030,6 +1030,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	struct inode *inode;
 	struct dentry *root;
 	struct net *net = data;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 	int err;
 
 	sb->s_blocksize = PAGE_CACHE_SIZE;
@@ -1054,6 +1055,7 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	if (err)
 		goto err_depopulate;
 	sb->s_fs_info = get_net(net);
+	sn->pipefs_sb = sb;
 	return 0;
 
 err_depopulate:
@@ -1074,7 +1076,9 @@ rpc_mount(struct file_system_type *fs_type,
 void rpc_kill_sb(struct super_block *sb)
 {
 	struct net *net = sb->s_fs_info;
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
+	sn->pipefs_sb = NULL;
 	put_net(net);
 	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_UMOUNT,

^ permalink raw reply related

* [PATCH v2 6/7] SUNRPC: pipefs per-net operations helper introduced
From: Stanislav Kinsbursky @ 2011-11-08 12:13 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

During per-net pipes creation and destruction we have to make sure, that pipefs
sb exists for the whole creation/destruction cycle. This is done by using
special mutex which controls pipefs sb reference on network namespace context.
Helper consists of two parts: first of them (rpc_get_dentry_net) searches for
dentry with specified name and returns with mutex taken on success. When pipe
creation or destructions is completed, caller should release this mutex by
rpc_put_dentry_net call.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 include/linux/sunrpc/rpc_pipe_fs.h |    3 +++
 net/sunrpc/netns.h                 |    1 +
 net/sunrpc/rpc_pipe.c              |   36 ++++++++++++++++++++++++++++++++++++
 net/sunrpc/sunrpc_syms.c           |    1 +
 4 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/include/linux/sunrpc/rpc_pipe_fs.h b/include/linux/sunrpc/rpc_pipe_fs.h
index 4585985..f32490c 100644
--- a/include/linux/sunrpc/rpc_pipe_fs.h
+++ b/include/linux/sunrpc/rpc_pipe_fs.h
@@ -53,6 +53,9 @@ enum {
 
 extern struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
 				      const unsigned char *dir_name);
+extern void rpc_pipefs_init_net(struct net *net);
+extern struct super_block *rpc_get_sb_net(const struct net *net);
+extern void rpc_put_sb_net(const struct net *net);
 
 extern ssize_t rpc_pipe_generic_upcall(struct file *, struct rpc_pipe_msg *,
 				       char __user *, size_t);
diff --git a/net/sunrpc/netns.h b/net/sunrpc/netns.h
index b384252..11d2f48 100644
--- a/net/sunrpc/netns.h
+++ b/net/sunrpc/netns.h
@@ -11,6 +11,7 @@ struct sunrpc_net {
 	struct cache_detail *ip_map_cache;
 
 	struct super_block *pipefs_sb;
+	struct mutex pipefs_sb_lock;
 };
 
 extern int sunrpc_net_id;
diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index 831e81d..e40ec55 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -1024,6 +1024,40 @@ struct dentry *rpc_d_lookup_sb(const struct super_block *sb,
 }
 EXPORT_SYMBOL_GPL(rpc_d_lookup_sb);
 
+void rpc_pipefs_init_net(struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	mutex_init(&sn->pipefs_sb_lock);
+}
+
+/*
+ * This call will be used for per network namespace operations calls.
+ * Note: Function will be returned with pipefs_sb_lock taken if superblock was
+ * found. This lock have to be released by rpc_put_sb_net() when all operations
+ * will be completed.
+ */
+struct super_block *rpc_get_sb_net(const struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	mutex_lock(&sn->pipefs_sb_lock);
+	if (sn->pipefs_sb)
+		return sn->pipefs_sb;
+	mutex_unlock(&sn->pipefs_sb_lock);
+	return NULL;
+}
+EXPORT_SYMBOL_GPL(rpc_get_sb_net);
+
+void rpc_put_sb_net(const struct net *net)
+{
+	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
+
+	BUG_ON(sn->pipefs_sb == NULL);
+	mutex_unlock(&sn->pipefs_sb_lock);
+}
+EXPORT_SYMBOL_GPL(rpc_put_sb_net);
+
 static int
 rpc_fill_super(struct super_block *sb, void *data, int silent)
 {
@@ -1078,7 +1112,9 @@ void rpc_kill_sb(struct super_block *sb)
 	struct net *net = sb->s_fs_info;
 	struct sunrpc_net *sn = net_generic(net, sunrpc_net_id);
 
+	mutex_lock(&sn->pipefs_sb_lock);
 	sn->pipefs_sb = NULL;
+	mutex_unlock(&sn->pipefs_sb_lock);
 	put_net(net);
 	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_UMOUNT,
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c
index 8ec9778..7086d11 100644
--- a/net/sunrpc/sunrpc_syms.c
+++ b/net/sunrpc/sunrpc_syms.c
@@ -38,6 +38,7 @@ static __net_init int sunrpc_init_net(struct net *net)
 	if (err)
 		goto err_ipmap;
 
+	rpc_pipefs_init_net(net);
 	return 0;
 
 err_ipmap:

^ permalink raw reply related

* [PATCH v2 7/7] SUNRPC: added debug messages to RPC pipefs
From: Stanislav Kinsbursky @ 2011-11-08 12:13 UTC (permalink / raw)
  To: Trond.Myklebust
  Cc: linux-nfs, xemul, neilb, netdev, linux-kernel, jbottomley,
	bfields, davem, devel
In-Reply-To: <20111108111056.6206.11410.stgit@localhost6.localdomain6>

This patch adds debug messages for notification events.

Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

---
 net/sunrpc/rpc_pipe.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/net/sunrpc/rpc_pipe.c b/net/sunrpc/rpc_pipe.c
index e40ec55..0cafd59 100644
--- a/net/sunrpc/rpc_pipe.c
+++ b/net/sunrpc/rpc_pipe.c
@@ -33,6 +33,10 @@
 #include "netns.h"
 #include "sunrpc.h"
 
+#define RPCDBG_FACILITY RPCDBG_DEBUG
+
+#define NET_NAME(net)	((net == &init_net) ? " (init_net)" : "")
+
 static struct vfsmount *rpc_mnt __read_mostly;
 static int rpc_mount_count;
 
@@ -1083,6 +1087,8 @@ rpc_fill_super(struct super_block *sb, void *data, int silent)
 	}
 	if (rpc_populate(root, files, RPCAUTH_lockd, RPCAUTH_RootEOF, NULL))
 		return -ENOMEM;
+	dprintk("RPC:	sending pipefs MOUNT notification for net %p%s\n", net,
+								NET_NAME(net));
 	err = blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_MOUNT,
 					   sb);
@@ -1116,6 +1122,8 @@ void rpc_kill_sb(struct super_block *sb)
 	sn->pipefs_sb = NULL;
 	mutex_unlock(&sn->pipefs_sb_lock);
 	put_net(net);
+	dprintk("RPC:	sending pipefs UMOUNT notification for net %p%s\n", net,
+								NET_NAME(net));
 	blocking_notifier_call_chain(&rpc_pipefs_notifier_list,
 					   RPC_PIPEFS_UMOUNT,
 					   sb);

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox