Pull ceph updates from Ilya Dryomov: - some messenger improvements (Eric and Max) - address an issue (also affected userspace) of incorrect permissions being granted to users who have access to multiple different CephFS instances within the same cluster (Kotresh) - a bunch of assorted CephFS fixes (Slava) * tag 'ceph-for-6.18-rc1' of https://github.com/ceph/ceph-client: ceph: add bug tracking system info to MAINTAINERS ceph: fix multifs mds auth caps issue ceph: cleanup in ceph_alloc_readdir_reply_buffer() ceph: fix potential NULL dereference issue in ceph_fill_trace() libceph: add empty check to ceph_con_get_out_msg() libceph: pass the message pointer instead of loading con->out_msg libceph: make ceph_con_get_out_msg() return the message pointer ceph: fix potential race condition on operations with CEPH_I_ODIRECT flag ceph: refactor wake_up_bit() pattern of calling ceph: fix potential race condition in ceph_ioctl_lazyio() ceph: fix overflowed constant issue in ceph_do_objects_copy() ceph: fix wrong sizeof argument issue in register_session() ceph: add checking of wait_for_completion_killable() return value ceph: make ceph_start_io_*() killable libceph: Use HMAC-SHA256 library instead of crypto_shash
Unified · Split
| @@ -5694,6 +5694,7 @@ M: Xiubo Li <xiubli@redhat.com> · 5693 unmodified lines | |||
| 5694 | L: ceph-devel@vger.kernel.org | 5694 | L: ceph-devel@vger.kernel.org |
| 5695 | S: Supported | 5695 | S: Supported |
| 5696 | W: http://ceph.com/ | 5696 | W: http://ceph.com/ |
| 5697 | B: https://tracker.ceph.com/ | ||
| 5697 | T: git https://github.com/ceph/ceph-client.git | 5698 | T: git https://github.com/ceph/ceph-client.git |
| 5698 | F: include/linux/ceph/ | 5699 | F: include/linux/ceph/ |
| 5699 | F: include/linux/crush/ | 5700 | F: include/linux/crush/ |
| @@ -5705,6 +5706,7 @@ M: Ilya Dryomov <idryomov@gmail.com> · 5 unmodified lines | |||
| 5705 | L: ceph-devel@vger.kernel.org | 5706 | L: ceph-devel@vger.kernel.org |
| 5706 | S: Supported | 5707 | S: Supported |
| 5707 | W: http://ceph.com/ | 5708 | W: http://ceph.com/ |
| 5709 | B: https://tracker.ceph.com/ | ||
| 5708 | T: git https://github.com/ceph/ceph-client.git | 5710 | T: git https://github.com/ceph/ceph-client.git |
| 5709 | F: Documentation/filesystems/ceph.rst | 5711 | F: Documentation/filesystems/ceph.rst |
| 5710 | F: fs/ceph/ | 5712 | F: fs/ceph/ |
| @@ -21357,6 +21359,7 @@ R: Dongsheng Yang <dongsheng.yang@easystack.cn> · 15646 unmodified lines | |||
| 21357 | L: ceph-devel@vger.kernel.org | 21359 | L: ceph-devel@vger.kernel.org |
| 21358 | S: Supported | 21360 | S: Supported |
| 21359 | W: http://ceph.com/ | 21361 | W: http://ceph.com/ |
| 21362 | B: https://tracker.ceph.com/ | ||
| 21360 | T: git https://github.com/ceph/ceph-client.git | 21363 | T: git https://github.com/ceph/ceph-client.git |
| 21361 | F: Documentation/ABI/testing/sysfs-bus-rbd | 21364 | F: Documentation/ABI/testing/sysfs-bus-rbd |
| 21362 | F: drivers/block/rbd.c | 21365 | F: drivers/block/rbd.c |
| @@ -1260,8 +1260,7 @@ static void ceph_async_unlink_cb(struct ceph_mds_client *mdsc, · 1259 unmodified lines | |||
| 1260 | spin_unlock(&fsc->async_unlink_conflict_lock); | 1260 | spin_unlock(&fsc->async_unlink_conflict_lock); |
| 1261 | 1261 | ||
| 1262 | spin_lock(&dentry->d_lock); | 1262 | spin_lock(&dentry->d_lock); |
| 1263 | di->flags &= ~CEPH_DENTRY_ASYNC_UNLINK; | 1263 | clear_and_wake_up_bit(CEPH_DENTRY_ASYNC_UNLINK_BIT, &di->flags); |
| 1264 | wake_up_bit(&di->flags, CEPH_DENTRY_ASYNC_UNLINK_BIT); | ||
| 1265 | spin_unlock(&dentry->d_lock); | 1264 | spin_unlock(&dentry->d_lock); |
| 1266 | 1265 | ||
| 1267 | synchronize_rcu(); | 1266 | synchronize_rcu(); |
| @@ -579,8 +579,7 @@ static void wake_async_create_waiters(struct inode *inode, · 578 unmodified lines | |||
| 579 | 579 | ||
| 580 | spin_lock(&ci->i_ceph_lock); | 580 | spin_lock(&ci->i_ceph_lock); |
| 581 | if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) { | 581 | if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) { |
| 582 | ci->i_ceph_flags &= ~CEPH_I_ASYNC_CREATE; | 582 | clear_and_wake_up_bit(CEPH_ASYNC_CREATE_BIT, &ci->i_ceph_flags); |
| 583 | wake_up_bit(&ci->i_ceph_flags, CEPH_ASYNC_CREATE_BIT); | ||
| 584 | 583 | ||
| 585 | if (ci->i_ceph_flags & CEPH_I_ASYNC_CHECK_CAPS) { | 584 | if (ci->i_ceph_flags & CEPH_I_ASYNC_CHECK_CAPS) { |
| 586 | ci->i_ceph_flags &= ~CEPH_I_ASYNC_CHECK_CAPS; | 585 | ci->i_ceph_flags &= ~CEPH_I_ASYNC_CHECK_CAPS; |
| @@ -762,8 +761,7 @@ static int ceph_finish_async_create(struct inode *dir, struct inode *inode, · 175 unmodified lines | |||
| 762 | } | 761 | } |
| 763 | 762 | ||
| 764 | spin_lock(&dentry->d_lock); | 763 | spin_lock(&dentry->d_lock); |
| 765 | di->flags &= ~CEPH_DENTRY_ASYNC_CREATE; | 764 | clear_and_wake_up_bit(CEPH_DENTRY_ASYNC_CREATE_BIT, &di->flags); |
| 766 | wake_up_bit(&di->flags, CEPH_DENTRY_ASYNC_CREATE_BIT); | ||
| 767 | spin_unlock(&dentry->d_lock); | 765 | spin_unlock(&dentry->d_lock); |
| 768 | 766 | ||
| 769 | return ret; | 767 | return ret; |
| @@ -2121,10 +2119,10 @@ again: · 1351 unmodified lines | |||
| 2121 | if (ceph_inode_is_shutdown(inode)) | 2119 | if (ceph_inode_is_shutdown(inode)) |
| 2122 | return -ESTALE; | 2120 | return -ESTALE; |
| 2123 | 2121 | ||
| 2124 | if (direct_lock) | 2122 | ret = direct_lock ? ceph_start_io_direct(inode) : |
| 2125 | ceph_start_io_direct(inode); | 2123 | ceph_start_io_read(inode); |
| 2126 | else | 2124 | if (ret) |
| 2127 | ceph_start_io_read(inode); | 2125 | return ret; |
| 2128 | 2126 | ||
| 2129 | if (!(fi->flags & CEPH_F_SYNC) && !direct_lock) | 2127 | if (!(fi->flags & CEPH_F_SYNC) && !direct_lock) |
| 2130 | want |= CEPH_CAP_FILE_CACHE; | 2128 | want |= CEPH_CAP_FILE_CACHE; |
| @@ -2277,7 +2275,9 @@ static ssize_t ceph_splice_read(struct file *in, loff_t *ppos, · 146 unmodified lines | |||
| 2277 | (fi->flags & CEPH_F_SYNC)) | 2275 | (fi->flags & CEPH_F_SYNC)) |
| 2278 | return copy_splice_read(in, ppos, pipe, len, flags); | 2276 | return copy_splice_read(in, ppos, pipe, len, flags); |
| 2279 | 2277 | ||
| 2280 | ceph_start_io_read(inode); | 2278 | ret = ceph_start_io_read(inode); |
| 2279 | if (ret) | ||
| 2280 | return ret; | ||
| 2281 | 2281 | ||
| 2282 | want = CEPH_CAP_FILE_CACHE; | 2282 | want = CEPH_CAP_FILE_CACHE; |
| 2283 | if (fi->fmode & CEPH_FILE_MODE_LAZY) | 2283 | if (fi->fmode & CEPH_FILE_MODE_LAZY) |
| @@ -2356,10 +2356,10 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from) · 72 unmodified lines | |||
| 2356 | direct_lock = true; | 2356 | direct_lock = true; |
| 2357 | 2357 | ||
| 2358 | retry_snap: | 2358 | retry_snap: |
| 2359 | if (direct_lock) | 2359 | err = direct_lock ? ceph_start_io_direct(inode) : |
| 2360 | ceph_start_io_direct(inode); | 2360 | ceph_start_io_write(inode); |
| 2361 | else | 2361 | if (err) |
| 2362 | ceph_start_io_write(inode); | 2362 | goto out_unlocked; |
| 2363 | 2363 | ||
| 2364 | if (iocb->ki_flags & IOCB_APPEND) { | 2364 | if (iocb->ki_flags & IOCB_APPEND) { |
| 2365 | err = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false); | 2365 | err = ceph_do_getattr(inode, CEPH_STAT_CAP_SIZE, false); |
| @@ -2878,7 +2878,7 @@ static ssize_t ceph_do_objects_copy(struct ceph_inode_info *src_ci, u64 *src_off · 512 unmodified lines | |||
| 2878 | struct ceph_object_id src_oid, dst_oid; | 2878 | struct ceph_object_id src_oid, dst_oid; |
| 2879 | struct ceph_osd_client *osdc; | 2879 | struct ceph_osd_client *osdc; |
| 2880 | struct ceph_osd_request *req; | 2880 | struct ceph_osd_request *req; |
| 2881 | size_t bytes = 0; | 2881 | ssize_t bytes = 0; |
| 2882 | u64 src_objnum, src_objoff, dst_objnum, dst_objoff; | 2882 | u64 src_objnum, src_objoff, dst_objnum, dst_objoff; |
| 2883 | u32 src_objlen, dst_objlen; | 2883 | u32 src_objlen, dst_objlen; |
| 2884 | u32 object_size = src_ci->i_layout.object_size; | 2884 | u32 object_size = src_ci->i_layout.object_size; |
| @@ -2928,7 +2928,7 @@ static ssize_t ceph_do_objects_copy(struct ceph_inode_info *src_ci, u64 *src_off · 43 unmodified lines | |||
| 2928 | "OSDs don't support copy-from2; disabling copy offload\n"); | 2928 | "OSDs don't support copy-from2; disabling copy offload\n"); |
| 2929 | } | 2929 | } |
| 2930 | doutc(cl, "returned %d\n", ret); | 2930 | doutc(cl, "returned %d\n", ret); |
| 2931 | if (!bytes) | 2931 | if (bytes <= 0) |
| 2932 | bytes = ret; | 2932 | bytes = ret; |
| 2933 | goto out; | 2933 | goto out; |
| 2934 | } | 2934 | } |
| @@ -1794,6 +1794,11 @@ retry_lookup: · 1793 unmodified lines | |||
| 1794 | goto done; | 1794 | goto done; |
| 1795 | } | 1795 | } |
| 1796 | 1796 | ||
| 1797 | if (unlikely(!in)) { | ||
| 1798 | err = -EINVAL; | ||
| 1799 | goto done; | ||
| 1800 | } | ||
| 1801 | |||
| 1797 | /* attach proper inode */ | 1802 | /* attach proper inode */ |
| 1798 | if (d_really_is_negative(dn)) { | 1803 | if (d_really_is_negative(dn)) { |
| 1799 | ceph_dir_clear_ordered(dir); | 1804 | ceph_dir_clear_ordered(dir); |
| @@ -1829,6 +1834,12 @@ retry_lookup: · 29 unmodified lines | |||
| 1829 | doutc(cl, " linking snapped dir %p to dn %p\n", in, | 1834 | doutc(cl, " linking snapped dir %p to dn %p\n", in, |
| 1830 | req->r_dentry); | 1835 | req->r_dentry); |
| 1831 | ceph_dir_clear_ordered(dir); | 1836 | ceph_dir_clear_ordered(dir); |
| 1837 | |||
| 1838 | if (unlikely(!in)) { | ||
| 1839 | err = -EINVAL; | ||
| 1840 | goto done; | ||
| 1841 | } | ||
| 1842 | |||
| 1832 | ihold(in); | 1843 | ihold(in); |
| 1833 | err = splice_dentry(&req->r_dentry, in); | 1844 | err = splice_dentry(&req->r_dentry, in); |
| 1834 | if (err < 0) | 1845 | if (err < 0) |
| @@ -21,14 +21,23 @@ · 20 unmodified lines | |||
| 21 | /* Call with exclusively locked inode->i_rwsem */ | 21 | /* Call with exclusively locked inode->i_rwsem */ |
| 22 | static void ceph_block_o_direct(struct ceph_inode_info *ci, struct inode *inode) | 22 | static void ceph_block_o_direct(struct ceph_inode_info *ci, struct inode *inode) |
| 23 | { | 23 | { |
| 24 | bool is_odirect; | ||
| 25 | |||
| 24 | lockdep_assert_held_write(&inode->i_rwsem); | 26 | lockdep_assert_held_write(&inode->i_rwsem); |
| 25 | 27 | ||
| 26 | if (READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT) { | 28 | spin_lock(&ci->i_ceph_lock); |
| 27 | spin_lock(&ci->i_ceph_lock); | 29 | /* ensure that bit state is consistent */ |
| 28 | ci->i_ceph_flags &= ~CEPH_I_ODIRECT; | 30 | smp_mb__before_atomic(); |
| 29 | spin_unlock(&ci->i_ceph_lock); | 31 | is_odirect = READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT; |
| 30 | inode_dio_wait(inode); | 32 | if (is_odirect) { |
| 33 | clear_bit(CEPH_I_ODIRECT_BIT, &ci->i_ceph_flags); | ||
| 34 | /* ensure modified bit is visible */ | ||
| 35 | smp_mb__after_atomic(); | ||
| 31 | } | 36 | } |
| 37 | spin_unlock(&ci->i_ceph_lock); | ||
| 38 | |||
| 39 | if (is_odirect) | ||
| 40 | inode_dio_wait(inode); | ||
| 32 | } | 41 | } |
| 33 | 42 | ||
| 34 | /** | 43 | /** |
| @@ -47,20 +56,35 @@ static void ceph_block_o_direct(struct ceph_inode_info *ci, struct inode *inode) · 12 unmodified lines | |||
| 47 | * Note that buffered writes and truncates both take a write lock on | 56 | * Note that buffered writes and truncates both take a write lock on |
| 48 | * inode->i_rwsem, meaning that those are serialised w.r.t. the reads. | 57 | * inode->i_rwsem, meaning that those are serialised w.r.t. the reads. |
| 49 | */ | 58 | */ |
| 50 | void | 59 | int ceph_start_io_read(struct inode *inode) |
| 51 | ceph_start_io_read(struct inode *inode) | ||
| 52 | { | 60 | { |
| 53 | struct ceph_inode_info *ci = ceph_inode(inode); | 61 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 62 | bool is_odirect; | ||
| 63 | int err; | ||
| 54 | 64 | ||
| 55 | /* Be an optimist! */ | 65 | /* Be an optimist! */ |
| 56 | down_read(&inode->i_rwsem); | 66 | err = down_read_killable(&inode->i_rwsem); |
| 57 | if (!(READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT)) | 67 | if (err) |
| 58 | return; | 68 | return err; |
| 69 | |||
| 70 | spin_lock(&ci->i_ceph_lock); | ||
| 71 | /* ensure that bit state is consistent */ | ||
| 72 | smp_mb__before_atomic(); | ||
| 73 | is_odirect = READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT; | ||
| 74 | spin_unlock(&ci->i_ceph_lock); | ||
| 75 | if (!is_odirect) | ||
| 76 | return 0; | ||
| 59 | up_read(&inode->i_rwsem); | 77 | up_read(&inode->i_rwsem); |
| 78 | |||
| 60 | /* Slow path.... */ | 79 | /* Slow path.... */ |
| 61 | down_write(&inode->i_rwsem); | 80 | err = down_write_killable(&inode->i_rwsem); |
| 81 | if (err) | ||
| 82 | return err; | ||
| 83 | |||
| 62 | ceph_block_o_direct(ci, inode); | 84 | ceph_block_o_direct(ci, inode); |
| 63 | downgrade_write(&inode->i_rwsem); | 85 | downgrade_write(&inode->i_rwsem); |
| 86 | |||
| 87 | return 0; | ||
| 64 | } | 88 | } |
| 65 | 89 | ||
| 66 | /** | 90 | /** |
| @@ -83,11 +107,12 @@ ceph_end_io_read(struct inode *inode) · 16 unmodified lines | |||
| 83 | * Declare that a buffered write operation is about to start, and ensure | 107 | * Declare that a buffered write operation is about to start, and ensure |
| 84 | * that we block all direct I/O. | 108 | * that we block all direct I/O. |
| 85 | */ | 109 | */ |
| 86 | void | 110 | int ceph_start_io_write(struct inode *inode) |
| 87 | ceph_start_io_write(struct inode *inode) | ||
| 88 | { | 111 | { |
| 89 | down_write(&inode->i_rwsem); | 112 | int err = down_write_killable(&inode->i_rwsem); |
| 90 | ceph_block_o_direct(ceph_inode(inode), inode); | 113 | if (!err) |
| 114 | ceph_block_o_direct(ceph_inode(inode), inode); | ||
| 115 | return err; | ||
| 91 | } | 116 | } |
| 92 | 117 | ||
| 93 | /** | 118 | /** |
| @@ -106,12 +131,22 @@ ceph_end_io_write(struct inode *inode) · 12 unmodified lines | |||
| 106 | /* Call with exclusively locked inode->i_rwsem */ | 131 | /* Call with exclusively locked inode->i_rwsem */ |
| 107 | static void ceph_block_buffered(struct ceph_inode_info *ci, struct inode *inode) | 132 | static void ceph_block_buffered(struct ceph_inode_info *ci, struct inode *inode) |
| 108 | { | 133 | { |
| 134 | bool is_odirect; | ||
| 135 | |||
| 109 | lockdep_assert_held_write(&inode->i_rwsem); | 136 | lockdep_assert_held_write(&inode->i_rwsem); |
| 110 | 137 | ||
| 111 | if (!(READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT)) { | 138 | spin_lock(&ci->i_ceph_lock); |
| 112 | spin_lock(&ci->i_ceph_lock); | 139 | /* ensure that bit state is consistent */ |
| 113 | ci->i_ceph_flags |= CEPH_I_ODIRECT; | 140 | smp_mb__before_atomic(); |
| 114 | spin_unlock(&ci->i_ceph_lock); | 141 | is_odirect = READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT; |
| 142 | if (!is_odirect) { | ||
| 143 | set_bit(CEPH_I_ODIRECT_BIT, &ci->i_ceph_flags); | ||
| 144 | /* ensure modified bit is visible */ | ||
| 145 | smp_mb__after_atomic(); | ||
| 146 | } | ||
| 147 | spin_unlock(&ci->i_ceph_lock); | ||
| 148 | |||
| 149 | if (!is_odirect) { | ||
| 115 | /* FIXME: unmap_mapping_range? */ | 150 | /* FIXME: unmap_mapping_range? */ |
| 116 | filemap_write_and_wait(inode->i_mapping); | 151 | filemap_write_and_wait(inode->i_mapping); |
| 117 | } | 152 | } |
| @@ -133,20 +168,35 @@ static void ceph_block_buffered(struct ceph_inode_info *ci, struct inode *inode) · 15 unmodified lines | |||
| 133 | * Note that buffered writes and truncates both take a write lock on | 168 | * Note that buffered writes and truncates both take a write lock on |
| 134 | * inode->i_rwsem, meaning that those are serialised w.r.t. O_DIRECT. | 169 | * inode->i_rwsem, meaning that those are serialised w.r.t. O_DIRECT. |
| 135 | */ | 170 | */ |
| 136 | void | 171 | int ceph_start_io_direct(struct inode *inode) |
| 137 | ceph_start_io_direct(struct inode *inode) | ||
| 138 | { | 172 | { |
| 139 | struct ceph_inode_info *ci = ceph_inode(inode); | 173 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 174 | bool is_odirect; | ||
| 175 | int err; | ||
| 140 | 176 | ||
| 141 | /* Be an optimist! */ | 177 | /* Be an optimist! */ |
| 142 | down_read(&inode->i_rwsem); | 178 | err = down_read_killable(&inode->i_rwsem); |
| 143 | if (READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT) | 179 | if (err) |
| 144 | return; | 180 | return err; |
| 181 | |||
| 182 | spin_lock(&ci->i_ceph_lock); | ||
| 183 | /* ensure that bit state is consistent */ | ||
| 184 | smp_mb__before_atomic(); | ||
| 185 | is_odirect = READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT; | ||
| 186 | spin_unlock(&ci->i_ceph_lock); | ||
| 187 | if (is_odirect) | ||
| 188 | return 0; | ||
| 145 | up_read(&inode->i_rwsem); | 189 | up_read(&inode->i_rwsem); |
| 190 | |||
| 146 | /* Slow path.... */ | 191 | /* Slow path.... */ |
| 147 | down_write(&inode->i_rwsem); | 192 | err = down_write_killable(&inode->i_rwsem); |
| 193 | if (err) | ||
| 194 | return err; | ||
| 195 | |||
| 148 | ceph_block_buffered(ci, inode); | 196 | ceph_block_buffered(ci, inode); |
| 149 | downgrade_write(&inode->i_rwsem); | 197 | downgrade_write(&inode->i_rwsem); |
| 198 | |||
| 199 | return 0; | ||
| 150 | } | 200 | } |
| 151 | 201 | ||
| 152 | /** | 202 | /** |
| @@ -2,11 +2,13 @@ · 1 unmodified line | |||
| 2 | #ifndef _FS_CEPH_IO_H | 2 | #ifndef _FS_CEPH_IO_H |
| 3 | #define _FS_CEPH_IO_H | 3 | #define _FS_CEPH_IO_H |
| 4 | 4 | ||
| 5 | void ceph_start_io_read(struct inode *inode); | 5 | #include <linux/compiler_attributes.h> |
| 6 | |||
| 7 | int __must_check ceph_start_io_read(struct inode *inode); | ||
| 6 | void ceph_end_io_read(struct inode *inode); | 8 | void ceph_end_io_read(struct inode *inode); |
| 7 | void ceph_start_io_write(struct inode *inode); | 9 | int __must_check ceph_start_io_write(struct inode *inode); |
| 8 | void ceph_end_io_write(struct inode *inode); | 10 | void ceph_end_io_write(struct inode *inode); |
| 9 | void ceph_start_io_direct(struct inode *inode); | 11 | int __must_check ceph_start_io_direct(struct inode *inode); |
| 10 | void ceph_end_io_direct(struct inode *inode); | 12 | void ceph_end_io_direct(struct inode *inode); |
| 11 | 13 | ||
| 12 | #endif /* FS_CEPH_IO_H */ | 14 | #endif /* FS_CEPH_IO_H */ |
| @@ -246,21 +246,28 @@ static long ceph_ioctl_lazyio(struct file *file) · 245 unmodified lines | |||
| 246 | struct ceph_inode_info *ci = ceph_inode(inode); | 246 | struct ceph_inode_info *ci = ceph_inode(inode); |
| 247 | struct ceph_mds_client *mdsc = ceph_inode_to_fs_client(inode)->mdsc; | 247 | struct ceph_mds_client *mdsc = ceph_inode_to_fs_client(inode)->mdsc; |
| 248 | struct ceph_client *cl = mdsc->fsc->client; | 248 | struct ceph_client *cl = mdsc->fsc->client; |
| 249 | bool is_file_already_lazy = false; | ||
| 249 | 250 | ||
| 251 | spin_lock(&ci->i_ceph_lock); | ||
| 250 | if ((fi->fmode & CEPH_FILE_MODE_LAZY) == 0) { | 252 | if ((fi->fmode & CEPH_FILE_MODE_LAZY) == 0) { |
| 251 | spin_lock(&ci->i_ceph_lock); | ||
| 252 | fi->fmode |= CEPH_FILE_MODE_LAZY; | 253 | fi->fmode |= CEPH_FILE_MODE_LAZY; |
| 253 | ci->i_nr_by_mode[ffs(CEPH_FILE_MODE_LAZY)]++; | 254 | ci->i_nr_by_mode[ffs(CEPH_FILE_MODE_LAZY)]++; |
| 254 | __ceph_touch_fmode(ci, mdsc, fi->fmode); | 255 | __ceph_touch_fmode(ci, mdsc, fi->fmode); |
| 255 | spin_unlock(&ci->i_ceph_lock); | 256 | } else { |
| 257 | is_file_already_lazy = true; | ||
| 258 | } | ||
| 259 | spin_unlock(&ci->i_ceph_lock); | ||
| 260 | |||
| 261 | if (is_file_already_lazy) { | ||
| 262 | doutc(cl, "file %p %p %llx.%llx already lazy\n", file, inode, | ||
| 263 | ceph_vinop(inode)); | ||
| 264 | } else { | ||
| 256 | doutc(cl, "file %p %p %llx.%llx marked lazy\n", file, inode, | 265 | doutc(cl, "file %p %p %llx.%llx marked lazy\n", file, inode, |
| 257 | ceph_vinop(inode)); | 266 | ceph_vinop(inode)); |
| 258 | 267 | ||
| 259 | ceph_check_caps(ci, 0); | 268 | ceph_check_caps(ci, 0); |
| 260 | } else { | ||
| 261 | doutc(cl, "file %p %p %llx.%llx already lazy\n", file, inode, | ||
| 262 | ceph_vinop(inode)); | ||
| 263 | } | 269 | } |
| 270 | |||
| 264 | return 0; | 271 | return 0; |
| 265 | } | 272 | } |
| 266 | 273 | ||
| @@ -221,7 +221,10 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc, · 220 unmodified lines | |||
| 221 | if (err && err != -ERESTARTSYS) | 221 | if (err && err != -ERESTARTSYS) |
| 222 | return err; | 222 | return err; |
| 223 | 223 | ||
| 224 | wait_for_completion_killable(&req->r_safe_completion); | 224 | err = wait_for_completion_killable(&req->r_safe_completion); |
| 225 | if (err) | ||
| 226 | return err; | ||
| 227 | |||
| 225 | return 0; | 228 | return 0; |
| 226 | } | 229 | } |
| 227 | 230 | ||
| @@ -979,14 +979,15 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, · 978 unmodified lines | |||
| 979 | if (mds >= mdsc->max_sessions) { | 979 | if (mds >= mdsc->max_sessions) { |
| 980 | int newmax = 1 << get_count_order(mds + 1); | 980 | int newmax = 1 << get_count_order(mds + 1); |
| 981 | struct ceph_mds_session **sa; | 981 | struct ceph_mds_session **sa; |
| 982 | size_t ptr_size = sizeof(struct ceph_mds_session *); | ||
| 982 | 983 | ||
| 983 | doutc(cl, "realloc to %d\n", newmax); | 984 | doutc(cl, "realloc to %d\n", newmax); |
| 984 | sa = kcalloc(newmax, sizeof(void *), GFP_NOFS); | 985 | sa = kcalloc(newmax, ptr_size, GFP_NOFS); |
| 985 | if (!sa) | 986 | if (!sa) |
| 986 | goto fail_realloc; | 987 | goto fail_realloc; |
| 987 | if (mdsc->sessions) { | 988 | if (mdsc->sessions) { |
| 988 | memcpy(sa, mdsc->sessions, | 989 | memcpy(sa, mdsc->sessions, |
| 989 | mdsc->max_sessions * sizeof(void *)); | 990 | mdsc->max_sessions * ptr_size); |
| 990 | kfree(mdsc->sessions); | 991 | kfree(mdsc->sessions); |
| 991 | } | 992 | } |
| 992 | mdsc->sessions = sa; | 993 | mdsc->sessions = sa; |
| @@ -2532,6 +2533,7 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req, · 1539 unmodified lines | |||
| 2532 | struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options; | 2533 | struct ceph_mount_options *opt = req->r_mdsc->fsc->mount_options; |
| 2533 | size_t size = sizeof(struct ceph_mds_reply_dir_entry); | 2534 | size_t size = sizeof(struct ceph_mds_reply_dir_entry); |
| 2534 | unsigned int num_entries; | 2535 | unsigned int num_entries; |
| 2536 | u64 bytes_count; | ||
| 2535 | int order; | 2537 | int order; |
| 2536 | 2538 | ||
| 2537 | spin_lock(&ci->i_ceph_lock); | 2539 | spin_lock(&ci->i_ceph_lock); |
| @@ -2540,7 +2542,11 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req, · 2 unmodified lines | |||
| 2540 | num_entries = max(num_entries, 1U); | 2542 | num_entries = max(num_entries, 1U); |
| 2541 | num_entries = min(num_entries, opt->max_readdir); | 2543 | num_entries = min(num_entries, opt->max_readdir); |
| 2542 | 2544 | ||
| 2543 | order = get_order(size * num_entries); | 2545 | bytes_count = (u64)size * num_entries; |
| 2546 | if (unlikely(bytes_count > ULONG_MAX)) | ||
| 2547 | bytes_count = ULONG_MAX; | ||
| 2548 | |||
| 2549 | order = get_order((unsigned long)bytes_count); | ||
| 2544 | while (order >= 0) { | 2550 | while (order >= 0) { |
| 2545 | rinfo->dir_entries = (void*)__get_free_pages(GFP_KERNEL | | 2551 | rinfo->dir_entries = (void*)__get_free_pages(GFP_KERNEL | |
| 2546 | __GFP_NOWARN | | 2552 | __GFP_NOWARN | |
| @@ -2550,7 +2556,7 @@ int ceph_alloc_readdir_reply_buffer(struct ceph_mds_request *req, · 3 unmodified lines | |||
| 2550 | break; | 2556 | break; |
| 2551 | order--; | 2557 | order--; |
| 2552 | } | 2558 | } |
| 2553 | if (!rinfo->dir_entries) | 2559 | if (!rinfo->dir_entries || unlikely(order < 0)) |
| 2554 | return -ENOMEM; | 2560 | return -ENOMEM; |
| 2555 | 2561 | ||
| 2556 | num_entries = (PAGE_SIZE << order) / size; | 2562 | num_entries = (PAGE_SIZE << order) / size; |
| @@ -5649,11 +5655,19 @@ static int ceph_mds_auth_match(struct ceph_mds_client *mdsc, · 3092 unmodified lines | |||
| 5649 | u32 caller_uid = from_kuid(&init_user_ns, cred->fsuid); | 5655 | u32 caller_uid = from_kuid(&init_user_ns, cred->fsuid); |
| 5650 | u32 caller_gid = from_kgid(&init_user_ns, cred->fsgid); | 5656 | u32 caller_gid = from_kgid(&init_user_ns, cred->fsgid); |
| 5651 | struct ceph_client *cl = mdsc->fsc->client; | 5657 | struct ceph_client *cl = mdsc->fsc->client; |
| 5658 | const char *fs_name = mdsc->fsc->mount_options->mds_namespace; | ||
| 5652 | const char *spath = mdsc->fsc->mount_options->server_path; | 5659 | const char *spath = mdsc->fsc->mount_options->server_path; |
| 5653 | bool gid_matched = false; | 5660 | bool gid_matched = false; |
| 5654 | u32 gid, tlen, len; | 5661 | u32 gid, tlen, len; |
| 5655 | int i, j; | 5662 | int i, j; |
| 5656 | 5663 | ||
| 5664 | doutc(cl, "fsname check fs_name=%s match.fs_name=%s\n", | ||
| 5665 | fs_name, auth->match.fs_name ? auth->match.fs_name : ""); | ||
| 5666 | if (auth->match.fs_name && strcmp(auth->match.fs_name, fs_name)) { | ||
| 5667 | /* fsname mismatch, try next one */ | ||
| 5668 | return 0; | ||
| 5669 | } | ||
| 5670 | |||
| 5657 | doutc(cl, "match.uid %lld\n", auth->match.uid); | 5671 | doutc(cl, "match.uid %lld\n", auth->match.uid); |
| 5658 | if (auth->match.uid != MDS_AUTH_UID_ANY) { | 5672 | if (auth->match.uid != MDS_AUTH_UID_ANY) { |
| 5659 | if (auth->match.uid != caller_uid) | 5673 | if (auth->match.uid != caller_uid) |
| @@ -353,10 +353,22 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, · 352 unmodified lines | |||
| 353 | __decode_and_drop_type(p, end, u8, bad_ext); | 353 | __decode_and_drop_type(p, end, u8, bad_ext); |
| 354 | } | 354 | } |
| 355 | if (mdsmap_ev >= 8) { | 355 | if (mdsmap_ev >= 8) { |
| 356 | u32 fsname_len; | ||
| 356 | /* enabled */ | 357 | /* enabled */ |
| 357 | ceph_decode_8_safe(p, end, m->m_enabled, bad_ext); | 358 | ceph_decode_8_safe(p, end, m->m_enabled, bad_ext); |
| 358 | /* fs_name */ | 359 | /* fs_name */ |
| 359 | ceph_decode_skip_string(p, end, bad_ext); | 360 | ceph_decode_32_safe(p, end, fsname_len, bad_ext); |
| 361 | |||
| 362 | /* validate fsname against mds_namespace */ | ||
| 363 | if (!namespace_equals(mdsc->fsc->mount_options, *p, | ||
| 364 | fsname_len)) { | ||
| 365 | pr_warn_client(cl, "fsname %*pE doesn't match mds_namespace %s\n", | ||
| 366 | (int)fsname_len, (char *)*p, | ||
| 367 | mdsc->fsc->mount_options->mds_namespace); | ||
| 368 | goto bad; | ||
| 369 | } | ||
| 370 | /* skip fsname after validation */ | ||
| 371 | ceph_decode_skip_n(p, end, fsname_len, bad); | ||
| 360 | } | 372 | } |
| 361 | /* damaged */ | 373 | /* damaged */ |
| 362 | if (mdsmap_ev >= 9) { | 374 | if (mdsmap_ev >= 9) { |
| @@ -246,20 +246,6 @@ static void canonicalize_path(char *path) · 245 unmodified lines | |||
| 246 | path[j] = '\0'; | 246 | path[j] = '\0'; |
| 247 | } | 247 | } |
| 248 | 248 | ||
| 249 | /* | ||
| 250 | * Check if the mds namespace in ceph_mount_options matches | ||
| 251 | * the passed in namespace string. First time match (when | ||
| 252 | * ->mds_namespace is NULL) is treated specially, since | ||
| 253 | * ->mds_namespace needs to be initialized by the caller. | ||
| 254 | */ | ||
| 255 | static int namespace_equals(struct ceph_mount_options *fsopt, | ||
| 256 | const char *namespace, size_t len) | ||
| 257 | { | ||
| 258 | return !(fsopt->mds_namespace && | ||
| 259 | (strlen(fsopt->mds_namespace) != len || | ||
| 260 | strncmp(fsopt->mds_namespace, namespace, len))); | ||
| 261 | } | ||
| 262 | |||
| 263 | static int ceph_parse_old_source(const char *dev_name, const char *dev_name_end, | 249 | static int ceph_parse_old_source(const char *dev_name, const char *dev_name_end, |
| 264 | struct fs_context *fc) | 250 | struct fs_context *fc) |
| 265 | { | 251 | { |
| @@ -104,6 +104,20 @@ struct ceph_mount_options { · 103 unmodified lines | |||
| 104 | struct fscrypt_dummy_policy dummy_enc_policy; | 104 | struct fscrypt_dummy_policy dummy_enc_policy; |
| 105 | }; | 105 | }; |
| 106 | 106 | ||
| 107 | /* | ||
| 108 | * Check if the mds namespace in ceph_mount_options matches | ||
| 109 | * the passed in namespace string. First time match (when | ||
| 110 | * ->mds_namespace is NULL) is treated specially, since | ||
| 111 | * ->mds_namespace needs to be initialized by the caller. | ||
| 112 | */ | ||
| 113 | static inline int namespace_equals(struct ceph_mount_options *fsopt, | ||
| 114 | const char *namespace, size_t len) | ||
| 115 | { | ||
| 116 | return !(fsopt->mds_namespace && | ||
| 117 | (strlen(fsopt->mds_namespace) != len || | ||
| 118 | strncmp(fsopt->mds_namespace, namespace, len))); | ||
| 119 | } | ||
| 120 | |||
| 107 | /* mount state */ | 121 | /* mount state */ |
| 108 | enum { | 122 | enum { |
| 109 | CEPH_MOUNT_MOUNTING, | 123 | CEPH_MOUNT_MOUNTING, |
| @@ -639,7 +653,8 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, · 529 unmodified lines | |||
| 639 | #define CEPH_I_FLUSH_SNAPS (1 << 8) /* need flush snapss */ | 653 | #define CEPH_I_FLUSH_SNAPS (1 << 8) /* need flush snapss */ |
| 640 | #define CEPH_I_ERROR_WRITE (1 << 9) /* have seen write errors */ | 654 | #define CEPH_I_ERROR_WRITE (1 << 9) /* have seen write errors */ |
| 641 | #define CEPH_I_ERROR_FILELOCK (1 << 10) /* have seen file lock errors */ | 655 | #define CEPH_I_ERROR_FILELOCK (1 << 10) /* have seen file lock errors */ |
| 642 | #define CEPH_I_ODIRECT (1 << 11) /* inode in direct I/O mode */ | 656 | #define CEPH_I_ODIRECT_BIT (11) /* inode in direct I/O mode */ |
| 657 | #define CEPH_I_ODIRECT (1 << CEPH_I_ODIRECT_BIT) | ||
| 643 | #define CEPH_ASYNC_CREATE_BIT (12) /* async create in flight for this */ | 658 | #define CEPH_ASYNC_CREATE_BIT (12) /* async create in flight for this */ |
| 644 | #define CEPH_I_ASYNC_CREATE (1 << CEPH_ASYNC_CREATE_BIT) | 659 | #define CEPH_I_ASYNC_CREATE (1 << CEPH_ASYNC_CREATE_BIT) |
| 645 | #define CEPH_I_SHUTDOWN (1 << 13) /* inode is no longer usable */ | 660 | #define CEPH_I_SHUTDOWN (1 << 13) /* inode is no longer usable */ |
| @@ -2,6 +2,7 @@ · 1 unmodified line | |||
| 2 | #ifndef __FS_CEPH_MESSENGER_H | 2 | #ifndef __FS_CEPH_MESSENGER_H |
| 3 | #define __FS_CEPH_MESSENGER_H | 3 | #define __FS_CEPH_MESSENGER_H |
| 4 | 4 | ||
| 5 | #include <crypto/sha2.h> | ||
| 5 | #include <linux/bvec.h> | 6 | #include <linux/bvec.h> |
| 6 | #include <linux/crypto.h> | 7 | #include <linux/crypto.h> |
| 7 | #include <linux/kref.h> | 8 | #include <linux/kref.h> |
| @@ -412,7 +413,8 @@ struct ceph_connection_v2_info { · 404 unmodified lines | |||
| 412 | struct ceph_msg_data_cursor in_cursor; | 413 | struct ceph_msg_data_cursor in_cursor; |
| 413 | struct ceph_msg_data_cursor out_cursor; | 414 | struct ceph_msg_data_cursor out_cursor; |
| 414 | 415 | ||
| 415 | struct crypto_shash *hmac_tfm; /* post-auth signature */ | 416 | struct hmac_sha256_key hmac_key; /* post-auth signature */ |
| 417 | bool hmac_key_set; | ||
| 416 | struct crypto_aead *gcm_tfm; /* on-wire encryption */ | 418 | struct crypto_aead *gcm_tfm; /* on-wire encryption */ |
| 417 | struct aead_request *gcm_req; | 419 | struct aead_request *gcm_req; |
| 418 | struct crypto_wait gcm_wait; | 420 | struct crypto_wait gcm_wait; |
| @@ -548,12 +550,12 @@ void ceph_addr_set_port(struct ceph_entity_addr *addr, int p); · 129 unmodified lines | |||
| 548 | void ceph_con_process_message(struct ceph_connection *con); | 550 | void ceph_con_process_message(struct ceph_connection *con); |
| 549 | int ceph_con_in_msg_alloc(struct ceph_connection *con, | 551 | int ceph_con_in_msg_alloc(struct ceph_connection *con, |
| 550 | struct ceph_msg_header *hdr, int *skip); | 552 | struct ceph_msg_header *hdr, int *skip); |
| 551 | void ceph_con_get_out_msg(struct ceph_connection *con); | 553 | struct ceph_msg *ceph_con_get_out_msg(struct ceph_connection *con); |
| 552 | 554 | ||
| 553 | /* messenger_v1.c */ | 555 | /* messenger_v1.c */ |
| 554 | int ceph_con_v1_try_read(struct ceph_connection *con); | 556 | int ceph_con_v1_try_read(struct ceph_connection *con); |
| 555 | int ceph_con_v1_try_write(struct ceph_connection *con); | 557 | int ceph_con_v1_try_write(struct ceph_connection *con); |
| 556 | void ceph_con_v1_revoke(struct ceph_connection *con); | 558 | void ceph_con_v1_revoke(struct ceph_connection *con, struct ceph_msg *msg); |
| 557 | void ceph_con_v1_revoke_incoming(struct ceph_connection *con); | 559 | void ceph_con_v1_revoke_incoming(struct ceph_connection *con); |
| 558 | bool ceph_con_v1_opened(struct ceph_connection *con); | 560 | bool ceph_con_v1_opened(struct ceph_connection *con); |
| 559 | void ceph_con_v1_reset_session(struct ceph_connection *con); | 561 | void ceph_con_v1_reset_session(struct ceph_connection *con); |
| @@ -562,7 +564,7 @@ void ceph_con_v1_reset_protocol(struct ceph_connection *con); · 2 unmodified lines | |||
| 562 | /* messenger_v2.c */ | 564 | /* messenger_v2.c */ |
| 563 | int ceph_con_v2_try_read(struct ceph_connection *con); | 565 | int ceph_con_v2_try_read(struct ceph_connection *con); |
| 564 | int ceph_con_v2_try_write(struct ceph_connection *con); | 566 | int ceph_con_v2_try_write(struct ceph_connection *con); |
| 565 | void ceph_con_v2_revoke(struct ceph_connection *con); | 567 | void ceph_con_v2_revoke(struct ceph_connection *con, struct ceph_msg *msg); |
| 566 | void ceph_con_v2_revoke_incoming(struct ceph_connection *con); | 568 | void ceph_con_v2_revoke_incoming(struct ceph_connection *con); |
| 567 | bool ceph_con_v2_opened(struct ceph_connection *con); | 569 | bool ceph_con_v2_opened(struct ceph_connection *con); |
| 568 | void ceph_con_v2_reset_session(struct ceph_connection *con); | 570 | void ceph_con_v2_reset_session(struct ceph_connection *con); |
| @@ -6,8 +6,7 @@ config CEPH_LIB · 5 unmodified lines | |||
| 6 | select CRYPTO_AES | 6 | select CRYPTO_AES |
| 7 | select CRYPTO_CBC | 7 | select CRYPTO_CBC |
| 8 | select CRYPTO_GCM | 8 | select CRYPTO_GCM |
| 9 | select CRYPTO_HMAC | 9 | select CRYPTO_LIB_SHA256 |
| 10 | select CRYPTO_SHA256 | ||
| 11 | select CRYPTO | 10 | select CRYPTO |
| 12 | select KEYS | 11 | select KEYS |
| 13 | default n | 12 | default n |
| @@ -1794,9 +1794,9 @@ void ceph_msg_revoke(struct ceph_msg *msg) · 1793 unmodified lines | |||
| 1794 | WARN_ON(con->state != CEPH_CON_S_OPEN); | 1794 | WARN_ON(con->state != CEPH_CON_S_OPEN); |
| 1795 | dout("%s con %p msg %p was sending\n", __func__, con, msg); | 1795 | dout("%s con %p msg %p was sending\n", __func__, con, msg); |
| 1796 | if (ceph_msgr2(from_msgr(con->msgr))) | 1796 | if (ceph_msgr2(from_msgr(con->msgr))) |
| 1797 | ceph_con_v2_revoke(con); | 1797 | ceph_con_v2_revoke(con, msg); |
| 1798 | else | 1798 | else |
| 1799 | ceph_con_v1_revoke(con); | 1799 | ceph_con_v1_revoke(con, msg); |
| 1800 | ceph_msg_put(con->out_msg); | 1800 | ceph_msg_put(con->out_msg); |
| 1801 | con->out_msg = NULL; | 1801 | con->out_msg = NULL; |
| 1802 | } else { | 1802 | } else { |
| @@ -2111,11 +2111,13 @@ int ceph_con_in_msg_alloc(struct ceph_connection *con, · 308 unmodified lines | |||
| 2111 | return ret; | 2111 | return ret; |
| 2112 | } | 2112 | } |
| 2113 | 2113 | ||
| 2114 | void ceph_con_get_out_msg(struct ceph_connection *con) | 2114 | struct ceph_msg *ceph_con_get_out_msg(struct ceph_connection *con) |
| 2115 | { | 2115 | { |
| 2116 | struct ceph_msg *msg; | 2116 | struct ceph_msg *msg; |
| 2117 | 2117 | ||
| 2118 | BUG_ON(list_empty(&con->out_queue)); | 2118 | if (list_empty(&con->out_queue)) |
| 2119 | return NULL; | ||
| 2120 | |||
| 2119 | msg = list_first_entry(&con->out_queue, struct ceph_msg, list_head); | 2121 | msg = list_first_entry(&con->out_queue, struct ceph_msg, list_head); |
| 2120 | WARN_ON(msg->con != con); | 2122 | WARN_ON(msg->con != con); |
| 2121 | 2123 | ||
| @@ -2142,7 +2144,7 @@ void ceph_con_get_out_msg(struct ceph_connection *con) · 20 unmodified lines | |||
| 2142 | * message or in case of a fault. | 2144 | * message or in case of a fault. |
| 2143 | */ | 2145 | */ |
| 2144 | WARN_ON(con->out_msg); | 2146 | WARN_ON(con->out_msg); |
| 2145 | con->out_msg = ceph_msg_get(msg); | 2147 | return con->out_msg = ceph_msg_get(msg); |
| 2146 | } | 2148 | } |
| 2147 | 2149 | ||
| 2148 | /* | 2150 | /* |
| @@ -169,10 +169,9 @@ static void prepare_message_data(struct ceph_msg *msg, u32 data_len) · 168 unmodified lines | |||
| 169 | * Prepare footer for currently outgoing message, and finish things | 169 | * Prepare footer for currently outgoing message, and finish things |
| 170 | * off. Assumes out_kvec* are already valid.. we just add on to the end. | 170 | * off. Assumes out_kvec* are already valid.. we just add on to the end. |
| 171 | */ | 171 | */ |
| 172 | static void prepare_write_message_footer(struct ceph_connection *con) | 172 | static void prepare_write_message_footer(struct ceph_connection *con, |
| 173 | struct ceph_msg *m) | ||
| 173 | { | 174 | { |
| 174 | struct ceph_msg *m = con->out_msg; | ||
| 175 | |||
| 176 | m->footer.flags |= CEPH_MSG_FOOTER_COMPLETE; | 175 | m->footer.flags |= CEPH_MSG_FOOTER_COMPLETE; |
| 177 | 176 | ||
| 178 | dout("prepare_write_message_footer %p\n", con); | 177 | dout("prepare_write_message_footer %p\n", con); |
| @@ -192,9 +191,9 @@ static void prepare_write_message_footer(struct ceph_connection *con) · 13 unmodified lines | |||
| 192 | /* | 191 | /* |
| 193 | * Prepare headers for the next outgoing message. | 192 | * Prepare headers for the next outgoing message. |
| 194 | */ | 193 | */ |
| 195 | static void prepare_write_message(struct ceph_connection *con) | 194 | static void prepare_write_message(struct ceph_connection *con, |
| 195 | struct ceph_msg *m) | ||
| 196 | { | 196 | { |
| 197 | struct ceph_msg *m; | ||
| 198 | u32 crc; | 197 | u32 crc; |
| 199 | 198 | ||
| 200 | con_out_kvec_reset(con); | 199 | con_out_kvec_reset(con); |
| @@ -210,9 +209,6 @@ static void prepare_write_message(struct ceph_connection *con) · 9 unmodified lines | |||
| 210 | &con->v1.out_temp_ack); | 209 | &con->v1.out_temp_ack); |
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | ceph_con_get_out_msg(con); | ||
| 214 | m = con->out_msg; | ||
| 215 | |||
| 216 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%zd\n", | 212 | dout("prepare_write_message %p seq %lld type %d len %d+%d+%zd\n", |
| 217 | m, con->out_seq, le16_to_cpu(m->hdr.type), | 213 | m, con->out_seq, le16_to_cpu(m->hdr.type), |
| 218 | le32_to_cpu(m->hdr.front_len), le32_to_cpu(m->hdr.middle_len), | 214 | le32_to_cpu(m->hdr.front_len), le32_to_cpu(m->hdr.middle_len), |
| @@ -231,31 +227,31 @@ static void prepare_write_message(struct ceph_connection *con) · 12 unmodified lines | |||
| 231 | 227 | ||
| 232 | /* fill in hdr crc and finalize hdr */ | 228 | /* fill in hdr crc and finalize hdr */ |
| 233 | crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc)); | 229 | crc = crc32c(0, &m->hdr, offsetof(struct ceph_msg_header, crc)); |
| 234 | con->out_msg->hdr.crc = cpu_to_le32(crc); | 230 | m->hdr.crc = cpu_to_le32(crc); |
| 235 | memcpy(&con->v1.out_hdr, &con->out_msg->hdr, sizeof(con->v1.out_hdr)); | 231 | memcpy(&con->v1.out_hdr, &m->hdr, sizeof(con->v1.out_hdr)); |
| 236 | 232 | ||
| 237 | /* fill in front and middle crc, footer */ | 233 | /* fill in front and middle crc, footer */ |
| 238 | crc = crc32c(0, m->front.iov_base, m->front.iov_len); | 234 | crc = crc32c(0, m->front.iov_base, m->front.iov_len); |
| 239 | con->out_msg->footer.front_crc = cpu_to_le32(crc); | 235 | m->footer.front_crc = cpu_to_le32(crc); |
| 240 | if (m->middle) { | 236 | if (m->middle) { |
| 241 | crc = crc32c(0, m->middle->vec.iov_base, | 237 | crc = crc32c(0, m->middle->vec.iov_base, |
| 242 | m->middle->vec.iov_len); | 238 | m->middle->vec.iov_len); |
| 243 | con->out_msg->footer.middle_crc = cpu_to_le32(crc); | 239 | m->footer.middle_crc = cpu_to_le32(crc); |
| 244 | } else | 240 | } else |
| 245 | con->out_msg->footer.middle_crc = 0; | 241 | m->footer.middle_crc = 0; |
| 246 | dout("%s front_crc %u middle_crc %u\n", __func__, | 242 | dout("%s front_crc %u middle_crc %u\n", __func__, |
| 247 | le32_to_cpu(con->out_msg->footer.front_crc), | 243 | le32_to_cpu(m->footer.front_crc), |
| 248 | le32_to_cpu(con->out_msg->footer.middle_crc)); | 244 | le32_to_cpu(m->footer.middle_crc)); |
| 249 | con->out_msg->footer.flags = 0; | 245 | m->footer.flags = 0; |
| 250 | 246 | ||
| 251 | /* is there a data payload? */ | 247 | /* is there a data payload? */ |
| 252 | con->out_msg->footer.data_crc = 0; | 248 | m->footer.data_crc = 0; |
| 253 | if (m->data_length) { | 249 | if (m->data_length) { |
| 254 | prepare_message_data(con->out_msg, m->data_length); | 250 | prepare_message_data(m, m->data_length); |
| 255 | con->v1.out_more = 1; /* data + footer will follow */ | 251 | con->v1.out_more = 1; /* data + footer will follow */ |
| 256 | } else { | 252 | } else { |
| 257 | /* no, queue up footer too and be done */ | 253 | /* no, queue up footer too and be done */ |
| 258 | prepare_write_message_footer(con); | 254 | prepare_write_message_footer(con, m); |
| 259 | } | 255 | } |
| 260 | 256 | ||
| 261 | ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING); | 257 | ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING); |
| @@ -462,9 +458,9 @@ out: · 200 unmodified lines | |||
| 462 | * 0 -> socket full, but more to do | 458 | * 0 -> socket full, but more to do |
| 463 | * <0 -> error | 459 | * <0 -> error |
| 464 | */ | 460 | */ |
| 465 | static int write_partial_message_data(struct ceph_connection *con) | 461 | static int write_partial_message_data(struct ceph_connection *con, |
| 462 | struct ceph_msg *msg) | ||
| 466 | { | 463 | { |
| 467 | struct ceph_msg *msg = con->out_msg; | ||
| 468 | struct ceph_msg_data_cursor *cursor = &msg->cursor; | 464 | struct ceph_msg_data_cursor *cursor = &msg->cursor; |
| 469 | bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC); | 465 | bool do_datacrc = !ceph_test_opt(from_msgr(con->msgr), NOCRC); |
| 470 | u32 crc; | 466 | u32 crc; |
| @@ -516,7 +512,7 @@ static int write_partial_message_data(struct ceph_connection *con) · 45 unmodified lines | |||
| 516 | else | 512 | else |
| 517 | msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC; | 513 | msg->footer.flags |= CEPH_MSG_FOOTER_NOCRC; |
| 518 | con_out_kvec_reset(con); | 514 | con_out_kvec_reset(con); |
| 519 | prepare_write_message_footer(con); | 515 | prepare_write_message_footer(con, msg); |
| 520 | 516 | ||
| 521 | return 1; /* must return > 0 to indicate success */ | 517 | return 1; /* must return > 0 to indicate success */ |
| 522 | } | 518 | } |
| @@ -1472,6 +1468,7 @@ bad_tag: · 949 unmodified lines | |||
| 1472 | */ | 1468 | */ |
| 1473 | int ceph_con_v1_try_write(struct ceph_connection *con) | 1469 | int ceph_con_v1_try_write(struct ceph_connection *con) |
| 1474 | { | 1470 | { |
| 1471 | struct ceph_msg *msg; | ||
| 1475 | int ret = 1; | 1472 | int ret = 1; |
| 1476 | 1473 | ||
| 1477 | dout("try_write start %p state %d\n", con, con->state); | 1474 | dout("try_write start %p state %d\n", con, con->state); |
| @@ -1518,14 +1515,15 @@ more: · 40 unmodified lines | |||
| 1518 | } | 1515 | } |
| 1519 | 1516 | ||
| 1520 | /* msg pages? */ | 1517 | /* msg pages? */ |
| 1521 | if (con->out_msg) { | 1518 | msg = con->out_msg; |
| 1519 | if (msg) { | ||
| 1522 | if (con->v1.out_msg_done) { | 1520 | if (con->v1.out_msg_done) { |
| 1523 | ceph_msg_put(con->out_msg); | 1521 | ceph_msg_put(msg); |
| 1524 | con->out_msg = NULL; /* we're done with this one */ | 1522 | con->out_msg = NULL; /* we're done with this one */ |
| 1525 | goto do_next; | 1523 | goto do_next; |
| 1526 | } | 1524 | } |
| 1527 | 1525 | ||
| 1528 | ret = write_partial_message_data(con); | 1526 | ret = write_partial_message_data(con, msg); |
| 1529 | if (ret == 1) | 1527 | if (ret == 1) |
| 1530 | goto more; /* we need to send the footer, too! */ | 1528 | goto more; /* we need to send the footer, too! */ |
| 1531 | if (ret == 0) | 1529 | if (ret == 0) |
| @@ -1545,8 +1543,8 @@ do_next: · 13 unmodified lines | |||
| 1545 | goto more; | 1543 | goto more; |
| 1546 | } | 1544 | } |
| 1547 | /* is anything else pending? */ | 1545 | /* is anything else pending? */ |
| 1548 | if (!list_empty(&con->out_queue)) { | 1546 | if ((msg = ceph_con_get_out_msg(con)) != NULL) { |
| 1549 | prepare_write_message(con); | 1547 | prepare_write_message(con, msg); |
| 1550 | goto more; | 1548 | goto more; |
| 1551 | } | 1549 | } |
| 1552 | if (con->in_seq > con->in_seq_acked) { | 1550 | if (con->in_seq > con->in_seq_acked) { |
| @@ -1564,10 +1562,8 @@ out: · 11 unmodified lines | |||
| 1564 | return ret; | 1562 | return ret; |
| 1565 | } | 1563 | } |
| 1566 | 1564 | ||
| 1567 | void ceph_con_v1_revoke(struct ceph_connection *con) | 1565 | void ceph_con_v1_revoke(struct ceph_connection *con, struct ceph_msg *msg) |
| 1568 | { | 1566 | { |
| 1569 | struct ceph_msg *msg = con->out_msg; | ||
| 1570 | |||
| 1571 | WARN_ON(con->v1.out_skip); | 1567 | WARN_ON(con->v1.out_skip); |
| 1572 | /* footer */ | 1568 | /* footer */ |
| 1573 | if (con->v1.out_msg_done) { | 1569 | if (con->v1.out_msg_done) { |
| @@ -709,7 +709,7 @@ static int setup_crypto(struct ceph_connection *con, · 708 unmodified lines | |||
| 709 | 709 | ||
| 710 | dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n", | 710 | dout("%s con %p con_mode %d session_key_len %d con_secret_len %d\n", |
| 711 | __func__, con, con->v2.con_mode, session_key_len, con_secret_len); | 711 | __func__, con, con->v2.con_mode, session_key_len, con_secret_len); |
| 712 | WARN_ON(con->v2.hmac_tfm || con->v2.gcm_tfm || con->v2.gcm_req); | 712 | WARN_ON(con->v2.hmac_key_set || con->v2.gcm_tfm || con->v2.gcm_req); |
| 713 | 713 | ||
| 714 | if (con->v2.con_mode != CEPH_CON_MODE_CRC && | 714 | if (con->v2.con_mode != CEPH_CON_MODE_CRC && |
| 715 | con->v2.con_mode != CEPH_CON_MODE_SECURE) { | 715 | con->v2.con_mode != CEPH_CON_MODE_SECURE) { |
| @@ -723,22 +723,8 @@ static int setup_crypto(struct ceph_connection *con, · 7 unmodified lines | |||
| 723 | return 0; /* auth_none */ | 723 | return 0; /* auth_none */ |
| 724 | } | 724 | } |
| 725 | 725 | ||
| 726 | noio_flag = memalloc_noio_save(); | 726 | hmac_sha256_preparekey(&con->v2.hmac_key, session_key, session_key_len); |
| 727 | con->v2.hmac_tfm = crypto_alloc_shash("hmac(sha256)", 0, 0); | 727 | con->v2.hmac_key_set = true; |
| 728 | memalloc_noio_restore(noio_flag); | ||
| 729 | if (IS_ERR(con->v2.hmac_tfm)) { | ||
| 730 | ret = PTR_ERR(con->v2.hmac_tfm); | ||
| 731 | con->v2.hmac_tfm = NULL; | ||
| 732 | pr_err("failed to allocate hmac tfm context: %d\n", ret); | ||
| 733 | return ret; | ||
| 734 | } | ||
| 735 | |||
| 736 | ret = crypto_shash_setkey(con->v2.hmac_tfm, session_key, | ||
| 737 | session_key_len); | ||
| 738 | if (ret) { | ||
| 739 | pr_err("failed to set hmac key: %d\n", ret); | ||
| 740 | return ret; | ||
| 741 | } | ||
| 742 | 728 | ||
| 743 | if (con->v2.con_mode == CEPH_CON_MODE_CRC) { | 729 | if (con->v2.con_mode == CEPH_CON_MODE_CRC) { |
| 744 | WARN_ON(con_secret_len); | 730 | WARN_ON(con_secret_len); |
| @@ -793,38 +779,26 @@ static int setup_crypto(struct ceph_connection *con, · 48 unmodified lines | |||
| 793 | return 0; /* auth_x, secure mode */ | 779 | return 0; /* auth_x, secure mode */ |
| 794 | } | 780 | } |
| 795 | 781 | ||
| 796 | static int ceph_hmac_sha256(struct ceph_connection *con, | 782 | static void ceph_hmac_sha256(struct ceph_connection *con, |
| 797 | const struct kvec *kvecs, int kvec_cnt, u8 *hmac) | 783 | const struct kvec *kvecs, int kvec_cnt, |
| 784 | u8 hmac[SHA256_DIGEST_SIZE]) | ||
| 798 | { | 785 | { |
| 799 | SHASH_DESC_ON_STACK(desc, con->v2.hmac_tfm); /* tfm arg is ignored */ | 786 | struct hmac_sha256_ctx ctx; |
| 800 | int ret; | ||
| 801 | int i; | 787 | int i; |
| 802 | 788 | ||
| 803 | dout("%s con %p hmac_tfm %p kvec_cnt %d\n", __func__, con, | 789 | dout("%s con %p hmac_key_set %d kvec_cnt %d\n", __func__, con, |
| 804 | con->v2.hmac_tfm, kvec_cnt); | 790 | con->v2.hmac_key_set, kvec_cnt); |
| 805 | 791 | ||
| 806 | if (!con->v2.hmac_tfm) { | 792 | if (!con->v2.hmac_key_set) { |
| 807 | memset(hmac, 0, SHA256_DIGEST_SIZE); | 793 | memset(hmac, 0, SHA256_DIGEST_SIZE); |
| 808 | return 0; /* auth_none */ | 794 | return; /* auth_none */ |
| 809 | } | 795 | } |
| 810 | 796 | ||
| 811 | desc->tfm = con->v2.hmac_tfm; | 797 | /* auth_x, both plain and secure modes */ |
| 812 | ret = crypto_shash_init(desc); | 798 | hmac_sha256_init(&ctx, &con->v2.hmac_key); |
| 813 | if (ret) | 799 | for (i = 0; i < kvec_cnt; i++) |
| 814 | goto out; | 800 | hmac_sha256_update(&ctx, kvecs[i].iov_base, kvecs[i].iov_len); |
| 815 | 801 | hmac_sha256_final(&ctx, hmac); | |
| 816 | for (i = 0; i < kvec_cnt; i++) { | ||
| 817 | ret = crypto_shash_update(desc, kvecs[i].iov_base, | ||
| 818 | kvecs[i].iov_len); | ||
| 819 | if (ret) | ||
| 820 | goto out; | ||
| 821 | } | ||
| 822 | |||
| 823 | ret = crypto_shash_final(desc, hmac); | ||
| 824 | |||
| 825 | out: | ||
| 826 | shash_desc_zero(desc); | ||
| 827 | return ret; /* auth_x, both plain and secure modes */ | ||
| 828 | } | 802 | } |
| 829 | 803 | ||
| 830 | static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce) | 804 | static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce) |
| @@ -1455,17 +1429,14 @@ static int prepare_auth_request_more(struct ceph_connection *con, · 624 unmodified lines | |||
| 1455 | static int prepare_auth_signature(struct ceph_connection *con) | 1429 | static int prepare_auth_signature(struct ceph_connection *con) |
| 1456 | { | 1430 | { |
| 1457 | void *buf; | 1431 | void *buf; |
| 1458 | int ret; | ||
| 1459 | 1432 | ||
| 1460 | buf = alloc_conn_buf(con, head_onwire_len(SHA256_DIGEST_SIZE, | 1433 | buf = alloc_conn_buf(con, head_onwire_len(SHA256_DIGEST_SIZE, |
| 1461 | con_secure(con))); | 1434 | con_secure(con))); |
| 1462 | if (!buf) | 1435 | if (!buf) |
| 1463 | return -ENOMEM; | 1436 | return -ENOMEM; |
| 1464 | 1437 | ||
| 1465 | ret = ceph_hmac_sha256(con, con->v2.in_sign_kvecs, | 1438 | ceph_hmac_sha256(con, con->v2.in_sign_kvecs, con->v2.in_sign_kvec_cnt, |
| 1466 | con->v2.in_sign_kvec_cnt, CTRL_BODY(buf)); | 1439 | CTRL_BODY(buf)); |
| 1467 | if (ret) | ||
| 1468 | return ret; | ||
| 1469 | 1440 | ||
| 1470 | return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf, | 1441 | return prepare_control(con, FRAME_TAG_AUTH_SIGNATURE, buf, |
| 1471 | SHA256_DIGEST_SIZE); | 1442 | SHA256_DIGEST_SIZE); |
| @@ -1589,10 +1560,11 @@ static int prepare_ack(struct ceph_connection *con) · 117 unmodified lines | |||
| 1589 | return prepare_control(con, FRAME_TAG_ACK, con->v2.out_buf, 8); | 1560 | return prepare_control(con, FRAME_TAG_ACK, con->v2.out_buf, 8); |
| 1590 | } | 1561 | } |
| 1591 | 1562 | ||
| 1592 | static void prepare_epilogue_plain(struct ceph_connection *con, bool aborted) | 1563 | static void prepare_epilogue_plain(struct ceph_connection *con, |
| 1564 | struct ceph_msg *msg, bool aborted) | ||
| 1593 | { | 1565 | { |
| 1594 | dout("%s con %p msg %p aborted %d crcs %u %u %u\n", __func__, con, | 1566 | dout("%s con %p msg %p aborted %d crcs %u %u %u\n", __func__, con, |
| 1595 | con->out_msg, aborted, con->v2.out_epil.front_crc, | 1567 | msg, aborted, con->v2.out_epil.front_crc, |
| 1596 | con->v2.out_epil.middle_crc, con->v2.out_epil.data_crc); | 1568 | con->v2.out_epil.middle_crc, con->v2.out_epil.data_crc); |
| 1597 | 1569 | ||
| 1598 | encode_epilogue_plain(con, aborted); | 1570 | encode_epilogue_plain(con, aborted); |
| @@ -1603,10 +1575,9 @@ static void prepare_epilogue_plain(struct ceph_connection *con, bool aborted) · 4 unmodified lines | |||
| 1603 | * For "used" empty segments, crc is -1. For unused (trailing) | 1575 | * For "used" empty segments, crc is -1. For unused (trailing) |
| 1604 | * segments, crc is 0. | 1576 | * segments, crc is 0. |
| 1605 | */ | 1577 | */ |
| 1606 | static void prepare_message_plain(struct ceph_connection *con) | 1578 | static void prepare_message_plain(struct ceph_connection *con, |
| 1579 | struct ceph_msg *msg) | ||
| 1607 | { | 1580 | { |
| 1608 | struct ceph_msg *msg = con->out_msg; | ||
| 1609 | |||
| 1610 | prepare_head_plain(con, con->v2.out_buf, | 1581 | prepare_head_plain(con, con->v2.out_buf, |
| 1611 | sizeof(struct ceph_msg_header2), NULL, 0, false); | 1582 | sizeof(struct ceph_msg_header2), NULL, 0, false); |
| 1612 | 1583 | ||
| @@ -1647,7 +1618,7 @@ static void prepare_message_plain(struct ceph_connection *con) · 34 unmodified lines | |||
| 1647 | con->v2.out_state = OUT_S_QUEUE_DATA; | 1618 | con->v2.out_state = OUT_S_QUEUE_DATA; |
| 1648 | } else { | 1619 | } else { |
| 1649 | con->v2.out_epil.data_crc = 0; | 1620 | con->v2.out_epil.data_crc = 0; |
| 1650 | prepare_epilogue_plain(con, false); | 1621 | prepare_epilogue_plain(con, msg, false); |
| 1651 | con->v2.out_state = OUT_S_FINISH_MESSAGE; | 1622 | con->v2.out_state = OUT_S_FINISH_MESSAGE; |
| 1652 | } | 1623 | } |
| 1653 | } | 1624 | } |
| @@ -1659,7 +1630,8 @@ static void prepare_message_plain(struct ceph_connection *con) · 5 unmodified lines | |||
| 1659 | * allocate pages for the entire tail of the message (currently up | 1630 | * allocate pages for the entire tail of the message (currently up |
| 1660 | * to ~32M) and two sgs arrays (up to ~256K each)... | 1631 | * to ~32M) and two sgs arrays (up to ~256K each)... |
| 1661 | */ | 1632 | */ |
| 1662 | static int prepare_message_secure(struct ceph_connection *con) | 1633 | static int prepare_message_secure(struct ceph_connection *con, |
| 1634 | struct ceph_msg *msg) | ||
| 1663 | { | 1635 | { |
| 1664 | void *zerop = page_address(ceph_zero_page); | 1636 | void *zerop = page_address(ceph_zero_page); |
| 1665 | struct sg_table enc_sgt = {}; | 1637 | struct sg_table enc_sgt = {}; |
| @@ -1674,7 +1646,7 @@ static int prepare_message_secure(struct ceph_connection *con) · 8 unmodified lines | |||
| 1674 | if (ret) | 1646 | if (ret) |
| 1675 | return ret; | 1647 | return ret; |
| 1676 | 1648 | ||
| 1677 | tail_len = tail_onwire_len(con->out_msg, true); | 1649 | tail_len = tail_onwire_len(msg, true); |
| 1678 | if (!tail_len) { | 1650 | if (!tail_len) { |
| 1679 | /* | 1651 | /* |
| 1680 | * Empty message: once the head is written, | 1652 | * Empty message: once the head is written, |
| @@ -1685,7 +1657,7 @@ static int prepare_message_secure(struct ceph_connection *con) · 4 unmodified lines | |||
| 1685 | } | 1657 | } |
| 1686 | 1658 | ||
| 1687 | encode_epilogue_secure(con, false); | 1659 | encode_epilogue_secure(con, false); |
| 1688 | ret = setup_message_sgs(&sgt, con->out_msg, zerop, zerop, zerop, | 1660 | ret = setup_message_sgs(&sgt, msg, zerop, zerop, zerop, |
| 1689 | &con->v2.out_epil, NULL, 0, false); | 1661 | &con->v2.out_epil, NULL, 0, false); |
| 1690 | if (ret) | 1662 | if (ret) |
| 1691 | goto out; | 1663 | goto out; |
| @@ -1714,7 +1686,7 @@ static int prepare_message_secure(struct ceph_connection *con) · 22 unmodified lines | |||
| 1714 | goto out; | 1686 | goto out; |
| 1715 | 1687 | ||
| 1716 | dout("%s con %p msg %p sg_cnt %d enc_page_cnt %d\n", __func__, con, | 1688 | dout("%s con %p msg %p sg_cnt %d enc_page_cnt %d\n", __func__, con, |
| 1717 | con->out_msg, sgt.orig_nents, enc_page_cnt); | 1689 | msg, sgt.orig_nents, enc_page_cnt); |
| 1718 | con->v2.out_state = OUT_S_QUEUE_ENC_PAGE; | 1690 | con->v2.out_state = OUT_S_QUEUE_ENC_PAGE; |
| 1719 | 1691 | ||
| 1720 | out: | 1692 | out: |
| @@ -1723,19 +1695,19 @@ out: · 2 unmodified lines | |||
| 1723 | return ret; | 1695 | return ret; |
| 1724 | } | 1696 | } |
| 1725 | 1697 | ||
| 1726 | static int prepare_message(struct ceph_connection *con) | 1698 | static int prepare_message(struct ceph_connection *con, struct ceph_msg *msg) |
| 1727 | { | 1699 | { |
| 1728 | int lens[] = { | 1700 | int lens[] = { |
| 1729 | sizeof(struct ceph_msg_header2), | 1701 | sizeof(struct ceph_msg_header2), |
| 1730 | front_len(con->out_msg), | 1702 | front_len(msg), |
| 1731 | middle_len(con->out_msg), | 1703 | middle_len(msg), |
| 1732 | data_len(con->out_msg) | 1704 | data_len(msg) |
| 1733 | }; | 1705 | }; |
| 1734 | struct ceph_frame_desc desc; | 1706 | struct ceph_frame_desc desc; |
| 1735 | int ret; | 1707 | int ret; |
| 1736 | 1708 | ||
| 1737 | dout("%s con %p msg %p logical %d+%d+%d+%d\n", __func__, con, | 1709 | dout("%s con %p msg %p logical %d+%d+%d+%d\n", __func__, con, |
| 1738 | con->out_msg, lens[0], lens[1], lens[2], lens[3]); | 1710 | msg, lens[0], lens[1], lens[2], lens[3]); |
| 1739 | 1711 | ||
| 1740 | if (con->in_seq > con->in_seq_acked) { | 1712 | if (con->in_seq > con->in_seq_acked) { |
| 1741 | dout("%s con %p in_seq_acked %llu -> %llu\n", __func__, con, | 1713 | dout("%s con %p in_seq_acked %llu -> %llu\n", __func__, con, |
| @@ -1746,15 +1718,15 @@ static int prepare_message(struct ceph_connection *con) · 4 unmodified lines | |||
| 1746 | reset_out_kvecs(con); | 1718 | reset_out_kvecs(con); |
| 1747 | init_frame_desc(&desc, FRAME_TAG_MESSAGE, lens, 4); | 1719 | init_frame_desc(&desc, FRAME_TAG_MESSAGE, lens, 4); |
| 1748 | encode_preamble(&desc, con->v2.out_buf); | 1720 | encode_preamble(&desc, con->v2.out_buf); |
| 1749 | fill_header2(CTRL_BODY(con->v2.out_buf), &con->out_msg->hdr, | 1721 | fill_header2(CTRL_BODY(con->v2.out_buf), &msg->hdr, |
| 1750 | con->in_seq_acked); | 1722 | con->in_seq_acked); |
| 1751 | 1723 | ||
| 1752 | if (con_secure(con)) { | 1724 | if (con_secure(con)) { |
| 1753 | ret = prepare_message_secure(con); | 1725 | ret = prepare_message_secure(con, msg); |
| 1754 | if (ret) | 1726 | if (ret) |
| 1755 | return ret; | 1727 | return ret; |
| 1756 | } else { | 1728 | } else { |
| 1757 | prepare_message_plain(con); | 1729 | prepare_message_plain(con, msg); |
| 1758 | } | 1730 | } |
| 1759 | 1731 | ||
| 1760 | ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING); | 1732 | ceph_con_flag_set(con, CEPH_CON_F_WRITE_PENDING); |
| @@ -2460,10 +2432,8 @@ static int process_auth_signature(struct ceph_connection *con, · 699 unmodified lines | |||
| 2460 | return -EINVAL; | 2432 | return -EINVAL; |
| 2461 | } | 2433 | } |
| 2462 | 2434 | ||
| 2463 | ret = ceph_hmac_sha256(con, con->v2.out_sign_kvecs, | 2435 | ceph_hmac_sha256(con, con->v2.out_sign_kvecs, con->v2.out_sign_kvec_cnt, |
| 2464 | con->v2.out_sign_kvec_cnt, hmac); | 2436 | hmac); |
| 2465 | if (ret) | ||
| 2466 | return ret; | ||
| 2467 | 2437 | ||
| 2468 | ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad); | 2438 | ceph_decode_need(&p, end, SHA256_DIGEST_SIZE, bad); |
| 2469 | if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) { | 2439 | if (crypto_memneq(p, hmac, SHA256_DIGEST_SIZE)) { |
| @@ -3184,20 +3154,20 @@ int ceph_con_v2_try_read(struct ceph_connection *con) · 714 unmodified lines | |||
| 3184 | } | 3154 | } |
| 3185 | } | 3155 | } |
| 3186 | 3156 | ||
| 3187 | static void queue_data(struct ceph_connection *con) | 3157 | static void queue_data(struct ceph_connection *con, struct ceph_msg *msg) |
| 3188 | { | 3158 | { |
| 3189 | struct bio_vec bv; | 3159 | struct bio_vec bv; |
| 3190 | 3160 | ||
| 3191 | con->v2.out_epil.data_crc = -1; | 3161 | con->v2.out_epil.data_crc = -1; |
| 3192 | ceph_msg_data_cursor_init(&con->v2.out_cursor, con->out_msg, | 3162 | ceph_msg_data_cursor_init(&con->v2.out_cursor, msg, |
| 3193 | data_len(con->out_msg)); | 3163 | data_len(msg)); |
| 3194 | 3164 | ||
| 3195 | get_bvec_at(&con->v2.out_cursor, &bv); | 3165 | get_bvec_at(&con->v2.out_cursor, &bv); |
| 3196 | set_out_bvec(con, &bv, true); | 3166 | set_out_bvec(con, &bv, true); |
| 3197 | con->v2.out_state = OUT_S_QUEUE_DATA_CONT; | 3167 | con->v2.out_state = OUT_S_QUEUE_DATA_CONT; |
| 3198 | } | 3168 | } |
| 3199 | 3169 | ||
| 3200 | static void queue_data_cont(struct ceph_connection *con) | 3170 | static void queue_data_cont(struct ceph_connection *con, struct ceph_msg *msg) |
| 3201 | { | 3171 | { |
| 3202 | struct bio_vec bv; | 3172 | struct bio_vec bv; |
| 3203 | 3173 | ||
| @@ -3218,7 +3188,7 @@ static void queue_data_cont(struct ceph_connection *con) · 14 unmodified lines | |||
| 3218 | * we are done. | 3188 | * we are done. |
| 3219 | */ | 3189 | */ |
| 3220 | reset_out_kvecs(con); | 3190 | reset_out_kvecs(con); |
| 3221 | prepare_epilogue_plain(con, false); | 3191 | prepare_epilogue_plain(con, msg, false); |
| 3222 | con->v2.out_state = OUT_S_FINISH_MESSAGE; | 3192 | con->v2.out_state = OUT_S_FINISH_MESSAGE; |
| 3223 | } | 3193 | } |
| 3224 | 3194 | ||
| @@ -3250,7 +3220,7 @@ static void queue_enc_page(struct ceph_connection *con) · 25 unmodified lines | |||
| 3250 | con->v2.out_state = OUT_S_FINISH_MESSAGE; | 3220 | con->v2.out_state = OUT_S_FINISH_MESSAGE; |
| 3251 | } | 3221 | } |
| 3252 | 3222 | ||
| 3253 | static void queue_zeros(struct ceph_connection *con) | 3223 | static void queue_zeros(struct ceph_connection *con, struct ceph_msg *msg) |
| 3254 | { | 3224 | { |
| 3255 | dout("%s con %p out_zero %d\n", __func__, con, con->v2.out_zero); | 3225 | dout("%s con %p out_zero %d\n", __func__, con, con->v2.out_zero); |
| 3256 | 3226 | ||
| @@ -3267,7 +3237,7 @@ static void queue_zeros(struct ceph_connection *con) · 10 unmodified lines | |||
| 3267 | * Once it's written, we are done patching up for the revoke. | 3237 | * Once it's written, we are done patching up for the revoke. |
| 3268 | */ | 3238 | */ |
| 3269 | reset_out_kvecs(con); | 3239 | reset_out_kvecs(con); |
| 3270 | prepare_epilogue_plain(con, true); | 3240 | prepare_epilogue_plain(con, msg, true); |
| 3271 | con->v2.out_state = OUT_S_FINISH_MESSAGE; | 3241 | con->v2.out_state = OUT_S_FINISH_MESSAGE; |
| 3272 | } | 3242 | } |
| 3273 | 3243 | ||
| @@ -3294,6 +3264,7 @@ static void finish_message(struct ceph_connection *con) · 20 unmodified lines | |||
| 3294 | 3264 | ||
| 3295 | static int populate_out_iter(struct ceph_connection *con) | 3265 | static int populate_out_iter(struct ceph_connection *con) |
| 3296 | { | 3266 | { |
| 3267 | struct ceph_msg *msg; | ||
| 3297 | int ret; | 3268 | int ret; |
| 3298 | 3269 | ||
| 3299 | dout("%s con %p state %d out_state %d\n", __func__, con, con->state, | 3270 | dout("%s con %p state %d out_state %d\n", __func__, con, con->state, |
| @@ -3309,18 +3280,18 @@ static int populate_out_iter(struct ceph_connection *con) · 9 unmodified lines | |||
| 3309 | switch (con->v2.out_state) { | 3280 | switch (con->v2.out_state) { |
| 3310 | case OUT_S_QUEUE_DATA: | 3281 | case OUT_S_QUEUE_DATA: |
| 3311 | WARN_ON(!con->out_msg); | 3282 | WARN_ON(!con->out_msg); |
| 3312 | queue_data(con); | 3283 | queue_data(con, con->out_msg); |
| 3313 | goto populated; | 3284 | goto populated; |
| 3314 | case OUT_S_QUEUE_DATA_CONT: | 3285 | case OUT_S_QUEUE_DATA_CONT: |
| 3315 | WARN_ON(!con->out_msg); | 3286 | WARN_ON(!con->out_msg); |
| 3316 | queue_data_cont(con); | 3287 | queue_data_cont(con, con->out_msg); |
| 3317 | goto populated; | 3288 | goto populated; |
| 3318 | case OUT_S_QUEUE_ENC_PAGE: | 3289 | case OUT_S_QUEUE_ENC_PAGE: |
| 3319 | queue_enc_page(con); | 3290 | queue_enc_page(con); |
| 3320 | goto populated; | 3291 | goto populated; |
| 3321 | case OUT_S_QUEUE_ZEROS: | 3292 | case OUT_S_QUEUE_ZEROS: |
| 3322 | WARN_ON(con->out_msg); /* revoked */ | 3293 | WARN_ON(con->out_msg); /* revoked */ |
| 3323 | queue_zeros(con); | 3294 | queue_zeros(con, con->out_msg); |
| 3324 | goto populated; | 3295 | goto populated; |
| 3325 | case OUT_S_FINISH_MESSAGE: | 3296 | case OUT_S_FINISH_MESSAGE: |
| 3326 | finish_message(con); | 3297 | finish_message(con); |
| @@ -3339,9 +3310,8 @@ static int populate_out_iter(struct ceph_connection *con) · 12 unmodified lines | |||
| 3339 | pr_err("prepare_keepalive2 failed: %d\n", ret); | 3310 | pr_err("prepare_keepalive2 failed: %d\n", ret); |
| 3340 | return ret; | 3311 | return ret; |
| 3341 | } | 3312 | } |
| 3342 | } else if (!list_empty(&con->out_queue)) { | 3313 | } else if ((msg = ceph_con_get_out_msg(con)) != NULL) { |
| 3343 | ceph_con_get_out_msg(con); | 3314 | ret = prepare_message(con, msg); |
| 3344 | ret = prepare_message(con); | ||
| 3345 | if (ret) { | 3315 | if (ret) { |
| 3346 | pr_err("prepare_message failed: %d\n", ret); | 3316 | pr_err("prepare_message failed: %d\n", ret); |
| 3347 | return ret; | 3317 | return ret; |
| @@ -3453,17 +3423,18 @@ static u32 crc32c_zeros(u32 crc, int zero_len) · 105 unmodified lines | |||
| 3453 | return crc; | 3423 | return crc; |
| 3454 | } | 3424 | } |
| 3455 | 3425 | ||
| 3456 | static void prepare_zero_front(struct ceph_connection *con, int resid) | 3426 | static void prepare_zero_front(struct ceph_connection *con, |
| 3427 | struct ceph_msg *msg, int resid) | ||
| 3457 | { | 3428 | { |
| 3458 | int sent; | 3429 | int sent; |
| 3459 | 3430 | ||
| 3460 | WARN_ON(!resid || resid > front_len(con->out_msg)); | 3431 | WARN_ON(!resid || resid > front_len(msg)); |
| 3461 | sent = front_len(con->out_msg) - resid; | 3432 | sent = front_len(msg) - resid; |
| 3462 | dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid); | 3433 | dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid); |
| 3463 | 3434 | ||
| 3464 | if (sent) { | 3435 | if (sent) { |
| 3465 | con->v2.out_epil.front_crc = | 3436 | con->v2.out_epil.front_crc = |
| 3466 | crc32c(-1, con->out_msg->front.iov_base, sent); | 3437 | crc32c(-1, msg->front.iov_base, sent); |
| 3467 | con->v2.out_epil.front_crc = | 3438 | con->v2.out_epil.front_crc = |
| 3468 | crc32c_zeros(con->v2.out_epil.front_crc, resid); | 3439 | crc32c_zeros(con->v2.out_epil.front_crc, resid); |
| 3469 | } else { | 3440 | } else { |
| @@ -3474,17 +3445,18 @@ static void prepare_zero_front(struct ceph_connection *con, int resid) · 4 unmodified lines | |||
| 3474 | out_zero_add(con, resid); | 3445 | out_zero_add(con, resid); |
| 3475 | } | 3446 | } |
| 3476 | 3447 | ||
| 3477 | static void prepare_zero_middle(struct ceph_connection *con, int resid) | 3448 | static void prepare_zero_middle(struct ceph_connection *con, |
| 3449 | struct ceph_msg *msg, int resid) | ||
| 3478 | { | 3450 | { |
| 3479 | int sent; | 3451 | int sent; |
| 3480 | 3452 | ||
| 3481 | WARN_ON(!resid || resid > middle_len(con->out_msg)); | 3453 | WARN_ON(!resid || resid > middle_len(msg)); |
| 3482 | sent = middle_len(con->out_msg) - resid; | 3454 | sent = middle_len(msg) - resid; |
| 3483 | dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid); | 3455 | dout("%s con %p sent %d resid %d\n", __func__, con, sent, resid); |
| 3484 | 3456 | ||
| 3485 | if (sent) { | 3457 | if (sent) { |
| 3486 | con->v2.out_epil.middle_crc = | 3458 | con->v2.out_epil.middle_crc = |
| 3487 | crc32c(-1, con->out_msg->middle->vec.iov_base, sent); | 3459 | crc32c(-1, msg->middle->vec.iov_base, sent); |
| 3488 | con->v2.out_epil.middle_crc = | 3460 | con->v2.out_epil.middle_crc = |
| 3489 | crc32c_zeros(con->v2.out_epil.middle_crc, resid); | 3461 | crc32c_zeros(con->v2.out_epil.middle_crc, resid); |
| 3490 | } else { | 3462 | } else { |
| @@ -3495,61 +3467,64 @@ static void prepare_zero_middle(struct ceph_connection *con, int resid) · 4 unmodified lines | |||
| 3495 | out_zero_add(con, resid); | 3467 | out_zero_add(con, resid); |
| 3496 | } | 3468 | } |
| 3497 | 3469 | ||
| 3498 | static void prepare_zero_data(struct ceph_connection *con) | 3470 | static void prepare_zero_data(struct ceph_connection *con, |
| 3471 | struct ceph_msg *msg) | ||
| 3499 | { | 3472 | { |
| 3500 | dout("%s con %p\n", __func__, con); | 3473 | dout("%s con %p\n", __func__, con); |
| 3501 | con->v2.out_epil.data_crc = crc32c_zeros(-1, data_len(con->out_msg)); | 3474 | con->v2.out_epil.data_crc = crc32c_zeros(-1, data_len(msg)); |
| 3502 | out_zero_add(con, data_len(con->out_msg)); | 3475 | out_zero_add(con, data_len(msg)); |
| 3503 | } | 3476 | } |
| 3504 | 3477 | ||
| 3505 | static void revoke_at_queue_data(struct ceph_connection *con) | 3478 | static void revoke_at_queue_data(struct ceph_connection *con, |
| 3479 | struct ceph_msg *msg) | ||
| 3506 | { | 3480 | { |
| 3507 | int boundary; | 3481 | int boundary; |
| 3508 | int resid; | 3482 | int resid; |
| 3509 | 3483 | ||
| 3510 | WARN_ON(!data_len(con->out_msg)); | 3484 | WARN_ON(!data_len(msg)); |
| 3511 | WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter)); | 3485 | WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter)); |
| 3512 | resid = iov_iter_count(&con->v2.out_iter); | 3486 | resid = iov_iter_count(&con->v2.out_iter); |
| 3513 | 3487 | ||
| 3514 | boundary = front_len(con->out_msg) + middle_len(con->out_msg); | 3488 | boundary = front_len(msg) + middle_len(msg); |
| 3515 | if (resid > boundary) { | 3489 | if (resid > boundary) { |
| 3516 | resid -= boundary; | 3490 | resid -= boundary; |
| 3517 | WARN_ON(resid > MESSAGE_HEAD_PLAIN_LEN); | 3491 | WARN_ON(resid > MESSAGE_HEAD_PLAIN_LEN); |
| 3518 | dout("%s con %p was sending head\n", __func__, con); | 3492 | dout("%s con %p was sending head\n", __func__, con); |
| 3519 | if (front_len(con->out_msg)) | 3493 | if (front_len(msg)) |
| 3520 | prepare_zero_front(con, front_len(con->out_msg)); | 3494 | prepare_zero_front(con, msg, front_len(msg)); |
| 3521 | if (middle_len(con->out_msg)) | 3495 | if (middle_len(msg)) |
| 3522 | prepare_zero_middle(con, middle_len(con->out_msg)); | 3496 | prepare_zero_middle(con, msg, middle_len(msg)); |
| 3523 | prepare_zero_data(con); | 3497 | prepare_zero_data(con, msg); |
| 3524 | WARN_ON(iov_iter_count(&con->v2.out_iter) != resid); | 3498 | WARN_ON(iov_iter_count(&con->v2.out_iter) != resid); |
| 3525 | con->v2.out_state = OUT_S_QUEUE_ZEROS; | 3499 | con->v2.out_state = OUT_S_QUEUE_ZEROS; |
| 3526 | return; | 3500 | return; |
| 3527 | } | 3501 | } |
| 3528 | 3502 | ||
| 3529 | boundary = middle_len(con->out_msg); | 3503 | boundary = middle_len(msg); |
| 3530 | if (resid > boundary) { | 3504 | if (resid > boundary) { |
| 3531 | resid -= boundary; | 3505 | resid -= boundary; |
| 3532 | dout("%s con %p was sending front\n", __func__, con); | 3506 | dout("%s con %p was sending front\n", __func__, con); |
| 3533 | prepare_zero_front(con, resid); | 3507 | prepare_zero_front(con, msg, resid); |
| 3534 | if (middle_len(con->out_msg)) | 3508 | if (middle_len(msg)) |
| 3535 | prepare_zero_middle(con, middle_len(con->out_msg)); | 3509 | prepare_zero_middle(con, msg, middle_len(msg)); |
| 3536 | prepare_zero_data(con); | 3510 | prepare_zero_data(con, msg); |
| 3537 | queue_zeros(con); | 3511 | queue_zeros(con, msg); |
| 3538 | return; | 3512 | return; |
| 3539 | } | 3513 | } |
| 3540 | 3514 | ||
| 3541 | WARN_ON(!resid); | 3515 | WARN_ON(!resid); |
| 3542 | dout("%s con %p was sending middle\n", __func__, con); | 3516 | dout("%s con %p was sending middle\n", __func__, con); |
| 3543 | prepare_zero_middle(con, resid); | 3517 | prepare_zero_middle(con, msg, resid); |
| 3544 | prepare_zero_data(con); | 3518 | prepare_zero_data(con, msg); |
| 3545 | queue_zeros(con); | 3519 | queue_zeros(con, msg); |
| 3546 | } | 3520 | } |
| 3547 | 3521 | ||
| 3548 | static void revoke_at_queue_data_cont(struct ceph_connection *con) | 3522 | static void revoke_at_queue_data_cont(struct ceph_connection *con, |
| 3523 | struct ceph_msg *msg) | ||
| 3549 | { | 3524 | { |
| 3550 | int sent, resid; /* current piece of data */ | 3525 | int sent, resid; /* current piece of data */ |
| 3551 | 3526 | ||
| 3552 | WARN_ON(!data_len(con->out_msg)); | 3527 | WARN_ON(!data_len(msg)); |
| 3553 | WARN_ON(!iov_iter_is_bvec(&con->v2.out_iter)); | 3528 | WARN_ON(!iov_iter_is_bvec(&con->v2.out_iter)); |
| 3554 | resid = iov_iter_count(&con->v2.out_iter); | 3529 | resid = iov_iter_count(&con->v2.out_iter); |
| 3555 | WARN_ON(!resid || resid > con->v2.out_bvec.bv_len); | 3530 | WARN_ON(!resid || resid > con->v2.out_bvec.bv_len); |
| @@ -3568,10 +3543,11 @@ static void revoke_at_queue_data_cont(struct ceph_connection *con) · 12 unmodified lines | |||
| 3568 | 3543 | ||
| 3569 | con->v2.out_iter.count -= resid; | 3544 | con->v2.out_iter.count -= resid; |
| 3570 | out_zero_add(con, con->v2.out_cursor.total_resid); | 3545 | out_zero_add(con, con->v2.out_cursor.total_resid); |
| 3571 | queue_zeros(con); | 3546 | queue_zeros(con, msg); |
| 3572 | } | 3547 | } |
| 3573 | 3548 | ||
| 3574 | static void revoke_at_finish_message(struct ceph_connection *con) | 3549 | static void revoke_at_finish_message(struct ceph_connection *con, |
| 3550 | struct ceph_msg *msg) | ||
| 3575 | { | 3551 | { |
| 3576 | int boundary; | 3552 | int boundary; |
| 3577 | int resid; | 3553 | int resid; |
| @@ -3579,39 +3555,39 @@ static void revoke_at_finish_message(struct ceph_connection *con) · 1 unmodified line | |||
| 3579 | WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter)); | 3555 | WARN_ON(!iov_iter_is_kvec(&con->v2.out_iter)); |
| 3580 | resid = iov_iter_count(&con->v2.out_iter); | 3556 | resid = iov_iter_count(&con->v2.out_iter); |
| 3581 | 3557 | ||
| 3582 | if (!front_len(con->out_msg) && !middle_len(con->out_msg) && | 3558 | if (!front_len(msg) && !middle_len(msg) && |
| 3583 | !data_len(con->out_msg)) { | 3559 | !data_len(msg)) { |
| 3584 | WARN_ON(!resid || resid > MESSAGE_HEAD_PLAIN_LEN); | 3560 | WARN_ON(!resid || resid > MESSAGE_HEAD_PLAIN_LEN); |
| 3585 | dout("%s con %p was sending head (empty message) - noop\n", | 3561 | dout("%s con %p was sending head (empty message) - noop\n", |
| 3586 | __func__, con); | 3562 | __func__, con); |
| 3587 | return; | 3563 | return; |
| 3588 | } | 3564 | } |
| 3589 | 3565 | ||
| 3590 | boundary = front_len(con->out_msg) + middle_len(con->out_msg) + | 3566 | boundary = front_len(msg) + middle_len(msg) + |
| 3591 | CEPH_EPILOGUE_PLAIN_LEN; | 3567 | CEPH_EPILOGUE_PLAIN_LEN; |
| 3592 | if (resid > boundary) { | 3568 | if (resid > boundary) { |
| 3593 | resid -= boundary; | 3569 | resid -= boundary; |
| 3594 | WARN_ON(resid > MESSAGE_HEAD_PLAIN_LEN); | 3570 | WARN_ON(resid > MESSAGE_HEAD_PLAIN_LEN); |
| 3595 | dout("%s con %p was sending head\n", __func__, con); | 3571 | dout("%s con %p was sending head\n", __func__, con); |
| 3596 | if (front_len(con->out_msg)) | 3572 | if (front_len(msg)) |
| 3597 | prepare_zero_front(con, front_len(con->out_msg)); | 3573 | prepare_zero_front(con, msg, front_len(msg)); |
| 3598 | if (middle_len(con->out_msg)) | 3574 | if (middle_len(msg)) |
| 3599 | prepare_zero_middle(con, middle_len(con->out_msg)); | 3575 | prepare_zero_middle(con, msg, middle_len(msg)); |
| 3600 | con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN; | 3576 | con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN; |
| 3601 | WARN_ON(iov_iter_count(&con->v2.out_iter) != resid); | 3577 | WARN_ON(iov_iter_count(&con->v2.out_iter) != resid); |
| 3602 | con->v2.out_state = OUT_S_QUEUE_ZEROS; | 3578 | con->v2.out_state = OUT_S_QUEUE_ZEROS; |
| 3603 | return; | 3579 | return; |
| 3604 | } | 3580 | } |
| 3605 | 3581 | ||
| 3606 | boundary = middle_len(con->out_msg) + CEPH_EPILOGUE_PLAIN_LEN; | 3582 | boundary = middle_len(msg) + CEPH_EPILOGUE_PLAIN_LEN; |
| 3607 | if (resid > boundary) { | 3583 | if (resid > boundary) { |
| 3608 | resid -= boundary; | 3584 | resid -= boundary; |
| 3609 | dout("%s con %p was sending front\n", __func__, con); | 3585 | dout("%s con %p was sending front\n", __func__, con); |
| 3610 | prepare_zero_front(con, resid); | 3586 | prepare_zero_front(con, msg, resid); |
| 3611 | if (middle_len(con->out_msg)) | 3587 | if (middle_len(msg)) |
| 3612 | prepare_zero_middle(con, middle_len(con->out_msg)); | 3588 | prepare_zero_middle(con, msg, middle_len(msg)); |
| 3613 | con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN; | 3589 | con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN; |
| 3614 | queue_zeros(con); | 3590 | queue_zeros(con, msg); |
| 3615 | return; | 3591 | return; |
| 3616 | } | 3592 | } |
| 3617 | 3593 | ||
| @@ -3619,9 +3595,9 @@ static void revoke_at_finish_message(struct ceph_connection *con) · 1 unmodified line | |||
| 3619 | if (resid > boundary) { | 3595 | if (resid > boundary) { |
| 3620 | resid -= boundary; | 3596 | resid -= boundary; |
| 3621 | dout("%s con %p was sending middle\n", __func__, con); | 3597 | dout("%s con %p was sending middle\n", __func__, con); |
| 3622 | prepare_zero_middle(con, resid); | 3598 | prepare_zero_middle(con, msg, resid); |
| 3623 | con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN; | 3599 | con->v2.out_iter.count -= CEPH_EPILOGUE_PLAIN_LEN; |
| 3624 | queue_zeros(con); | 3600 | queue_zeros(con, msg); |
| 3625 | return; | 3601 | return; |
| 3626 | } | 3602 | } |
| 3627 | 3603 | ||
| @@ -3629,7 +3605,7 @@ static void revoke_at_finish_message(struct ceph_connection *con) · 1 unmodified line | |||
| 3629 | dout("%s con %p was sending epilogue - noop\n", __func__, con); | 3605 | dout("%s con %p was sending epilogue - noop\n", __func__, con); |
| 3630 | } | 3606 | } |
| 3631 | 3607 | ||
| 3632 | void ceph_con_v2_revoke(struct ceph_connection *con) | 3608 | void ceph_con_v2_revoke(struct ceph_connection *con, struct ceph_msg *msg) |
| 3633 | { | 3609 | { |
| 3634 | WARN_ON(con->v2.out_zero); | 3610 | WARN_ON(con->v2.out_zero); |
| 3635 | 3611 | ||
| @@ -3642,13 +3618,13 @@ void ceph_con_v2_revoke(struct ceph_connection *con) · 6 unmodified lines | |||
| 3642 | 3618 | ||
| 3643 | switch (con->v2.out_state) { | 3619 | switch (con->v2.out_state) { |
| 3644 | case OUT_S_QUEUE_DATA: | 3620 | case OUT_S_QUEUE_DATA: |
| 3645 | revoke_at_queue_data(con); | 3621 | revoke_at_queue_data(con, msg); |
| 3646 | break; | 3622 | break; |
| 3647 | case OUT_S_QUEUE_DATA_CONT: | 3623 | case OUT_S_QUEUE_DATA_CONT: |
| 3648 | revoke_at_queue_data_cont(con); | 3624 | revoke_at_queue_data_cont(con, msg); |
| 3649 | break; | 3625 | break; |
| 3650 | case OUT_S_FINISH_MESSAGE: | 3626 | case OUT_S_FINISH_MESSAGE: |
| 3651 | revoke_at_finish_message(con); | 3627 | revoke_at_finish_message(con, msg); |
| 3652 | break; | 3628 | break; |
| 3653 | default: | 3629 | default: |
| 3654 | WARN(1, "bad out_state %d", con->v2.out_state); | 3630 | WARN(1, "bad out_state %d", con->v2.out_state); |
| @@ -3814,10 +3790,8 @@ void ceph_con_v2_reset_protocol(struct ceph_connection *con) · 159 unmodified lines | |||
| 3814 | memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN); | 3790 | memzero_explicit(&con->v2.in_gcm_nonce, CEPH_GCM_IV_LEN); |
| 3815 | memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN); | 3791 | memzero_explicit(&con->v2.out_gcm_nonce, CEPH_GCM_IV_LEN); |
| 3816 | 3792 | ||
| 3817 | if (con->v2.hmac_tfm) { | 3793 | memzero_explicit(&con->v2.hmac_key, sizeof(con->v2.hmac_key)); |
| 3818 | crypto_free_shash(con->v2.hmac_tfm); | 3794 | con->v2.hmac_key_set = false; |
| 3819 | con->v2.hmac_tfm = NULL; | ||
| 3820 | } | ||
| 3821 | if (con->v2.gcm_req) { | 3795 | if (con->v2.gcm_req) { |
| 3822 | aead_request_free(con->v2.gcm_req); | 3796 | aead_request_free(con->v2.gcm_req); |
| 3823 | con->v2.gcm_req = NULL; | 3797 | con->v2.gcm_req = NULL; |