+++ /dev/null
-From 3e8f43a089f06279c5f76a9ccd42578eebf7bfa5 Mon Sep 17 00:00:00 2001
-From: "Yan, Zheng" <zheng.z.yan@intel.com>
-Date: Thu, 20 Sep 2012 17:42:25 +0800
-Subject: ceph: Fix oops when handling mdsmap that decreases max_mds
-
-From: "Yan, Zheng" <zheng.z.yan@intel.com>
-
-commit 3e8f43a089f06279c5f76a9ccd42578eebf7bfa5 upstream.
-
-When i >= newmap->m_max_mds, ceph_mdsmap_get_addr(newmap, i) return
-NULL. Passing NULL to memcmp() triggers oops.
-
-Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
-Signed-off-by: Sage Weil <sage@inktank.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- fs/ceph/mds_client.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
---- a/fs/ceph/mds_client.c
-+++ b/fs/ceph/mds_client.c
-@@ -2621,7 +2621,8 @@ static void check_new_map(struct ceph_md
- ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
- session_state_name(s->s_state));
-
-- if (memcmp(ceph_mdsmap_get_addr(oldmap, i),
-+ if (i >= newmap->m_max_mds ||
-+ memcmp(ceph_mdsmap_get_addr(oldmap, i),
- ceph_mdsmap_get_addr(newmap, i),
- sizeof(struct ceph_entity_addr))) {
- if (s->s_state == CEPH_MDS_SESSION_OPENING) {
+++ /dev/null
-From d63b77f4c552cc3a20506871046ab0fcbc332609 Mon Sep 17 00:00:00 2001
-From: Sage Weil <sage@inktank.com>
-Date: Mon, 24 Sep 2012 20:59:48 -0700
-Subject: libceph: check for invalid mapping
-
-From: Sage Weil <sage@inktank.com>
-
-commit d63b77f4c552cc3a20506871046ab0fcbc332609 upstream.
-
-If we encounter an invalid (e.g., zeroed) mapping, return an error
-and avoid a divide by zero.
-
-Signed-off-by: Sage Weil <sage@inktank.com>
-Reviewed-by: Alex Elder <elder@inktank.com>
-Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-
----
- include/linux/ceph/osd_client.h | 2 +-
- include/linux/ceph/osdmap.h | 6 +++---
- net/ceph/osd_client.c | 32 ++++++++++++++++++++------------
- net/ceph/osdmap.c | 18 ++++++++++++++++--
- 4 files changed, 40 insertions(+), 18 deletions(-)
-
---- a/include/linux/ceph/osd_client.h
-+++ b/include/linux/ceph/osd_client.h
-@@ -202,7 +202,7 @@ extern void ceph_osdc_handle_reply(struc
- extern void ceph_osdc_handle_map(struct ceph_osd_client *osdc,
- struct ceph_msg *msg);
-
--extern void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
-+extern int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
- struct ceph_file_layout *layout,
- u64 snapid,
- u64 off, u64 *plen, u64 *bno,
---- a/include/linux/ceph/osdmap.h
-+++ b/include/linux/ceph/osdmap.h
-@@ -111,9 +111,9 @@ extern struct ceph_osdmap *osdmap_apply_
- extern void ceph_osdmap_destroy(struct ceph_osdmap *map);
-
- /* calculate mapping of a file extent to an object */
--extern void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
-- u64 off, u64 *plen,
-- u64 *bno, u64 *oxoff, u64 *oxlen);
-+extern int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
-+ u64 off, u64 *plen,
-+ u64 *bno, u64 *oxoff, u64 *oxlen);
-
- /* calculate mapping of object to a placement group */
- extern int ceph_calc_object_layout(struct ceph_object_layout *ol,
---- a/net/ceph/osd_client.c
-+++ b/net/ceph/osd_client.c
-@@ -52,7 +52,7 @@ static int op_has_extent(int op)
- op == CEPH_OSD_OP_WRITE);
- }
-
--void ceph_calc_raw_layout(struct ceph_osd_client *osdc,
-+int ceph_calc_raw_layout(struct ceph_osd_client *osdc,
- struct ceph_file_layout *layout,
- u64 snapid,
- u64 off, u64 *plen, u64 *bno,
-@@ -62,12 +62,15 @@ void ceph_calc_raw_layout(struct ceph_os
- struct ceph_osd_request_head *reqhead = req->r_request->front.iov_base;
- u64 orig_len = *plen;
- u64 objoff, objlen; /* extent in object */
-+ int r;
-
- reqhead->snapid = cpu_to_le64(snapid);
-
- /* object extent? */
-- ceph_calc_file_object_mapping(layout, off, plen, bno,
-- &objoff, &objlen);
-+ r = ceph_calc_file_object_mapping(layout, off, plen, bno,
-+ &objoff, &objlen);
-+ if (r < 0)
-+ return r;
- if (*plen < orig_len)
- dout(" skipping last %llu, final file extent %llu~%llu\n",
- orig_len - *plen, off, *plen);
-@@ -83,7 +86,7 @@ void ceph_calc_raw_layout(struct ceph_os
-
- dout("calc_layout bno=%llx %llu~%llu (%d pages)\n",
- *bno, objoff, objlen, req->r_num_pages);
--
-+ return 0;
- }
- EXPORT_SYMBOL(ceph_calc_raw_layout);
-
-@@ -112,20 +115,25 @@ EXPORT_SYMBOL(ceph_calc_raw_layout);
- *
- * fill osd op in request message.
- */
--static void calc_layout(struct ceph_osd_client *osdc,
-- struct ceph_vino vino,
-- struct ceph_file_layout *layout,
-- u64 off, u64 *plen,
-- struct ceph_osd_request *req,
-- struct ceph_osd_req_op *op)
-+static int calc_layout(struct ceph_osd_client *osdc,
-+ struct ceph_vino vino,
-+ struct ceph_file_layout *layout,
-+ u64 off, u64 *plen,
-+ struct ceph_osd_request *req,
-+ struct ceph_osd_req_op *op)
- {
- u64 bno;
-+ int r;
-
-- ceph_calc_raw_layout(osdc, layout, vino.snap, off,
-- plen, &bno, req, op);
-+ r = ceph_calc_raw_layout(osdc, layout, vino.snap, off,
-+ plen, &bno, req, op);
-+ if (r < 0)
-+ return r;
-
- snprintf(req->r_oid, sizeof(req->r_oid), "%llx.%08llx", vino.ino, bno);
- req->r_oid_len = strlen(req->r_oid);
-+
-+ return r;
- }
-
- /*
---- a/net/ceph/osdmap.c
-+++ b/net/ceph/osdmap.c
-@@ -941,7 +941,7 @@ bad:
- * for now, we write only a single su, until we can
- * pass a stride back to the caller.
- */
--void ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
-+int ceph_calc_file_object_mapping(struct ceph_file_layout *layout,
- u64 off, u64 *plen,
- u64 *ono,
- u64 *oxoff, u64 *oxlen)
-@@ -955,11 +955,17 @@ void ceph_calc_file_object_mapping(struc
-
- dout("mapping %llu~%llu osize %u fl_su %u\n", off, *plen,
- osize, su);
-+ if (su == 0 || sc == 0)
-+ goto invalid;
- su_per_object = osize / su;
-+ if (su_per_object == 0)
-+ goto invalid;
- dout("osize %u / su %u = su_per_object %u\n", osize, su,
- su_per_object);
-
-- BUG_ON((su & ~PAGE_MASK) != 0);
-+ if ((su & ~PAGE_MASK) != 0)
-+ goto invalid;
-+
- /* bl = *off / su; */
- t = off;
- do_div(t, su);
-@@ -987,6 +993,14 @@ void ceph_calc_file_object_mapping(struc
- *plen = *oxlen;
-
- dout(" obj extent %llu~%llu\n", *oxoff, *oxlen);
-+ return 0;
-+
-+invalid:
-+ dout(" invalid layout\n");
-+ *ono = 0;
-+ *oxoff = 0;
-+ *oxlen = 0;
-+ return -EINVAL;
- }
- EXPORT_SYMBOL(ceph_calc_file_object_mapping);
-