Skip to content

Commit 8bd9238

Browse files
committed
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
2 parents 91b436f + d74d6c0 commit 8bd9238

File tree

17 files changed

+323
-248
lines changed

17 files changed

+323
-248
lines changed

MAINTAINERS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5694,6 +5694,7 @@ M: Xiubo Li <[email protected]>
56945694
56955695
S: Supported
56965696
W: http://ceph.com/
5697+
B: https://tracker.ceph.com/
56975698
T: git https://github.com/ceph/ceph-client.git
56985699
F: include/linux/ceph/
56995700
F: include/linux/crush/
@@ -5705,6 +5706,7 @@ M: Ilya Dryomov <[email protected]>
57055706
57065707
S: Supported
57075708
W: http://ceph.com/
5709+
B: https://tracker.ceph.com/
57085710
T: git https://github.com/ceph/ceph-client.git
57095711
F: Documentation/filesystems/ceph.rst
57105712
F: fs/ceph/
@@ -21357,6 +21359,7 @@ R: Dongsheng Yang <[email protected]>
2135721359
2135821360
S: Supported
2135921361
W: http://ceph.com/
21362+
B: https://tracker.ceph.com/
2136021363
T: git https://github.com/ceph/ceph-client.git
2136121364
F: Documentation/ABI/testing/sysfs-bus-rbd
2136221365
F: drivers/block/rbd.c

fs/ceph/dir.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,8 +1260,7 @@ static void ceph_async_unlink_cb(struct ceph_mds_client *mdsc,
12601260
spin_unlock(&fsc->async_unlink_conflict_lock);
12611261

12621262
spin_lock(&dentry->d_lock);
1263-
di->flags &= ~CEPH_DENTRY_ASYNC_UNLINK;
1264-
wake_up_bit(&di->flags, CEPH_DENTRY_ASYNC_UNLINK_BIT);
1263+
clear_and_wake_up_bit(CEPH_DENTRY_ASYNC_UNLINK_BIT, &di->flags);
12651264
spin_unlock(&dentry->d_lock);
12661265

12671266
synchronize_rcu();

fs/ceph/file.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -579,8 +579,7 @@ static void wake_async_create_waiters(struct inode *inode,
579579

580580
spin_lock(&ci->i_ceph_lock);
581581
if (ci->i_ceph_flags & CEPH_I_ASYNC_CREATE) {
582-
ci->i_ceph_flags &= ~CEPH_I_ASYNC_CREATE;
583-
wake_up_bit(&ci->i_ceph_flags, CEPH_ASYNC_CREATE_BIT);
582+
clear_and_wake_up_bit(CEPH_ASYNC_CREATE_BIT, &ci->i_ceph_flags);
584583

585584
if (ci->i_ceph_flags & CEPH_I_ASYNC_CHECK_CAPS) {
586585
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,
762761
}
763762

764763
spin_lock(&dentry->d_lock);
765-
di->flags &= ~CEPH_DENTRY_ASYNC_CREATE;
766-
wake_up_bit(&di->flags, CEPH_DENTRY_ASYNC_CREATE_BIT);
764+
clear_and_wake_up_bit(CEPH_DENTRY_ASYNC_CREATE_BIT, &di->flags);
767765
spin_unlock(&dentry->d_lock);
768766

769767
return ret;
@@ -2121,10 +2119,10 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
21212119
if (ceph_inode_is_shutdown(inode))
21222120
return -ESTALE;
21232121

2124-
if (direct_lock)
2125-
ceph_start_io_direct(inode);
2126-
else
2127-
ceph_start_io_read(inode);
2122+
ret = direct_lock ? ceph_start_io_direct(inode) :
2123+
ceph_start_io_read(inode);
2124+
if (ret)
2125+
return ret;
21282126

21292127
if (!(fi->flags & CEPH_F_SYNC) && !direct_lock)
21302128
want |= CEPH_CAP_FILE_CACHE;
@@ -2277,7 +2275,9 @@ static ssize_t ceph_splice_read(struct file *in, loff_t *ppos,
22772275
(fi->flags & CEPH_F_SYNC))
22782276
return copy_splice_read(in, ppos, pipe, len, flags);
22792277

2280-
ceph_start_io_read(inode);
2278+
ret = ceph_start_io_read(inode);
2279+
if (ret)
2280+
return ret;
22812281

22822282
want = CEPH_CAP_FILE_CACHE;
22832283
if (fi->fmode & CEPH_FILE_MODE_LAZY)
@@ -2356,10 +2356,10 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
23562356
direct_lock = true;
23572357

23582358
retry_snap:
2359-
if (direct_lock)
2360-
ceph_start_io_direct(inode);
2361-
else
2362-
ceph_start_io_write(inode);
2359+
err = direct_lock ? ceph_start_io_direct(inode) :
2360+
ceph_start_io_write(inode);
2361+
if (err)
2362+
goto out_unlocked;
23632363

23642364
if (iocb->ki_flags & IOCB_APPEND) {
23652365
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
28782878
struct ceph_object_id src_oid, dst_oid;
28792879
struct ceph_osd_client *osdc;
28802880
struct ceph_osd_request *req;
2881-
size_t bytes = 0;
2881+
ssize_t bytes = 0;
28822882
u64 src_objnum, src_objoff, dst_objnum, dst_objoff;
28832883
u32 src_objlen, dst_objlen;
28842884
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
29282928
"OSDs don't support copy-from2; disabling copy offload\n");
29292929
}
29302930
doutc(cl, "returned %d\n", ret);
2931-
if (!bytes)
2931+
if (bytes <= 0)
29322932
bytes = ret;
29332933
goto out;
29342934
}

fs/ceph/inode.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,6 +1794,11 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
17941794
goto done;
17951795
}
17961796

