Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dlm-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm

Pull dlm updates from David Teigland:
"This includes more dlm networking cleanups and improvements for making
dlm shutdowns more robust"

* tag 'dlm-5.13' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
fs: dlm: fix missing unlock on error in accept_from_sock()
fs: dlm: add shutdown hook
fs: dlm: flush swork on shutdown
fs: dlm: remove unaligned memory access handling
fs: dlm: check on minimum msglen size
fs: dlm: simplify writequeue handling
fs: dlm: use GFP_ZERO for page buffer
fs: dlm: change allocation limits
fs: dlm: add check if dlm is currently running
fs: dlm: add errno handling to check callback
fs: dlm: set subclass for othercon sock_mutex
fs: dlm: set connected bit after accept
fs: dlm: fix mark setting deadlock
fs: dlm: fix debugfs dump

+202 -142
+58 -28
fs/dlm/config.c
··· 125 125 CONFIGFS_ATTR(cluster_, cluster_name); 126 126 127 127 static ssize_t cluster_set(struct dlm_cluster *cl, unsigned int *cl_field, 128 - int *info_field, bool (*check_cb)(unsigned int x), 128 + int *info_field, int (*check_cb)(unsigned int x), 129 129 const char *buf, size_t len) 130 130 { 131 131 unsigned int x; ··· 137 137 if (rc) 138 138 return rc; 139 139 140 - if (check_cb && check_cb(x)) 141 - return -EINVAL; 140 + if (check_cb) { 141 + rc = check_cb(x); 142 + if (rc) 143 + return rc; 144 + } 142 145 143 146 *cl_field = x; 144 147 *info_field = x; ··· 164 161 } \ 165 162 CONFIGFS_ATTR(cluster_, name); 166 163 167 - static bool dlm_check_zero(unsigned int x) 164 + static int dlm_check_protocol_and_dlm_running(unsigned int x) 168 165 { 169 - return !x; 166 + switch (x) { 167 + case 0: 168 + /* TCP */ 169 + break; 170 + case 1: 171 + /* SCTP */ 172 + break; 173 + default: 174 + return -EINVAL; 175 + } 176 + 177 + if (dlm_allow_conn) 178 + return -EBUSY; 179 + 180 + return 0; 170 181 } 171 182 172 - static bool dlm_check_buffer_size(unsigned int x) 183 + static int dlm_check_zero_and_dlm_running(unsigned int x) 173 184 { 174 - return (x < DEFAULT_BUFFER_SIZE); 185 + if (!x) 186 + return -EINVAL; 187 + 188 + if (dlm_allow_conn) 189 + return -EBUSY; 190 + 191 + return 0; 175 192 } 176 193 177 - CLUSTER_ATTR(tcp_port, dlm_check_zero); 194 + static int dlm_check_zero(unsigned int x) 195 + { 196 + if (!x) 197 + return -EINVAL; 198 + 199 + return 0; 200 + } 201 + 202 + static int dlm_check_buffer_size(unsigned int x) 203 + { 204 + if (x < DEFAULT_BUFFER_SIZE) 205 + return -EINVAL; 206 + 207 + return 0; 208 + } 209 + 210 + CLUSTER_ATTR(tcp_port, dlm_check_zero_and_dlm_running); 178 211 CLUSTER_ATTR(buffer_size, dlm_check_buffer_size); 179 212 CLUSTER_ATTR(rsbtbl_size, dlm_check_zero); 180 213 CLUSTER_ATTR(recover_timer, dlm_check_zero); ··· 218 179 CLUSTER_ATTR(scan_secs, dlm_check_zero); 219 180 CLUSTER_ATTR(log_debug, NULL); 220 181 CLUSTER_ATTR(log_info, NULL); 221 - CLUSTER_ATTR(protocol, NULL); 182 + CLUSTER_ATTR(protocol, dlm_check_protocol_and_dlm_running); 222 183 CLUSTER_ATTR(mark, NULL); 223 184 CLUSTER_ATTR(timewarn_cs, dlm_check_zero); 224 185 CLUSTER_ATTR(waitwarn_us, NULL); ··· 727 688 static ssize_t comm_mark_store(struct config_item *item, const char *buf, 728 689 size_t len) 729 690 { 691 + struct dlm_comm *comm; 730 692 unsigned int mark; 731 693 int rc; 732 694 ··· 735 695 if (rc) 736 696 return rc; 737 697 738 - config_item_to_comm(item)->mark = mark; 698 + if (mark == 0) 699 + mark = dlm_config.ci_mark; 700 + 701 + comm = config_item_to_comm(item); 702 + rc = dlm_lowcomms_nodes_set_mark(comm->nodeid, mark); 703 + if (rc) 704 + return rc; 705 + 706 + comm->mark = mark; 739 707 return len; 740 708 } 741 709 ··· 916 868 *seq = cm->seq; 917 869 put_comm(cm); 918 870 return 0; 919 - } 920 - 921 - void dlm_comm_mark(int nodeid, unsigned int *mark) 922 - { 923 - struct dlm_comm *cm; 924 - 925 - cm = get_comm(nodeid); 926 - if (!cm) { 927 - *mark = dlm_config.ci_mark; 928 - return; 929 - } 930 - 931 - if (cm->mark) 932 - *mark = cm->mark; 933 - else 934 - *mark = dlm_config.ci_mark; 935 - 936 - put_comm(cm); 937 871 } 938 872 939 873 int dlm_our_nodeid(void)
-1
fs/dlm/config.h
··· 48 48 int dlm_config_nodes(char *lsname, struct dlm_config_node **nodes_out, 49 49 int *count_out); 50 50 int dlm_comm_seq(int nodeid, uint32_t *seq); 51 - void dlm_comm_mark(int nodeid, unsigned int *mark); 52 51 int dlm_our_nodeid(void); 53 52 int dlm_our_addr(struct sockaddr_storage *addr, int num); 54 53
+1
fs/dlm/debug_fs.c
··· 542 542 543 543 if (bucket >= ls->ls_rsbtbl_size) { 544 544 kfree(ri); 545 + ++*pos; 545 546 return NULL; 546 547 } 547 548 tree = toss ? &ls->ls_rsbtbl[bucket].toss : &ls->ls_rsbtbl[bucket].keep;
-2
fs/dlm/lock.c
··· 3541 3541 if (!mh) 3542 3542 return -ENOBUFS; 3543 3543 3544 - memset(mb, 0, mb_len); 3545 - 3546 3544 ms = (struct dlm_message *) mb; 3547 3545 3548 3546 ms->m_header.h_version = (DLM_HEADER_MAJOR | DLM_HEADER_MINOR);
+11 -9
fs/dlm/lockspace.c
··· 404 404 return error; 405 405 } 406 406 407 - static void threads_stop(void) 408 - { 409 - dlm_scand_stop(); 410 - dlm_lowcomms_stop(); 411 - } 412 - 413 407 static int new_lockspace(const char *name, const char *cluster, 414 408 uint32_t flags, int lvblen, 415 409 const struct dlm_lockspace_ops *ops, void *ops_arg, ··· 696 702 ls_count++; 697 703 if (error > 0) 698 704 error = 0; 699 - if (!ls_count) 700 - threads_stop(); 705 + if (!ls_count) { 706 + dlm_scand_stop(); 707 + dlm_lowcomms_shutdown(); 708 + dlm_lowcomms_stop(); 709 + } 701 710 out: 702 711 mutex_unlock(&ls_lock); 703 712 return error; ··· 784 787 do_uevent(ls, 0); 785 788 786 789 dlm_recoverd_stop(ls); 790 + 791 + if (ls_count == 1) { 792 + dlm_scand_stop(); 793 + dlm_lowcomms_shutdown(); 794 + } 787 795 788 796 dlm_callback_stop(ls); 789 797 ··· 882 880 if (!error) 883 881 ls_count--; 884 882 if (!ls_count) 885 - threads_stop(); 883 + dlm_lowcomms_stop(); 886 884 mutex_unlock(&ls_lock); 887 885 888 886 return error;
+111 -83
fs/dlm/lowcomms.c
··· 102 102 struct work_struct rwork; 103 103 }; 104 104 105 + #define DLM_WQ_REMAIN_BYTES(e) (PAGE_SIZE - e->end) 106 + #define DLM_WQ_LENGTH_BYTES(e) (e->end - e->offset) 107 + 105 108 /* An entry waiting to be sent */ 106 109 struct writequeue_entry { 107 110 struct list_head list; ··· 119 116 struct dlm_node_addr { 120 117 struct list_head list; 121 118 int nodeid; 119 + int mark; 122 120 int addr_count; 123 121 int curr_addr_index; 124 122 struct sockaddr_storage *addr[DLM_MAX_ADDR_COUNT]; ··· 138 134 static struct listen_connection listen_con; 139 135 static struct sockaddr_storage *dlm_local_addr[DLM_MAX_ADDR_COUNT]; 140 136 static int dlm_local_count; 141 - static int dlm_allow_conn; 137 + int dlm_allow_conn; 142 138 143 139 /* Work queues */ 144 140 static struct workqueue_struct *recv_workqueue; ··· 307 303 } 308 304 309 305 static int nodeid_to_addr(int nodeid, struct sockaddr_storage *sas_out, 310 - struct sockaddr *sa_out, bool try_new_addr) 306 + struct sockaddr *sa_out, bool try_new_addr, 307 + unsigned int *mark) 311 308 { 312 309 struct sockaddr_storage sas; 313 310 struct dlm_node_addr *na; ··· 336 331 if (!na->addr_count) 337 332 return -ENOENT; 338 333 334 + *mark = na->mark; 335 + 339 336 if (sas_out) 340 337 memcpy(sas_out, &sas, sizeof(struct sockaddr_storage)); 341 338 ··· 357 350 return 0; 358 351 } 359 352 360 - static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid) 353 + static int addr_to_nodeid(struct sockaddr_storage *addr, int *nodeid, 354 + unsigned int *mark) 361 355 { 362 356 struct dlm_node_addr *na; 363 357 int rv = -EEXIST; ··· 372 364 for (addr_i = 0; addr_i < na->addr_count; addr_i++) { 373 365 if (addr_compare(na->addr[addr_i], addr)) { 374 366 *nodeid = na->nodeid; 367 + *mark = na->mark; 375 368 rv = 0; 376 369 goto unlock; 377 370 } ··· 421 412 new_node->nodeid = nodeid; 422 413 new_node->addr[0] = new_addr; 423 414 new_node->addr_count = 1; 415 + new_node->mark = dlm_config.ci_mark; 424 416 list_add(&new_node->list, &dlm_node_addrs); 425 417 spin_unlock(&dlm_node_addrs_spin); 426 418 return 0; ··· 526 516 if (!con) 527 517 return -ENOMEM; 528 518 lowcomms_connect_sock(con); 519 + return 0; 520 + } 521 + 522 + int dlm_lowcomms_nodes_set_mark(int nodeid, unsigned int mark) 523 + { 524 + struct dlm_node_addr *na; 525 + 526 + spin_lock(&dlm_node_addrs_spin); 527 + na = find_node_addr(nodeid); 528 + if (!na) { 529 + spin_unlock(&dlm_node_addrs_spin); 530 + return -ENOENT; 531 + } 532 + 533 + na->mark = mark; 534 + spin_unlock(&dlm_node_addrs_spin); 535 + 529 536 return 0; 530 537 } 531 538 ··· 712 685 { 713 686 int ret; 714 687 715 - if (cancel_work_sync(&con->swork)) { 716 - log_print("canceled swork for node %d", con->nodeid); 717 - clear_bit(CF_WRITE_PENDING, &con->flags); 718 - } 688 + flush_work(&con->swork); 719 689 720 690 mutex_lock(&con->sock_mutex); 721 691 /* nothing to shutdown */ ··· 891 867 892 868 /* Get the new node's NODEID */ 893 869 make_sockaddr(&peeraddr, 0, &len); 894 - if (addr_to_nodeid(&peeraddr, &nodeid)) { 870 + if (addr_to_nodeid(&peeraddr, &nodeid, &mark)) { 895 871 unsigned char *b=(unsigned char *)&peeraddr; 896 872 log_print("connect from non cluster node"); 897 873 print_hex_dump_bytes("ss: ", DUMP_PREFIX_NONE, ··· 899 875 sock_release(newsock); 900 876 return -1; 901 877 } 902 - 903 - dlm_comm_mark(nodeid, &mark); 904 - sock_set_mark(newsock->sk, mark); 905 878 906 879 log_print("got connection from %d", nodeid); 907 880 ··· 912 891 result = -ENOMEM; 913 892 goto accept_err; 914 893 } 894 + 895 + sock_set_mark(newsock->sk, mark); 915 896 916 897 mutex_lock(&newcon->sock_mutex); 917 898 if (newcon->sock) { ··· 931 908 result = dlm_con_init(othercon, nodeid); 932 909 if (result < 0) { 933 910 kfree(othercon); 911 + mutex_unlock(&newcon->sock_mutex); 934 912 goto accept_err; 935 913 } 936 914 915 + lockdep_set_subclass(&othercon->sock_mutex, 1); 937 916 newcon->othercon = othercon; 938 917 } else { 939 918 /* close other sock con if we have something new */ 940 919 close_connection(othercon, false, true, false); 941 920 } 942 921 943 - mutex_lock_nested(&othercon->sock_mutex, 1); 922 + mutex_lock(&othercon->sock_mutex); 944 923 add_sock(newsock, othercon); 945 924 addcon = othercon; 946 925 mutex_unlock(&othercon->sock_mutex); ··· 955 930 addcon = newcon; 956 931 } 957 932 933 + set_bit(CF_CONNECTED, &addcon->flags); 958 934 mutex_unlock(&newcon->sock_mutex); 959 935 960 936 /* ··· 1041 1015 struct socket *sock; 1042 1016 unsigned int mark; 1043 1017 1044 - dlm_comm_mark(con->nodeid, &mark); 1045 - 1046 1018 mutex_lock(&con->sock_mutex); 1047 1019 1048 1020 /* Some odd races can cause double-connects, ignore them */ ··· 1053 1029 } 1054 1030 1055 1031 memset(&daddr, 0, sizeof(daddr)); 1056 - result = nodeid_to_addr(con->nodeid, &daddr, NULL, true); 1032 + result = nodeid_to_addr(con->nodeid, &daddr, NULL, true, &mark); 1057 1033 if (result < 0) { 1058 1034 log_print("no address for nodeid %d", con->nodeid); 1059 1035 goto out; ··· 1128 1104 static void tcp_connect_to_sock(struct connection *con) 1129 1105 { 1130 1106 struct sockaddr_storage saddr, src_addr; 1107 + unsigned int mark; 1131 1108 int addr_len; 1132 1109 struct socket *sock = NULL; 1133 - unsigned int mark; 1134 1110 int result; 1135 - 1136 - dlm_comm_mark(con->nodeid, &mark); 1137 1111 1138 1112 mutex_lock(&con->sock_mutex); 1139 1113 if (con->retries++ > MAX_CONNECT_RETRIES) ··· 1147 1125 if (result < 0) 1148 1126 goto out_err; 1149 1127 1150 - sock_set_mark(sock->sk, mark); 1151 - 1152 1128 memset(&saddr, 0, sizeof(saddr)); 1153 - result = nodeid_to_addr(con->nodeid, &saddr, NULL, false); 1129 + result = nodeid_to_addr(con->nodeid, &saddr, NULL, false, &mark); 1154 1130 if (result < 0) { 1155 1131 log_print("no address for nodeid %d", con->nodeid); 1156 1132 goto out_err; 1157 1133 } 1134 + 1135 + sock_set_mark(sock->sk, mark); 1158 1136 1159 1137 add_sock(sock, con); 1160 1138 ··· 1352 1330 { 1353 1331 struct writequeue_entry *entry; 1354 1332 1355 - entry = kmalloc(sizeof(struct writequeue_entry), allocation); 1333 + entry = kzalloc(sizeof(*entry), allocation); 1356 1334 if (!entry) 1357 1335 return NULL; 1358 1336 1359 - entry->page = alloc_page(allocation); 1337 + entry->page = alloc_page(allocation | __GFP_ZERO); 1360 1338 if (!entry->page) { 1361 1339 kfree(entry); 1362 1340 return NULL; 1363 1341 } 1364 1342 1365 - entry->offset = 0; 1366 - entry->len = 0; 1367 - entry->end = 0; 1368 - entry->users = 0; 1369 1343 entry->con = con; 1344 + entry->users = 1; 1370 1345 1371 1346 return entry; 1372 1347 } 1373 1348 1349 + static struct writequeue_entry *new_wq_entry(struct connection *con, int len, 1350 + gfp_t allocation, char **ppc) 1351 + { 1352 + struct writequeue_entry *e; 1353 + 1354 + spin_lock(&con->writequeue_lock); 1355 + if (!list_empty(&con->writequeue)) { 1356 + e = list_last_entry(&con->writequeue, struct writequeue_entry, list); 1357 + if (DLM_WQ_REMAIN_BYTES(e) >= len) { 1358 + *ppc = page_address(e->page) + e->end; 1359 + e->end += len; 1360 + e->users++; 1361 + spin_unlock(&con->writequeue_lock); 1362 + 1363 + return e; 1364 + } 1365 + } 1366 + spin_unlock(&con->writequeue_lock); 1367 + 1368 + e = new_writequeue_entry(con, allocation); 1369 + if (!e) 1370 + return NULL; 1371 + 1372 + *ppc = page_address(e->page); 1373 + e->end += len; 1374 + 1375 + spin_lock(&con->writequeue_lock); 1376 + list_add_tail(&e->list, &con->writequeue); 1377 + spin_unlock(&con->writequeue_lock); 1378 + 1379 + return e; 1380 + }; 1381 + 1374 1382 void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc) 1375 1383 { 1376 1384 struct connection *con; 1377 - struct writequeue_entry *e; 1378 - int offset = 0; 1379 1385 1380 - if (len > LOWCOMMS_MAX_TX_BUFFER_LEN) { 1381 - BUILD_BUG_ON(PAGE_SIZE < LOWCOMMS_MAX_TX_BUFFER_LEN); 1386 + if (len > DEFAULT_BUFFER_SIZE || 1387 + len < sizeof(struct dlm_header)) { 1388 + BUILD_BUG_ON(PAGE_SIZE < DEFAULT_BUFFER_SIZE); 1382 1389 log_print("failed to allocate a buffer of size %d", len); 1390 + WARN_ON(1); 1383 1391 return NULL; 1384 1392 } 1385 1393 ··· 1417 1365 if (!con) 1418 1366 return NULL; 1419 1367 1420 - spin_lock(&con->writequeue_lock); 1421 - e = list_entry(con->writequeue.prev, struct writequeue_entry, list); 1422 - if ((&e->list == &con->writequeue) || 1423 - (PAGE_SIZE - e->end < len)) { 1424 - e = NULL; 1425 - } else { 1426 - offset = e->end; 1427 - e->end += len; 1428 - e->users++; 1429 - } 1430 - spin_unlock(&con->writequeue_lock); 1431 - 1432 - if (e) { 1433 - got_one: 1434 - *ppc = page_address(e->page) + offset; 1435 - return e; 1436 - } 1437 - 1438 - e = new_writequeue_entry(con, allocation); 1439 - if (e) { 1440 - spin_lock(&con->writequeue_lock); 1441 - offset = e->end; 1442 - e->end += len; 1443 - e->users++; 1444 - list_add_tail(&e->list, &con->writequeue); 1445 - spin_unlock(&con->writequeue_lock); 1446 - goto got_one; 1447 - } 1448 - return NULL; 1368 + return new_wq_entry(con, len, allocation, ppc); 1449 1369 } 1450 1370 1451 1371 void dlm_lowcomms_commit_buffer(void *mh) ··· 1430 1406 users = --e->users; 1431 1407 if (users) 1432 1408 goto out; 1433 - e->len = e->end - e->offset; 1409 + 1410 + e->len = DLM_WQ_LENGTH_BYTES(e); 1434 1411 spin_unlock(&con->writequeue_lock); 1435 1412 1436 1413 queue_work(send_workqueue, &con->swork); ··· 1457 1432 1458 1433 spin_lock(&con->writequeue_lock); 1459 1434 for (;;) { 1460 - e = list_entry(con->writequeue.next, struct writequeue_entry, 1461 - list); 1462 - if ((struct list_head *) e == &con->writequeue) 1435 + if (list_empty(&con->writequeue)) 1463 1436 break; 1464 1437 1438 + e = list_first_entry(&con->writequeue, struct writequeue_entry, list); 1465 1439 len = e->len; 1466 1440 offset = e->offset; 1467 1441 BUG_ON(len == 0 && e->users == 0); ··· 1613 1589 return 0; 1614 1590 } 1615 1591 1592 + static void shutdown_conn(struct connection *con) 1593 + { 1594 + if (con->shutdown_action) 1595 + con->shutdown_action(con); 1596 + } 1597 + 1598 + void dlm_lowcomms_shutdown(void) 1599 + { 1600 + /* Set all the flags to prevent any 1601 + * socket activity. 1602 + */ 1603 + dlm_allow_conn = 0; 1604 + 1605 + if (recv_workqueue) 1606 + flush_workqueue(recv_workqueue); 1607 + if (send_workqueue) 1608 + flush_workqueue(send_workqueue); 1609 + 1610 + dlm_close_sock(&listen_con.sock); 1611 + 1612 + foreach_conn(shutdown_conn); 1613 + } 1614 + 1616 1615 static void _stop_conn(struct connection *con, bool and_other) 1617 1616 { 1618 1617 mutex_lock(&con->sock_mutex); ··· 1655 1608 static void stop_conn(struct connection *con) 1656 1609 { 1657 1610 _stop_conn(con, true); 1658 - } 1659 - 1660 - static void shutdown_conn(struct connection *con) 1661 - { 1662 - if (con->shutdown_action) 1663 - con->shutdown_action(con); 1664 1611 } 1665 1612 1666 1613 static void connection_release(struct rcu_head *rcu) ··· 1713 1672 1714 1673 void dlm_lowcomms_stop(void) 1715 1674 { 1716 - /* Set all the flags to prevent any 1717 - socket activity. 1718 - */ 1719 - dlm_allow_conn = 0; 1720 - 1721 - if (recv_workqueue) 1722 - flush_workqueue(recv_workqueue); 1723 - if (send_workqueue) 1724 - flush_workqueue(send_workqueue); 1725 - 1726 - dlm_close_sock(&listen_con.sock); 1727 - 1728 - foreach_conn(shutdown_conn); 1729 1675 work_flush(); 1730 1676 foreach_conn(free_conn); 1731 1677 work_stop();
+5
fs/dlm/lowcomms.h
··· 14 14 15 15 #define LOWCOMMS_MAX_TX_BUFFER_LEN 4096 16 16 17 + /* switch to check if dlm is running */ 18 + extern int dlm_allow_conn; 19 + 17 20 int dlm_lowcomms_start(void); 21 + void dlm_lowcomms_shutdown(void); 18 22 void dlm_lowcomms_stop(void); 19 23 void dlm_lowcomms_exit(void); 20 24 int dlm_lowcomms_close(int nodeid); 21 25 void *dlm_lowcomms_get_buffer(int nodeid, int len, gfp_t allocation, char **ppc); 22 26 void dlm_lowcomms_commit_buffer(void *mh); 23 27 int dlm_lowcomms_connect_node(int nodeid); 28 + int dlm_lowcomms_nodes_set_mark(int nodeid, unsigned int mark); 24 29 int dlm_lowcomms_addr(int nodeid, struct sockaddr_storage *addr, int len); 25 30 26 31 #endif /* __LOWCOMMS_DOT_H__ */
+16 -17
fs/dlm/midcomms.c
··· 22 22 * into packets and sends them to the comms layer. 23 23 */ 24 24 25 - #include <asm/unaligned.h> 26 - 27 25 #include "dlm_internal.h" 28 26 #include "lowcomms.h" 29 27 #include "config.h" ··· 43 45 while (len >= sizeof(struct dlm_header)) { 44 46 hd = (struct dlm_header *)ptr; 45 47 46 - /* no message should be more than this otherwise we 47 - * cannot deliver this message to upper layers 48 + /* no message should be more than DEFAULT_BUFFER_SIZE or 49 + * less than dlm_header size. 50 + * 51 + * Some messages does not have a 8 byte length boundary yet 52 + * which can occur in a unaligned memory access of some dlm 53 + * messages. However this problem need to be fixed at the 54 + * sending side, for now it seems nobody run into architecture 55 + * related issues yet but it slows down some processing. 56 + * Fixing this issue should be scheduled in future by doing 57 + * the next major version bump. 48 58 */ 49 - msglen = get_unaligned_le16(&hd->h_length); 50 - if (msglen > DEFAULT_BUFFER_SIZE) { 51 - log_print("received invalid length header: %u, will abort message parsing", 52 - msglen); 59 + msglen = le16_to_cpu(hd->h_length); 60 + if (msglen > DEFAULT_BUFFER_SIZE || 61 + msglen < sizeof(struct dlm_header)) { 62 + log_print("received invalid length header: %u from node %d, will abort message parsing", 63 + msglen, nodeid); 53 64 return -EBADMSG; 54 65 } 55 66 ··· 91 84 goto skip; 92 85 } 93 86 94 - /* for aligned memory access, we just copy current message 95 - * to begin of the buffer which contains already parsed buffer 96 - * data and should provide align access for upper layers 97 - * because the start address of the buffer has a aligned 98 - * address. This memmove can be removed when the upperlayer 99 - * is capable of unaligned memory access. 100 - */ 101 - memmove(buf, ptr, msglen); 102 - dlm_receive_buffer((union dlm_packet *)buf, nodeid); 87 + dlm_receive_buffer((union dlm_packet *)ptr, nodeid); 103 88 104 89 skip: 105 90 ret += msglen;
-2
fs/dlm/rcom.c
··· 41 41 to_nodeid, type, len); 42 42 return -ENOBUFS; 43 43 } 44 - memset(mb, 0, mb_len); 45 44 46 45 rc = (struct dlm_rcom *) mb; 47 46 ··· 461 462 mh = dlm_lowcomms_get_buffer(nodeid, mb_len, GFP_NOFS, &mb); 462 463 if (!mh) 463 464 return -ENOBUFS; 464 - memset(mb, 0, mb_len); 465 465 466 466 rc = (struct dlm_rcom *) mb; 467 467