Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph-client

* '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

+72 -39
+3
fs/ceph/auth_x.c
··· 613 613 remove_ticket_handler(ac, th); 614 614 } 615 615 616 + if (xi->auth_authorizer.buf) 617 + ceph_buffer_put(xi->auth_authorizer.buf); 618 + 616 619 kfree(ac->private); 617 620 ac->private = NULL; 618 621 }
+30 -5
fs/ceph/mds_client.c
··· 1514 1514 ceph_encode_filepath(&p, end, ino1, path1); 1515 1515 ceph_encode_filepath(&p, end, ino2, path2); 1516 1516 1517 + /* make note of release offset, in case we need to replay */ 1518 + req->r_request_release_offset = p - msg->front.iov_base; 1519 + 1517 1520 /* cap releases */ 1518 1521 releases = 0; 1519 1522 if (req->r_inode_drop) ··· 1583 1580 dout("prepare_send_request %p tid %lld %s (attempt %d)\n", req, 1584 1581 req->r_tid, ceph_mds_op_name(req->r_op), req->r_attempts); 1585 1582 1583 + if (req->r_got_unsafe) { 1584 + /* 1585 + * Replay. Do not regenerate message (and rebuild 1586 + * paths, etc.); just use the original message. 1587 + * Rebuilding paths will break for renames because 1588 + * d_move mangles the src name. 1589 + */ 1590 + msg = req->r_request; 1591 + rhead = msg->front.iov_base; 1592 + 1593 + flags = le32_to_cpu(rhead->flags); 1594 + flags |= CEPH_MDS_FLAG_REPLAY; 1595 + rhead->flags = cpu_to_le32(flags); 1596 + 1597 + if (req->r_target_inode) 1598 + rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode)); 1599 + 1600 + rhead->num_retry = req->r_attempts - 1; 1601 + 1602 + /* remove cap/dentry releases from message */ 1603 + rhead->num_releases = 0; 1604 + msg->hdr.front_len = cpu_to_le32(req->r_request_release_offset); 1605 + msg->front.iov_len = req->r_request_release_offset; 1606 + return 0; 1607 + } 1608 + 1586 1609 if (req->r_request) { 1587 1610 ceph_msg_put(req->r_request); 1588 1611 req->r_request = NULL; ··· 1630 1601 rhead->flags = cpu_to_le32(flags); 1631 1602 rhead->num_fwd = req->r_num_fwd; 1632 1603 rhead->num_retry = req->r_attempts - 1; 1604 + rhead->ino = 0; 1633 1605 1634 1606 dout(" r_locked_dir = %p\n", req->r_locked_dir); 1635 - 1636 - if (req->r_target_inode && req->r_got_unsafe) 1637 - rhead->ino = cpu_to_le64(ceph_ino(req->r_target_inode)); 1638 - else 1639 - rhead->ino = 0; 1640 1607 return 0; 1641 1608 } 1642 1609
+1
fs/ceph/mds_client.h
··· 188 188 int r_old_inode_drop, r_old_inode_unless; 189 189 190 190 struct ceph_msg *r_request; /* original request */ 191 + int r_request_release_offset; 191 192 struct ceph_msg *r_reply; 192 193 struct ceph_mds_reply_info_parsed r_reply_info; 193 194 int r_err;
+37 -34
fs/ceph/messenger.c
··· 43 43 * nicely render a sockaddr as a string. 44 44 */ 45 45 #define MAX_ADDR_STR 20 46 - static char addr_str[MAX_ADDR_STR][40]; 46 + #define MAX_ADDR_STR_LEN 60 47 + static char addr_str[MAX_ADDR_STR][MAX_ADDR_STR_LEN]; 47 48 static DEFINE_SPINLOCK(addr_str_lock); 48 49 static int last_addr_str; 49 50 ··· 53 52 int i; 54 53 char *s; 55 54 struct sockaddr_in *in4 = (void *)ss; 56 - unsigned char *quad = (void *)&in4->sin_addr.s_addr; 57 55 struct sockaddr_in6 *in6 = (void *)ss; 58 56 59 57 spin_lock(&addr_str_lock); ··· 64 64 65 65 switch (ss->ss_family) { 66 66 case AF_INET: 67 - sprintf(s, "%u.%u.%u.%u:%u", 68 - (unsigned int)quad[0], 69 - (unsigned int)quad[1], 70 - (unsigned int)quad[2], 71 - (unsigned int)quad[3], 72 - (unsigned int)ntohs(in4->sin_port)); 67 + snprintf(s, MAX_ADDR_STR_LEN, "%pI4:%u", &in4->sin_addr, 68 + (unsigned int)ntohs(in4->sin_port)); 73 69 break; 74 70 75 71 case AF_INET6: 76 - sprintf(s, "%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%u", 77 - in6->sin6_addr.s6_addr16[0], 78 - in6->sin6_addr.s6_addr16[1], 79 - in6->sin6_addr.s6_addr16[2], 80 - in6->sin6_addr.s6_addr16[3], 81 - in6->sin6_addr.s6_addr16[4], 82 - in6->sin6_addr.s6_addr16[5], 83 - in6->sin6_addr.s6_addr16[6], 84 - in6->sin6_addr.s6_addr16[7], 85 - (unsigned int)ntohs(in6->sin6_port)); 72 + snprintf(s, MAX_ADDR_STR_LEN, "[%pI6c]:%u", &in6->sin6_addr, 73 + (unsigned int)ntohs(in6->sin6_port)); 86 74 break; 87 75 88 76 default: ··· 203 215 */ 204 216 static struct socket *ceph_tcp_connect(struct ceph_connection *con) 205 217 { 206 - struct sockaddr *paddr = (struct sockaddr *)&con->peer_addr.in_addr; 218 + struct sockaddr_storage *paddr = &con->peer_addr.in_addr; 207 219 struct socket *sock; 208 220 int ret; 209 221 210 222 BUG_ON(con->sock); 211 - ret = sock_create_kern(AF_INET, SOCK_STREAM, IPPROTO_TCP, &sock); 223 + ret = sock_create_kern(con->peer_addr.in_addr.ss_family, SOCK_STREAM, 224 + IPPROTO_TCP, &sock); 212 225 if (ret) 213 226 return ERR_PTR(ret); 214 227 con->sock = sock; ··· 223 234 224 235 dout("connect %s\n", pr_addr(&con->peer_addr.in_addr)); 225 236 226 - ret = sock->ops->connect(sock, paddr, sizeof(*paddr), O_NONBLOCK); 237 + ret = sock->ops->connect(sock, (struct sockaddr *)paddr, sizeof(*paddr), 238 + O_NONBLOCK); 227 239 if (ret == -EINPROGRESS) { 228 240 dout("connect %s EINPROGRESS sk_state = %u\n", 229 241 pr_addr(&con->peer_addr.in_addr), ··· 999 1009 struct sockaddr_in *in4 = (void *)ss; 1000 1010 struct sockaddr_in6 *in6 = (void *)ss; 1001 1011 int port; 1012 + char delim = ','; 1013 + 1014 + if (*p == '[') { 1015 + delim = ']'; 1016 + p++; 1017 + } 1002 1018 1003 1019 memset(ss, 0, sizeof(*ss)); 1004 1020 if (in4_pton(p, end - p, (u8 *)&in4->sin_addr.s_addr, 1005 - ',', &ipend)) { 1021 + delim, &ipend)) 1006 1022 ss->ss_family = AF_INET; 1007 - } else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, 1008 - ',', &ipend)) { 1023 + else if (in6_pton(p, end - p, (u8 *)&in6->sin6_addr.s6_addr, 1024 + delim, &ipend)) 1009 1025 ss->ss_family = AF_INET6; 1010 - } else { 1026 + else 1011 1027 goto bad; 1012 - } 1013 1028 p = ipend; 1029 + 1030 + if (delim == ']') { 1031 + if (*p != ']') { 1032 + dout("missing matching ']'\n"); 1033 + goto bad; 1034 + } 1035 + p++; 1036 + } 1014 1037 1015 1038 /* port? */ 1016 1039 if (p < end && *p == ':') { ··· 1058 1055 return 0; 1059 1056 1060 1057 bad: 1061 - pr_err("parse_ips bad ip '%s'\n", c); 1058 + pr_err("parse_ips bad ip '%.*s'\n", (int)(end - c), c); 1062 1059 return -EINVAL; 1063 1060 } 1064 1061 ··· 2018 2015 { 2019 2016 mutex_lock(&con->mutex); 2020 2017 if (!list_empty(&msg->list_head)) { 2021 - dout("con_revoke %p msg %p\n", con, msg); 2018 + dout("con_revoke %p msg %p - was on queue\n", con, msg); 2022 2019 list_del_init(&msg->list_head); 2023 2020 ceph_msg_put(msg); 2024 2021 msg->hdr.seq = 0; 2025 - if (con->out_msg == msg) { 2026 - ceph_msg_put(con->out_msg); 2027 - con->out_msg = NULL; 2028 - } 2022 + } 2023 + if (con->out_msg == msg) { 2024 + dout("con_revoke %p msg %p - was sending\n", con, msg); 2025 + con->out_msg = NULL; 2029 2026 if (con->out_kvec_is_msg) { 2030 2027 con->out_skip = con->out_kvec_bytes; 2031 2028 con->out_kvec_is_msg = false; 2032 2029 } 2033 - } else { 2034 - dout("con_revoke %p msg %p - not queued (sent?)\n", con, msg); 2030 + ceph_msg_put(msg); 2031 + msg->hdr.seq = 0; 2035 2032 } 2036 2033 mutex_unlock(&con->mutex); 2037 2034 }
+1
fs/ceph/osdmap.c
··· 568 568 if (ev > CEPH_PG_POOL_VERSION) { 569 569 pr_warning("got unknown v %d > %d of ceph_pg_pool\n", 570 570 ev, CEPH_PG_POOL_VERSION); 571 + kfree(pi); 571 572 goto bad; 572 573 } 573 574 __decode_pool(p, pi);