Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions fs/ext4/resize.c
Original file line number Diff line number Diff line change
Expand Up @@ -1900,6 +1900,16 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
}
brelse(bh);

/*
* For bigalloc, trim the requested size to the nearest cluster
* boundary to avoid creating an unusable filesystem. We do this
* silently, instead of returning an error, to avoid breaking
* callers that blindly resize the filesystem to the full size of
* the underlying block device.
*/
if (EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC))
n_blocks_count &= ~((1 << EXT4_CLUSTER_BITS(sb)) - 1);

retry:
o_blocks_count = ext4_blocks_count(es);

Expand Down
19 changes: 5 additions & 14 deletions net/sched/sch_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,15 +741,12 @@ static u32 qdisc_alloc_handle(struct net_device *dev)
void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,
unsigned int len)
{
bool qdisc_is_offloaded = sch->flags & TCQ_F_OFFLOADED;
const struct Qdisc_class_ops *cops;
unsigned long cl;
u32 parentid;
bool notify;
int drops;

if (n == 0 && len == 0)
return;
drops = max_t(int, n, 0);
rcu_read_lock();
while ((parentid = sch->parent)) {
Expand All @@ -758,17 +755,8 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,

if (sch->flags & TCQ_F_NOPARENT)
break;
/* Notify parent qdisc only if child qdisc becomes empty.
*
* If child was empty even before update then backlog
* counter is screwed and we skip notification because
* parent class is already passive.
*
* If the original child was offloaded then it is allowed
* to be seem as empty, so the parent is notified anyway.
*/
notify = !sch->q.qlen && !WARN_ON_ONCE(!n &&
!qdisc_is_offloaded);
/* Notify parent qdisc only if child qdisc becomes empty. */
notify = !sch->q.qlen;
/* TODO: perform the search on a per txq basis */
sch = qdisc_lookup(qdisc_dev(sch), TC_H_MAJ(parentid));
if (sch == NULL) {
Expand All @@ -777,6 +765,9 @@ void qdisc_tree_reduce_backlog(struct Qdisc *sch, unsigned int n,
}
cops = sch->ops->cl_ops;
if (notify && cops->qlen_notify) {
/* Note that qlen_notify must be idempotent as it may get called
* multiple times.
*/
cl = cops->find(sch, parentid);
cops->qlen_notify(sch, cl);
}
Expand Down
3 changes: 2 additions & 1 deletion net/sched/sch_drr.c
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ static struct drr_class *drr_classify(struct sk_buff *skb, struct Qdisc *sch,
static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
unsigned int len = qdisc_pkt_len(skb);
struct drr_sched *q = qdisc_priv(sch);
struct drr_class *cl;
int err = 0;
Expand All @@ -362,7 +363,7 @@ static int drr_enqueue(struct sk_buff *skb, struct Qdisc *sch,
cl->deficit = cl->quantum;
}

qdisc_qstats_backlog_inc(sch, skb);
sch->qstats.backlog += len;
sch->q.qlen++;
return err;
}
Expand Down
3 changes: 2 additions & 1 deletion net/sched/sch_dsmark.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static struct tcf_block *dsmark_tcf_block(struct Qdisc *sch, unsigned long cl)
static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
unsigned int len = qdisc_pkt_len(skb);
struct dsmark_qdisc_data *p = qdisc_priv(sch);
int err;

Expand Down Expand Up @@ -268,7 +269,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch,
return err;
}

qdisc_qstats_backlog_inc(sch, skb);
sch->qstats.backlog += len;
sch->q.qlen++;

return NET_XMIT_SUCCESS;
Expand Down
9 changes: 4 additions & 5 deletions net/sched/sch_hfsc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1552,6 +1552,7 @@ hfsc_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb)
static int
hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
{
unsigned int len = qdisc_pkt_len(skb);
struct hfsc_class *cl;
int uninitialized_var(err);

Expand All @@ -1572,9 +1573,10 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
return err;
}

if (cl->qdisc->q.qlen == 1) {
unsigned int len = qdisc_pkt_len(skb);
sch->qstats.backlog += len;
sch->q.qlen++;

if (cl->qdisc->q.qlen == 1) {
if (cl->cl_flags & HFSC_RSC)
init_ed(cl, len);
if (cl->cl_flags & HFSC_FSC)
Expand All @@ -1589,9 +1591,6 @@ hfsc_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)

}

qdisc_qstats_backlog_inc(sch, skb);
sch->q.qlen++;

return NET_XMIT_SUCCESS;
}

