--- /dev/null
+From 92a49fb0f79f3300e6e50ddf56238e70678e4202 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@inktank.com>
+Date: Fri, 22 Feb 2013 15:31:00 -0800
+Subject: ceph: fix statvfs fr_size
+
+From: Sage Weil <sage@inktank.com>
+
+commit 92a49fb0f79f3300e6e50ddf56238e70678e4202 upstream.
+
+Different versions of glibc are broken in different ways, but the short of
+it is that for the time being, frsize should == bsize, and be used as the
+multiple for the blocks, free, and available fields. This mirrors what is
+done for NFS. The previous reporting of the page size for frsize meant
+that newer glibc and df would report a very small value for the fs size.
+
+Fixes http://tracker.ceph.com/issues/3793.
+
+Signed-off-by: Sage Weil <sage@inktank.com>
+Reviewed-by: Greg Farnum <greg@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/super.c | 7 ++++++-
+ fs/ceph/super.h | 2 +-
+ 2 files changed, 7 insertions(+), 2 deletions(-)
+
+--- a/fs/ceph/super.c
++++ b/fs/ceph/super.c
+@@ -70,8 +70,14 @@ static int ceph_statfs(struct dentry *de
+ /*
+ * express utilization in terms of large blocks to avoid
+ * overflow on 32-bit machines.
++ *
++ * NOTE: for the time being, we make bsize == frsize to humor
++ * not-yet-ancient versions of glibc that are broken.
++ * Someday, we will probably want to report a real block
++ * size... whatever that may mean for a network file system!
+ */
+ buf->f_bsize = 1 << CEPH_BLOCK_SHIFT;
++ buf->f_frsize = 1 << CEPH_BLOCK_SHIFT;
+ buf->f_blocks = le64_to_cpu(st.kb) >> (CEPH_BLOCK_SHIFT-10);
+ buf->f_bfree = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
+ buf->f_bavail = le64_to_cpu(st.kb_avail) >> (CEPH_BLOCK_SHIFT-10);
+@@ -79,7 +85,6 @@ static int ceph_statfs(struct dentry *de
+ buf->f_files = le64_to_cpu(st.num_objects);
+ buf->f_ffree = -1;
+ buf->f_namelen = NAME_MAX;
+- buf->f_frsize = PAGE_CACHE_SIZE;
+
+ /* leave fsid little-endian, regardless of host endianness */
+ fsid = *(u64 *)(&monmap->fsid) ^ *((u64 *)&monmap->fsid + 1);
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -21,7 +21,7 @@
+
+ /* large granularity for statfs utilization stats to facilitate
+ * large volume sizes on 32-bit machines. */
+-#define CEPH_BLOCK_SHIFT 20 /* 1 MB */
++#define CEPH_BLOCK_SHIFT 22 /* 4 MB */
+ #define CEPH_BLOCK (1 << CEPH_BLOCK_SHIFT)
+
+ #define CEPH_MOUNT_OPT_DIRSTAT (1<<4) /* `cat dirname` for stats */
--- /dev/null
+From 0bed9b5c523d577378b6f83eab5835fe30c27208 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@inktank.com>
+Date: Mon, 25 Mar 2013 10:26:01 -0700
+Subject: libceph: add update_authorizer auth method
+
+From: Sage Weil <sage@inktank.com>
+
+commit 0bed9b5c523d577378b6f83eab5835fe30c27208 upstream.
+
+Currently the messenger calls out to a get_authorizer con op, which will
+create a new authorizer if it doesn't yet have one. In the meantime, when
+we rotate our service keys, the authorizer doesn't get updated. Eventually
+it will be rejected by the server on a new connection attempt and get
+invalidated, and we will then rebuild a new authorizer, but this is not
+ideal.
+
+Instead, if we do have an authorizer, call a new update_authorizer op that
+will verify that the current authorizer is using the latest secret. If it
+is not, we will build a new one that does. This avoids the transient
+failure.
+
+This fixes one of the sorry sequence of events for bug
+
+ http://tracker.ceph.com/issues/4282
+
+Signed-off-by: Sage Weil <sage@inktank.com>
+Reviewed-by: Alex Elder <elder@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/mds_client.c | 7 ++++++-
+ include/linux/ceph/auth.h | 3 +++
+ net/ceph/auth_x.c | 23 +++++++++++++++++++++++
+ net/ceph/auth_x.h | 1 +
+ net/ceph/osd_client.c | 5 +++++
+ 5 files changed, 38 insertions(+), 1 deletion(-)
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -3425,7 +3425,12 @@ static struct ceph_auth_handshake *get_a
+ }
+ if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) {
+ int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
+- auth);
++ auth);
++ if (ret)
++ return ERR_PTR(ret);
++ } else if (ac->ops && ac->ops_update_authorizer) {
++ int ret = ac->ops->update_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
++ auth);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+--- a/include/linux/ceph/auth.h
++++ b/include/linux/ceph/auth.h
+@@ -52,6 +52,9 @@ struct ceph_auth_client_ops {
+ */
+ int (*create_authorizer)(struct ceph_auth_client *ac, int peer_type,
+ struct ceph_auth_handshake *auth);
++ /* ensure that an existing authorizer is up to date */
++ int (*update_authorizer)(struct ceph_auth_client *ac, int peer_type,
++ struct ceph_auth_handshake *auth);
+ int (*verify_authorizer_reply)(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a, size_t len);
+ void (*destroy_authorizer)(struct ceph_auth_client *ac,
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -298,6 +298,7 @@ static int ceph_x_build_authorizer(struc
+ return -ENOMEM;
+ }
+ au->service = th->service;
++ au->secret_id = th->secret_id;
+
+ msg_a = au->buf->vec.iov_base;
+ msg_a->struct_v = 1;
+@@ -555,6 +556,27 @@ static int ceph_x_create_authorizer(
+ return 0;
+ }
+
++static int ceph_x_update_authorizer(
++ struct ceph_auth_client *ac, int peer_type,
++ struct ceph_auth_handshake *auth)
++{
++ struct ceph_x_authorizer *au;
++ struct ceph_x_ticket_handler *th;
++ int ret;
++
++ th = get_ticket_handler(ac, peer_type);
++ if (IS_ERR(th))
++ return PTR_ERR(th);
++
++ au = (struct ceph_x_authorizer *)auth->authorizer;
++ if (au->secret_id < th->secret_id) {
++ dout("ceph_x_update_authorizer service %u secret %llu < %llu\n",
++ au->service, au->secret_id, th->secret_id);
++ return ceph_x_build_authorizer(ac, th, au);
++ }
++ return 0;
++}
++
+ static int ceph_x_verify_authorizer_reply(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a, size_t len)
+ {
+@@ -641,6 +663,7 @@ static const struct ceph_auth_client_ops
+ .build_request = ceph_x_build_request,
+ .handle_reply = ceph_x_handle_reply,
+ .create_authorizer = ceph_x_create_authorizer,
++ .update_authorizer = ceph_x_update_authorizer,
+ .verify_authorizer_reply = ceph_x_verify_authorizer_reply,
+ .destroy_authorizer = ceph_x_destroy_authorizer,
+ .invalidate_authorizer = ceph_x_invalidate_authorizer,
+--- a/net/ceph/auth_x.h
++++ b/net/ceph/auth_x.h
+@@ -29,6 +29,7 @@ struct ceph_x_authorizer {
+ struct ceph_buffer *buf;
+ unsigned service;
+ u64 nonce;
++ u64 secret_id;
+ char reply_buf[128]; /* big enough for encrypted blob */
+ };
+
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -2136,6 +2136,11 @@ static struct ceph_auth_handshake *get_a
+ auth);
+ if (ret)
+ return ERR_PTR(ret);
++ } else if (ac->ops && ac->ops->update_authorizer) {
++ int ret = ac->ops->update_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
++ auth);
++ if (ret)
++ return ERR_PTR(ret);
+ }
+ *proto = ac->protocol;
+
--- /dev/null
+From 20e55c4cc758e4dccdfd92ae8e9588dd624b2cd7 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@inktank.com>
+Date: Mon, 25 Mar 2013 09:30:13 -0700
+Subject: libceph: clear messenger auth_retry flag when we authenticate
+
+From: Sage Weil <sage@inktank.com>
+
+commit 20e55c4cc758e4dccdfd92ae8e9588dd624b2cd7 upstream.
+
+We maintain a counter of failed auth attempts to allow us to retry once
+before failing. However, if the second attempt succeeds, the flag isn't
+cleared, which makes us think auth failed again later when the connection
+resets for other reasons (like a socket error).
+
+This is one part of the sorry sequence of events in bug
+
+ http://tracker.ceph.com/issues/4282
+
+Signed-off-by: Sage Weil <sage@inktank.com>
+Reviewed-by: Alex Elder <elder@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/messenger.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/net/ceph/messenger.c
++++ b/net/ceph/messenger.c
+@@ -1542,7 +1542,6 @@ static int process_connect(struct ceph_c
+ con->error_msg = "connect authorization failure";
+ return -1;
+ }
+- con->auth_retry = 1;
+ con_out_kvec_reset(con);
+ ret = prepare_write_connect(con);
+ if (ret < 0)
+@@ -1627,7 +1626,7 @@ static int process_connect(struct ceph_c
+
+ WARN_ON(con->state != CON_STATE_NEGOTIATING);
+ con->state = CON_STATE_OPEN;
+-
++ con->auth_retry = 0; /* we authenticated; clear flag */
+ con->peer_global_seq = le32_to_cpu(con->in_reply.global_seq);
+ con->connect_seq++;
+ con->peer_features = server_feat;
--- /dev/null
+From 4b8e8b5d78b8322351d44487c1b76f7e9d3412bc Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@inktank.com>
+Date: Mon, 25 Mar 2013 10:25:49 -0700
+Subject: libceph: fix authorizer invalidation
+
+From: Sage Weil <sage@inktank.com>
+
+commit 4b8e8b5d78b8322351d44487c1b76f7e9d3412bc upstream.
+
+We were invalidating the authorizer by removing the ticket handler
+entirely. This was effective in inducing us to request a new authorizer,
+but in the meantime it mean that any authorizer we generated would get a
+new and initialized handler with secret_id=0, which would always be
+rejected by the server side with a confusing error message:
+
+ auth: could not find secret_id=0
+ cephx: verify_authorizer could not get service secret for service osd secret_id=0
+
+Instead, simply clear the validity field. This will still induce the auth
+code to request a new secret, but will let us continue to use the old
+ticket in the meantime. The messenger code will probably continue to fail,
+but the exponential backoff will kick in, and eventually the we will get a
+new (hopefully more valid) ticket from the mon and be able to continue.
+
+Signed-off-by: Sage Weil <sage@inktank.com>
+Reviewed-by: Alex Elder <elder@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ net/ceph/auth_x.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -630,7 +630,7 @@ static void ceph_x_invalidate_authorizer
+
+ th = get_ticket_handler(ac, peer_type);
+ if (!IS_ERR(th))
+- remove_ticket_handler(ac, th);
++ memset(&th->validity, 0, sizeof(th->validity));
+ }
+
+
--- /dev/null
+From e9966076cdd952e19f2dd4854cd719be0d7cbebc Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@inktank.com>
+Date: Mon, 25 Mar 2013 10:26:30 -0700
+Subject: libceph: wrap auth methods in a mutex
+
+From: Sage Weil <sage@inktank.com>
+
+commit e9966076cdd952e19f2dd4854cd719be0d7cbebc upstream.
+
+The auth code is called from a variety of contexts, include the mon_client
+(protected by the monc's mutex) and the messenger callbacks (currently
+protected by nothing). Avoid chaos by protecting all auth state with a
+mutex. Nothing is blocking, so this should be simple and lightweight.
+
+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/auth.h | 2 +
+ net/ceph/auth.c | 78 +++++++++++++++++++++++++++++++++-------------
+ 2 files changed, 58 insertions(+), 22 deletions(-)
+
+--- a/include/linux/ceph/auth.h
++++ b/include/linux/ceph/auth.h
+@@ -78,6 +78,8 @@ struct ceph_auth_client {
+ u64 global_id; /* our unique id in system */
+ const struct ceph_crypto_key *key; /* our secret key */
+ unsigned want_keys; /* which services we want */
++
++ struct mutex mutex;
+ };
+
+ extern struct ceph_auth_client *ceph_auth_init(const char *name,
+--- a/net/ceph/auth.c
++++ b/net/ceph/auth.c
+@@ -47,6 +47,7 @@ struct ceph_auth_client *ceph_auth_init(
+ if (!ac)
+ goto out;
+
++ mutex_init(&ac->mutex);
+ ac->negotiating = true;
+ if (name)
+ ac->name = name;
+@@ -73,10 +74,12 @@ void ceph_auth_destroy(struct ceph_auth_
+ */
+ void ceph_auth_reset(struct ceph_auth_client *ac)
+ {
++ mutex_lock(&ac->mutex);
+ dout("auth_reset %p\n", ac);
+ if (ac->ops && !ac->negotiating)
+ ac->ops->reset(ac);
+ ac->negotiating = true;
++ mutex_unlock(&ac->mutex);
+ }
+
+ int ceph_entity_name_encode(const char *name, void **p, void *end)
+@@ -102,6 +105,7 @@ int ceph_auth_build_hello(struct ceph_au
+ int i, num;
+ int ret;
+
++ mutex_lock(&ac->mutex);
+ dout("auth_build_hello\n");
+ monhdr->have_version = 0;
+ monhdr->session_mon = cpu_to_le16(-1);
+@@ -122,15 +126,19 @@ int ceph_auth_build_hello(struct ceph_au
+
+ ret = ceph_entity_name_encode(ac->name, &p, end);
+ if (ret < 0)
+- return ret;
++ goto out;
+ ceph_decode_need(&p, end, sizeof(u64), bad);
+ ceph_encode_64(&p, ac->global_id);
+
+ ceph_encode_32(&lenp, p - lenp - sizeof(u32));
+- return p - buf;
++ ret = p - buf;
++out:
++ mutex_unlock(&ac->mutex);
++ return ret;
+
+ bad:
+- return -ERANGE;
++ ret = -ERANGE;
++ goto out;
+ }
+
+ static int ceph_build_auth_request(struct ceph_auth_client *ac,
+@@ -151,11 +159,13 @@ static int ceph_build_auth_request(struc
+ if (ret < 0) {
+ pr_err("error %d building auth method %s request\n", ret,
+ ac->ops->name);
+- return ret;
++ goto out;
+ }
+ dout(" built request %d bytes\n", ret);
+ ceph_encode_32(&p, ret);
+- return p + ret - msg_buf;
++ ret = p + ret - msg_buf;
++out:
++ return ret;
+ }
+
+ /*
+@@ -176,6 +186,7 @@ int ceph_handle_auth_reply(struct ceph_a
+ int result_msg_len;
+ int ret = -EINVAL;
+
++ mutex_lock(&ac->mutex);
+ dout("handle_auth_reply %p %p\n", p, end);
+ ceph_decode_need(&p, end, sizeof(u32) * 3 + sizeof(u64), bad);
+ protocol = ceph_decode_32(&p);
+@@ -227,35 +238,44 @@ int ceph_handle_auth_reply(struct ceph_a
+
+ ret = ac->ops->handle_reply(ac, result, payload, payload_end);
+ if (ret == -EAGAIN) {
+- return ceph_build_auth_request(ac, reply_buf, reply_len);
++ ret = ceph_build_auth_request(ac, reply_buf, reply_len);
+ } else if (ret) {
+ pr_err("auth method '%s' error %d\n", ac->ops->name, ret);
+- return ret;
+ }
+- return 0;
+
+-bad:
+- pr_err("failed to decode auth msg\n");
+ out:
++ mutex_unlock(&ac->mutex);
+ return ret;
++
++bad:
++ pr_err("failed to decode auth msg\n");
++ ret = -EINVAL;
++ goto out;
+ }
+
+ int ceph_build_auth(struct ceph_auth_client *ac,
+ void *msg_buf, size_t msg_len)
+ {
++ int ret = 0;
++
++ mutex_lock(&ac->mutex);
+ if (!ac->protocol)
+- return ceph_auth_build_hello(ac, msg_buf, msg_len);
+- BUG_ON(!ac->ops);
+- if (ac->ops->should_authenticate(ac))
+- return ceph_build_auth_request(ac, msg_buf, msg_len);
+- return 0;
++ ret = ceph_auth_build_hello(ac, msg_buf, msg_len);
++ else if (ac->ops->should_authenticate(ac))
++ ret = ceph_build_auth_request(ac, msg_buf, msg_len);
++ mutex_unlock(&ac->mutex);
++ return ret;
+ }
+
+ int ceph_auth_is_authenticated(struct ceph_auth_client *ac)
+ {
+- if (!ac->ops)
+- return 0;
+- return ac->ops->is_authenticated(ac);
++ int ret = 0;
++
++ mutex_lock(&ac->mutex);
++ if (ac->ops)
++ ret = ac->ops->is_authenticated(ac);
++ mutex_unlock(&ac->mutex);
++ return ret;
+ }
+ EXPORT_SYMBOL(ceph_auth_is_authenticated);
+
+@@ -263,17 +283,23 @@ int ceph_auth_create_authorizer(struct c
+ int peer_type,
+ struct ceph_auth_handshake *auth)
+ {
++ int ret = 0;
++
++ mutex_lock(&ac->mutex);
+ if (ac->ops && ac->ops->create_authorizer)
+- return ac->ops->create_authorizer(ac, peer_type, auth);
+- return 0;
++ ret = ac->ops->create_authorizer(ac, peer_type, auth);
++ mutex_unlock(&ac->mutex);
++ return ret;
+ }
+ EXPORT_SYMBOL(ceph_auth_create_authorizer);
+
+ void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a)
+ {
++ mutex_lock(&ac->mutex);
+ if (ac->ops && ac->ops->destroy_authorizer)
+ ac->ops->destroy_authorizer(ac, a);
++ mutex_unlock(&ac->mutex);
+ }
+ EXPORT_SYMBOL(ceph_auth_destroy_authorizer);
+
+@@ -283,8 +309,10 @@ int ceph_auth_update_authorizer(struct c
+ {
+ int ret = 0;
+
++ mutex_lock(&ac->mutex);
+ if (ac->ops && ac->ops->update_authorizer)
+ ret = ac->ops->update_authorizer(ac, peer_type, a);
++ mutex_unlock(&ac->mutex);
+ return ret;
+ }
+ EXPORT_SYMBOL(ceph_auth_update_authorizer);
+@@ -292,15 +320,21 @@ EXPORT_SYMBOL(ceph_auth_update_authorize
+ int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
+ struct ceph_authorizer *a, size_t len)
+ {
++ int ret = 0;
++
++ mutex_lock(&ac->mutex);
+ if (ac->ops && ac->ops->verify_authorizer_reply)
+- return ac->ops->verify_authorizer_reply(ac, a, len);
+- return 0;
++ ret = ac->ops->verify_authorizer_reply(ac, a, len);
++ mutex_unlock(&ac->mutex);
++ return ret;
+ }
+ EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
+
+ void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
+ {
++ mutex_lock(&ac->mutex);
+ if (ac->ops && ac->ops->invalidate_authorizer)
+ ac->ops->invalidate_authorizer(ac, peer_type);
++ mutex_unlock(&ac->mutex);
+ }
+ EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
--- /dev/null
+From 27859f9773e4a0b2042435b13400ee2c891a61f4 Mon Sep 17 00:00:00 2001
+From: Sage Weil <sage@inktank.com>
+Date: Mon, 25 Mar 2013 10:26:14 -0700
+Subject: libceph: wrap auth ops in wrapper functions
+
+From: Sage Weil <sage@inktank.com>
+
+commit 27859f9773e4a0b2042435b13400ee2c891a61f4 upstream.
+
+Use wrapper functions that check whether the auth op exists so that callers
+do not need a bunch of conditional checks. Simplifies the external
+interface.
+
+Signed-off-by: Sage Weil <sage@inktank.com>
+Reviewed-by: Alex Elder <elder@inktank.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/ceph/mds_client.c | 26 +++++++++++--------------
+ include/linux/ceph/auth.h | 13 ++++++++++++
+ net/ceph/auth.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
+ net/ceph/auth_x.c | 1
+ net/ceph/mon_client.c | 7 ++----
+ net/ceph/osd_client.c | 26 ++++++++-----------------
+ 6 files changed, 84 insertions(+), 36 deletions(-)
+
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -335,9 +335,9 @@ void ceph_put_mds_session(struct ceph_md
+ atomic_read(&s->s_ref), atomic_read(&s->s_ref)-1);
+ if (atomic_dec_and_test(&s->s_ref)) {
+ if (s->s_auth.authorizer)
+- s->s_mdsc->fsc->client->monc.auth->ops->destroy_authorizer(
+- s->s_mdsc->fsc->client->monc.auth,
+- s->s_auth.authorizer);
++ ceph_auth_destroy_authorizer(
++ s->s_mdsc->fsc->client->monc.auth,
++ s->s_auth.authorizer);
+ kfree(s);
+ }
+ }
+@@ -3419,18 +3419,17 @@ static struct ceph_auth_handshake *get_a
+ struct ceph_auth_handshake *auth = &s->s_auth;
+
+ if (force_new && auth->authorizer) {
+- if (ac->ops && ac->ops->destroy_authorizer)
+- ac->ops->destroy_authorizer(ac, auth->authorizer);
++ ceph_auth_destroy_authorizer(ac, auth->authorizer);
+ auth->authorizer = NULL;
+ }
+- if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) {
+- int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
+- auth);
++ if (!auth->authorizer) {
++ int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
++ auth);
+ if (ret)
+ return ERR_PTR(ret);
+- } else if (ac->ops && ac->ops_update_authorizer) {
+- int ret = ac->ops->update_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
+- auth);
++ } else {
++ int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_MDS,
++ auth);
+ if (ret)
+ return ERR_PTR(ret);
+ }
+@@ -3446,7 +3445,7 @@ static int verify_authorizer_reply(struc
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
+
+- return ac->ops->verify_authorizer_reply(ac, s->s_auth.authorizer, len);
++ return ceph_auth_verify_authorizer_reply(ac, s->s_auth.authorizer, len);
+ }
+
+ static int invalidate_authorizer(struct ceph_connection *con)
+@@ -3455,8 +3454,7 @@ static int invalidate_authorizer(struct
+ struct ceph_mds_client *mdsc = s->s_mdsc;
+ struct ceph_auth_client *ac = mdsc->fsc->client->monc.auth;
+
+- if (ac->ops->invalidate_authorizer)
+- ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS);
++ ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_MDS);
+
+ return ceph_monc_validate_auth(&mdsc->fsc->client->monc);
+ }
+--- a/include/linux/ceph/auth.h
++++ b/include/linux/ceph/auth.h
+@@ -97,5 +97,18 @@ extern int ceph_build_auth(struct ceph_a
+ void *msg_buf, size_t msg_len);
+
+ extern int ceph_auth_is_authenticated(struct ceph_auth_client *ac);
++extern int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
++ int peer_type,
++ struct ceph_auth_handshake *auth);
++extern void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac,
++ struct ceph_authorizer *a);
++extern int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
++ int peer_type,
++ struct ceph_auth_handshake *a);
++extern int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
++ struct ceph_authorizer *a,
++ size_t len);
++extern void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac,
++ int peer_type);
+
+ #endif
+--- a/net/ceph/auth.c
++++ b/net/ceph/auth.c
+@@ -257,3 +257,50 @@ int ceph_auth_is_authenticated(struct ce
+ return 0;
+ return ac->ops->is_authenticated(ac);
+ }
++EXPORT_SYMBOL(ceph_auth_is_authenticated);
++
++int ceph_auth_create_authorizer(struct ceph_auth_client *ac,
++ int peer_type,
++ struct ceph_auth_handshake *auth)
++{
++ if (ac->ops && ac->ops->create_authorizer)
++ return ac->ops->create_authorizer(ac, peer_type, auth);
++ return 0;
++}
++EXPORT_SYMBOL(ceph_auth_create_authorizer);
++
++void ceph_auth_destroy_authorizer(struct ceph_auth_client *ac,
++ struct ceph_authorizer *a)
++{
++ if (ac->ops && ac->ops->destroy_authorizer)
++ ac->ops->destroy_authorizer(ac, a);
++}
++EXPORT_SYMBOL(ceph_auth_destroy_authorizer);
++
++int ceph_auth_update_authorizer(struct ceph_auth_client *ac,
++ int peer_type,
++ struct ceph_auth_handshake *a)
++{
++ int ret = 0;
++
++ if (ac->ops && ac->ops->update_authorizer)
++ ret = ac->ops->update_authorizer(ac, peer_type, a);
++ return ret;
++}
++EXPORT_SYMBOL(ceph_auth_update_authorizer);
++
++int ceph_auth_verify_authorizer_reply(struct ceph_auth_client *ac,
++ struct ceph_authorizer *a, size_t len)
++{
++ if (ac->ops && ac->ops->verify_authorizer_reply)
++ return ac->ops->verify_authorizer_reply(ac, a, len);
++ return 0;
++}
++EXPORT_SYMBOL(ceph_auth_verify_authorizer_reply);
++
++void ceph_auth_invalidate_authorizer(struct ceph_auth_client *ac, int peer_type)
++{
++ if (ac->ops && ac->ops->invalidate_authorizer)
++ ac->ops->invalidate_authorizer(ac, peer_type);
++}
++EXPORT_SYMBOL(ceph_auth_invalidate_authorizer);
+--- a/net/ceph/auth_x.c
++++ b/net/ceph/auth_x.c
+@@ -562,7 +562,6 @@ static int ceph_x_update_authorizer(
+ {
+ struct ceph_x_authorizer *au;
+ struct ceph_x_ticket_handler *th;
+- int ret;
+
+ th = get_ticket_handler(ac, peer_type);
+ if (IS_ERR(th))
+--- a/net/ceph/mon_client.c
++++ b/net/ceph/mon_client.c
+@@ -737,7 +737,7 @@ static void delayed_work(struct work_str
+
+ __validate_auth(monc);
+
+- if (monc->auth->ops->is_authenticated(monc->auth))
++ if (ceph_auth_is_authenticated(monc->auth))
+ __send_subscribe(monc);
+ }
+ __schedule_delayed(monc);
+@@ -893,8 +893,7 @@ static void handle_auth_reply(struct cep
+
+ mutex_lock(&monc->mutex);
+ had_debugfs_info = have_debugfs_info(monc);
+- if (monc->auth->ops)
+- was_auth = monc->auth->ops->is_authenticated(monc->auth);
++ was_auth = ceph_auth_is_authenticated(monc->auth);
+ monc->pending_auth = 0;
+ ret = ceph_handle_auth_reply(monc->auth, msg->front.iov_base,
+ msg->front.iov_len,
+@@ -905,7 +904,7 @@ static void handle_auth_reply(struct cep
+ wake_up_all(&monc->client->auth_wq);
+ } else if (ret > 0) {
+ __send_prepared_auth_request(monc, ret);
+- } else if (!was_auth && monc->auth->ops->is_authenticated(monc->auth)) {
++ } else if (!was_auth && ceph_auth_is_authenticated(monc->auth)) {
+ dout("authenticated, starting session\n");
+
+ monc->client->msgr.inst.name.type = CEPH_ENTITY_TYPE_CLIENT;
+--- a/net/ceph/osd_client.c
++++ b/net/ceph/osd_client.c
+@@ -671,8 +671,7 @@ static void put_osd(struct ceph_osd *osd
+ if (atomic_dec_and_test(&osd->o_ref) && osd->o_auth.authorizer) {
+ struct ceph_auth_client *ac = osd->o_osdc->client->monc.auth;
+
+- if (ac->ops && ac->ops->destroy_authorizer)
+- ac->ops->destroy_authorizer(ac, osd->o_auth.authorizer);
++ ceph_auth_destroy_authorizer(ac, osd->o_auth.authorizer);
+ kfree(osd);
+ }
+ }
+@@ -2127,17 +2126,16 @@ static struct ceph_auth_handshake *get_a
+ struct ceph_auth_handshake *auth = &o->o_auth;
+
+ if (force_new && auth->authorizer) {
+- if (ac->ops && ac->ops->destroy_authorizer)
+- ac->ops->destroy_authorizer(ac, auth->authorizer);
++ ceph_auth_destroy_authorizer(ac, auth->authorizer);
+ auth->authorizer = NULL;
+ }
+- if (!auth->authorizer && ac->ops && ac->ops->create_authorizer) {
+- int ret = ac->ops->create_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
+- auth);
++ if (!auth->authorizer) {
++ int ret = ceph_auth_create_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
++ auth);
+ if (ret)
+ return ERR_PTR(ret);
+- } else if (ac->ops && ac->ops->update_authorizer) {
+- int ret = ac->ops->update_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
++ } else {
++ int ret = ceph_auth_update_authorizer(ac, CEPH_ENTITY_TYPE_OSD,
+ auth);
+ if (ret)
+ return ERR_PTR(ret);
+@@ -2154,11 +2152,7 @@ static int verify_authorizer_reply(struc
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+- /*
+- * XXX If ac->ops or ac->ops->verify_authorizer_reply is null,
+- * XXX which do we do: succeed or fail?
+- */
+- return ac->ops->verify_authorizer_reply(ac, o->o_auth.authorizer, len);
++ return ceph_auth_verify_authorizer_reply(ac, o->o_auth.authorizer, len);
+ }
+
+ static int invalidate_authorizer(struct ceph_connection *con)
+@@ -2167,9 +2161,7 @@ static int invalidate_authorizer(struct
+ struct ceph_osd_client *osdc = o->o_osdc;
+ struct ceph_auth_client *ac = osdc->client->monc.auth;
+
+- if (ac->ops && ac->ops->invalidate_authorizer)
+- ac->ops->invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD);
+-
++ ceph_auth_invalidate_authorizer(ac, CEPH_ENTITY_TYPE_OSD);
+ return ceph_monc_validate_auth(&osdc->client->monc);
+ }
+
md-raid1-consider-write-as-successful-only-if-at-least-one-non-faulty-and-non-rebuilding-drive-completed-it.patch
mm-migration-add-migrate_entry_wait_huge.patch
x86-fix-typo-in-kexec-register-clearing.patch
+libceph-clear-messenger-auth_retry-flag-when-we-authenticate.patch
+libceph-fix-authorizer-invalidation.patch
+libceph-add-update_authorizer-auth-method.patch
+libceph-wrap-auth-ops-in-wrapper-functions.patch
+libceph-wrap-auth-methods-in-a-mutex.patch
+ceph-fix-statvfs-fr_size.patch