Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[linux-2.6-microblaze.git] / net / sched / sch_atm.c
index 572fe25..c5fcdf1 100644 (file)
@@ -41,6 +41,7 @@
 #define VCC2FLOW(vcc) ((struct atm_flow_data *) ((vcc)->user_back))
 
 struct atm_flow_data {
+       struct Qdisc_class_common common;
        struct Qdisc            *q;     /* FIFO, TBF, etc. */
        struct tcf_proto __rcu  *filter_list;
        struct tcf_block        *block;
@@ -49,7 +50,6 @@ struct atm_flow_data {
                                           struct sk_buff *skb); /* chaining */
        struct atm_qdisc_data   *parent;        /* parent qdisc */
        struct socket           *sock;          /* for closing */
-       u32                     classid;        /* x:y type ID */
        int                     ref;            /* reference count */
        struct gnet_stats_basic_packed  bstats;
        struct gnet_stats_queue qstats;
@@ -75,7 +75,7 @@ static inline struct atm_flow_data *lookup_flow(struct Qdisc *sch, u32 classid)
        struct atm_flow_data *flow;
 
        list_for_each_entry(flow, &p->flows, list) {
-               if (flow->classid == classid)
+               if (flow->common.classid == classid)
                        return flow;
        }
        return NULL;
@@ -108,23 +108,29 @@ static struct Qdisc *atm_tc_leaf(struct Qdisc *sch, unsigned long cl)
        return flow ? flow->q : NULL;
 }
 
-static unsigned long atm_tc_get(struct Qdisc *sch, u32 classid)
+static unsigned long atm_tc_find(struct Qdisc *sch, u32 classid)
 {
        struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch);
        struct atm_flow_data *flow;
 
-       pr_debug("atm_tc_get(sch %p,[qdisc %p],classid %x)\n", sch, p, classid);
+       pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid);
        flow = lookup_flow(sch, classid);
-       if (flow)
-               flow->ref++;
-       pr_debug("atm_tc_get: flow %p\n", flow);
+       pr_debug("%s: flow %p\n", __func__, flow);
        return (unsigned long)flow;
 }
 
 static unsigned long atm_tc_bind_filter(struct Qdisc *sch,
                                        unsigned long parent, u32 classid)
 {
-       return atm_tc_get(sch, classid);
+       struct atm_qdisc_data *p __maybe_unused = qdisc_priv(sch);
+       struct atm_flow_data *flow;
+
+       pr_debug("%s(sch %p,[qdisc %p],classid %x)\n", __func__, sch, p, classid);
+       flow = lookup_flow(sch, classid);
+       if (flow)
+               flow->ref++;
+       pr_debug("%s: flow %p\n", __func__, flow);
+       return (unsigned long)flow;
 }
 
 /*
@@ -234,7 +240,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
                excess = NULL;
        else {
                excess = (struct atm_flow_data *)
-                       atm_tc_get(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
+                       atm_tc_find(sch, nla_get_u32(tb[TCA_ATM_EXCESS]));
                if (!excess)
                        return -ENOENT;
        }
@@ -262,10 +268,9 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
 
                for (i = 1; i < 0x8000; i++) {
                        classid = TC_H_MAKE(sch->handle, 0x8000 | i);
-                       cl = atm_tc_get(sch, classid);
+                       cl = atm_tc_find(sch, classid);
                        if (!cl)
                                break;
-                       atm_tc_put(sch, cl);
                }
        }
        pr_debug("atm_tc_change: new id %x\n", classid);
@@ -293,7 +298,7 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
        flow->old_pop = flow->vcc->pop;
        flow->parent = p;
        flow->vcc->pop = sch_atm_pop;
-       flow->classid = classid;
+       flow->common.classid = classid;
        flow->ref = 1;
        flow->excess = excess;
        list_add(&flow->list, &p->link.list);
@@ -305,8 +310,6 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
        *arg = (unsigned long)flow;
        return 0;
 err_out:
-       if (excess)
-               atm_tc_put(sch, (unsigned long)excess);
        sockfd_put(sock);
        return error;
 }
@@ -377,7 +380,7 @@ static int atm_tc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
        result = TC_ACT_OK;     /* be nice to gcc */
        flow = NULL;
        if (TC_H_MAJ(skb->priority) != sch->handle ||
-           !(flow = (struct atm_flow_data *)atm_tc_get(sch, skb->priority))) {
+           !(flow = (struct atm_flow_data *)atm_tc_find(sch, skb->priority))) {
                struct tcf_proto *fl;
 
                list_for_each_entry(flow, &p->flows, list) {
@@ -549,7 +552,7 @@ static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt)
 
        p->link.vcc = NULL;
        p->link.sock = NULL;
-       p->link.classid = sch->handle;
+       p->link.common.classid = sch->handle;
        p->link.ref = 1;
        tasklet_init(&p->task, sch_atm_dequeue, (unsigned long)sch);
        return 0;
@@ -572,8 +575,10 @@ static void atm_tc_destroy(struct Qdisc *sch)
        struct atm_flow_data *flow, *tmp;
 
        pr_debug("atm_tc_destroy(sch %p,[qdisc %p])\n", sch, p);
-       list_for_each_entry(flow, &p->flows, list)
+       list_for_each_entry(flow, &p->flows, list) {
                tcf_block_put(flow->block);
+               flow->block = NULL;
+       }
 
        list_for_each_entry_safe(flow, tmp, &p->flows, list) {
                if (flow->ref > 1)
@@ -594,7 +599,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
                sch, p, flow, skb, tcm);
        if (list_empty(&flow->list))
                return -EINVAL;
-       tcm->tcm_handle = flow->classid;
+       tcm->tcm_handle = flow->common.classid;
        tcm->tcm_info = flow->q->handle;
 
        nest = nla_nest_start(skb, TCA_OPTIONS);
@@ -619,7 +624,7 @@ static int atm_tc_dump_class(struct Qdisc *sch, unsigned long cl,
                        goto nla_put_failure;
        }
        if (flow->excess) {
-               if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->classid))
+               if (nla_put_u32(skb, TCA_ATM_EXCESS, flow->common.classid))
                        goto nla_put_failure;
        } else {
                if (nla_put_u32(skb, TCA_ATM_EXCESS, 0))
@@ -653,8 +658,7 @@ static int atm_tc_dump(struct Qdisc *sch, struct sk_buff *skb)
 static const struct Qdisc_class_ops atm_class_ops = {
        .graft          = atm_tc_graft,
        .leaf           = atm_tc_leaf,
-       .get            = atm_tc_get,
-       .put            = atm_tc_put,
+       .find           = atm_tc_find,
        .change         = atm_tc_change,
        .delete         = atm_tc_delete,
        .walk           = atm_tc_walk,