History

Merge tag 'ceph-for-6.18-rc1' of https://github.com/ceph/ceph-client

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

Linus Torvalds committed 1 year ago

Commit 8bd92382 parents 91b436f d74d6c017 files · +323 −248Browse files

Unified · Split

17 files
  1. MAINTAINERS +3 −0
  2. fs/ceph/dir.c +1 −2
  3. fs/ceph/file.c +15 −15
  4. fs/ceph/inode.c +11 −0
  5. fs/ceph/io.c +75 −25
  6. fs/ceph/io.h +5 −3
  7. fs/ceph/ioctl.c +12 −5
  8. fs/ceph/locks.c +4 −1
  9. fs/ceph/mds_client.c +18 −4
  10. fs/ceph/mdsmap.c +13 −1
  11. fs/ceph/super.c +0 −14
  12. fs/ceph/super.h +16 −1
  13. include/linux/ceph/messenger.h +6 −4
  14. net/ceph/Kconfig +1 −2
  15. net/ceph/messenger.c +7 −5
  16. net/ceph/messenger_v1.c +26 −30
  17. net/ceph/messenger_v2.c +110 −136
MAINTAINERS+3−0
@@ -5694,6 +5694,7 @@ M: Xiubo Li <xiubli@redhat.com> · 5693 unmodified lines
5694L: ceph-devel@vger.kernel.org5694L: ceph-devel@vger.kernel.org
5695S: Supported5695S: Supported
5696W: http://ceph.com/5696W: http://ceph.com/
5697B: https://tracker.ceph.com/
5697T: git https://github.com/ceph/ceph-client.git5698T: git https://github.com/ceph/ceph-client.git
5698F: include/linux/ceph/5699F: include/linux/ceph/
5699F: include/linux/crush/5700F: include/linux/crush/
@@ -5705,6 +5706,7 @@ M: Ilya Dryomov <idryomov@gmail.com> · 5 unmodified lines
5705L: ceph-devel@vger.kernel.org5706L: ceph-devel@vger.kernel.org
5706S: Supported5707S: Supported
5707W: http://ceph.com/5708W: http://ceph.com/
5709B: https://tracker.ceph.com/
5708T: git https://github.com/ceph/ceph-client.git5710T: git https://github.com/ceph/ceph-client.git
5709F: Documentation/filesystems/ceph.rst5711F: Documentation/filesystems/ceph.rst
5710F: fs/ceph/5712F: fs/ceph/
@@ -21357,6 +21359,7 @@ R: Dongsheng Yang <dongsheng.yang@easystack.cn> · 15646 unmodified lines
21357L: ceph-devel@vger.kernel.org21359L: ceph-devel@vger.kernel.org
21358S: Supported21360S: Supported
21359W: http://ceph.com/21361W: http://ceph.com/
21362B: https://tracker.ceph.com/
21360T: git https://github.com/ceph/ceph-client.git21363T: git https://github.com/ceph/ceph-client.git
21361F: Documentation/ABI/testing/sysfs-bus-rbd21364F: Documentation/ABI/testing/sysfs-bus-rbd
21362F: drivers/block/rbd.c21365F: drivers/block/rbd.c
fs/ceph/dir.c+1−2
@@ -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();
fs/ceph/file.c+15−15
@@ -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 else2124 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
2358retry_snap:2358retry_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 else2361 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 }
fs/ceph/inode.c+11−0
@@ -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)
fs/ceph/io.c+75−25
@@ -21,14 +21,23 @@ · 20 unmodified lines
21/* Call with exclusively locked inode->i_rwsem */21/* Call with exclusively locked inode->i_rwsem */
22static void ceph_block_o_direct(struct ceph_inode_info *ci, struct inode *inode)22static 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 on56 * 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 */
50void59int ceph_start_io_read(struct inode *inode)
51ceph_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 ensure107 * 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 */
86void110int ceph_start_io_write(struct inode *inode)
87ceph_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 */
107static void ceph_block_buffered(struct ceph_inode_info *ci, struct inode *inode)132static 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 on168 * 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 */
136void171int ceph_start_io_direct(struct inode *inode)
137ceph_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/**
fs/ceph/io.h+5−3
@@ -2,11 +2,13 @@ · 1 unmodified line
2#ifndef _FS_CEPH_IO_H2#ifndef _FS_CEPH_IO_H
3#define _FS_CEPH_IO_H3#define _FS_CEPH_IO_H
4 4
5void ceph_start_io_read(struct inode *inode);5#include <linux/compiler_attributes.h>
6
7int __must_check ceph_start_io_read(struct inode *inode);
6void ceph_end_io_read(struct inode *inode);8void ceph_end_io_read(struct inode *inode);
7void ceph_start_io_write(struct inode *inode);9int __must_check ceph_start_io_write(struct inode *inode);
8void ceph_end_io_write(struct inode *inode);10void ceph_end_io_write(struct inode *inode);
9void ceph_start_io_direct(struct inode *inode);11int __must_check ceph_start_io_direct(struct inode *inode);
10void ceph_end_io_direct(struct inode *inode);12void ceph_end_io_direct(struct inode *inode);
11 13
12#endif /* FS_CEPH_IO_H */14#endif /* FS_CEPH_IO_H */
fs/ceph/ioctl.c+12−5
@@ -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
fs/ceph/locks.c+4−1
@@ -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
fs/ceph/mds_client.c+18−4
@@ -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)
fs/ceph/mdsmap.c+13−1
@@ -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) {
fs/ceph/super.c+0−14
@@ -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 */
255static 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
263static int ceph_parse_old_source(const char *dev_name, const char *dev_name_end,249static 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{
fs/ceph/super.h+16−1
@@ -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 */
113static 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 */
108enum {122enum {
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 */
include/linux/ceph/messenger.h+6−4
@@ -2,6 +2,7 @@ · 1 unmodified line
2#ifndef __FS_CEPH_MESSENGER_H2#ifndef __FS_CEPH_MESSENGER_H
3#define __FS_CEPH_MESSENGER_H3#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
548void ceph_con_process_message(struct ceph_connection *con);550void ceph_con_process_message(struct ceph_connection *con);
549int ceph_con_in_msg_alloc(struct ceph_connection *con,551int 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);
551void ceph_con_get_out_msg(struct ceph_connection *con);553struct ceph_msg *ceph_con_get_out_msg(struct ceph_connection *con);
552 554
553/* messenger_v1.c */555/* messenger_v1.c */
554int ceph_con_v1_try_read(struct ceph_connection *con);556int ceph_con_v1_try_read(struct ceph_connection *con);
555int ceph_con_v1_try_write(struct ceph_connection *con);557int ceph_con_v1_try_write(struct ceph_connection *con);
556void ceph_con_v1_revoke(struct ceph_connection *con);558void ceph_con_v1_revoke(struct ceph_connection *con, struct ceph_msg *msg);
557void ceph_con_v1_revoke_incoming(struct ceph_connection *con);559void ceph_con_v1_revoke_incoming(struct ceph_connection *con);
558bool ceph_con_v1_opened(struct ceph_connection *con);560bool ceph_con_v1_opened(struct ceph_connection *con);
559void ceph_con_v1_reset_session(struct ceph_connection *con);561void 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 */
563int ceph_con_v2_try_read(struct ceph_connection *con);565int ceph_con_v2_try_read(struct ceph_connection *con);
564int ceph_con_v2_try_write(struct ceph_connection *con);566int ceph_con_v2_try_write(struct ceph_connection *con);
565void ceph_con_v2_revoke(struct ceph_connection *con);567void ceph_con_v2_revoke(struct ceph_connection *con, struct ceph_msg *msg);
566void ceph_con_v2_revoke_incoming(struct ceph_connection *con);568void ceph_con_v2_revoke_incoming(struct ceph_connection *con);
567bool ceph_con_v2_opened(struct ceph_connection *con);569bool ceph_con_v2_opened(struct ceph_connection *con);
568void ceph_con_v2_reset_session(struct ceph_connection *con);570void ceph_con_v2_reset_session(struct ceph_connection *con);
net/ceph/Kconfig+1−2
@@ -6,8 +6,7 @@ config CEPH_LIB · 5 unmodified lines
6 select CRYPTO_AES6 select CRYPTO_AES
7 select CRYPTO_CBC7 select CRYPTO_CBC
8 select CRYPTO_GCM8 select CRYPTO_GCM
9 select CRYPTO_HMAC9 select CRYPTO_LIB_SHA256
10 select CRYPTO_SHA256
11 select CRYPTO10 select CRYPTO
12 select KEYS11 select KEYS
13 default n12 default n
net/ceph/messenger.c+7−5
@@ -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 else1798 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
2114void ceph_con_get_out_msg(struct ceph_connection *con)2114struct 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/*
net/ceph/messenger_v1.c+26−30
@@ -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 things169 * 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 */
172static void prepare_write_message_footer(struct ceph_connection *con)172static 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 */
195static void prepare_write_message(struct ceph_connection *con)194static 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 } else240 } 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 do458 * 0 -> socket full, but more to do
463 * <0 -> error459 * <0 -> error
464 */460 */
465static int write_partial_message_data(struct ceph_connection *con)461static 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 else512 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 */
1473int ceph_con_v1_try_write(struct ceph_connection *con)1469int 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
1567void ceph_con_v1_revoke(struct ceph_connection *con)1565void 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) {
net/ceph/messenger_v2.c+110−136
@@ -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
796static int ceph_hmac_sha256(struct ceph_connection *con,782static 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
825out:
826 shash_desc_zero(desc);
827 return ret; /* auth_x, both plain and secure modes */
828}802}
829 803
830static void gcm_inc_nonce(struct ceph_gcm_nonce *nonce)804static 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
1455static int prepare_auth_signature(struct ceph_connection *con)1429static 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
1592static void prepare_epilogue_plain(struct ceph_connection *con, bool aborted)1563static 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 */
1606static void prepare_message_plain(struct ceph_connection *con)1578static 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 up1630 * 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 */
1662static int prepare_message_secure(struct ceph_connection *con)1633static 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
1720out:1692out:
@@ -1723,19 +1695,19 @@ out: · 2 unmodified lines
1723 return ret;1695 return ret;
1724}1696}
1725 1697
1726static int prepare_message(struct ceph_connection *con)1698static 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
3187static void queue_data(struct ceph_connection *con)3157static 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
3200static void queue_data_cont(struct ceph_connection *con)3170static 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
3253static void queue_zeros(struct ceph_connection *con)3223static 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
3295static int populate_out_iter(struct ceph_connection *con)3265static 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
3456static void prepare_zero_front(struct ceph_connection *con, int resid)3426static 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
3477static void prepare_zero_middle(struct ceph_connection *con, int resid)3448static 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
3498static void prepare_zero_data(struct ceph_connection *con)3470static 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
3505static void revoke_at_queue_data(struct ceph_connection *con)3478static 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
3548static void revoke_at_queue_data_cont(struct ceph_connection *con)3522static 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
3574static void revoke_at_finish_message(struct ceph_connection *con)3549static 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
3632void ceph_con_v2_revoke(struct ceph_connection *con)3608void 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;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t