Expand Down
3 changes: 2 additions & 1 deletion net/sched/sch_htb.c
Original file line number Diff line number Diff line change
Expand Up @@ -597,6 +597,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
int uninitialized_var(ret);
unsigned int len = qdisc_pkt_len(skb);
struct htb_sched *q = qdisc_priv(sch);
struct htb_class *cl = htb_classify(skb, sch, &ret);

Expand Down Expand Up @@ -626,7 +627,7 @@ static int htb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
htb_activate(q, cl);
}

qdisc_qstats_backlog_inc(sch, skb);
sch->qstats.backlog += len;
sch->q.qlen++;
return NET_XMIT_SUCCESS;
}
Expand Down
3 changes: 2 additions & 1 deletion net/sched/sch_prio.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ prio_classify(struct sk_buff *skb, struct Qdisc *sch, int *qerr)
static int
prio_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)
{
unsigned int len = qdisc_pkt_len(skb);
struct Qdisc *qdisc;
int ret;

Expand All @@ -87,7 +88,7 @@ prio_enqueue(struct sk_buff *skb, struct Qdisc *sch, struct sk_buff **to_free)

ret = qdisc_enqueue(skb, qdisc, to_free);
if (ret == NET_XMIT_SUCCESS) {
qdisc_qstats_backlog_inc(sch, skb);
sch->qstats.backlog += len;
sch->q.qlen++;
return NET_XMIT_SUCCESS;
}
Expand Down
16 changes: 9 additions & 7 deletions net/sched/sch_qfq.c
Original file line number Diff line number Diff line change
Expand Up @@ -1233,6 +1233,7 @@ static struct qfq_aggregate *qfq_choose_next_agg(struct qfq_sched *q)
static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
unsigned int len = qdisc_pkt_len(skb), gso_segs;
struct qfq_sched *q = qdisc_priv(sch);
struct qfq_class *cl;
struct qfq_aggregate *agg;
Expand All @@ -1247,17 +1248,17 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
}
pr_debug("qfq_enqueue: cl = %x\n", cl->common.classid);

if (unlikely(cl->agg->lmax < qdisc_pkt_len(skb))) {
if (unlikely(cl->agg->lmax < len)) {
pr_debug("qfq: increasing maxpkt from %u to %u for class %u",
cl->agg->lmax, qdisc_pkt_len(skb), cl->common.classid);
err = qfq_change_agg(sch, cl, cl->agg->class_weight,
qdisc_pkt_len(skb));
cl->agg->lmax, len, cl->common.classid);
err = qfq_change_agg(sch, cl, cl->agg->class_weight, len);
if (err) {
cl->qstats.drops++;
return qdisc_drop(skb, sch, to_free);
}
}

gso_segs = skb_is_gso(skb) ? skb_shinfo(skb)->gso_segs : 1;
err = qdisc_enqueue(skb, cl->qdisc, to_free);
if (unlikely(err != NET_XMIT_SUCCESS)) {
pr_debug("qfq_enqueue: enqueue failed %d\n", err);
Expand All @@ -1268,16 +1269,17 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch,
return err;
}

bstats_update(&cl->bstats, skb);
qdisc_qstats_backlog_inc(sch, skb);
cl->bstats.bytes += len;
cl->bstats.packets += gso_segs;
sch->qstats.backlog += len;
++sch->q.qlen;

agg = cl->agg;
/* if the queue was not empty, then done here */
if (cl->qdisc->q.qlen != 1) {
if (unlikely(skb == cl->qdisc->ops->peek(cl->qdisc)) &&
list_first_entry(&agg->active, struct qfq_class, alist)
== cl && cl->deficit < qdisc_pkt_len(skb))
== cl && cl->deficit < len)
list_move_tail(&cl->alist, &agg->active);

return err;
Expand Down
3 changes: 2 additions & 1 deletion net/sched/sch_tbf.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
struct sk_buff **to_free)
{
struct tbf_sched_data *q = qdisc_priv(sch);
unsigned int len = qdisc_pkt_len(skb);
int ret;

if (qdisc_pkt_len(skb) > q->max_size) {
Expand All @@ -199,7 +200,7 @@ static int tbf_enqueue(struct sk_buff *skb, struct Qdisc *sch,
return ret;
}

qdisc_qstats_backlog_inc(sch, skb);
sch->qstats.backlog += len;
sch->q.qlen++;
return NET_XMIT_SUCCESS;
}
Expand Down