1797+
if (unlikely(!in)) {
1798+
err = -EINVAL;
1799+
goto done;
1800+
}
1801+
17971802
/* attach proper inode */
17981803
if (d_really_is_negative(dn)) {
17991804
ceph_dir_clear_ordered(dir);
@@ -1829,6 +1834,12 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
18291834
doutc(cl, " linking snapped dir %p to dn %p\n", in,
18301835
req->r_dentry);
18311836
ceph_dir_clear_ordered(dir);
1837+
1838+
if (unlikely(!in)) {
1839+
err = -EINVAL;
1840+
goto done;
1841+
}
1842+
18321843
ihold(in);
18331844
err = splice_dentry(&req->r_dentry, in);
18341845
if (err < 0)

fs/ceph/io.c

Lines changed: 75 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,23 @@
2121
/* Call with exclusively locked inode->i_rwsem */
2222
static void ceph_block_o_direct(struct ceph_inode_info *ci, struct inode *inode)
2323
{
24+
bool is_odirect;
25+
2426
lockdep_assert_held_write(&inode->i_rwsem);
2527

26-
if (READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT) {
27-
spin_lock(&ci->i_ceph_lock);
28-
ci->i_ceph_flags &= ~CEPH_I_ODIRECT;
29-
spin_unlock(&ci->i_ceph_lock);
30-
inode_dio_wait(inode);
28+
spin_lock(&ci->i_ceph_lock);
29+
/* ensure that bit state is consistent */
30+
smp_mb__before_atomic();
31+
is_odirect = READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT;
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();
3136
}
37+
spin_unlock(&ci->i_ceph_lock);
38+
39+
if (is_odirect)
40+
inode_dio_wait(inode);
3241
}
3342

3443
/**
@@ -47,20 +56,35 @@ static void ceph_block_o_direct(struct ceph_inode_info *ci, struct inode *inode)
4756
* Note that buffered writes and truncates both take a write lock on
4857
* inode->i_rwsem, meaning that those are serialised w.r.t. the reads.
4958
*/
50-
void
51-
ceph_start_io_read(struct inode *inode)
59+
int ceph_start_io_read(struct inode *inode)
5260
{
5361
struct ceph_inode_info *ci = ceph_inode(inode);
62+
bool is_odirect;
63+
int err;
5464

5565
/* Be an optimist! */
56-
down_read(&inode->i_rwsem);
57-
if (!(READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT))
58-
return;
66+
err = down_read_killable(&inode->i_rwsem);
67+
if (err)
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;
5977
up_read(&inode->i_rwsem);
78+
6079
/* Slow path.... */
61-
down_write(&inode->i_rwsem);
80+
err = down_write_killable(&inode->i_rwsem);
81+
if (err)
82+
return err;
83+
6284
ceph_block_o_direct(ci, inode);
6385
downgrade_write(&inode->i_rwsem);
86+
87+
return 0;
6488
}
6589

6690
/**
@@ -83,11 +107,12 @@ ceph_end_io_read(struct inode *inode)
83107
* Declare that a buffered write operation is about to start, and ensure
84108
* that we block all direct I/O.
85109
*/
86-
void
87-
ceph_start_io_write(struct inode *inode)
110+
int ceph_start_io_write(struct inode *inode)
88111
{
89-
down_write(&inode->i_rwsem);
90-
ceph_block_o_direct(ceph_inode(inode), inode);
112+
int err = down_write_killable(&inode->i_rwsem);
113+
if (!err)
114+
ceph_block_o_direct(ceph_inode(inode), inode);
115+
return err;
91116
}
92117

93118
/**
@@ -106,12 +131,22 @@ ceph_end_io_write(struct inode *inode)
106131
/* Call with exclusively locked inode->i_rwsem */
107132
static void ceph_block_buffered(struct ceph_inode_info *ci, struct inode *inode)
108133
{
134+
bool is_odirect;
135+
109136
lockdep_assert_held_write(&inode->i_rwsem);
110137

111-
if (!(READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT)) {
112-
spin_lock(&ci->i_ceph_lock);
113-
ci->i_ceph_flags |= CEPH_I_ODIRECT;
114-
spin_unlock(&ci->i_ceph_lock);
138+
spin_lock(&ci->i_ceph_lock);
139+
/* ensure that bit state is consistent */
140+
smp_mb__before_atomic();
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) {
115150
/* FIXME: unmap_mapping_range? */
116151
filemap_write_and_wait(inode->i_mapping);
117152
}
@@ -133,20 +168,35 @@ static void ceph_block_buffered(struct ceph_inode_info *ci, struct inode *inode)
133168
* Note that buffered writes and truncates both take a write lock on
134169
* inode->i_rwsem, meaning that those are serialised w.r.t. O_DIRECT.
135170
*/
136-
void
137-
ceph_start_io_direct(struct inode *inode)
171+
int ceph_start_io_direct(struct inode *inode)
138172
{
139173
struct ceph_inode_info *ci = ceph_inode(inode);
174+
bool is_odirect;
175+
int err;
140176

141177
/* Be an optimist! */
142-
down_read(&inode->i_rwsem);
143-
if (READ_ONCE(ci->i_ceph_flags) & CEPH_I_ODIRECT)
144-
return;
178+
err = down_read_killable(&inode->i_rwsem);
179+
if (err)
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;
145189
up_read(&inode->i_rwsem);
190+
146191
/* Slow path.... */
147-
down_write(&inode->i_rwsem);
192+
err = down_write_killable(&inode->i_rwsem);
193+
if (err)
194+
return err;
195+
148196
ceph_block_buffered(ci, inode);
149197
downgrade_write(&inode->i_rwsem);
198+
199+
return 0;
150200
}
151201

152202
/**

fs/ceph/io.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22
#ifndef _FS_CEPH_IO_H
33
#define _FS_CEPH_IO_H
44

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);
68
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);
810
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);
1012
void ceph_end_io_direct(struct inode *inode);
1113

1214
#endif /* FS_CEPH_IO_H */

fs/ceph/ioctl.c

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -246,21 +246,28 @@ static long ceph_ioctl_lazyio(struct file *file)
246246
struct ceph_inode_info *ci = ceph_inode(inode);
247247
struct ceph_mds_client *mdsc = ceph_inode_to_fs_client(inode)->mdsc;
248248
struct ceph_client *cl = mdsc->fsc->client;
249+
bool is_file_already_lazy = false;
249250

251+
spin_lock(&ci->i_ceph_lock);
250252
if ((fi->fmode & CEPH_FILE_MODE_LAZY) == 0) {
251-
spin_lock(&ci->i_ceph_lock);
252253
fi->fmode |= CEPH_FILE_MODE_LAZY;
253254
ci->i_nr_by_mode[ffs(CEPH_FILE_MODE_LAZY)]++;
254255
__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 {
256265
doutc(cl, "file %p %p %llx.%llx marked lazy\n", file, inode,
257266
ceph_vinop(inode));
258267

259268
ceph_check_caps(ci, 0);
260-
} else {
261-
doutc(cl, "file %p %p %llx.%llx already lazy\n", file, inode,
262-
ceph_vinop(inode));
263269
}
270+
264271
return 0;
265272
}
266273

fs/ceph/locks.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,10 @@ static int ceph_lock_wait_for_completion(struct ceph_mds_client *mdsc,
221221
if (err && err != -ERESTARTSYS)
222222
return err;
223223

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+
225228
return 0;
226229
}
227230

0 commit comments

Comments
 (0)