Commit e63d7dfd authored by Alexander Aring's avatar Alexander Aring Committed by David S. Miller

net: sched: sch: add extack for init callback

This patch adds extack support for init callback to prepare per-qdisc
specific changes for extack.

Cc: David Ahern <dsahern@gmail.com>
Acked-by: default avatarJamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: default avatarAlexander Aring <aring@mojatatu.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 09215598
...@@ -189,7 +189,8 @@ struct Qdisc_ops { ...@@ -189,7 +189,8 @@ struct Qdisc_ops {
struct sk_buff * (*dequeue)(struct Qdisc *); struct sk_buff * (*dequeue)(struct Qdisc *);
struct sk_buff * (*peek)(struct Qdisc *); struct sk_buff * (*peek)(struct Qdisc *);
int (*init)(struct Qdisc *sch, struct nlattr *arg); int (*init)(struct Qdisc *sch, struct nlattr *arg,
struct netlink_ext_ack *extack);
void (*reset)(struct Qdisc *); void (*reset)(struct Qdisc *);
void (*destroy)(struct Qdisc *); void (*destroy)(struct Qdisc *);
int (*change)(struct Qdisc *sch, int (*change)(struct Qdisc *sch,
......
...@@ -1084,7 +1084,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, ...@@ -1084,7 +1084,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
} }
if (ops->init) { if (ops->init) {
err = ops->init(sch, tca[TCA_OPTIONS]); err = ops->init(sch, tca[TCA_OPTIONS], extack);
if (err != 0) if (err != 0)
goto err_out5; goto err_out5;
} }
......
...@@ -531,7 +531,8 @@ static struct sk_buff *atm_tc_peek(struct Qdisc *sch) ...@@ -531,7 +531,8 @@ static struct sk_buff *atm_tc_peek(struct Qdisc *sch)
return p->link.q->ops->peek(p->link.q); return p->link.q->ops->peek(p->link.q);
} }
static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt) static int atm_tc_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct atm_qdisc_data *p = qdisc_priv(sch); struct atm_qdisc_data *p = qdisc_priv(sch);
int err; int err;
......
...@@ -1132,7 +1132,8 @@ static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = { ...@@ -1132,7 +1132,8 @@ static const struct nla_policy cbq_policy[TCA_CBQ_MAX + 1] = {
[TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) }, [TCA_CBQ_POLICE] = { .len = sizeof(struct tc_cbq_police) },
}; };
static int cbq_init(struct Qdisc *sch, struct nlattr *opt) static int cbq_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct cbq_sched_data *q = qdisc_priv(sch); struct cbq_sched_data *q = qdisc_priv(sch);
struct nlattr *tb[TCA_CBQ_MAX + 1]; struct nlattr *tb[TCA_CBQ_MAX + 1];
......
...@@ -291,7 +291,8 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -291,7 +291,8 @@ static int cbs_change(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int cbs_init(struct Qdisc *sch, struct nlattr *opt) static int cbs_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct cbs_sched_data *q = qdisc_priv(sch); struct cbs_sched_data *q = qdisc_priv(sch);
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
......
...@@ -431,7 +431,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -431,7 +431,8 @@ static int choke_change(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int choke_init(struct Qdisc *sch, struct nlattr *opt) static int choke_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
return choke_change(sch, opt); return choke_change(sch, opt);
} }
......
...@@ -184,7 +184,8 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -184,7 +184,8 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int codel_init(struct Qdisc *sch, struct nlattr *opt) static int codel_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct codel_sched_data *q = qdisc_priv(sch); struct codel_sched_data *q = qdisc_priv(sch);
......
...@@ -408,7 +408,8 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch) ...@@ -408,7 +408,8 @@ static struct sk_buff *drr_dequeue(struct Qdisc *sch)
return NULL; return NULL;
} }
static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt) static int drr_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct drr_sched *q = qdisc_priv(sch); struct drr_sched *q = qdisc_priv(sch);
int err; int err;
......
...@@ -330,7 +330,8 @@ static struct sk_buff *dsmark_peek(struct Qdisc *sch) ...@@ -330,7 +330,8 @@ static struct sk_buff *dsmark_peek(struct Qdisc *sch)
return p->q->ops->peek(p->q); return p->q->ops->peek(p->q);
} }
static int dsmark_init(struct Qdisc *sch, struct nlattr *opt) static int dsmark_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct dsmark_qdisc_data *p = qdisc_priv(sch); struct dsmark_qdisc_data *p = qdisc_priv(sch);
struct nlattr *tb[TCA_DSMARK_MAX + 1]; struct nlattr *tb[TCA_DSMARK_MAX + 1];
......
...@@ -55,7 +55,8 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch, ...@@ -55,7 +55,8 @@ static int pfifo_tail_enqueue(struct sk_buff *skb, struct Qdisc *sch,
return NET_XMIT_CN; return NET_XMIT_CN;
} }
static int fifo_init(struct Qdisc *sch, struct nlattr *opt) static int fifo_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
bool bypass; bool bypass;
bool is_bfifo = sch->ops == &bfifo_qdisc_ops; bool is_bfifo = sch->ops == &bfifo_qdisc_ops;
...@@ -88,6 +89,11 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt) ...@@ -88,6 +89,11 @@ static int fifo_init(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int fifo_change(struct Qdisc *sch, struct nlattr *opt)
{
return fifo_init(sch, opt, NULL);
}
static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb) static int fifo_dump(struct Qdisc *sch, struct sk_buff *skb)
{ {
struct tc_fifo_qopt opt = { .limit = sch->limit }; struct tc_fifo_qopt opt = { .limit = sch->limit };
...@@ -108,7 +114,7 @@ struct Qdisc_ops pfifo_qdisc_ops __read_mostly = { ...@@ -108,7 +114,7 @@ struct Qdisc_ops pfifo_qdisc_ops __read_mostly = {
.peek = qdisc_peek_head, .peek = qdisc_peek_head,
.init = fifo_init, .init = fifo_init,
.reset = qdisc_reset_queue, .reset = qdisc_reset_queue,
.change = fifo_init, .change = fifo_change,
.dump = fifo_dump, .dump = fifo_dump,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -122,7 +128,7 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = { ...@@ -122,7 +128,7 @@ struct Qdisc_ops bfifo_qdisc_ops __read_mostly = {
.peek = qdisc_peek_head, .peek = qdisc_peek_head,
.init = fifo_init, .init = fifo_init,
.reset = qdisc_reset_queue, .reset = qdisc_reset_queue,
.change = fifo_init, .change = fifo_change,
.dump = fifo_dump, .dump = fifo_dump,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
...@@ -136,7 +142,7 @@ struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = { ...@@ -136,7 +142,7 @@ struct Qdisc_ops pfifo_head_drop_qdisc_ops __read_mostly = {
.peek = qdisc_peek_head, .peek = qdisc_peek_head,
.init = fifo_init, .init = fifo_init,
.reset = qdisc_reset_queue, .reset = qdisc_reset_queue,
.change = fifo_init, .change = fifo_change,
.dump = fifo_dump, .dump = fifo_dump,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
......
...@@ -788,7 +788,8 @@ static void fq_destroy(struct Qdisc *sch) ...@@ -788,7 +788,8 @@ static void fq_destroy(struct Qdisc *sch)
qdisc_watchdog_cancel(&q->watchdog); qdisc_watchdog_cancel(&q->watchdog);
} }
static int fq_init(struct Qdisc *sch, struct nlattr *opt) static int fq_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct fq_sched_data *q = qdisc_priv(sch); struct fq_sched_data *q = qdisc_priv(sch);
int err; int err;
......
...@@ -458,7 +458,8 @@ static void fq_codel_destroy(struct Qdisc *sch) ...@@ -458,7 +458,8 @@ static void fq_codel_destroy(struct Qdisc *sch)
kvfree(q->flows); kvfree(q->flows);
} }
static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt) static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct fq_codel_sched_data *q = qdisc_priv(sch); struct fq_codel_sched_data *q = qdisc_priv(sch);
int i; int i;
......
...@@ -551,7 +551,8 @@ struct Qdisc noop_qdisc = { ...@@ -551,7 +551,8 @@ struct Qdisc noop_qdisc = {
}; };
EXPORT_SYMBOL(noop_qdisc); EXPORT_SYMBOL(noop_qdisc);
static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt) static int noqueue_init(struct Qdisc *qdisc, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
/* register_qdisc() assigns a default of noop_enqueue if unset, /* register_qdisc() assigns a default of noop_enqueue if unset,
* but __dev_queue_xmit() treats noqueue only as such * but __dev_queue_xmit() treats noqueue only as such
...@@ -690,7 +691,8 @@ static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb) ...@@ -690,7 +691,8 @@ static int pfifo_fast_dump(struct Qdisc *qdisc, struct sk_buff *skb)
return -1; return -1;
} }
static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt) static int pfifo_fast_init(struct Qdisc *qdisc, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
unsigned int qlen = qdisc_dev(qdisc)->tx_queue_len; unsigned int qlen = qdisc_dev(qdisc)->tx_queue_len;
struct pfifo_fast_priv *priv = qdisc_priv(qdisc); struct pfifo_fast_priv *priv = qdisc_priv(qdisc);
...@@ -840,7 +842,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue, ...@@ -840,7 +842,7 @@ struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
} }
sch->parent = parentid; sch->parent = parentid;
if (!ops->init || ops->init(sch, NULL) == 0) if (!ops->init || ops->init(sch, NULL, NULL) == 0)
return sch; return sch;
qdisc_destroy(sch); qdisc_destroy(sch);
......
...@@ -466,7 +466,8 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -466,7 +466,8 @@ static int gred_change(struct Qdisc *sch, struct nlattr *opt)
return err; return err;
} }
static int gred_init(struct Qdisc *sch, struct nlattr *opt) static int gred_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct nlattr *tb[TCA_GRED_MAX + 1]; struct nlattr *tb[TCA_GRED_MAX + 1];
int err; int err;
......
...@@ -1388,7 +1388,8 @@ hfsc_schedule_watchdog(struct Qdisc *sch) ...@@ -1388,7 +1388,8 @@ hfsc_schedule_watchdog(struct Qdisc *sch)
} }
static int static int
hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt) hfsc_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct hfsc_sched *q = qdisc_priv(sch); struct hfsc_sched *q = qdisc_priv(sch);
struct tc_hfsc_qopt *qopt; struct tc_hfsc_qopt *qopt;
......
...@@ -571,7 +571,8 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -571,7 +571,8 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int hhf_init(struct Qdisc *sch, struct nlattr *opt) static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct hhf_sched_data *q = qdisc_priv(sch); struct hhf_sched_data *q = qdisc_priv(sch);
int i; int i;
......
...@@ -1017,7 +1017,8 @@ static void htb_work_func(struct work_struct *work) ...@@ -1017,7 +1017,8 @@ static void htb_work_func(struct work_struct *work)
rcu_read_unlock(); rcu_read_unlock();
} }
static int htb_init(struct Qdisc *sch, struct nlattr *opt) static int htb_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct htb_sched *q = qdisc_priv(sch); struct htb_sched *q = qdisc_priv(sch);
struct nlattr *tb[TCA_HTB_MAX + 1]; struct nlattr *tb[TCA_HTB_MAX + 1];
......
...@@ -62,7 +62,8 @@ static void clsact_chain_head_change(struct tcf_proto *tp_head, void *priv) ...@@ -62,7 +62,8 @@ static void clsact_chain_head_change(struct tcf_proto *tp_head, void *priv)
mini_qdisc_pair_swap(miniqp, tp_head); mini_qdisc_pair_swap(miniqp, tp_head);
} }
static int ingress_init(struct Qdisc *sch, struct nlattr *opt) static int ingress_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct ingress_sched_data *q = qdisc_priv(sch); struct ingress_sched_data *q = qdisc_priv(sch);
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
...@@ -167,7 +168,8 @@ static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl) ...@@ -167,7 +168,8 @@ static struct tcf_block *clsact_tcf_block(struct Qdisc *sch, unsigned long cl)
} }
} }
static int clsact_init(struct Qdisc *sch, struct nlattr *opt) static int clsact_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct clsact_sched_data *q = qdisc_priv(sch); struct clsact_sched_data *q = qdisc_priv(sch);
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
......
...@@ -36,7 +36,8 @@ static void mq_destroy(struct Qdisc *sch) ...@@ -36,7 +36,8 @@ static void mq_destroy(struct Qdisc *sch)
kfree(priv->qdiscs); kfree(priv->qdiscs);
} }
static int mq_init(struct Qdisc *sch, struct nlattr *opt) static int mq_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
struct mq_sched *priv = qdisc_priv(sch); struct mq_sched *priv = qdisc_priv(sch);
......
...@@ -132,7 +132,8 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla, ...@@ -132,7 +132,8 @@ static int parse_attr(struct nlattr *tb[], int maxtype, struct nlattr *nla,
return 0; return 0;
} }
static int mqprio_init(struct Qdisc *sch, struct nlattr *opt) static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
struct mqprio_sched *priv = qdisc_priv(sch); struct mqprio_sched *priv = qdisc_priv(sch);
......
...@@ -236,7 +236,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt) ...@@ -236,7 +236,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int multiq_init(struct Qdisc *sch, struct nlattr *opt) static int multiq_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct multiq_sched_data *q = qdisc_priv(sch); struct multiq_sched_data *q = qdisc_priv(sch);
int i, err; int i, err;
......
...@@ -984,7 +984,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -984,7 +984,8 @@ static int netem_change(struct Qdisc *sch, struct nlattr *opt)
return ret; return ret;
} }
static int netem_init(struct Qdisc *sch, struct nlattr *opt) static int netem_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct netem_sched_data *q = qdisc_priv(sch); struct netem_sched_data *q = qdisc_priv(sch);
int ret; int ret;
......
...@@ -439,7 +439,8 @@ static void pie_timer(struct timer_list *t) ...@@ -439,7 +439,8 @@ static void pie_timer(struct timer_list *t)
} }
static int pie_init(struct Qdisc *sch, struct nlattr *opt) static int pie_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct pie_sched_data *q = qdisc_priv(sch); struct pie_sched_data *q = qdisc_priv(sch);
......
...@@ -123,7 +123,8 @@ static struct sk_buff *plug_dequeue(struct Qdisc *sch) ...@@ -123,7 +123,8 @@ static struct sk_buff *plug_dequeue(struct Qdisc *sch)
return qdisc_dequeue_head(sch); return qdisc_dequeue_head(sch);
} }
static int plug_init(struct Qdisc *sch, struct nlattr *opt) static int plug_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct plug_sched_data *q = qdisc_priv(sch); struct plug_sched_data *q = qdisc_priv(sch);
......
...@@ -205,7 +205,8 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt) ...@@ -205,7 +205,8 @@ static int prio_tune(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int prio_init(struct Qdisc *sch, struct nlattr *opt) static int prio_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct prio_sched_data *q = qdisc_priv(sch); struct prio_sched_data *q = qdisc_priv(sch);
int err; int err;
......
...@@ -1413,7 +1413,8 @@ static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg) ...@@ -1413,7 +1413,8 @@ static void qfq_qlen_notify(struct Qdisc *sch, unsigned long arg)
qfq_deactivate_class(q, cl); qfq_deactivate_class(q, cl);
} }
static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt) static int qfq_init_qdisc(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct qfq_sched *q = qdisc_priv(sch); struct qfq_sched *q = qdisc_priv(sch);
struct qfq_group *grp; struct qfq_group *grp;
......
...@@ -272,7 +272,8 @@ static inline void red_adaptative_timer(struct timer_list *t) ...@@ -272,7 +272,8 @@ static inline void red_adaptative_timer(struct timer_list *t)
spin_unlock(root_lock); spin_unlock(root_lock);
} }
static int red_init(struct Qdisc *sch, struct nlattr *opt) static int red_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct red_sched_data *q = qdisc_priv(sch); struct red_sched_data *q = qdisc_priv(sch);
......
...@@ -549,7 +549,8 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -549,7 +549,8 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt)
return 0; return 0;
} }
static int sfb_init(struct Qdisc *sch, struct nlattr *opt) static int sfb_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct sfb_sched_data *q = qdisc_priv(sch); struct sfb_sched_data *q = qdisc_priv(sch);
int err; int err;
......
...@@ -721,7 +721,8 @@ static void sfq_destroy(struct Qdisc *sch) ...@@ -721,7 +721,8 @@ static void sfq_destroy(struct Qdisc *sch)
kfree(q->red_parms); kfree(q->red_parms);
} }
static int sfq_init(struct Qdisc *sch, struct nlattr *opt) static int sfq_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct sfq_sched_data *q = qdisc_priv(sch); struct sfq_sched_data *q = qdisc_priv(sch);
int i; int i;
......
...@@ -421,7 +421,8 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) ...@@ -421,7 +421,8 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt)
return err; return err;
} }
static int tbf_init(struct Qdisc *sch, struct nlattr *opt) static int tbf_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct tbf_sched_data *q = qdisc_priv(sch); struct tbf_sched_data *q = qdisc_priv(sch);
......
...@@ -167,7 +167,8 @@ teql_destroy(struct Qdisc *sch) ...@@ -167,7 +167,8 @@ teql_destroy(struct Qdisc *sch)
} }
} }
static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt) static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{ {
struct net_device *dev = qdisc_dev(sch); struct net_device *dev = qdisc_dev(sch);
struct teql_master *m = (struct teql_master *)sch->ops; struct teql_master *m = (struct teql_master *)sch->ops;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment