* [PATCH 3/4] sis190: mdio operation failure is not correctly detected
From: Francois Romieu @ 2007-12-10 22:31 UTC (permalink / raw)
To: jeff; +Cc: Andrew Morton, netdev, K.M. Liu
In-Reply-To: <20071210222732.GA8675@electric-eye.fr.zoreil.com>
i ranges from 0 to 100 in the 'for' loop a few lines above.
Reported by davem.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: K.M. Liu <kmliu@sis.com.tw>
---
drivers/net/sis190.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index f6a921c..973b369 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -372,7 +372,7 @@ static void __mdio_cmd(void __iomem *ioaddr, u32 ctl)
msleep(1);
}
- if (i > 999)
+ if (i > 99)
printk(KERN_ERR PFX "PHY command failed !\n");
}
--
1.5.3.3
^ permalink raw reply related
* [PATCH 2/4] sis190: remove duplicate INIT_WORK
From: Francois Romieu @ 2007-12-10 22:30 UTC (permalink / raw)
To: jeff; +Cc: Andrew Morton, netdev, K.M. Liu
In-Reply-To: <20071210222732.GA8675@electric-eye.fr.zoreil.com>
It is already done in sis190_init_one.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: K.M. Liu <kmliu@sis.com.tw>
---
drivers/net/sis190.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 51bbb60..f6a921c 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -1041,8 +1041,6 @@ static int sis190_open(struct net_device *dev)
if (rc < 0)
goto err_free_rx_1;
- INIT_WORK(&tp->phy_task, sis190_phy_task);
-
sis190_request_timer(dev);
rc = request_irq(dev->irq, sis190_interrupt, IRQF_SHARED, dev->name, dev);
--
1.5.3.3
^ permalink raw reply related
* [PATCH 0/4] Pull request for 'sis190' branch
From: Francois Romieu @ 2007-12-10 22:27 UTC (permalink / raw)
To: jeff; +Cc: Andrew Morton, netdev, K.M. Liu
Please pull from branch 'sis190' in repository
git://git.kernel.org/pub/scm/linux/kernel/git/romieu/netdev-2.6.git sis190
to get the changes below.
Distance from 'upstream-linus' (7962024e9d16e9349d76b553326f3fa7be64305e)
-------------------------------------------------------------------------
c27e14e508664471b8e44ef1f81ec080213ea314
348de67fe200e25d8cb80cff35642192436cfeda
004a22d03d62cd08e5287273a5143447db009cd0
14deb44ffe7220be2de697d616f28cce17e72297
Diffstat
--------
drivers/net/sis190.c | 21 ++++++++++-----------
1 files changed, 10 insertions(+), 11 deletions(-)
Shortlog
--------
Francois Romieu (4):
sis190: add cmos ram access code for the SiS19x/968 chipset pair
sis190: remove duplicate INIT_WORK
sis190: mdio operation failure is not correctly detected
sis190: scheduling while atomic error
Patch
-----
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 7200883..c0db182 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -372,7 +372,7 @@ static void __mdio_cmd(void __iomem *ioaddr, u32 ctl)
msleep(1);
}
- if (i > 999)
+ if (i > 99)
printk(KERN_ERR PFX "PHY command failed !\n");
}
@@ -847,10 +847,8 @@ static void sis190_soft_reset(void __iomem *ioaddr)
{
SIS_W32(IntrControl, 0x8000);
SIS_PCI_COMMIT();
- msleep(1);
SIS_W32(IntrControl, 0x0);
sis190_asic_down(ioaddr);
- msleep(1);
}
static void sis190_hw_start(struct net_device *dev)
@@ -1041,8 +1039,6 @@ static int sis190_open(struct net_device *dev)
if (rc < 0)
goto err_free_rx_1;
- INIT_WORK(&tp->phy_task, sis190_phy_task);
-
sis190_request_timer(dev);
rc = request_irq(dev->irq, sis190_interrupt, IRQF_SHARED, dev->name, dev);
@@ -1549,28 +1545,31 @@ static int __devinit sis190_get_mac_addr_from_eeprom(struct pci_dev *pdev,
}
/**
- * sis190_get_mac_addr_from_apc - Get MAC address for SiS965 model
+ * sis190_get_mac_addr_from_apc - Get MAC address for SiS96x model
* @pdev: PCI device
* @dev: network device to get address for
*
- * SiS965 model, use APC CMOS RAM to store MAC address.
+ * SiS96x model, use APC CMOS RAM to store MAC address.
* APC CMOS RAM is accessed through ISA bridge.
* MAC address is read into @net_dev->dev_addr.
*/
static int __devinit sis190_get_mac_addr_from_apc(struct pci_dev *pdev,
struct net_device *dev)
{
+ static const u16 __devinitdata ids[] = { 0x0965, 0x0966, 0x0968 };
struct sis190_private *tp = netdev_priv(dev);
struct pci_dev *isa_bridge;
u8 reg, tmp8;
- int i;
+ unsigned int i;
net_probe(tp, KERN_INFO "%s: Read MAC address from APC.\n",
pci_name(pdev));
- isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0965, NULL);
- if (!isa_bridge)
- isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, 0x0966, NULL);
+ for (i = 0; i < ARRAY_SIZE(ids); i++) {
+ isa_bridge = pci_get_device(PCI_VENDOR_ID_SI, ids[i], NULL);
+ if (isa_bridge)
+ break;
+ }
if (!isa_bridge) {
net_probe(tp, KERN_INFO "%s: Can not find ISA bridge.\n",
--
Ueimor
^ permalink raw reply related
* [PATCH net-2.6.25] qdisc: new rate limiter (v2)
From: Stephen Hemminger @ 2007-12-10 21:28 UTC (permalink / raw)
To: Patrick McHardy, David S. Miller; +Cc: netdev
In-Reply-To: <475A0804.1060006@trash.net>
This is a time based rate limiter for use in network testing. When doing
network tests it is often useful to test at reduced bandwidths. The existing
Token Bucket Filter provides rate control, but causes bursty traffic that
can cause different performance than real world. Another alternative is
the PSPacer, but it depends on pause frames which may also cause issues.
The qdisc depends on high resolution timers and clocks, so it will probably
use more CPU than others making it a poor choice for use when doing traffic
shaping for QOS.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
include/linux/pkt_sched.h | 15 +
net/sched/Kconfig | 13 +
net/sched/Makefile | 1
net/sched/sch_rlim.c | 354 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 383 insertions(+)
--- a/include/linux/pkt_sched.h 2007-12-10 13:08:36.000000000 -0800
+++ b/include/linux/pkt_sched.h 2007-12-10 13:08:39.000000000 -0800
@@ -475,4 +475,19 @@ struct tc_netem_corrupt
#define NETEM_DIST_SCALE 8192
+enum
+{
+ TCA_RLIM_UNSPEC,
+ TCA_RLIM_PARMS,
+ __TCA_RLIM_MAX,
+};
+#define TCA_RLIM_MAX (__TCA_RLIM_MAX - 1)
+
+struct tc_rlim_qopt
+{
+ __u64 rate; /* bits per sec */
+ __u32 overhead; /* crc overhad */
+ __u32 limit; /* fifo limit (packets) */
+};
+
#endif
--- a/net/sched/Kconfig 2007-12-10 13:08:36.000000000 -0800
+++ b/net/sched/Kconfig 2007-12-10 13:08:39.000000000 -0800
@@ -196,6 +196,19 @@ config NET_SCH_NETEM
If unsure, say N.
+config NET_SCH_RLIM
+ tristate "Network Rate Limiter"
+ ---help---
+ Say Y here if you want to use timer based network rate limiter
+ algorithm.
+
+ See the top of <file:net/sched/sch_rlim.c> for more details.
+
+ To compile this code as a module, choose M here: the
+ module will be called sch_rlim.
+
+ If unsure, say N.
+
config NET_SCH_INGRESS
tristate "Ingress Qdisc"
---help---
--- a/net/sched/Makefile 2007-12-10 13:08:36.000000000 -0800
+++ b/net/sched/Makefile 2007-12-10 13:08:39.000000000 -0800
@@ -28,6 +28,7 @@ obj-$(CONFIG_NET_SCH_TEQL) += sch_teql.o
obj-$(CONFIG_NET_SCH_PRIO) += sch_prio.o
obj-$(CONFIG_NET_SCH_ATM) += sch_atm.o
obj-$(CONFIG_NET_SCH_NETEM) += sch_netem.o
+obj-$(CONFIG_NET_SCH_RLIM) += sch_rlim.o
obj-$(CONFIG_NET_CLS_U32) += cls_u32.o
obj-$(CONFIG_NET_CLS_ROUTE4) += cls_route.o
obj-$(CONFIG_NET_CLS_FW) += cls_fw.o
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/net/sched/sch_rlim.c 2007-12-10 13:26:39.000000000 -0800
@@ -0,0 +1,353 @@
+/*
+ * net/sched/sch_rate.c Timer based rate control
+ *
+ * Copyright (c) 2007 Stephen Hemminger <shemminger@linux-foundation.org>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/skbuff.h>
+#include <net/netlink.h>
+#include <net/pkt_sched.h>
+#include <asm/div64.h>
+
+/* Simple Rate control
+
+ Algorthim used in NISTnet and others.
+ Logically similar to Token Bucket, but more real time and less lumpy.
+
+ A packet is not allowed to be dequeued until a after the deadline.
+ Each packet dequeued increases the deadline by rate * size.
+
+ If qdisc throttles, it starts a timer, which will wake it up
+ when it is ready to transmit. This scheduler works much better
+ if high resolution timers are available.
+
+ Like classful TBF, limit is just kept for backwards compatibility.
+ It is passed to the default pfifo qdisc - if the inner qdisc is
+ changed the limit is not effective anymore.
+
+*/
+
+/* Use scaled math to get 1/64 ns resolution */
+#define NSEC_SCALE 6
+
+struct rlim_sched_data {
+ ktime_t next_send; /* next scheduled departure */
+ u64 cost; /* nsec/byte * 64 */
+ u32 overhead; /* crc/preamble bytes */
+ u32 limit; /* upper bound on fifo (packets) */
+
+ struct Qdisc *qdisc; /* Inner qdisc, default - bfifo queue */
+ struct qdisc_watchdog watchdog;
+};
+
+static int rlim_enqueue(struct sk_buff *skb, struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ int ret;
+
+ ret = q->qdisc->enqueue(skb, q->qdisc);
+ if (ret)
+ sch->qstats.drops++;
+ else {
+ sch->q.qlen++;
+ sch->bstats.bytes += skb->len;
+ sch->bstats.packets++;
+ }
+
+ return ret;
+}
+
+
+static u64 pkt_time(const struct rlim_sched_data *q,
+ const struct sk_buff *skb)
+{
+ return (q->cost * (skb->len + q->overhead)) >> NSEC_SCALE;
+}
+
+static unsigned int rlim_drop(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ unsigned int len = 0;
+
+ if (q->qdisc->ops->drop && (len = q->qdisc->ops->drop(q->qdisc)) != 0) {
+ sch->q.qlen--;
+ sch->qstats.drops++;
+ }
+
+ return len;
+}
+
+static struct sk_buff *rlim_dequeue(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ struct sk_buff *skb;
+ ktime_t now = ktime_get();
+
+ /* if haven't reached the correct time slot, start timer */
+ if (now.tv64 < q->next_send.tv64) {
+ sch->flags |= TCQ_F_THROTTLED;
+ hrtimer_start(&q->watchdog.timer, q->next_send,
+ HRTIMER_MODE_ABS);
+ return NULL;
+ }
+
+ skb = q->qdisc->dequeue(q->qdisc);
+ if (skb) {
+ q->next_send = ktime_add_ns(now, pkt_time(q, skb));
+ sch->q.qlen--;
+ sch->flags &= ~TCQ_F_THROTTLED;
+ }
+ return skb;
+}
+
+static int rlim_requeue(struct sk_buff *skb, struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ int ret;
+
+ ret = q->qdisc->ops->requeue(skb, q->qdisc);
+ if (!ret) {
+ q->next_send = ktime_sub_ns(q->next_send, pkt_time(q, skb));
+ sch->q.qlen++;
+ sch->qstats.requeues++;
+ }
+
+ return ret;
+}
+
+static void rlim_reset(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ qdisc_reset(q->qdisc);
+ sch->q.qlen = 0;
+
+ q->next_send = ktime_get();
+ qdisc_watchdog_cancel(&q->watchdog);
+}
+
+
+/* Pass size change message down to embedded FIFO */
+static int set_fifo_limit(struct Qdisc *q, int limit)
+{
+ struct rtattr *rta;
+ int ret = -ENOMEM;
+
+ /* Hack to avoid sending change message to non-FIFO */
+ if (strncmp(q->ops->id + 1, "fifo", 4) != 0)
+ return 0;
+
+ rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL);
+ if (rta) {
+ rta->rta_type = RTM_NEWQDISC;
+ rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt));
+ ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit;
+
+ ret = q->ops->change(q, rta);
+ kfree(rta);
+ }
+ return ret;
+}
+
+static int rlim_change(struct Qdisc *sch, struct rtattr *opt)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ struct rtattr *tb[TCA_RLIM_PARMS];
+ const struct tc_rlim_qopt *qopt;
+ int err;
+
+ if (rtattr_parse_nested(tb, TCA_RLIM_PARMS, opt) ||
+ tb[TCA_RLIM_PARMS-1] == NULL ||
+ RTA_PAYLOAD(tb[TCA_RLIM_PARMS-1]) < sizeof(struct tc_rlim_qopt))
+ return -EINVAL;
+
+ qopt = RTA_DATA(tb[TCA_RLIM_PARMS-1]);
+ err = set_fifo_limit(q->qdisc, qopt->limit);
+ if (err)
+ return err;
+
+ q->limit = qopt->limit;
+ q->overhead = qopt->overhead;
+ if (qopt->rate == 0)
+ q->cost = 0; /* unlimited */
+ else
+ q->cost = div64_64((u64)NSEC_PER_SEC << NSEC_SCALE,
+ qopt->rate);
+ return 0;
+}
+
+static int rlim_init(struct Qdisc *sch, struct rtattr *opt)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ if (opt == NULL || RTA_PAYLOAD(opt) < sizeof(struct tc_rlim_qopt))
+ return -EINVAL;
+
+ qdisc_watchdog_init(&q->watchdog, sch);
+
+ q->qdisc = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops,
+ TC_H_MAKE(sch->handle, 1));
+ if (!q->qdisc)
+ return -ENOMEM;
+
+ q->next_send = ktime_get();
+
+ return rlim_change(sch, opt);
+}
+
+static void rlim_destroy(struct Qdisc *sch)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ qdisc_watchdog_cancel(&q->watchdog);
+ qdisc_destroy(q->qdisc);
+}
+
+static int rlim_dump(struct Qdisc *sch, struct sk_buff *skb)
+{
+ const struct rlim_sched_data *q = qdisc_priv(sch);
+ unsigned char *b = skb_tail_pointer(skb);
+ struct rtattr *rta;
+ struct tc_rlim_qopt opt;
+
+ rta = (struct rtattr *)b;
+ RTA_PUT(skb, TCA_OPTIONS, 0, NULL);
+
+ opt.limit = q->limit;
+ opt.overhead = q->overhead;
+ if (q->cost == 0)
+ opt.rate = 0;
+ else
+ opt.rate = div64_64(NSEC_PER_SEC << NSEC_SCALE, q->cost);
+
+ RTA_PUT(skb, TCA_RLIM_PARMS, sizeof(opt), &opt);
+ rta->rta_len = skb_tail_pointer(skb) - b;
+
+ return skb->len;
+
+rtattr_failure:
+ nlmsg_trim(skb, b);
+ return -1;
+}
+
+static int rlim_graft(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
+ struct Qdisc **old)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ if (new == NULL)
+ new = &noop_qdisc;
+
+ sch_tree_lock(sch);
+ *old = xchg(&q->qdisc, new);
+ qdisc_tree_decrease_qlen(*old, (*old)->q.qlen);
+ qdisc_reset(*old);
+ sch_tree_unlock(sch);
+
+ return 0;
+}
+
+static struct Qdisc *rlim_leaf(struct Qdisc *sch, unsigned long arg)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+ return q->qdisc;
+}
+
+static unsigned long rlim_get(struct Qdisc *sch, u32 classid)
+{
+ return 1;
+}
+
+static void rlim_put(struct Qdisc *sch, unsigned long arg)
+{
+}
+
+static int rlim_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
+ struct rtattr **tca, unsigned long *arg)
+{
+ return -ENOSYS;
+}
+
+static int rlim_delete(struct Qdisc *sch, unsigned long arg)
+{
+ return -ENOSYS;
+}
+
+static void rlim_walk(struct Qdisc *sch, struct qdisc_walker *walker)
+{
+ if (!walker->stop) {
+ if (walker->count >= walker->skip)
+ if (walker->fn(sch, 1, walker) < 0) {
+ walker->stop = 1;
+ return;
+ }
+ walker->count++;
+ }
+}
+
+static struct tcf_proto **rlim_find_tcf(struct Qdisc *sch, unsigned long cl)
+{
+ return NULL;
+}
+
+static int rlim_dump_class(struct Qdisc *sch, unsigned long cl,
+ struct sk_buff *skb, struct tcmsg *tcm)
+{
+ struct rlim_sched_data *q = qdisc_priv(sch);
+
+ if (cl != 1) /* only one class */
+ return -ENOENT;
+
+ tcm->tcm_handle |= TC_H_MIN(1);
+ tcm->tcm_info = q->qdisc->handle;
+
+ return 0;
+}
+
+static const struct Qdisc_class_ops rlim_class_ops = {
+ .graft = rlim_graft,
+ .leaf = rlim_leaf,
+ .get = rlim_get,
+ .put = rlim_put,
+ .change = rlim_change_class,
+ .delete = rlim_delete,
+ .walk = rlim_walk,
+ .tcf_chain = rlim_find_tcf,
+ .dump = rlim_dump_class,
+};
+
+static struct Qdisc_ops rlim_qdisc_ops = {
+ .id = "rlim",
+ .cl_ops = &rlim_class_ops,
+ .priv_size = sizeof(struct rlim_sched_data),
+ .enqueue = rlim_enqueue,
+ .dequeue = rlim_dequeue,
+ .requeue = rlim_requeue,
+ .drop = rlim_drop,
+ .init = rlim_init,
+ .reset = rlim_reset,
+ .destroy = rlim_destroy,
+ .change = rlim_change,
+ .dump = rlim_dump,
+ .owner = THIS_MODULE,
+};
+
+static int __init rlim_module_init(void)
+{
+ return register_qdisc(&rlim_qdisc_ops);
+}
+
+static void __exit rlim_module_exit(void)
+{
+ unregister_qdisc(&rlim_qdisc_ops);
+}
+
+module_init(rlim_module_init)
+module_exit(rlim_module_exit)
+MODULE_LICENSE("GPL");
^ permalink raw reply
* Re: 2.6.24-rc4-mm1
From: Andrew Morton @ 2007-12-10 21:11 UTC (permalink / raw)
To: Reuben Farrelly; +Cc: linux-kernel, netdev
In-Reply-To: <475D51C7.6010809@reub.net>
On Tue, 11 Dec 2007 01:48:39 +1100
Reuben Farrelly <reuben-linuxkernel@reub.net> wrote:
>
>
> On 5/12/2007 4:17 PM, Andrew Morton wrote:
> > Temporarily at
> >
> > http://userweb.kernel.org/~akpm/2.6.24-rc4-mm1/
> >
> > Will appear later at
> >
> > ftp://ftp.kernel.org/pub/linux/kernel/people/akpm/patches/2.6/2.6.24-rc4/2.6.24-rc4-mm1/
> >
> >
> > - Lots of device IDs have been removed from the e1000 driver and moved over
> > to e1000e. So if your e1000 stops working, you forgot to set CONFIG_E1000E.
> >
> > - The s390 build is still broken.
>
> I'm seeing this most incredibly unhelpful (to debug) but fortunately
> reproduceable problem (so far 4/4 times) on this -mm kernel. I thought this
> problem may have been related to another bug which I have reported (A TCP oops)
> but even after applying a likely fix for that I am still seeing this problem.
>
> The machine boots up perfectly fine and runs good until I load it up.
> In this case I can reliably cause this to occur by pulling a 3G ISO across the
> GigE network from my Linux box to my PC. After maybe 50M or so, the console
> just displays this (ignore initial boot banner):
>
> ----------
>
> * Starting local ... [ ok ]
>
>
> This is tornado.reub.net (Linux x86_64 2.6.24-rc4-mm1) 00:24:01
>
> tornado login: *** buffer overf
>
> -------
>
> Yes - after displaying the 'f' in what I can only guess is the word 'overflow',
> the box spontaneously reboots. There is no further console output until it
> starts to come back up again.
>
> The problem does not exist in 2.6.23-gentoo kernels nor in a vanilla
> 2.6.24-rc4-git6 (phew!), so this looks to be an -mm only problem at this stage.
>
> I enabled a number of kernel debugging options but then I got no output at all
> when the machine crashed.
>
> I'm at a bit of a loss as to which subsystem this might be coming from, so I'm
> not sure who to CC.
>
> Box information is (still) up at http://www.reub.net/files/kernel/2.6.24-rc4-mm1/
>
hm. grepping around for "buffer overflow" doesn't turn up anything except in
drivers which you won't be using on that machine.
I'd be suspecting networking, obviously. If you're feeling keen could you please
grep a 2.6.24-rc4 tree and apply 2.6.24-rc4-mm1's origin.patch and git-net.patch
and see if the bug is still present?
^ permalink raw reply
* Re: [PATCH 8/8] [PATCH v2] [CCID3]: Interface CCID3 code with newer Loss Intervals Database
From: Arnaldo Carvalho de Melo @ 2007-12-10 21:04 UTC (permalink / raw)
To: Gerrit Renker; +Cc: dccp, netdev
In-Reply-To: <11971083882534-git-send-email-gerrit@erg.abdn.ac.uk>
Em Sat, Dec 08, 2007 at 10:06:28AM +0000, Gerrit Renker escreveu:
> This hooks up the TFRC Loss Interval database with CCID 3 packet reception.
> In addition, it makes the CCID-specific computation of the first loss
> interval (which requires access to all the guts of CCID3) local to ccid3.c.
>
> The patch also fixes an omission in the DCCP code, that of a default /
> fallback RTT value (defined in section 3.4 of RFC 4340 as 0.2 sec); while
> at it, the upper bound of 4 seconds for an RTT sample has been reduced to
> match the initial TCP RTO value of 3 seconds from[RFC 1122, 4.2.3.1].
>
> Signed-off-by: Gerrit Renker <gerrit@erg.abdn.ac.uk>
> Signed-off-by: Ian McDonald <ian.mcdonald@jandi.co.nz>
When interfacing we must make sure that ccid3 tfrc_lh_slab is created
and then tfrc_li_cachep is not needed. I'm doing this while keeping
the structure of the patches, i.e. one introducing, the other removing.
But we need to create tfrc_lh_slab if we want the tree to be bisectable.
I'm doing this and keeping your Signed-off-line, please holler if you
disagree for some reason.
- Arnaldo
^ permalink raw reply
* Re: [PATCH] drivers/net/ipg: Remove local definition of TRUE/FALSE
From: Richard Knutsson @ 2007-12-10 20:04 UTC (permalink / raw)
To: Pekka Enberg; +Cc: jgarzik, netdev, linux-kernel, romieu
In-Reply-To: <84144f020712101154u26b2d594jab199ea8804ed3bc@mail.gmail.com>
Pekka Enberg wrote:
> Hi Richard,
>
> On Dec 10, 2007 9:29 PM, Richard Knutsson <ricknu-0@student.ltu.se> wrote:
>
>> Remove local definition of TRUE/FALSE.
>>
>
> This is already fixed in Francois' tree:
>
> http://git.kernel.org/?p=linux/kernel/git/romieu/netdev-2.6.git;a=commitdiff;h=2af61e99e3d1c959840ea007ff56b15db794fb99
>
I see, thanks.
Richard Knutsson
^ permalink raw reply
* Re: [PATCH RFC] [5/9] modpost: Fix a buffer overflow in modpost
From: Sam Ravnborg @ 2007-12-10 20:07 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev, linux-kernel, rusty
In-Reply-To: <200712102057.29016.ak@suse.de>
On Mon, Dec 10, 2007 at 08:57:28PM +0100, Andi Kleen wrote:
> On Monday 10 December 2007 20:32, Sam Ravnborg wrote:
> > On Thu, Nov 22, 2007 at 03:43:10AM +0100, Andi Kleen wrote:
> > > When passing an file name > 1k the stack could be overflowed.
> > > Not really a security issue, but still better plugged.
> >
> > Looks good. A s-o-b line again please.
>
> Signed-off-by: Andi Kleen <ak@suse.de>
>
> > Although I am not so happy with the ue of gcc extensions.
>
> That's not a gcc extension. It's C99.
OK.
I have applied all three patches to kbuild.git.
As I did not follow the whole thread about the namespace I did not
take those.
And the first patch touching module.c should go in via akpm I think.
It is outside my core-competence area at least .
Sam
^ permalink raw reply
* Re: 2.6.24-rc4-mm1
From: Ilpo Järvinen @ 2007-12-10 20:05 UTC (permalink / raw)
To: David Miller
Cc: Andrew Morton, Reuben Farrelly, LKML, Linux Netdev List, Auke Kok
In-Reply-To: <Pine.LNX.4.64.0712101136190.18529@kivilampi-30.cs.helsinki.fi>
[-- Attachment #1: Type: TEXT/PLAIN, Size: 447 bytes --]
On Mon, 10 Dec 2007, Ilpo Järvinen wrote:
> Dave, please include this one to net-2.6.25.
...
> --
> [PATCH] [TCP]: Fix fack_count miscountings (multiple places)
I've better version of this coming up, so Dave please don't put this one
into net-2.6.25 (noticed that both the original and the after patch code
can get to an infinite loop and the new code is flawed in some rare cases
still as well). I'll submit a better version soon.
--
i.
^ permalink raw reply
* Re: [1/4] DST: Distributed storage documentation.
From: Evgeniy Polyakov @ 2007-12-10 20:03 UTC (permalink / raw)
To: Kay Sievers; +Cc: lkml, netdev, linux-fsdevel, Greg KH
In-Reply-To: <1197316609.6399.124.camel@lov.site>
On Mon, Dec 10, 2007 at 08:56:49PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> On Mon, 2007-12-10 at 22:51 +0300, Evgeniy Polyakov wrote:
> > On Mon, Dec 10, 2007 at 08:44:55PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> > > > > > Actually not - I have to set reference counter to something other than 1
> > > > > > or +/- 1, and thus will have to call kref_get() in a loop, which is a
> > > > > > very ugly step. Is there kref_set() or somethinglike that? At least not
> > > > > > in 2.6.22 what I'm using for now.
> > > > >
> > > > > Yeah, a loop would look pretty ugly. How about just adding kref_set(),
> > > > > if you need it.
> > > >
> > > > Well, then it distributed storage will not be able to build as
> > > > standalone module, and kref_set() itself will not be accepted as a single
> > > > patch, since there are no in-kernel users :)
> > > > It is easily doable though.
> > >
> > > Most rules have exceptions. :) Send a patch, so we can see how it looks
> > > like.
> >
> > It looks really non-trivial :)
>
> Yeah, it does. :)
> We miss an EXPORT_SYMBOL(), right?
Yep :)
diff --git a/include/linux/kref.h b/include/linux/kref.h
index 6fee353..5d18563 100644
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -24,6 +24,7 @@ struct kref {
atomic_t refcount;
};
+void kref_set(struct kref *kref, int num);
void kref_init(struct kref *kref);
void kref_get(struct kref *kref);
int kref_put(struct kref *kref, void (*release) (struct kref *kref));
diff --git a/lib/kref.c b/lib/kref.c
index a6dc3ec..9ecd6e8 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -15,13 +15,23 @@
#include <linux/module.h>
/**
+ * kref_set - initialize object and set refcount to requested number.
+ * @kref: object in question.
+ * @num: initial reference counter
+ */
+void kref_set(struct kref *kref, int num)
+{
+ atomic_set(&kref->refcount, num);
+ smp_mb();
+}
+
+/**
* kref_init - initialize object.
* @kref: object in question.
*/
void kref_init(struct kref *kref)
{
- atomic_set(&kref->refcount,1);
- smp_mb();
+ kref_set(kref, 1);
}
/**
@@ -61,6 +71,7 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref))
return 0;
}
+EXPORT_SYMBOL(kref_set);
EXPORT_SYMBOL(kref_init);
EXPORT_SYMBOL(kref_get);
EXPORT_SYMBOL(kref_put);
--
Evgeniy Polyakov
^ permalink raw reply related
* Re: [PATCH RFC] [5/9] modpost: Fix a buffer overflow in modpost
From: Andi Kleen @ 2007-12-10 19:57 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: netdev, linux-kernel, rusty
In-Reply-To: <20071210193202.GC17315@uranus.ravnborg.org>
On Monday 10 December 2007 20:32, Sam Ravnborg wrote:
> On Thu, Nov 22, 2007 at 03:43:10AM +0100, Andi Kleen wrote:
> > When passing an file name > 1k the stack could be overflowed.
> > Not really a security issue, but still better plugged.
>
> Looks good. A s-o-b line again please.
Signed-off-by: Andi Kleen <ak@suse.de>
> Although I am not so happy with the ue of gcc extensions.
That's not a gcc extension. It's C99.
-Andi
^ permalink raw reply
* Re: [1/4] DST: Distributed storage documentation.
From: Kay Sievers @ 2007-12-10 19:56 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: lkml, netdev, linux-fsdevel, Greg KH
In-Reply-To: <20071210195145.GA29132@2ka.mipt.ru>
On Mon, 2007-12-10 at 22:51 +0300, Evgeniy Polyakov wrote:
> On Mon, Dec 10, 2007 at 08:44:55PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> > > > > Actually not - I have to set reference counter to something other than 1
> > > > > or +/- 1, and thus will have to call kref_get() in a loop, which is a
> > > > > very ugly step. Is there kref_set() or somethinglike that? At least not
> > > > > in 2.6.22 what I'm using for now.
> > > >
> > > > Yeah, a loop would look pretty ugly. How about just adding kref_set(),
> > > > if you need it.
> > >
> > > Well, then it distributed storage will not be able to build as
> > > standalone module, and kref_set() itself will not be accepted as a single
> > > patch, since there are no in-kernel users :)
> > > It is easily doable though.
> >
> > Most rules have exceptions. :) Send a patch, so we can see how it looks
> > like.
>
> It looks really non-trivial :)
Yeah, it does. :)
We miss an EXPORT_SYMBOL(), right?
Kay
^ permalink raw reply
* Re: [PATCH] drivers/net/ipg: Remove local definition of TRUE/FALSE
From: Pekka Enberg @ 2007-12-10 19:54 UTC (permalink / raw)
To: Richard Knutsson; +Cc: jgarzik, netdev, linux-kernel, romieu
In-Reply-To: <20071210193139.16433.95480.sendpatchset@thinktank.campus.ltu.se>
Hi Richard,
On Dec 10, 2007 9:29 PM, Richard Knutsson <ricknu-0@student.ltu.se> wrote:
> Remove local definition of TRUE/FALSE.
This is already fixed in Francois' tree:
http://git.kernel.org/?p=linux/kernel/git/romieu/netdev-2.6.git;a=commitdiff;h=2af61e99e3d1c959840ea007ff56b15db794fb99
Pekka
^ permalink raw reply
* Re: [1/4] DST: Distributed storage documentation.
From: Evgeniy Polyakov @ 2007-12-10 19:51 UTC (permalink / raw)
To: Kay Sievers; +Cc: lkml, netdev, linux-fsdevel, Greg KH
In-Reply-To: <1197315895.6399.121.camel@lov.site>
On Mon, Dec 10, 2007 at 08:44:55PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> > > > Actually not - I have to set reference counter to something other than 1
> > > > or +/- 1, and thus will have to call kref_get() in a loop, which is a
> > > > very ugly step. Is there kref_set() or somethinglike that? At least not
> > > > in 2.6.22 what I'm using for now.
> > >
> > > Yeah, a loop would look pretty ugly. How about just adding kref_set(),
> > > if you need it.
> >
> > Well, then it distributed storage will not be able to build as
> > standalone module, and kref_set() itself will not be accepted as a single
> > patch, since there are no in-kernel users :)
> > It is easily doable though.
>
> Most rules have exceptions. :) Send a patch, so we can see how it looks
> like.
It looks really non-trivial :)
Signed-off-by: Evgeniy Polyakov <johnpol@2ka.mipt.ru>
diff --git a/include/linux/kref.h b/include/linux/kref.h
index 6fee353..5d18563 100644
--- a/include/linux/kref.h
+++ b/include/linux/kref.h
@@ -24,6 +24,7 @@ struct kref {
atomic_t refcount;
};
+void kref_set(struct kref *kref, int num);
void kref_init(struct kref *kref);
void kref_get(struct kref *kref);
int kref_put(struct kref *kref, void (*release) (struct kref *kref));
diff --git a/lib/kref.c b/lib/kref.c
index a6dc3ec..40aa9f9 100644
--- a/lib/kref.c
+++ b/lib/kref.c
@@ -15,13 +15,23 @@
#include <linux/module.h>
/**
+ * kref_set - initialize object and set refcount to requested number.
+ * @kref: object in question.
+ * @num: initial reference counter
+ */
+void kref_set(struct kref *kref, int num)
+{
+ atomic_set(&kref->refcount, num);
+ smp_mb();
+}
+
+/**
* kref_init - initialize object.
* @kref: object in question.
*/
void kref_init(struct kref *kref)
{
- atomic_set(&kref->refcount,1);
- smp_mb();
+ kref_set(kref, 1);
}
/**
--
Evgeniy Polyakov
^ permalink raw reply related
* Re: [1/4] DST: Distributed storage documentation.
From: Kay Sievers @ 2007-12-10 19:44 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: lkml, netdev, linux-fsdevel, Greg KH
In-Reply-To: <20071210193304.GA24737@2ka.mipt.ru>
On Mon, 2007-12-10 at 22:33 +0300, Evgeniy Polyakov wrote:
> On Mon, Dec 10, 2007 at 08:02:28PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> > > uganda:~/codes# ls -l /sys/devices/storage/n-0-ffff81003ebc220/
> > > total 0
> > > drwxr-xr-x 2 root root 0 2007-12-10 13:23 power
> > > -r--r--r-- 1 root root 4096 2007-12-10 13:30 size
> > > -r--r--r-- 1 root root 4096 2007-12-10 13:30 start
> > > -r--r--r-- 1 root root 4096 2007-12-10 13:30 type
> > > -rw-r--r-- 1 root root 4096 2007-12-10 13:30 uevent
> >
> > This is a "struct device" instance without a subsystem (bus/class),
> > right? It will not send an uevent to userspace. Is that intended? Why
> > don't you add them all to the dst bus?
>
> I created dst bus for storage devices only, nodes are very different
> objects, and actually they do not need any events from above, but I need
> to put some attributes somewhere, so it is 'empty' device.
Ok.
> > > Actually not - I have to set reference counter to something other than 1
> > > or +/- 1, and thus will have to call kref_get() in a loop, which is a
> > > very ugly step. Is there kref_set() or somethinglike that? At least not
> > > in 2.6.22 what I'm using for now.
> >
> > Yeah, a loop would look pretty ugly. How about just adding kref_set(),
> > if you need it.
>
> Well, then it distributed storage will not be able to build as
> standalone module, and kref_set() itself will not be accepted as a single
> patch, since there are no in-kernel users :)
> It is easily doable though.
Most rules have exceptions. :) Send a patch, so we can see how it looks
like.
> > > > Why don't you use groups for the attributes?
> > >
> > > For 3-4 attributes it is faster to register them in a loop than typing
> > > another structure :)
> >
> > Yeah, but if you would need to recover from an error when the creation
> > of a file fails, a group would do the proper "rollback".
>
> I do not care about such errors - if there is such an error for a file,
> which exports information about type of the node (i.e. string "L" or "R")
> or some other very meaningful info, then system has enough to care about
> instead of this, so dst does not do anything special - it ignores such
> errors :)
>
> On exit path it will be checked and removed correctly.
> If there will be additional sysfs files, I think group is a good way to
> implement them.
>
> > > > Why don't you use default attributes for the device, where you get all
> > > > error handling done by the core.
> > >
> > > What is 'default attributes' and for what devices?
> > > All my sysfs files are so much trivial, so they do not need anything
> > > special and I do not see what is error handling you mentioned.
> >
> > If all devices of a subsystem (bus/class) are of the same type, you can
> > set a default array of attributes in the "struct bus/class" to be
> > created at every device. If you have multiple types of devices in the
> > same subsytem (bus/class) you can to assign a the "device_type", which
> > has the default attribute group.
> > That way the core will create the files before the event is sent out to
> > userspace, and the files can be access from the event itself. Not sure
> > if that is needed for dst.
>
> Ok, I see.
>
> DST right now has 3 types of files - storage files, it is common for
> every storage device; node files, which are the same for every node; and
> per-algorithm private devices - they can be different (actually only
> mirroring algorithm exports something to userspace).
>
> I think it is possible to use default attributes for storage devices,
> but node device does not have a bus/class, so they will be untouched.
Sounds fine.
Thanks,
Kay
^ permalink raw reply
* [PATCH] iproute2: off by one in nested attribute parse
From: Stephen Hemminger @ 2007-12-10 19:38 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netdev
Fix off by one in nested attribute management.
Fixes segv in:
tc qdisc show dev eth1
due to uninitialized attribute table.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
lib/libnetlink.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/libnetlink.c b/lib/libnetlink.c
index 12883fe..d13596f 100644
--- a/lib/libnetlink.c
+++ b/lib/libnetlink.c
@@ -632,6 +632,6 @@ int __parse_rtattr_nested_compat(struct rtattr *tb[], int max, struct rtattr *rt
rta = RTA_DATA(rta) + RTA_ALIGN(len);
return parse_rtattr_nested(tb, max, rta);
}
- memset(tb, 0, sizeof(struct rtattr *) * max);
+ memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
return 0;
}
--
1.5.3.4
^ permalink raw reply related
* Re: [1/4] DST: Distributed storage documentation.
From: Evgeniy Polyakov @ 2007-12-10 19:33 UTC (permalink / raw)
To: Kay Sievers; +Cc: lkml, netdev, linux-fsdevel, Greg KH
In-Reply-To: <1197313348.6399.106.camel@lov.site>
On Mon, Dec 10, 2007 at 08:02:28PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> > uganda:~/codes# ls -l /sys/devices/storage/n-0-ffff81003ebc220/
> > total 0
> > drwxr-xr-x 2 root root 0 2007-12-10 13:23 power
> > -r--r--r-- 1 root root 4096 2007-12-10 13:30 size
> > -r--r--r-- 1 root root 4096 2007-12-10 13:30 start
> > -r--r--r-- 1 root root 4096 2007-12-10 13:30 type
> > -rw-r--r-- 1 root root 4096 2007-12-10 13:30 uevent
>
> This is a "struct device" instance without a subsystem (bus/class),
> right? It will not send an uevent to userspace. Is that intended? Why
> don't you add them all to the dst bus?
I created dst bus for storage devices only, nodes are very different
objects, and actually they do not need any events from above, but I need
to put some attributes somewhere, so it is 'empty' device.
> > Actually not - I have to set reference counter to something other than 1
> > or +/- 1, and thus will have to call kref_get() in a loop, which is a
> > very ugly step. Is there kref_set() or somethinglike that? At least not
> > in 2.6.22 what I'm using for now.
>
> Yeah, a loop would look pretty ugly. How about just adding kref_set(),
> if you need it.
Well, then it distributed storage will not be able to build as
standalone module, and kref_set() itself will not be accepted as a single
patch, since there are no in-kernel users :)
It is easily doable though.
> > > Why don't you use groups for the attributes?
> >
> > For 3-4 attributes it is faster to register them in a loop than typing
> > another structure :)
>
> Yeah, but if you would need to recover from an error when the creation
> of a file fails, a group would do the proper "rollback".
I do not care about such errors - if there is such an error for a file,
which exports information about type of the node (i.e. string "L" or "R")
or some other very meaningful info, then system has enough to care about
instead of this, so dst does not do anything special - it ignores such
errors :)
On exit path it will be checked and removed correctly.
If there will be additional sysfs files, I think group is a good way to
implement them.
> > > Why don't you use default attributes for the device, where you get all
> > > error handling done by the core.
> >
> > What is 'default attributes' and for what devices?
> > All my sysfs files are so much trivial, so they do not need anything
> > special and I do not see what is error handling you mentioned.
>
> If all devices of a subsystem (bus/class) are of the same type, you can
> set a default array of attributes in the "struct bus/class" to be
> created at every device. If you have multiple types of devices in the
> same subsytem (bus/class) you can to assign a the "device_type", which
> has the default attribute group.
> That way the core will create the files before the event is sent out to
> userspace, and the files can be access from the event itself. Not sure
> if that is needed for dst.
Ok, I see.
DST right now has 3 types of files - storage files, it is common for
every storage device; node files, which are the same for every node; and
per-algorithm private devices - they can be different (actually only
mirroring algorithm exports something to userspace).
I think it is possible to use default attributes for storage devices,
but node device does not have a bus/class, so they will be untouched.
> Thanks,
> Kay
--
Evgeniy Polyakov
^ permalink raw reply
* Re: [PATCH RFC] [5/9] modpost: Fix a buffer overflow in modpost
From: Sam Ravnborg @ 2007-12-10 19:32 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev, linux-kernel, rusty
In-Reply-To: <20071122024310.BB7E414D68@wotan.suse.de>
On Thu, Nov 22, 2007 at 03:43:10AM +0100, Andi Kleen wrote:
>
> When passing an file name > 1k the stack could be overflowed.
> Not really a security issue, but still better plugged.
Looks good. A s-o-b line again please.
Although I am not so happy with the ue of gcc extensions.
Sam
>
>
> ---
> scripts/mod/modpost.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> Index: linux/scripts/mod/modpost.c
> ===================================================================
> --- linux.orig/scripts/mod/modpost.c
> +++ linux/scripts/mod/modpost.c
> @@ -1656,7 +1656,6 @@ int main(int argc, char **argv)
> {
> struct module *mod;
> struct buffer buf = { };
> - char fname[SZ];
> char *kernel_read = NULL, *module_read = NULL;
> char *dump_write = NULL;
> int opt;
> @@ -1709,6 +1708,8 @@ int main(int argc, char **argv)
> err = 0;
>
> for (mod = modules; mod; mod = mod->next) {
> + char fname[strlen(mod->name) + 10];
> +
> if (mod->skip)
> continue;
>
^ permalink raw reply
* [PATCH] drivers/net/ipg: Remove local definition of TRUE/FALSE
From: Richard Knutsson @ 2007-12-10 19:29 UTC (permalink / raw)
To: jgarzik; +Cc: netdev, linux-kernel, Richard Knutsson
Remove local definition of TRUE/FALSE.
Signed-off-by: Richard Knutsson <ricknu-0@student.ltu.se>
---
diff --git a/drivers/net/ipg.h b/drivers/net/ipg.h
index d5d092c..4484778 100644
--- a/drivers/net/ipg.h
+++ b/drivers/net/ipg.h
@@ -490,38 +490,34 @@ enum ipg_regs {
* Tune
*/
-/* Miscellaneous Constants. */
-#define TRUE 1
-#define FALSE 0
-
/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS append on TX. */
-#define IPG_APPEND_FCS_ON_TX TRUE
+#define IPG_APPEND_FCS_ON_TX true
/* Assign IPG_APPEND_FCS_ON_TX > 0 for auto FCS strip on RX. */
-#define IPG_STRIP_FCS_ON_RX TRUE
+#define IPG_STRIP_FCS_ON_RX true
/* Assign IPG_DROP_ON_RX_ETH_ERRORS > 0 to drop RX frames with
* Ethernet errors.
*/
-#define IPG_DROP_ON_RX_ETH_ERRORS TRUE
+#define IPG_DROP_ON_RX_ETH_ERRORS true
/* Assign IPG_INSERT_MANUAL_VLAN_TAG > 0 to insert VLAN tags manually
* (via TFC).
*/
-#define IPG_INSERT_MANUAL_VLAN_TAG FALSE
+#define IPG_INSERT_MANUAL_VLAN_TAG false
/* Assign IPG_ADD_IPCHECKSUM_ON_TX > 0 for auto IP checksum on TX. */
-#define IPG_ADD_IPCHECKSUM_ON_TX FALSE
+#define IPG_ADD_IPCHECKSUM_ON_TX false
/* Assign IPG_ADD_TCPCHECKSUM_ON_TX > 0 for auto TCP checksum on TX.
* DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.
*/
-#define IPG_ADD_TCPCHECKSUM_ON_TX FALSE
+#define IPG_ADD_TCPCHECKSUM_ON_TX false
/* Assign IPG_ADD_UDPCHECKSUM_ON_TX > 0 for auto UDP checksum on TX.
* DO NOT USE FOR SILICON REVISIONS B3 AND EARLIER.
*/
-#define IPG_ADD_UDPCHECKSUM_ON_TX FALSE
+#define IPG_ADD_UDPCHECKSUM_ON_TX false
/* If inserting VLAN tags manually, assign the IPG_MANUAL_VLAN_xx
* constants as desired.
^ permalink raw reply related
* Re: [1/4] DST: Distributed storage documentation.
From: Kay Sievers @ 2007-12-10 19:02 UTC (permalink / raw)
To: Evgeniy Polyakov; +Cc: lkml, netdev, linux-fsdevel, Greg KH
In-Reply-To: <20071210145055.GB7184@2ka.mipt.ru>
On Mon, 2007-12-10 at 17:50 +0300, Evgeniy Polyakov wrote:
> On Mon, Dec 10, 2007 at 03:31:48PM +0100, Kay Sievers (kay.sievers@vrfy.org) wrote:
> > > I meant that for each new device, it will be placed into
> > > /sys/devices/its_name, but it can also be accessed via
> > > /sys/bus/dst/devices/
> >
> > Still, it looks like a path. :)
> >
> > Please don't reference any device directly with a /sys/devices/ path.
> > You have to use the subsystem links to the devices
> > in /sys/bus/dst/devices/. Devices are free to move around
> > in /sys/devices, even during runtime. Yours don't do, but anyway, please
> > remove all mentioning of direct access to /sys/devices/.
>
> Ok, I will update documentation to reference /sys/bus/dst/devices
> instead of /sys/devices
Great, thanks!
> > Btw, where is the top-level /sys/devices/storage/ coming from? I don't
> > see that in the code. We don't accept any new "virtual parents" here.
> >
> > Your devices will automatically appear in /sys/devices/virtual/dst/, and
> > not below your own parent. But that path does not matter anyway, because
> > you should only access them from the /sys/bus/dst/devices/ directory.
> >
> > And in general please don't claim generic names like "storage" in any
> > namespace for a very specific subsystem like this.
>
> It is not a parent - it is an example for device called 'storage', if it
> will be called 'testing', then path will be /sys/devices/testing or more
> correct /sys/bus/dst/devices/testing :)
Ah, I see.
> > > It is 'dst' bus.
> > >
> > > uganda:~/codes# ls -la /sys/devices/staorge/
> > > total 0
> > > drwxr-xr-x 4 root root 0 2007-12-10 11:46 .
> > > drwxr-xr-x 9 root root 0 2007-12-10 11:46 ..
> > > -r--r--r-- 1 root root 4096 2007-12-10 11:46 alg
> > > lrwxrwxrwx 1 root root 0 2007-12-10 11:46 bus -> ../../bus/dst
> > > drwxr-xr-x 3 root root 0 2007-12-10 11:46 n-0-ffff81003e24117
> > > -r--r--r-- 1 root root 4096 2007-12-10 11:46 name
> > > -r--r--r-- 1 root root 4096 2007-12-10 11:46 nodes
> > > drwxr-xr-x 2 root root 0 2007-12-10 11:46 power
> > > -rw-r--r-- 1 root root 4096 2007-12-10 11:46 remove_all_nodes
> > > lrwxrwxrwx 1 root root 0 2007-12-10 11:46 subsystem -> ../../bus/dst
> > > -rw-r--r-- 1 root root 4096 2007-12-10 11:46 uevent
> >
> > Ok, how does:
> > ls -l /sys/devices/storage/n-0-ffff81003e24117
> > look?
>
> uganda:~/codes# ls -l /sys/devices/storage/n-0-ffff81003ebc220/
> total 0
> drwxr-xr-x 2 root root 0 2007-12-10 13:23 power
> -r--r--r-- 1 root root 4096 2007-12-10 13:30 size
> -r--r--r-- 1 root root 4096 2007-12-10 13:30 start
> -r--r--r-- 1 root root 4096 2007-12-10 13:30 type
> -rw-r--r-- 1 root root 4096 2007-12-10 13:30 uevent
This is a "struct device" instance without a subsystem (bus/class),
right? It will not send an uevent to userspace. Is that intended? Why
don't you add them all to the dst bus?
> > > uganda:~/codes# ls -l /sys/bus/dst/
> > > total 0
> > > drwxr-xr-x 2 root root 0 2007-12-10 09:52 devices
> > > drwxr-xr-x 2 root root 0 2007-12-10 09:52 drivers
> > > -rw-r--r-- 1 root root 4096 2007-12-10 11:46 drivers_autoprobe
> > > --w------- 1 root root 4096 2007-12-10 11:46 drivers_probe
> >
> > How does:
> > ls -l /sys/bus/dst/devices
> > look?
>
> uganda:~/codes# ls -la /sys/bus/dst/devices/
> total 0
> drwxr-xr-x 2 root root 0 2007-12-10 13:30 .
> drwxr-xr-x 4 root root 0 2007-12-10 13:22 ..
> lrwxrwxrwx 1 root root 0 2007-12-10 13:30 storage -> ../../../devices/storage
>
> Here 'storage' is just a name for device called 'storage', it can be
> anything else.
Fine.
> > Further questions:
> > Why do you do your own refcounting instead of using kref?
>
> That's because I always used atomic operations as a reference counters
> and did not tried krefs :)
> They are the same actually (module tricky arches where smp_mb_* are
> required), so I can replace them in the next release.
On Mon, 2007-12-10 at 18:12 +0300, Evgeniy Polyakov wrote:
> Actually not - I have to set reference counter to something other than 1
> or +/- 1, and thus will have to call kref_get() in a loop, which is a
> very ugly step. Is there kref_set() or somethinglike that? At least not
> in 2.6.22 what I'm using for now.
Yeah, a loop would look pretty ugly. How about just adding kref_set(),
if you need it.
> > Why don't you use groups for the attributes?
>
> For 3-4 attributes it is faster to register them in a loop than typing
> another structure :)
Yeah, but if you would need to recover from an error when the creation
of a file fails, a group would do the proper "rollback".
> > Why don't you use default attributes for the device, where you get all
> > error handling done by the core.
>
> What is 'default attributes' and for what devices?
> All my sysfs files are so much trivial, so they do not need anything
> special and I do not see what is error handling you mentioned.
If all devices of a subsystem (bus/class) are of the same type, you can
set a default array of attributes in the "struct bus/class" to be
created at every device. If you have multiple types of devices in the
same subsytem (bus/class) you can to assign a the "device_type", which
has the default attribute group.
That way the core will create the files before the event is sent out to
userspace, and the files can be access from the event itself. Not sure
if that is needed for dst.
Thanks,
Kay
^ permalink raw reply
* Re: [PATCH RFC] [3/9] modpost: Declare the modpost error functions as printf like
From: Andi Kleen @ 2007-12-10 18:58 UTC (permalink / raw)
To: Sam Ravnborg; +Cc: Andi Kleen, netdev, linux-kernel, rusty
In-Reply-To: <20071210185008.GA17315@uranus.ravnborg.org>
On Mon, Dec 10, 2007 at 07:50:08PM +0100, Sam Ravnborg wrote:
> On Thu, Nov 22, 2007 at 03:43:08AM +0100, Andi Kleen wrote:
> >
> > This way gcc can warn for wrong format strings
>
> This loks good. Can I get i s-o-b then I will apply it.
Sorry must have been left out by mistake.
Signed-off-by: Andi Kleen <ak@suse.de>
for both patches.
-Andi
^ permalink raw reply
* Re: [PATCH RFC] [3/9] modpost: Declare the modpost error functions as printf like
From: Sam Ravnborg @ 2007-12-10 18:50 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev, linux-kernel, rusty
In-Reply-To: <20071122024308.9B40114D68@wotan.suse.de>
On Thu, Nov 22, 2007 at 03:43:08AM +0100, Andi Kleen wrote:
>
> This way gcc can warn for wrong format strings
This loks good. Can I get i s-o-b then I will apply it.
Sam
>
> ---
> scripts/mod/modpost.c | 8 +++++---
> 1 file changed, 5 insertions(+), 3 deletions(-)
>
> Index: linux/scripts/mod/modpost.c
> ===================================================================
> --- linux.orig/scripts/mod/modpost.c
> +++ linux/scripts/mod/modpost.c
> @@ -33,7 +33,9 @@ enum export {
> export_unused_gpl, export_gpl_future, export_unknown
> };
>
> -void fatal(const char *fmt, ...)
> +#define PRINTF __attribute__ ((format (printf, 1, 2)))
> +
> +PRINTF void fatal(const char *fmt, ...)
> {
> va_list arglist;
>
> @@ -46,7 +48,7 @@ void fatal(const char *fmt, ...)
> exit(1);
> }
>
> -void warn(const char *fmt, ...)
> +PRINTF void warn(const char *fmt, ...)
> {
> va_list arglist;
>
> @@ -57,7 +59,7 @@ void warn(const char *fmt, ...)
> va_end(arglist);
> }
>
> -void merror(const char *fmt, ...)
> +PRINTF void merror(const char *fmt, ...)
> {
> va_list arglist;
>
^ permalink raw reply
* Re: [PATCH RFC] [4/9] modpost: Fix format string warnings
From: Sam Ravnborg @ 2007-12-10 18:50 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev, linux-kernel, rusty
In-Reply-To: <20071122024309.AD8E314D68@wotan.suse.de>
On Thu, Nov 22, 2007 at 03:43:09AM +0100, Andi Kleen wrote:
>
> Fix wrong format strings in modpost exposed by the previous patch.
> Including one missing argument -- some random data was printed instead.
Looks good. Can I get a s-o-b then I will apply it.
Sam
>
> ---
> scripts/mod/modpost.c | 7 ++++---
> 1 file changed, 4 insertions(+), 3 deletions(-)
>
> Index: linux/scripts/mod/modpost.c
> ===================================================================
> --- linux.orig/scripts/mod/modpost.c
> +++ linux/scripts/mod/modpost.c
> @@ -388,7 +388,7 @@ static int parse_elf(struct elf_info *in
>
> /* Check if file offset is correct */
> if (hdr->e_shoff > info->size) {
> - fatal("section header offset=%u in file '%s' is bigger then filesize=%lu\n", hdr->e_shoff, filename, info->size);
> + fatal("section header offset=%lu in file '%s' is bigger then filesize=%lu\n", (unsigned long)hdr->e_shoff, filename, info->size);
> return 0;
> }
>
> @@ -409,7 +409,7 @@ static int parse_elf(struct elf_info *in
> const char *secname;
>
> if (sechdrs[i].sh_offset > info->size) {
> - fatal("%s is truncated. sechdrs[i].sh_offset=%u > sizeof(*hrd)=%ul\n", filename, (unsigned int)sechdrs[i].sh_offset, sizeof(*hdr));
> + fatal("%s is truncated. sechdrs[i].sh_offset=%lu > sizeof(*hrd)=%lu\n", filename, (unsigned long)sechdrs[i].sh_offset, sizeof(*hdr));
> return 0;
> }
> secname = secstrings + sechdrs[i].sh_name;
> @@ -907,7 +907,8 @@ static void warn_sec_mismatch(const char
> "before '%s' (at offset -0x%llx)\n",
> modname, fromsec, (unsigned long long)r.r_offset,
> secname, refsymname,
> - elf->strtab + after->st_name);
> + elf->strtab + after->st_name,
> + (unsigned long long)r.r_offset);
> } else {
> warn("%s(%s+0x%llx): Section mismatch: reference to %s:%s\n",
> modname, fromsec, (unsigned long long)r.r_offset,
^ permalink raw reply
* [PATCH] IPv6 support for NFS server
From: Aurélien Charbon @ 2007-12-10 18:34 UTC (permalink / raw)
To: Neil Brown, J. Bruce Fields, netdev ML, Mailing list NFSv4
[-- Attachment #1: Type: text/plain, Size: 13393 bytes --]
Here is a cleanup for the ip_map caching patch in nfs server.
It prepares for IPv6 text-based mounts and exports.
Tests: tested with only IPv4 network and basic nfs ops (mount, file
creation and modification)
-----
Signed-off-by: Aurelien Charbon <aurelien.charbon@bull.net>
diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/export.c
linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c
--- linux-2.6.24-rc4/fs/nfsd/export.c 2007-12-10 16:11:37.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c 2007-12-10
17:50:37.000000000 +0100
@@ -35,6 +35,7 @@
#include <linux/lockd/bind.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_api.h>
+#include <net/ipv6.h>
#define NFSDDBG_FACILITY NFSDDBG_EXPORT
@@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp)
{
struct auth_domain *dom;
int i, err;
+ struct in6_addr addr6;
/* First, consistency check. */
err = -EINVAL;
@@ -1574,9 +1576,12 @@ exp_addclient(struct nfsctl_client *ncp)
goto out_unlock;
/* Insert client into hashtable. */
- for (i = 0; i < ncp->cl_naddr; i++)
- auth_unix_add_addr(ncp->cl_addrlist[i], dom);
-
+ for (i = 0; i < ncp->cl_naddr; i++) {
+ /* Mapping address */
+ ipv6_addr_set(&addr6, 0, 0,
+ htonl(0x0000FFFF), ncp->cl_addrlist[i].s_addr);
+ auth_unix_add_addr(&addr6, dom);
+ }
auth_unix_forget_old(dom);
auth_domain_put(dom);
diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/nfsctl.c
linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c
--- linux-2.6.24-rc4/fs/nfsd/nfsctl.c 2007-12-10 16:11:37.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c 2007-12-10
18:15:22.000000000 +0100
@@ -37,6 +37,7 @@
#include <linux/nfsd/syscall.h>
#include <asm/uaccess.h>
+#include <net/ipv6.h>
/*
* We have a single directory with 9 nodes in it.
@@ -222,6 +223,7 @@ static ssize_t write_getfs(struct file *
struct auth_domain *clp;
int err = 0;
struct knfsd_fh *res;
+ struct in6_addr in6;
if (size < sizeof(*data))
return -EINVAL;
@@ -236,7 +238,13 @@ static ssize_t write_getfs(struct file *
res = (struct knfsd_fh*)buf;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+
+ /* IPv6 address mapping */
+ ipv6_addr_set(&in6, 0, 0,
+ htonl(0x0000FFFF),
+ (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
@@ -257,6 +265,7 @@ static ssize_t write_getfd(struct file *
int err = 0;
struct knfsd_fh fh;
char *res;
+ struct in6_addr in6;
if (size < sizeof(*data))
return -EINVAL;
@@ -271,7 +280,12 @@ static ssize_t write_getfd(struct file *
res = buf;
sin = (struct sockaddr_in *)&data->gd_addr;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+ /* IPv6 address mapping */
+ ipv6_addr_set(&in6, 0, 0,
+ htonl(0x0000FFFF),
+ (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
diff -p -u -r -N linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h
linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h
--- linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h 2007-12-10
16:01:43.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h
2007-12-10 17:09:34.000000000 +0100
@@ -120,10 +120,10 @@ extern void svc_auth_unregister(rpc_auth
extern struct auth_domain *unix_domain_find(char *name);
extern void auth_domain_put(struct auth_domain *item);
-extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain
*dom);
+extern int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain
*dom);
extern struct auth_domain *auth_domain_lookup(char *name, struct
auth_domain *new);
extern struct auth_domain *auth_domain_find(char *name);
-extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
+extern struct auth_domain *auth_unix_lookup(struct in6_addr *addr);
extern int auth_unix_forget_old(struct auth_domain *dom);
extern void svcauth_unix_purge(void);
extern void svcauth_unix_info_release(void *);
diff -p -u -r -N linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c
linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c
--- linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c 2007-12-10
16:01:46.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c
2007-12-10 17:38:50.000000000 +0100
@@ -11,7 +11,8 @@
#include <linux/hash.h>
#include <linux/string.h>
#include <net/sock.h>
-
+#include <net/ipv6.h>
+#include <linux/kernel.h>
#define RPCDBG_FACILITY RPCDBG_AUTH
@@ -84,7 +85,7 @@ static void svcauth_unix_domain_release(
struct ip_map {
struct cache_head h;
char m_class[8]; /* e.g. "nfsd" */
- struct in_addr m_addr;
+ struct in6_addr m_addr;
struct unix_domain *m_client;
int m_add_change;
};
@@ -112,12 +113,19 @@ static inline int hash_ip(__be32 ip)
return (hash ^ (hash>>8)) & 0xff;
}
#endif
+static inline int hash_ip6(struct in6_addr ip)
+{
+ return (hash_ip(ip.s6_addr32[0]) ^
+ hash_ip(ip.s6_addr32[1]) ^
+ hash_ip(ip.s6_addr32[2]) ^
+ hash_ip(ip.s6_addr32[3]));
+}
static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
{
struct ip_map *orig = container_of(corig, struct ip_map, h);
struct ip_map *new = container_of(cnew, struct ip_map, h);
return strcmp(orig->m_class, new->m_class) == 0
- && orig->m_addr.s_addr == new->m_addr.s_addr;
+ && ipv6_addr_equal(&orig->m_addr, &new->m_addr);
}
static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
{
@@ -125,7 +133,7 @@ static void ip_map_init(struct cache_hea
struct ip_map *item = container_of(citem, struct ip_map, h);
strcpy(new->m_class, item->m_class);
- new->m_addr.s_addr = item->m_addr.s_addr;
+ ipv6_addr_copy(&new->m_addr, &item->m_addr);
}
static void update(struct cache_head *cnew, struct cache_head *citem)
{
@@ -149,22 +157,24 @@ static void ip_map_request(struct cache_
struct cache_head *h,
char **bpp, int *blen)
{
- char text_addr[20];
+ char text_addr[40];
struct ip_map *im = container_of(h, struct ip_map, h);
- __be32 addr = im->m_addr.s_addr;
-
- snprintf(text_addr, 20, "%u.%u.%u.%u",
- ntohl(addr) >> 24 & 0xff,
- ntohl(addr) >> 16 & 0xff,
- ntohl(addr) >> 8 & 0xff,
- ntohl(addr) >> 0 & 0xff);
+ if (ipv6_addr_v4mapped(&(im->m_addr))) {
+ snprintf(text_addr, 20, NIPQUAD_FMT,
+ ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
+ } else {
+ snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
+ }
qword_add(bpp, blen, im->m_class);
qword_add(bpp, blen, text_addr);
(*bpp)[-1] = '\n';
}
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr);
static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom,
time_t expiry);
static int ip_map_parse(struct cache_detail *cd,
@@ -175,10 +185,10 @@ static int ip_map_parse(struct cache_det
* for scratch: */
char *buf = mesg;
int len;
- int b1,b2,b3,b4;
+ int b1, b2, b3, b4, b5, b6, b7, b8;
char c;
char class[8];
- struct in_addr addr;
+ struct in6_addr addr;
int err;
struct ip_map *ipmp;
@@ -197,9 +207,26 @@ static int ip_map_parse(struct cache_det
len = qword_get(&mesg, buf, mlen);
if (len <= 0) return -EINVAL;
- if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
+ if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
+ addr.s6_addr32[0] = 0;
+ addr.s6_addr32[1] = 0;
+ addr.s6_addr32[2] = htonl(0xffff);
+ addr.s6_addr32[3] =
+ htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
+ } else if (sscanf(buf, NIP6_FMT "%c",
+ &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
+ addr.s6_addr16[0] = htons(b1);
+ addr.s6_addr16[1] = htons(b2);
+ addr.s6_addr16[2] = htons(b3);
+ addr.s6_addr16[3] = htons(b4);
+ addr.s6_addr16[4] = htons(b5);
+ addr.s6_addr16[5] = htons(b6);
+ addr.s6_addr16[6] = htons(b7);
+ addr.s6_addr16[7] = htons(b8);
+ } else
return -EINVAL;
+
expiry = get_expiry(&mesg);
if (expiry ==0)
return -EINVAL;
@@ -215,10 +242,7 @@ static int ip_map_parse(struct cache_det
} else
dom = NULL;
- addr.s_addr =
- htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
-
- ipmp = ip_map_lookup(class,addr);
+ ipmp = ip_map_lookup(class, &addr);
if (ipmp) {
err = ip_map_update(ipmp,
container_of(dom, struct unix_domain, h),
@@ -238,7 +262,7 @@ static int ip_map_show(struct seq_file *
struct cache_head *h)
{
struct ip_map *im;
- struct in_addr addr;
+ struct in6_addr addr;
char *dom = "-no-domain-";
if (h == NULL) {
@@ -247,20 +271,24 @@ static int ip_map_show(struct seq_file *
}
im = container_of(h, struct ip_map, h);
/* class addr domain */
- addr = im->m_addr;
+ ipv6_addr_copy(&addr, &im->m_addr);
if (test_bit(CACHE_VALID, &h->flags) &&
!test_bit(CACHE_NEGATIVE, &h->flags))
dom = im->m_client->h.name;
- seq_printf(m, "%s %d.%d.%d.%d %s\n",
- im->m_class,
- ntohl(addr.s_addr) >> 24 & 0xff,
- ntohl(addr.s_addr) >> 16 & 0xff,
- ntohl(addr.s_addr) >> 8 & 0xff,
- ntohl(addr.s_addr) >> 0 & 0xff,
- dom
- );
+ if (ipv6_addr_v4mapped(&addr)) {
+ seq_printf(m, "%s" NIPQUAD_FMT "%s\n",
+ im->m_class,
+ ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 0 & 0xff,
+ dom);
+ } else {
+ seq_printf(m, "%s" NIP6_FMT "%s\n",
+ im->m_class, NIP6(addr), dom);
+ }
return 0;
}
@@ -280,16 +308,16 @@ struct cache_detail ip_map_cache = {
.alloc = ip_map_alloc,
};
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr)
{
struct ip_map ip;
struct cache_head *ch;
strcpy(ip.m_class, class);
- ip.m_addr = addr;
+ ipv6_addr_copy(&ip.m_addr, addr);
ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
hash_str(class, IP_HASHBITS) ^
- hash_ip(addr.s_addr));
+ hash_ip6(*addr));
if (ch)
return container_of(ch, struct ip_map, h);
@@ -318,14 +346,14 @@ static int ip_map_update(struct ip_map *
ch = sunrpc_cache_update(&ip_map_cache,
&ip.h, &ipm->h,
hash_str(ipm->m_class, IP_HASHBITS) ^
- hash_ip(ipm->m_addr.s_addr));
+ hash_ip6(ipm->m_addr));
if (!ch)
return -ENOMEM;
cache_put(ch, &ip_map_cache);
return 0;
}
-int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
+int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom)
{
struct unix_domain *udom;
struct ip_map *ipmp;
@@ -352,7 +380,7 @@ int auth_unix_forget_old(struct auth_dom
return 0;
}
-struct auth_domain *auth_unix_lookup(struct in_addr addr)
+struct auth_domain *auth_unix_lookup(struct in6_addr *addr)
{
struct ip_map *ipm;
struct auth_domain *rv;
@@ -641,9 +669,24 @@ static int unix_gid_find(uid_t uid, stru
int
svcauth_unix_set_client(struct svc_rqst *rqstp)
{
- struct sockaddr_in *sin = svc_addr_in(rqstp);
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6, sin6_storage;
struct ip_map *ipm;
+ switch (rqstp->rq_addr.ss_family) {
+ case AF_INET:
+ sin = svc_addr_in(rqstp);
+ sin6 = &sin6_storage;
+ ipv6_addr_set(&sin6->sin6_addr, 0, 0,
+ htonl(0x0000FFFF), sin->sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ sin6 = svc_addr_in6(rqstp);
+ break;
+ default:
+ BUG();
+ }
+
rqstp->rq_client = NULL;
if (rqstp->rq_proc == 0)
return SVC_OK;
@@ -651,7 +694,7 @@ svcauth_unix_set_client(struct svc_rqst
ipm = ip_map_cached_get(rqstp);
if (ipm == NULL)
ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
- sin->sin_addr);
+ &sin6->sin6_addr);
if (ipm == NULL)
return SVC_DENIED;
--
********************************
Aurelien Charbon
Linux NFSv4 team
Bull SAS
Echirolles - France
http://nfsv4.bullopensource.org/
********************************
[-- Attachment #2: linux-2.6.24-rc4-IPv6-cache.diff --]
[-- Type: text/x-patch, Size: 11772 bytes --]
Signed-off-by: Aurelien Charbon <aurelien.charbon@bull.net>
diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/export.c linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c
--- linux-2.6.24-rc4/fs/nfsd/export.c 2007-12-10 16:11:37.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c 2007-12-10 17:50:37.000000000 +0100
@@ -35,6 +35,7 @@
#include <linux/lockd/bind.h>
#include <linux/sunrpc/msg_prot.h>
#include <linux/sunrpc/gss_api.h>
+#include <net/ipv6.h>
#define NFSDDBG_FACILITY NFSDDBG_EXPORT
@@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp)
{
struct auth_domain *dom;
int i, err;
+ struct in6_addr addr6;
/* First, consistency check. */
err = -EINVAL;
@@ -1574,9 +1576,12 @@ exp_addclient(struct nfsctl_client *ncp)
goto out_unlock;
/* Insert client into hashtable. */
- for (i = 0; i < ncp->cl_naddr; i++)
- auth_unix_add_addr(ncp->cl_addrlist[i], dom);
-
+ for (i = 0; i < ncp->cl_naddr; i++) {
+ /* Mapping address */
+ ipv6_addr_set(&addr6, 0, 0,
+ htonl(0x0000FFFF), ncp->cl_addrlist[i].s_addr);
+ auth_unix_add_addr(&addr6, dom);
+ }
auth_unix_forget_old(dom);
auth_domain_put(dom);
diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/nfsctl.c linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c
--- linux-2.6.24-rc4/fs/nfsd/nfsctl.c 2007-12-10 16:11:37.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c 2007-12-10 18:15:22.000000000 +0100
@@ -37,6 +37,7 @@
#include <linux/nfsd/syscall.h>
#include <asm/uaccess.h>
+#include <net/ipv6.h>
/*
* We have a single directory with 9 nodes in it.
@@ -222,6 +223,7 @@ static ssize_t write_getfs(struct file *
struct auth_domain *clp;
int err = 0;
struct knfsd_fh *res;
+ struct in6_addr in6;
if (size < sizeof(*data))
return -EINVAL;
@@ -236,7 +238,13 @@ static ssize_t write_getfs(struct file *
res = (struct knfsd_fh*)buf;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+
+ /* IPv6 address mapping */
+ ipv6_addr_set(&in6, 0, 0,
+ htonl(0x0000FFFF),
+ (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
@@ -257,6 +265,7 @@ static ssize_t write_getfd(struct file *
int err = 0;
struct knfsd_fh fh;
char *res;
+ struct in6_addr in6;
if (size < sizeof(*data))
return -EINVAL;
@@ -271,7 +280,12 @@ static ssize_t write_getfd(struct file *
res = buf;
sin = (struct sockaddr_in *)&data->gd_addr;
exp_readlock();
- if (!(clp = auth_unix_lookup(sin->sin_addr)))
+ /* IPv6 address mapping */
+ ipv6_addr_set(&in6, 0, 0,
+ htonl(0x0000FFFF),
+ (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
+
+ if (!(clp = auth_unix_lookup(in6)))
err = -EPERM;
else {
err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
diff -p -u -r -N linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h
--- linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h 2007-12-10 16:01:43.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h 2007-12-10 17:09:34.000000000 +0100
@@ -120,10 +120,10 @@ extern void svc_auth_unregister(rpc_auth
extern struct auth_domain *unix_domain_find(char *name);
extern void auth_domain_put(struct auth_domain *item);
-extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
+extern int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom);
extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
extern struct auth_domain *auth_domain_find(char *name);
-extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
+extern struct auth_domain *auth_unix_lookup(struct in6_addr *addr);
extern int auth_unix_forget_old(struct auth_domain *dom);
extern void svcauth_unix_purge(void);
extern void svcauth_unix_info_release(void *);
diff -p -u -r -N linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c
--- linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c 2007-12-10 16:01:46.000000000 +0100
+++ linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c 2007-12-10 17:38:50.000000000 +0100
@@ -11,7 +11,8 @@
#include <linux/hash.h>
#include <linux/string.h>
#include <net/sock.h>
-
+#include <net/ipv6.h>
+#include <linux/kernel.h>
#define RPCDBG_FACILITY RPCDBG_AUTH
@@ -84,7 +85,7 @@ static void svcauth_unix_domain_release(
struct ip_map {
struct cache_head h;
char m_class[8]; /* e.g. "nfsd" */
- struct in_addr m_addr;
+ struct in6_addr m_addr;
struct unix_domain *m_client;
int m_add_change;
};
@@ -112,12 +113,19 @@ static inline int hash_ip(__be32 ip)
return (hash ^ (hash>>8)) & 0xff;
}
#endif
+static inline int hash_ip6(struct in6_addr ip)
+{
+ return (hash_ip(ip.s6_addr32[0]) ^
+ hash_ip(ip.s6_addr32[1]) ^
+ hash_ip(ip.s6_addr32[2]) ^
+ hash_ip(ip.s6_addr32[3]));
+}
static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
{
struct ip_map *orig = container_of(corig, struct ip_map, h);
struct ip_map *new = container_of(cnew, struct ip_map, h);
return strcmp(orig->m_class, new->m_class) == 0
- && orig->m_addr.s_addr == new->m_addr.s_addr;
+ && ipv6_addr_equal(&orig->m_addr, &new->m_addr);
}
static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
{
@@ -125,7 +133,7 @@ static void ip_map_init(struct cache_hea
struct ip_map *item = container_of(citem, struct ip_map, h);
strcpy(new->m_class, item->m_class);
- new->m_addr.s_addr = item->m_addr.s_addr;
+ ipv6_addr_copy(&new->m_addr, &item->m_addr);
}
static void update(struct cache_head *cnew, struct cache_head *citem)
{
@@ -149,22 +157,24 @@ static void ip_map_request(struct cache_
struct cache_head *h,
char **bpp, int *blen)
{
- char text_addr[20];
+ char text_addr[40];
struct ip_map *im = container_of(h, struct ip_map, h);
- __be32 addr = im->m_addr.s_addr;
-
- snprintf(text_addr, 20, "%u.%u.%u.%u",
- ntohl(addr) >> 24 & 0xff,
- ntohl(addr) >> 16 & 0xff,
- ntohl(addr) >> 8 & 0xff,
- ntohl(addr) >> 0 & 0xff);
+ if (ipv6_addr_v4mapped(&(im->m_addr))) {
+ snprintf(text_addr, 20, NIPQUAD_FMT,
+ ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
+ } else {
+ snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
+ }
qword_add(bpp, blen, im->m_class);
qword_add(bpp, blen, text_addr);
(*bpp)[-1] = '\n';
}
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr);
static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
static int ip_map_parse(struct cache_detail *cd,
@@ -175,10 +185,10 @@ static int ip_map_parse(struct cache_det
* for scratch: */
char *buf = mesg;
int len;
- int b1,b2,b3,b4;
+ int b1, b2, b3, b4, b5, b6, b7, b8;
char c;
char class[8];
- struct in_addr addr;
+ struct in6_addr addr;
int err;
struct ip_map *ipmp;
@@ -197,9 +207,26 @@ static int ip_map_parse(struct cache_det
len = qword_get(&mesg, buf, mlen);
if (len <= 0) return -EINVAL;
- if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
+ if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
+ addr.s6_addr32[0] = 0;
+ addr.s6_addr32[1] = 0;
+ addr.s6_addr32[2] = htonl(0xffff);
+ addr.s6_addr32[3] =
+ htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
+ } else if (sscanf(buf, NIP6_FMT "%c",
+ &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
+ addr.s6_addr16[0] = htons(b1);
+ addr.s6_addr16[1] = htons(b2);
+ addr.s6_addr16[2] = htons(b3);
+ addr.s6_addr16[3] = htons(b4);
+ addr.s6_addr16[4] = htons(b5);
+ addr.s6_addr16[5] = htons(b6);
+ addr.s6_addr16[6] = htons(b7);
+ addr.s6_addr16[7] = htons(b8);
+ } else
return -EINVAL;
+
expiry = get_expiry(&mesg);
if (expiry ==0)
return -EINVAL;
@@ -215,10 +242,7 @@ static int ip_map_parse(struct cache_det
} else
dom = NULL;
- addr.s_addr =
- htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
-
- ipmp = ip_map_lookup(class,addr);
+ ipmp = ip_map_lookup(class, &addr);
if (ipmp) {
err = ip_map_update(ipmp,
container_of(dom, struct unix_domain, h),
@@ -238,7 +262,7 @@ static int ip_map_show(struct seq_file *
struct cache_head *h)
{
struct ip_map *im;
- struct in_addr addr;
+ struct in6_addr addr;
char *dom = "-no-domain-";
if (h == NULL) {
@@ -247,20 +271,24 @@ static int ip_map_show(struct seq_file *
}
im = container_of(h, struct ip_map, h);
/* class addr domain */
- addr = im->m_addr;
+ ipv6_addr_copy(&addr, &im->m_addr);
if (test_bit(CACHE_VALID, &h->flags) &&
!test_bit(CACHE_NEGATIVE, &h->flags))
dom = im->m_client->h.name;
- seq_printf(m, "%s %d.%d.%d.%d %s\n",
- im->m_class,
- ntohl(addr.s_addr) >> 24 & 0xff,
- ntohl(addr.s_addr) >> 16 & 0xff,
- ntohl(addr.s_addr) >> 8 & 0xff,
- ntohl(addr.s_addr) >> 0 & 0xff,
- dom
- );
+ if (ipv6_addr_v4mapped(&addr)) {
+ seq_printf(m, "%s" NIPQUAD_FMT "%s\n",
+ im->m_class,
+ ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 8 & 0xff,
+ ntohl(addr.s6_addr32[3]) >> 0 & 0xff,
+ dom);
+ } else {
+ seq_printf(m, "%s" NIP6_FMT "%s\n",
+ im->m_class, NIP6(addr), dom);
+ }
return 0;
}
@@ -280,16 +308,16 @@ struct cache_detail ip_map_cache = {
.alloc = ip_map_alloc,
};
-static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
+static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr)
{
struct ip_map ip;
struct cache_head *ch;
strcpy(ip.m_class, class);
- ip.m_addr = addr;
+ ipv6_addr_copy(&ip.m_addr, addr);
ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
hash_str(class, IP_HASHBITS) ^
- hash_ip(addr.s_addr));
+ hash_ip6(*addr));
if (ch)
return container_of(ch, struct ip_map, h);
@@ -318,14 +346,14 @@ static int ip_map_update(struct ip_map *
ch = sunrpc_cache_update(&ip_map_cache,
&ip.h, &ipm->h,
hash_str(ipm->m_class, IP_HASHBITS) ^
- hash_ip(ipm->m_addr.s_addr));
+ hash_ip6(ipm->m_addr));
if (!ch)
return -ENOMEM;
cache_put(ch, &ip_map_cache);
return 0;
}
-int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
+int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom)
{
struct unix_domain *udom;
struct ip_map *ipmp;
@@ -352,7 +380,7 @@ int auth_unix_forget_old(struct auth_dom
return 0;
}
-struct auth_domain *auth_unix_lookup(struct in_addr addr)
+struct auth_domain *auth_unix_lookup(struct in6_addr *addr)
{
struct ip_map *ipm;
struct auth_domain *rv;
@@ -641,9 +669,24 @@ static int unix_gid_find(uid_t uid, stru
int
svcauth_unix_set_client(struct svc_rqst *rqstp)
{
- struct sockaddr_in *sin = svc_addr_in(rqstp);
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6, sin6_storage;
struct ip_map *ipm;
+ switch (rqstp->rq_addr.ss_family) {
+ case AF_INET:
+ sin = svc_addr_in(rqstp);
+ sin6 = &sin6_storage;
+ ipv6_addr_set(&sin6->sin6_addr, 0, 0,
+ htonl(0x0000FFFF), sin->sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ sin6 = svc_addr_in6(rqstp);
+ break;
+ default:
+ BUG();
+ }
+
rqstp->rq_client = NULL;
if (rqstp->rq_proc == 0)
return SVC_OK;
@@ -651,7 +694,7 @@ svcauth_unix_set_client(struct svc_rqst
ipm = ip_map_cached_get(rqstp);
if (ipm == NULL)
ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
- sin->sin_addr);
+ &sin6->sin6_addr);
if (ipm == NULL)
return SVC_DENIED;
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
NFSv4 mailing list
NFSv4@linux-nfs.org
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4
^ permalink raw reply
* Re: [PATCH] IPv6 support for NFS server
From: J. Bruce Fields @ 2007-12-10 18:34 UTC (permalink / raw)
To: Aurélien Charbon; +Cc: netdev ML, Mailing list NFSv4
In-Reply-To: <475D86C1.6070400@ext.bull.net>
On Mon, Dec 10, 2007 at 07:34:41PM +0100, Aurélien Charbon wrote:
>
> Here is a cleanup for the ip_map caching patch in nfs server.
>
> It prepares for IPv6 text-based mounts and exports.
>
> Tests: tested with only IPv4 network and basic nfs ops (mount, file
> creation and modification)
Thanks! And also tested with an unmodified rpc.mountd?
--b.
>
> -----
>
> Signed-off-by: Aurelien Charbon <aurelien.charbon@bull.net>
>
> diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/export.c
> linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c
> --- linux-2.6.24-rc4/fs/nfsd/export.c 2007-12-10 16:11:37.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c 2007-12-10
> 17:50:37.000000000 +0100
> @@ -35,6 +35,7 @@
> #include <linux/lockd/bind.h>
> #include <linux/sunrpc/msg_prot.h>
> #include <linux/sunrpc/gss_api.h>
> +#include <net/ipv6.h>
>
> #define NFSDDBG_FACILITY NFSDDBG_EXPORT
>
> @@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp)
> {
> struct auth_domain *dom;
> int i, err;
> + struct in6_addr addr6;
>
> /* First, consistency check. */
> err = -EINVAL;
> @@ -1574,9 +1576,12 @@ exp_addclient(struct nfsctl_client *ncp)
> goto out_unlock;
>
> /* Insert client into hashtable. */
> - for (i = 0; i < ncp->cl_naddr; i++)
> - auth_unix_add_addr(ncp->cl_addrlist[i], dom);
> -
> + for (i = 0; i < ncp->cl_naddr; i++) {
> + /* Mapping address */
> + ipv6_addr_set(&addr6, 0, 0,
> + htonl(0x0000FFFF), ncp->cl_addrlist[i].s_addr);
> + auth_unix_add_addr(&addr6, dom);
> + }
> auth_unix_forget_old(dom);
> auth_domain_put(dom);
>
> diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/nfsctl.c
> linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c
> --- linux-2.6.24-rc4/fs/nfsd/nfsctl.c 2007-12-10 16:11:37.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c 2007-12-10
> 18:15:22.000000000 +0100
> @@ -37,6 +37,7 @@
> #include <linux/nfsd/syscall.h>
>
> #include <asm/uaccess.h>
> +#include <net/ipv6.h>
>
> /*
> * We have a single directory with 9 nodes in it.
> @@ -222,6 +223,7 @@ static ssize_t write_getfs(struct file *
> struct auth_domain *clp;
> int err = 0;
> struct knfsd_fh *res;
> + struct in6_addr in6;
>
> if (size < sizeof(*data))
> return -EINVAL;
> @@ -236,7 +238,13 @@ static ssize_t write_getfs(struct file *
> res = (struct knfsd_fh*)buf;
>
> exp_readlock();
> - if (!(clp = auth_unix_lookup(sin->sin_addr)))
> +
> + /* IPv6 address mapping */
> + ipv6_addr_set(&in6, 0, 0,
> + htonl(0x0000FFFF),
> + (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
> +
> + if (!(clp = auth_unix_lookup(in6)))
> err = -EPERM;
> else {
> err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
> @@ -257,6 +265,7 @@ static ssize_t write_getfd(struct file *
> int err = 0;
> struct knfsd_fh fh;
> char *res;
> + struct in6_addr in6;
>
> if (size < sizeof(*data))
> return -EINVAL;
> @@ -271,7 +280,12 @@ static ssize_t write_getfd(struct file *
> res = buf;
> sin = (struct sockaddr_in *)&data->gd_addr;
> exp_readlock();
> - if (!(clp = auth_unix_lookup(sin->sin_addr)))
> + /* IPv6 address mapping */
> + ipv6_addr_set(&in6, 0, 0,
> + htonl(0x0000FFFF),
> + (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
> +
> + if (!(clp = auth_unix_lookup(in6)))
> err = -EPERM;
> else {
> err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
> diff -p -u -r -N linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h
> linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h
> --- linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h 2007-12-10
> 16:01:43.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h
> 2007-12-10 17:09:34.000000000 +0100
> @@ -120,10 +120,10 @@ extern void svc_auth_unregister(rpc_auth
>
> extern struct auth_domain *unix_domain_find(char *name);
> extern void auth_domain_put(struct auth_domain *item);
> -extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain
> *dom);
> +extern int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain
> *dom);
> extern struct auth_domain *auth_domain_lookup(char *name, struct
> auth_domain *new);
> extern struct auth_domain *auth_domain_find(char *name);
> -extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
> +extern struct auth_domain *auth_unix_lookup(struct in6_addr *addr);
> extern int auth_unix_forget_old(struct auth_domain *dom);
> extern void svcauth_unix_purge(void);
> extern void svcauth_unix_info_release(void *);
> diff -p -u -r -N linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c
> linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c
> --- linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c 2007-12-10
> 16:01:46.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c
> 2007-12-10 17:38:50.000000000 +0100
> @@ -11,7 +11,8 @@
> #include <linux/hash.h>
> #include <linux/string.h>
> #include <net/sock.h>
> -
> +#include <net/ipv6.h>
> +#include <linux/kernel.h>
> #define RPCDBG_FACILITY RPCDBG_AUTH
>
>
> @@ -84,7 +85,7 @@ static void svcauth_unix_domain_release(
> struct ip_map {
> struct cache_head h;
> char m_class[8]; /* e.g. "nfsd" */
> - struct in_addr m_addr;
> + struct in6_addr m_addr;
> struct unix_domain *m_client;
> int m_add_change;
> };
> @@ -112,12 +113,19 @@ static inline int hash_ip(__be32 ip)
> return (hash ^ (hash>>8)) & 0xff;
> }
> #endif
> +static inline int hash_ip6(struct in6_addr ip)
> +{
> + return (hash_ip(ip.s6_addr32[0]) ^
> + hash_ip(ip.s6_addr32[1]) ^
> + hash_ip(ip.s6_addr32[2]) ^
> + hash_ip(ip.s6_addr32[3]));
> +}
> static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
> {
> struct ip_map *orig = container_of(corig, struct ip_map, h);
> struct ip_map *new = container_of(cnew, struct ip_map, h);
> return strcmp(orig->m_class, new->m_class) == 0
> - && orig->m_addr.s_addr == new->m_addr.s_addr;
> + && ipv6_addr_equal(&orig->m_addr, &new->m_addr);
> }
> static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
> {
> @@ -125,7 +133,7 @@ static void ip_map_init(struct cache_hea
> struct ip_map *item = container_of(citem, struct ip_map, h);
>
> strcpy(new->m_class, item->m_class);
> - new->m_addr.s_addr = item->m_addr.s_addr;
> + ipv6_addr_copy(&new->m_addr, &item->m_addr);
> }
> static void update(struct cache_head *cnew, struct cache_head *citem)
> {
> @@ -149,22 +157,24 @@ static void ip_map_request(struct cache_
> struct cache_head *h,
> char **bpp, int *blen)
> {
> - char text_addr[20];
> + char text_addr[40];
> struct ip_map *im = container_of(h, struct ip_map, h);
> - __be32 addr = im->m_addr.s_addr;
> -
> - snprintf(text_addr, 20, "%u.%u.%u.%u",
> - ntohl(addr) >> 24 & 0xff,
> - ntohl(addr) >> 16 & 0xff,
> - ntohl(addr) >> 8 & 0xff,
> - ntohl(addr) >> 0 & 0xff);
>
> + if (ipv6_addr_v4mapped(&(im->m_addr))) {
> + snprintf(text_addr, 20, NIPQUAD_FMT,
> + ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
> + } else {
> + snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
> + }
> qword_add(bpp, blen, im->m_class);
> qword_add(bpp, blen, text_addr);
> (*bpp)[-1] = '\n';
> }
>
> -static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
> +static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr);
> static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom,
> time_t expiry);
>
> static int ip_map_parse(struct cache_detail *cd,
> @@ -175,10 +185,10 @@ static int ip_map_parse(struct cache_det
> * for scratch: */
> char *buf = mesg;
> int len;
> - int b1,b2,b3,b4;
> + int b1, b2, b3, b4, b5, b6, b7, b8;
> char c;
> char class[8];
> - struct in_addr addr;
> + struct in6_addr addr;
> int err;
>
> struct ip_map *ipmp;
> @@ -197,9 +207,26 @@ static int ip_map_parse(struct cache_det
> len = qword_get(&mesg, buf, mlen);
> if (len <= 0) return -EINVAL;
>
> - if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
> + if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
> + addr.s6_addr32[0] = 0;
> + addr.s6_addr32[1] = 0;
> + addr.s6_addr32[2] = htonl(0xffff);
> + addr.s6_addr32[3] =
> + htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
> + } else if (sscanf(buf, NIP6_FMT "%c",
> + &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
> + addr.s6_addr16[0] = htons(b1);
> + addr.s6_addr16[1] = htons(b2);
> + addr.s6_addr16[2] = htons(b3);
> + addr.s6_addr16[3] = htons(b4);
> + addr.s6_addr16[4] = htons(b5);
> + addr.s6_addr16[5] = htons(b6);
> + addr.s6_addr16[6] = htons(b7);
> + addr.s6_addr16[7] = htons(b8);
> + } else
> return -EINVAL;
>
> +
> expiry = get_expiry(&mesg);
> if (expiry ==0)
> return -EINVAL;
> @@ -215,10 +242,7 @@ static int ip_map_parse(struct cache_det
> } else
> dom = NULL;
>
> - addr.s_addr =
> - htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
> -
> - ipmp = ip_map_lookup(class,addr);
> + ipmp = ip_map_lookup(class, &addr);
> if (ipmp) {
> err = ip_map_update(ipmp,
> container_of(dom, struct unix_domain, h),
> @@ -238,7 +262,7 @@ static int ip_map_show(struct seq_file *
> struct cache_head *h)
> {
> struct ip_map *im;
> - struct in_addr addr;
> + struct in6_addr addr;
> char *dom = "-no-domain-";
>
> if (h == NULL) {
> @@ -247,20 +271,24 @@ static int ip_map_show(struct seq_file *
> }
> im = container_of(h, struct ip_map, h);
> /* class addr domain */
> - addr = im->m_addr;
> + ipv6_addr_copy(&addr, &im->m_addr);
>
> if (test_bit(CACHE_VALID, &h->flags) &&
> !test_bit(CACHE_NEGATIVE, &h->flags))
> dom = im->m_client->h.name;
>
> - seq_printf(m, "%s %d.%d.%d.%d %s\n",
> - im->m_class,
> - ntohl(addr.s_addr) >> 24 & 0xff,
> - ntohl(addr.s_addr) >> 16 & 0xff,
> - ntohl(addr.s_addr) >> 8 & 0xff,
> - ntohl(addr.s_addr) >> 0 & 0xff,
> - dom
> - );
> + if (ipv6_addr_v4mapped(&addr)) {
> + seq_printf(m, "%s" NIPQUAD_FMT "%s\n",
> + im->m_class,
> + ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
> + ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
> + ntohl(addr.s6_addr32[3]) >> 8 & 0xff,
> + ntohl(addr.s6_addr32[3]) >> 0 & 0xff,
> + dom);
> + } else {
> + seq_printf(m, "%s" NIP6_FMT "%s\n",
> + im->m_class, NIP6(addr), dom);
> + }
> return 0;
> }
>
> @@ -280,16 +308,16 @@ struct cache_detail ip_map_cache = {
> .alloc = ip_map_alloc,
> };
>
> -static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
> +static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr)
> {
> struct ip_map ip;
> struct cache_head *ch;
>
> strcpy(ip.m_class, class);
> - ip.m_addr = addr;
> + ipv6_addr_copy(&ip.m_addr, addr);
> ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
> hash_str(class, IP_HASHBITS) ^
> - hash_ip(addr.s_addr));
> + hash_ip6(*addr));
>
> if (ch)
> return container_of(ch, struct ip_map, h);
> @@ -318,14 +346,14 @@ static int ip_map_update(struct ip_map *
> ch = sunrpc_cache_update(&ip_map_cache,
> &ip.h, &ipm->h,
> hash_str(ipm->m_class, IP_HASHBITS) ^
> - hash_ip(ipm->m_addr.s_addr));
> + hash_ip6(ipm->m_addr));
> if (!ch)
> return -ENOMEM;
> cache_put(ch, &ip_map_cache);
> return 0;
> }
>
> -int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
> +int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom)
> {
> struct unix_domain *udom;
> struct ip_map *ipmp;
> @@ -352,7 +380,7 @@ int auth_unix_forget_old(struct auth_dom
> return 0;
> }
>
> -struct auth_domain *auth_unix_lookup(struct in_addr addr)
> +struct auth_domain *auth_unix_lookup(struct in6_addr *addr)
> {
> struct ip_map *ipm;
> struct auth_domain *rv;
> @@ -641,9 +669,24 @@ static int unix_gid_find(uid_t uid, stru
> int
> svcauth_unix_set_client(struct svc_rqst *rqstp)
> {
> - struct sockaddr_in *sin = svc_addr_in(rqstp);
> + struct sockaddr_in *sin;
> + struct sockaddr_in6 *sin6, sin6_storage;
> struct ip_map *ipm;
>
> + switch (rqstp->rq_addr.ss_family) {
> + case AF_INET:
> + sin = svc_addr_in(rqstp);
> + sin6 = &sin6_storage;
> + ipv6_addr_set(&sin6->sin6_addr, 0, 0,
> + htonl(0x0000FFFF), sin->sin_addr.s_addr);
> + break;
> + case AF_INET6:
> + sin6 = svc_addr_in6(rqstp);
> + break;
> + default:
> + BUG();
> + }
> +
> rqstp->rq_client = NULL;
> if (rqstp->rq_proc == 0)
> return SVC_OK;
> @@ -651,7 +694,7 @@ svcauth_unix_set_client(struct svc_rqst
> ipm = ip_map_cached_get(rqstp);
> if (ipm == NULL)
> ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
> - sin->sin_addr);
> + &sin6->sin6_addr);
>
> if (ipm == NULL)
> return SVC_DENIED;
>
> --
>
> ********************************
> Aurelien Charbon
> Linux NFSv4 team
> Bull SAS
> Echirolles - France
> http://nfsv4.bullopensource.org/
> ********************************
>
> Signed-off-by: Aurelien Charbon <aurelien.charbon@bull.net>
>
> diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/export.c linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c
> --- linux-2.6.24-rc4/fs/nfsd/export.c 2007-12-10 16:11:37.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/export.c 2007-12-10 17:50:37.000000000 +0100
> @@ -35,6 +35,7 @@
> #include <linux/lockd/bind.h>
> #include <linux/sunrpc/msg_prot.h>
> #include <linux/sunrpc/gss_api.h>
> +#include <net/ipv6.h>
>
> #define NFSDDBG_FACILITY NFSDDBG_EXPORT
>
> @@ -1556,6 +1557,7 @@ exp_addclient(struct nfsctl_client *ncp)
> {
> struct auth_domain *dom;
> int i, err;
> + struct in6_addr addr6;
>
> /* First, consistency check. */
> err = -EINVAL;
> @@ -1574,9 +1576,12 @@ exp_addclient(struct nfsctl_client *ncp)
> goto out_unlock;
>
> /* Insert client into hashtable. */
> - for (i = 0; i < ncp->cl_naddr; i++)
> - auth_unix_add_addr(ncp->cl_addrlist[i], dom);
> -
> + for (i = 0; i < ncp->cl_naddr; i++) {
> + /* Mapping address */
> + ipv6_addr_set(&addr6, 0, 0,
> + htonl(0x0000FFFF), ncp->cl_addrlist[i].s_addr);
> + auth_unix_add_addr(&addr6, dom);
> + }
> auth_unix_forget_old(dom);
> auth_domain_put(dom);
>
> diff -p -u -r -N linux-2.6.24-rc4/fs/nfsd/nfsctl.c linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c
> --- linux-2.6.24-rc4/fs/nfsd/nfsctl.c 2007-12-10 16:11:37.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/fs/nfsd/nfsctl.c 2007-12-10 18:15:22.000000000 +0100
> @@ -37,6 +37,7 @@
> #include <linux/nfsd/syscall.h>
>
> #include <asm/uaccess.h>
> +#include <net/ipv6.h>
>
> /*
> * We have a single directory with 9 nodes in it.
> @@ -222,6 +223,7 @@ static ssize_t write_getfs(struct file *
> struct auth_domain *clp;
> int err = 0;
> struct knfsd_fh *res;
> + struct in6_addr in6;
>
> if (size < sizeof(*data))
> return -EINVAL;
> @@ -236,7 +238,13 @@ static ssize_t write_getfs(struct file *
> res = (struct knfsd_fh*)buf;
>
> exp_readlock();
> - if (!(clp = auth_unix_lookup(sin->sin_addr)))
> +
> + /* IPv6 address mapping */
> + ipv6_addr_set(&in6, 0, 0,
> + htonl(0x0000FFFF),
> + (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
> +
> + if (!(clp = auth_unix_lookup(in6)))
> err = -EPERM;
> else {
> err = exp_rootfh(clp, data->gd_path, res, data->gd_maxlen);
> @@ -257,6 +265,7 @@ static ssize_t write_getfd(struct file *
> int err = 0;
> struct knfsd_fh fh;
> char *res;
> + struct in6_addr in6;
>
> if (size < sizeof(*data))
> return -EINVAL;
> @@ -271,7 +280,12 @@ static ssize_t write_getfd(struct file *
> res = buf;
> sin = (struct sockaddr_in *)&data->gd_addr;
> exp_readlock();
> - if (!(clp = auth_unix_lookup(sin->sin_addr)))
> + /* IPv6 address mapping */
> + ipv6_addr_set(&in6, 0, 0,
> + htonl(0x0000FFFF),
> + (((struct sockaddr_in *)&data->gd_addr)->sin_addr.s_addr));
> +
> + if (!(clp = auth_unix_lookup(in6)))
> err = -EPERM;
> else {
> err = exp_rootfh(clp, data->gd_path, &fh, NFS_FHSIZE);
> diff -p -u -r -N linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h
> --- linux-2.6.24-rc4/include/linux/sunrpc/svcauth.h 2007-12-10 16:01:43.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/include/linux/sunrpc/svcauth.h 2007-12-10 17:09:34.000000000 +0100
> @@ -120,10 +120,10 @@ extern void svc_auth_unregister(rpc_auth
>
> extern struct auth_domain *unix_domain_find(char *name);
> extern void auth_domain_put(struct auth_domain *item);
> -extern int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom);
> +extern int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom);
> extern struct auth_domain *auth_domain_lookup(char *name, struct auth_domain *new);
> extern struct auth_domain *auth_domain_find(char *name);
> -extern struct auth_domain *auth_unix_lookup(struct in_addr addr);
> +extern struct auth_domain *auth_unix_lookup(struct in6_addr *addr);
> extern int auth_unix_forget_old(struct auth_domain *dom);
> extern void svcauth_unix_purge(void);
> extern void svcauth_unix_info_release(void *);
> diff -p -u -r -N linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c
> --- linux-2.6.24-rc4/net/sunrpc/svcauth_unix.c 2007-12-10 16:01:46.000000000 +0100
> +++ linux-2.6.24-rc4-IPv6-cache-based/net/sunrpc/svcauth_unix.c 2007-12-10 17:38:50.000000000 +0100
> @@ -11,7 +11,8 @@
> #include <linux/hash.h>
> #include <linux/string.h>
> #include <net/sock.h>
> -
> +#include <net/ipv6.h>
> +#include <linux/kernel.h>
> #define RPCDBG_FACILITY RPCDBG_AUTH
>
>
> @@ -84,7 +85,7 @@ static void svcauth_unix_domain_release(
> struct ip_map {
> struct cache_head h;
> char m_class[8]; /* e.g. "nfsd" */
> - struct in_addr m_addr;
> + struct in6_addr m_addr;
> struct unix_domain *m_client;
> int m_add_change;
> };
> @@ -112,12 +113,19 @@ static inline int hash_ip(__be32 ip)
> return (hash ^ (hash>>8)) & 0xff;
> }
> #endif
> +static inline int hash_ip6(struct in6_addr ip)
> +{
> + return (hash_ip(ip.s6_addr32[0]) ^
> + hash_ip(ip.s6_addr32[1]) ^
> + hash_ip(ip.s6_addr32[2]) ^
> + hash_ip(ip.s6_addr32[3]));
> +}
> static int ip_map_match(struct cache_head *corig, struct cache_head *cnew)
> {
> struct ip_map *orig = container_of(corig, struct ip_map, h);
> struct ip_map *new = container_of(cnew, struct ip_map, h);
> return strcmp(orig->m_class, new->m_class) == 0
> - && orig->m_addr.s_addr == new->m_addr.s_addr;
> + && ipv6_addr_equal(&orig->m_addr, &new->m_addr);
> }
> static void ip_map_init(struct cache_head *cnew, struct cache_head *citem)
> {
> @@ -125,7 +133,7 @@ static void ip_map_init(struct cache_hea
> struct ip_map *item = container_of(citem, struct ip_map, h);
>
> strcpy(new->m_class, item->m_class);
> - new->m_addr.s_addr = item->m_addr.s_addr;
> + ipv6_addr_copy(&new->m_addr, &item->m_addr);
> }
> static void update(struct cache_head *cnew, struct cache_head *citem)
> {
> @@ -149,22 +157,24 @@ static void ip_map_request(struct cache_
> struct cache_head *h,
> char **bpp, int *blen)
> {
> - char text_addr[20];
> + char text_addr[40];
> struct ip_map *im = container_of(h, struct ip_map, h);
> - __be32 addr = im->m_addr.s_addr;
> -
> - snprintf(text_addr, 20, "%u.%u.%u.%u",
> - ntohl(addr) >> 24 & 0xff,
> - ntohl(addr) >> 16 & 0xff,
> - ntohl(addr) >> 8 & 0xff,
> - ntohl(addr) >> 0 & 0xff);
>
> + if (ipv6_addr_v4mapped(&(im->m_addr))) {
> + snprintf(text_addr, 20, NIPQUAD_FMT,
> + ntohl(im->m_addr.s6_addr32[3]) >> 24 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 16 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 8 & 0xff,
> + ntohl(im->m_addr.s6_addr32[3]) >> 0 & 0xff);
> + } else {
> + snprintf(text_addr, 40, NIP6_FMT, NIP6(im->m_addr));
> + }
> qword_add(bpp, blen, im->m_class);
> qword_add(bpp, blen, text_addr);
> (*bpp)[-1] = '\n';
> }
>
> -static struct ip_map *ip_map_lookup(char *class, struct in_addr addr);
> +static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr);
> static int ip_map_update(struct ip_map *ipm, struct unix_domain *udom, time_t expiry);
>
> static int ip_map_parse(struct cache_detail *cd,
> @@ -175,10 +185,10 @@ static int ip_map_parse(struct cache_det
> * for scratch: */
> char *buf = mesg;
> int len;
> - int b1,b2,b3,b4;
> + int b1, b2, b3, b4, b5, b6, b7, b8;
> char c;
> char class[8];
> - struct in_addr addr;
> + struct in6_addr addr;
> int err;
>
> struct ip_map *ipmp;
> @@ -197,9 +207,26 @@ static int ip_map_parse(struct cache_det
> len = qword_get(&mesg, buf, mlen);
> if (len <= 0) return -EINVAL;
>
> - if (sscanf(buf, "%u.%u.%u.%u%c", &b1, &b2, &b3, &b4, &c) != 4)
> + if (sscanf(buf, NIPQUAD_FMT "%c", &b1, &b2, &b3, &b4, &c) == 4) {
> + addr.s6_addr32[0] = 0;
> + addr.s6_addr32[1] = 0;
> + addr.s6_addr32[2] = htonl(0xffff);
> + addr.s6_addr32[3] =
> + htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
> + } else if (sscanf(buf, NIP6_FMT "%c",
> + &b1, &b2, &b3, &b4, &b5, &b6, &b7, &b8, &c) == 8) {
> + addr.s6_addr16[0] = htons(b1);
> + addr.s6_addr16[1] = htons(b2);
> + addr.s6_addr16[2] = htons(b3);
> + addr.s6_addr16[3] = htons(b4);
> + addr.s6_addr16[4] = htons(b5);
> + addr.s6_addr16[5] = htons(b6);
> + addr.s6_addr16[6] = htons(b7);
> + addr.s6_addr16[7] = htons(b8);
> + } else
> return -EINVAL;
>
> +
> expiry = get_expiry(&mesg);
> if (expiry ==0)
> return -EINVAL;
> @@ -215,10 +242,7 @@ static int ip_map_parse(struct cache_det
> } else
> dom = NULL;
>
> - addr.s_addr =
> - htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
> -
> - ipmp = ip_map_lookup(class,addr);
> + ipmp = ip_map_lookup(class, &addr);
> if (ipmp) {
> err = ip_map_update(ipmp,
> container_of(dom, struct unix_domain, h),
> @@ -238,7 +262,7 @@ static int ip_map_show(struct seq_file *
> struct cache_head *h)
> {
> struct ip_map *im;
> - struct in_addr addr;
> + struct in6_addr addr;
> char *dom = "-no-domain-";
>
> if (h == NULL) {
> @@ -247,20 +271,24 @@ static int ip_map_show(struct seq_file *
> }
> im = container_of(h, struct ip_map, h);
> /* class addr domain */
> - addr = im->m_addr;
> + ipv6_addr_copy(&addr, &im->m_addr);
>
> if (test_bit(CACHE_VALID, &h->flags) &&
> !test_bit(CACHE_NEGATIVE, &h->flags))
> dom = im->m_client->h.name;
>
> - seq_printf(m, "%s %d.%d.%d.%d %s\n",
> - im->m_class,
> - ntohl(addr.s_addr) >> 24 & 0xff,
> - ntohl(addr.s_addr) >> 16 & 0xff,
> - ntohl(addr.s_addr) >> 8 & 0xff,
> - ntohl(addr.s_addr) >> 0 & 0xff,
> - dom
> - );
> + if (ipv6_addr_v4mapped(&addr)) {
> + seq_printf(m, "%s" NIPQUAD_FMT "%s\n",
> + im->m_class,
> + ntohl(addr.s6_addr32[3]) >> 24 & 0xff,
> + ntohl(addr.s6_addr32[3]) >> 16 & 0xff,
> + ntohl(addr.s6_addr32[3]) >> 8 & 0xff,
> + ntohl(addr.s6_addr32[3]) >> 0 & 0xff,
> + dom);
> + } else {
> + seq_printf(m, "%s" NIP6_FMT "%s\n",
> + im->m_class, NIP6(addr), dom);
> + }
> return 0;
> }
>
> @@ -280,16 +308,16 @@ struct cache_detail ip_map_cache = {
> .alloc = ip_map_alloc,
> };
>
> -static struct ip_map *ip_map_lookup(char *class, struct in_addr addr)
> +static struct ip_map *ip_map_lookup(char *class, struct in6_addr *addr)
> {
> struct ip_map ip;
> struct cache_head *ch;
>
> strcpy(ip.m_class, class);
> - ip.m_addr = addr;
> + ipv6_addr_copy(&ip.m_addr, addr);
> ch = sunrpc_cache_lookup(&ip_map_cache, &ip.h,
> hash_str(class, IP_HASHBITS) ^
> - hash_ip(addr.s_addr));
> + hash_ip6(*addr));
>
> if (ch)
> return container_of(ch, struct ip_map, h);
> @@ -318,14 +346,14 @@ static int ip_map_update(struct ip_map *
> ch = sunrpc_cache_update(&ip_map_cache,
> &ip.h, &ipm->h,
> hash_str(ipm->m_class, IP_HASHBITS) ^
> - hash_ip(ipm->m_addr.s_addr));
> + hash_ip6(ipm->m_addr));
> if (!ch)
> return -ENOMEM;
> cache_put(ch, &ip_map_cache);
> return 0;
> }
>
> -int auth_unix_add_addr(struct in_addr addr, struct auth_domain *dom)
> +int auth_unix_add_addr(struct in6_addr *addr, struct auth_domain *dom)
> {
> struct unix_domain *udom;
> struct ip_map *ipmp;
> @@ -352,7 +380,7 @@ int auth_unix_forget_old(struct auth_dom
> return 0;
> }
>
> -struct auth_domain *auth_unix_lookup(struct in_addr addr)
> +struct auth_domain *auth_unix_lookup(struct in6_addr *addr)
> {
> struct ip_map *ipm;
> struct auth_domain *rv;
> @@ -641,9 +669,24 @@ static int unix_gid_find(uid_t uid, stru
> int
> svcauth_unix_set_client(struct svc_rqst *rqstp)
> {
> - struct sockaddr_in *sin = svc_addr_in(rqstp);
> + struct sockaddr_in *sin;
> + struct sockaddr_in6 *sin6, sin6_storage;
> struct ip_map *ipm;
>
> + switch (rqstp->rq_addr.ss_family) {
> + case AF_INET:
> + sin = svc_addr_in(rqstp);
> + sin6 = &sin6_storage;
> + ipv6_addr_set(&sin6->sin6_addr, 0, 0,
> + htonl(0x0000FFFF), sin->sin_addr.s_addr);
> + break;
> + case AF_INET6:
> + sin6 = svc_addr_in6(rqstp);
> + break;
> + default:
> + BUG();
> + }
> +
> rqstp->rq_client = NULL;
> if (rqstp->rq_proc == 0)
> return SVC_OK;
> @@ -651,7 +694,7 @@ svcauth_unix_set_client(struct svc_rqst
> ipm = ip_map_cached_get(rqstp);
> if (ipm == NULL)
> ipm = ip_map_lookup(rqstp->rq_server->sv_program->pg_class,
> - sin->sin_addr);
> + &sin6->sin6_addr);
>
> if (ipm == NULL)
> return SVC_DENIED;
_______________________________________________
NFSv4 mailing list
NFSv4@linux-nfs.org
http://linux-nfs.org/cgi-bin/mailman/listinfo/nfsv4
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox