Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0959371 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client:
  ceph: do not include cap/dentry releases in replayed messages
  ceph: reuse request message when replaying against recovering mds
  ceph: fix creation of ipv6 sockets
  ceph: fix parsing of ipv6 addresses
  ceph: fix printing of ipv6 addrs
  ceph: add kfree() to error path
  ceph: fix leak of mon authorizer
  ceph: fix message revocation
parents 83ba3710 e979cf50
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -613,6 +613,9 @@ static void ceph_x_destroy(struct ceph_auth_client *ac)
		remove_ticket_handler(ac, th);
	}

	if (xi->auth_authorizer.buf)
		ceph_buffer_put(xi->auth_authorizer.buf);

	kfree(ac->private);
	ac->private = NULL;
}
+30 −5
Original line number Diff line number Diff line
@@ -1514,6 +1514,9 @@ static struct ceph_msg *create_request_message(struct ceph_mds_client *mdsc,
	ceph_encode_filepath(&p, end, ino1, path1);
	ceph_encode_filepath(&p, end, ino2, path2);

	/* make note of release offset, in case we need to replay */
	req->r_request_release_offset = p - msg->front.iov_base;

	/* cap releases */
	releases = 0;
	if (req->r_inode_drop)
@@ -1580,6 +1583,32 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
	dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req,
	     req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts);

	if (req->r_got_unsafe) {
		/*
		 * Replay.  Do not regenerate message (and rebuild
		 * paths, etc.); just use the original message.
		 * Rebuilding paths will break for renames because
		 * d_move mangles the src name.
		 */
		msg = req->r_request;
		rhead = msg->front.iov_base;

		flags = le32_to_cpu(rhead->flags);
		flags |= CEPH_MDS_FLAG_REPLAY;
		rhead->flags = cpu_to_le32(flags);

		if (req->r_target_inode)
			rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));

		rhead->num_retry = req->r_attempts - 1;

		/* remove cap/dentry releases from message */
		rhead->num_releases = 0;
		msg->hdr.front_len = cpu_to_le32(req->r_request_release_offset);
		msg->front.iov_len = req->r_request_release_offset;
		return 0;
	}

	if (req->r_request) {
		ceph_msg_put(req->r_request);
		req->r_request = NULL;
@@ -1601,13 +1630,9 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
	rhead->flags = cpu_to_le32(flags);
	rhead->num_fwd = req->r_num_fwd;
	rhead->num_retry = req->r_attempts - 1;
	rhead->ino = 0;

	dout(" r_locked_dir = %p\n", req->r_locked_dir);

	if (req->r_target_inode && req->r_got_unsafe)
		rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode));
	else
		rhead->ino = 0;
	return 0;
}

