From: Greg Kroah-Hartman Date: Fri, 7 Jul 2017 09:10:09 +0000 (+0200) Subject: 4.11-stable patches X-Git-Tag: v4.9.37~37 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c0a1a329a6b394456014013160773ec4eac3c4b4;p=thirdparty%2Fkernel%2Fstable-queue.git 4.11-stable patches added patches: ceph-choose-readdir-frag-based-on-previous-readdir-reply.patch tracing-kprobes-allow-to-create-probe-with-a-module-name-starting-with-a-digit.patch --- diff --git a/queue-4.11/ceph-choose-readdir-frag-based-on-previous-readdir-reply.patch b/queue-4.11/ceph-choose-readdir-frag-based-on-previous-readdir-reply.patch new file mode 100644 index 00000000000..d71fb18dc63 --- /dev/null +++ b/queue-4.11/ceph-choose-readdir-frag-based-on-previous-readdir-reply.patch @@ -0,0 +1,91 @@ +From b50c2de51e611da90cf3cf04c058f7e9bbe79e93 Mon Sep 17 00:00:00 2001 +From: "Yan, Zheng" +Date: Mon, 24 Apr 2017 11:56:50 +0800 +Subject: ceph: choose readdir frag based on previous readdir reply + +From: Yan, Zheng + +commit b50c2de51e611da90cf3cf04c058f7e9bbe79e93 upstream. + +The dirfragtree is lazily updated, it's not always accurate. Infinite +loops happens in following circumstance. + +- client send request to read frag A +- frag A has been fragmented into frag B and C. So mds fills the reply + with contents of frag B +- client wants to read next frag C. ceph_choose_frag(frag value of C) + return frag A. + +The fix is using previous readdir reply to calculate next readdir frag +when possible. + +Signed-off-by: "Yan, Zheng" +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman + +--- + fs/ceph/dir.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +--- a/fs/ceph/dir.c ++++ b/fs/ceph/dir.c +@@ -294,7 +294,7 @@ static int ceph_readdir(struct file *fil + struct ceph_mds_client *mdsc = fsc->mdsc; + int i; + int err; +- u32 ftype; ++ unsigned frag = -1; + struct ceph_mds_reply_info_parsed *rinfo; + + dout("readdir %p file %p pos %llx\n", inode, file, ctx->pos); +@@ -341,7 +341,6 @@ more: + /* do we have the correct frag content buffered? */ + if (need_send_readdir(fi, ctx->pos)) { + struct ceph_mds_request *req; +- unsigned frag; + int op = ceph_snap(inode) == CEPH_SNAPDIR ? + CEPH_MDS_OP_LSSNAP : CEPH_MDS_OP_READDIR; + +@@ -352,8 +351,11 @@ more: + } + + if (is_hash_order(ctx->pos)) { +- frag = ceph_choose_frag(ci, fpos_hash(ctx->pos), +- NULL, NULL); ++ /* fragtree isn't always accurate. choose frag ++ * based on previous reply when possible. */ ++ if (frag == (unsigned)-1) ++ frag = ceph_choose_frag(ci, fpos_hash(ctx->pos), ++ NULL, NULL); + } else { + frag = fpos_frag(ctx->pos); + } +@@ -476,6 +478,7 @@ more: + struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i; + struct ceph_vino vino; + ino_t ino; ++ u32 ftype; + + BUG_ON(rde->offset < ctx->pos); + +@@ -498,15 +501,17 @@ more: + ctx->pos++; + } + ++ ceph_mdsc_put_request(fi->last_readdir); ++ fi->last_readdir = NULL; ++ + if (fi->next_offset > 2) { +- ceph_mdsc_put_request(fi->last_readdir); +- fi->last_readdir = NULL; ++ frag = fi->frag; + goto more; + } + + /* more frags? */ + if (!ceph_frag_is_rightmost(fi->frag)) { +- unsigned frag = ceph_frag_next(fi->frag); ++ frag = ceph_frag_next(fi->frag); + if (is_hash_order(ctx->pos)) { + loff_t new_pos = ceph_make_fpos(ceph_frag_value(frag), + fi->next_offset, true); diff --git a/queue-4.11/series b/queue-4.11/series index f7409222e01..fe45ec3710d 100644 --- a/queue-4.11/series +++ b/queue-4.11/series @@ -2,3 +2,5 @@ fs-add-a-valid_open_flags.patch fs-completely-ignore-unknown-open-flags.patch driver-core-platform-fix-race-condition-with-driver_override.patch rdma-uverbs-check-port-number-supplied-by-user-verbs-cmds.patch +ceph-choose-readdir-frag-based-on-previous-readdir-reply.patch +tracing-kprobes-allow-to-create-probe-with-a-module-name-starting-with-a-digit.patch diff --git a/queue-4.11/tracing-kprobes-allow-to-create-probe-with-a-module-name-starting-with-a-digit.patch b/queue-4.11/tracing-kprobes-allow-to-create-probe-with-a-module-name-starting-with-a-digit.patch new file mode 100644 index 00000000000..49a4b12a800 --- /dev/null +++ b/queue-4.11/tracing-kprobes-allow-to-create-probe-with-a-module-name-starting-with-a-digit.patch @@ -0,0 +1,74 @@ +From 9e52b32567126fe146f198971364f68d3bc5233f Mon Sep 17 00:00:00 2001 +From: Sabrina Dubroca +Date: Thu, 22 Jun 2017 11:24:42 +0200 +Subject: tracing/kprobes: Allow to create probe with a module name starting with a digit + +From: Sabrina Dubroca + +commit 9e52b32567126fe146f198971364f68d3bc5233f upstream. + +Always try to parse an address, since kstrtoul() will safely fail when +given a symbol as input. If that fails (which will be the case for a +symbol), try to parse a symbol instead. + +This allows creating a probe such as: + + p:probe/vlan_gro_receive 8021q:vlan_gro_receive+0 + +Which is necessary for this command to work: + + perf probe -m 8021q -a vlan_gro_receive + +Link: http://lkml.kernel.org/r/fd72d666f45b114e2c5b9cf7e27b91de1ec966f1.1498122881.git.sd@queasysnail.net + +Fixes: 413d37d1e ("tracing: Add kprobe-based event tracer") +Acked-by: Masami Hiramatsu +Signed-off-by: Sabrina Dubroca +Signed-off-by: Steven Rostedt (VMware) +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/trace/trace_kprobe.c | 21 ++++++++------------- + 1 file changed, 8 insertions(+), 13 deletions(-) + +--- a/kernel/trace/trace_kprobe.c ++++ b/kernel/trace/trace_kprobe.c +@@ -680,30 +680,25 @@ static int create_trace_kprobe(int argc, + pr_info("Probe point is not specified.\n"); + return -EINVAL; + } +- if (isdigit(argv[1][0])) { +- if (is_return) { +- pr_info("Return probe point must be a symbol.\n"); +- return -EINVAL; +- } +- /* an address specified */ +- ret = kstrtoul(&argv[1][0], 0, (unsigned long *)&addr); +- if (ret) { +- pr_info("Failed to parse address.\n"); +- return ret; +- } +- } else { ++ ++ /* try to parse an address. if that fails, try to read the ++ * input as a symbol. */ ++ if (kstrtoul(argv[1], 0, (unsigned long *)&addr)) { + /* a symbol specified */ + symbol = argv[1]; + /* TODO: support .init module functions */ + ret = traceprobe_split_symbol_offset(symbol, &offset); + if (ret) { +- pr_info("Failed to parse symbol.\n"); ++ pr_info("Failed to parse either an address or a symbol.\n"); + return ret; + } + if (offset && is_return) { + pr_info("Return probe must be used without offset.\n"); + return -EINVAL; + } ++ } else if (is_return) { ++ pr_info("Return probe point must be a symbol.\n"); ++ return -EINVAL; + } + argc -= 2; argv += 2; +