+1 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ struct ceph_mds_request {
	int r_old_inode_drop, r_old_inode_unless;

	struct ceph_msg  *r_request;  /* original request */
	int r_request_release_offset;
	struct ceph_msg  *r_reply;
	struct ceph_mds_reply_info_parsed r_reply_info;
	int r_err;
+37 −34
Original line number Diff line number Diff line
@@ -43,7 +43,8 @@ static void ceph_fault(struct ceph_connection *con);
 * nicely render a sockaddr as a string.
 */
#define MAX_ADDR_STR 20
static char addr_str[MAX_ADDR_STR][40];
#define MAX_ADDR_STR_LEN 60
static char addr_str[MAX_ADDR_STR][MAX_ADDR_STR_LEN];
static DEFINE_SPINLOCK(addr_str_lock);
static int last_addr_str;

@@ -52,7 +53,6 @@ const char *pr_addr(const struct sockaddr_storage *ss)
	int i;
	char *s;
	struct sockaddr_in *in4 = (void *)ss;
	unsigned char *quad = (void *)&in4->sin_addr.s_addr;
	struct sockaddr_in6 *in6 = (void *)ss;

	spin_lock(&addr_str_lock);
@@ -64,24 +64,12 @@ const char *pr_addr(const struct sockaddr_storage *ss)

	switch (ss->ss_family) {
	case AF_INET:
		sprintf(s, "%u.%u.%u.%u:%u",
			(unsigned int)quad[0],
			(unsigned int)quad[1],
			(unsigned int)quad[2],
			(unsigned int)quad[3],
		snprintf(s, MAX_ADDR_STR_LEN, "%pI4:%u", &in4->sin_addr,
			 (unsigned int)ntohs(in4->sin_port));
		break;

	case AF_INET6:
		sprintf(s, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u",
			in6->sin6_addr.s6_addr16[0],
			in6->sin6_addr.s6_addr16[1],
			in6->sin6_addr.s6_addr16[2],
			in6->sin6_addr.s6_addr16[3],
			in6->sin6_addr.s6_addr16[4],
			in6->sin6_addr.s6_addr16[5],
			in6->sin6_addr.s6_addr16[6],
			in6->sin6_addr.s6_addr16[7],
		snprintf(s, MAX_ADDR_STR_LEN, "[%pI6c]:%u", &in6->sin6_addr,
			 (unsigned int)ntohs(in6->sin6_port));
		break;

@@ -215,12 +203,13 @@ static void set_sock_callbacks(struct socket *sock,
 */
static struct socket *ceph_tcp_connect(struct ceph_connection *con)
{
	struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.in_addr;
	struct sockaddr_storage *paddr = &con->peer_addr.in_addr;
	struct socket *sock;
	int ret;

	BUG_ON(con->sock);
	ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
	ret = sock_create_kern(con->peer_addr.in_addr.ss_family, SOCK_STREAM,
			       IPPROTO_TCP, &sock);
	if (ret)
		return ERR_PTR(ret);
	con->sock = sock;
@@ -234,7 +223,8 @@ static struct socket *ceph_tcp_connect(struct ceph_connection *con)

	dout("connect %s\n", pr_addr(&con->peer_addr.in_addr));

	ret = sock->ops->connect(sock, paddr, sizeof(*paddr), O_NONBLOCK);
	ret = sock->ops->connect(sock, (struct sockaddr *)paddr, sizeof(*paddr),
				 O_NONBLOCK);
	if (ret == -EINPROGRESS) {
		dout("connect %s EINPROGRESS sk_state = %u\n",
		     pr_addr(&con->peer_addr.in_addr),
@@ -1009,19 +999,32 @@ int ceph_parse_ips(const char *c, const char *end,
		struct sockaddr_in *in4 = (void *)ss;
		struct sockaddr_in6 *in6 = (void *)ss;
		int port;
		char delim = ',';

		if (*p == '[') {
			delim = ']';
			p++;
		}

		memset(ss, 0, sizeof(*ss));
		if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr,
			     ',', &ipend)) {
			     delim, &ipend))
			ss->ss_family = AF_INET;
		} else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
				    ',', &ipend)) {
		else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr,
				  delim, &ipend))
			ss->ss_family = AF_INET6;
		} else {
		else
			goto bad;
		}
		p = ipend;

		if (delim == ']') {
			if (*p != ']') {
				dout("missing matching ']'\n");
				goto bad;
			}
			p++;
		}

		/* port? */
		if (p < end && *p == ':') {
			port = 0;
@@ -1055,7 +1058,7 @@ int ceph_parse_ips(const char *c, const char *end,
	return 0;

bad:
	pr_err("parse_ips bad ip '%s'\n", c);
	pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c);
	return -EINVAL;
}

@@ -2015,20 +2018,20 @@ void ceph_con_revoke(struct ceph_connection *con, struct ceph_msg *msg)
{
	mutex_lock(&con->mutex);
	if (!list_empty(&msg->list_head)) {
		dout("con_revoke %p msg %p\n", con, msg);
		dout("con_revoke %p msg %p - was on queue\n", con, msg);
		list_del_init(&msg->list_head);
		ceph_msg_put(msg);
		msg->hdr.seq = 0;
	}
	if (con->out_msg == msg) {
			ceph_msg_put(con->out_msg);
		dout("con_revoke %p msg %p - was sending\n", con, msg);
		con->out_msg = NULL;
		}
		if (con->out_kvec_is_msg) {
			con->out_skip = con->out_kvec_bytes;
			con->out_kvec_is_msg = false;
		}
	} else {
		dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg);
		ceph_msg_put(msg);
		msg->hdr.seq = 0;
	}
	mutex_unlock(&con->mutex);
}
+1 −0
Original line number Diff line number Diff line
@@ -568,6 +568,7 @@ struct ceph_osdmap *osdmap_decode(void **p, void *end)
		if (ev > CEPH_PG_POOL_VERSION) {
			pr_warning("got unknown v %d > %d of ceph_pg_pool\n",
				   ev, CEPH_PG_POOL_VERSION);
			kfree(pi);
			goto bad;
		}
		__decode_pool(p, pi);