History

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

Pull ceph updates from Ilya Dryomov: "A wide variety of mostly CephFS fixes and cleanups, split between changes that address edge cases (Sam, Xiubo, Matthew), efficiency improvements (Max) and AI-assisted hardening (Michael, Jeremy). One thing that stands out is Alex's change to how CephFS behaves in NEARFULL scenarios: the long-standing "make all writes synchronous" behavior has become opt-in. It was always somewhat controversial and doesn't make much sense for modern deployments; the new default is to continue normal operation (i.e. buffer writes as MDS allows, etc). The behavior in case the cluster reaches any FULL state remains the same as before" * tag 'ceph-for-7.3-rc1' of https://github.com/ceph/ceph-client: (32 commits) ceph: force a cap message when a deferred revoke can't be acked immediately libceph: reject buckets with mismatched CRUSH ids ceph: reject export_targets ranks >= CEPH_MAX_MDS in mdsmap decode ceph: fix leaked inode reference on writeback abort at umount libceph: remove ceph_put_page_vector() libceph: validate banner payload length ceph: make nearfull sync writes opt-in ceph: do not repeat ceph_trim_dentries() if no progress possible ceph: drop mdsc->mutex before decoding the MDS reply ceph: fix UAF in check_new_map() on session freed during unlock ceph: fix UAF in __kick_flushing_caps() on cf entry freed during unlock ceph: pass inode pointer around instead of reloading it ceph: mark cap remove with RB_CLEAR_NODE() instead of setting ci=NULL ceph: add helper function ceph_cap_is_removed() ceph: make __ceph_remove_cap() static ceph: cap delegated inode count in ceph_parse_deleg_inos() ceph: bound num_export_targets array for mds info v2/v3 ceph: bound MDSCapAuth path and fs_name decode in handle_session() ceph: bound xattr value length in __build_xattrs() ceph: bound copied dentry name length in NFS export get_name ...

Linus Torvalds committed 2 months ago

Commit 548e7bc2 parents ce727a0 8fdf94620 files · +462 −131Browse files

Unified · Split

20 files
  1. Documentation/filesystems/ceph.rst +6 −0
  2. fs/ceph/addr.c +22 −8
  3. fs/ceph/caps.c +116 −50
  4. fs/ceph/crypto.c +37 −13
  5. fs/ceph/crypto.h +2 −2
  6. fs/ceph/dir.c +16 −6
  7. fs/ceph/export.c +17 −9
  8. fs/ceph/file.c +53 −3
  9. fs/ceph/inode.c +2 −1
  10. fs/ceph/mds_client.c +89 −21
  11. fs/ceph/mds_client.h +1 −0
  12. fs/ceph/mdsmap.c +10 −1
  13. fs/ceph/super.c +10 −0
  14. fs/ceph/super.h +43 −2
  15. fs/ceph/xattr.c +1 −0
  16. include/linux/ceph/libceph.h +0 −2
  17. net/ceph/messenger_v2.c +5 −0
  18. net/ceph/osd_client.c +30 −0
  19. net/ceph/osdmap.c +2 −0
  20. net/ceph/pagevec.c +0 −13
Documentation/filesystems/ceph.rst+6−0
@@ -194,6 +194,12 @@ Mount Options · 193 unmodified lines
194194 copies. Currently, it's only used in copy_file_range, which will revert
195195 to the default VFS implementation if this option is used.
196196
197+ nearfull_sync
198+ Force written data to stable storage when the cluster or file data pool is
199+ marked NEARFULL. This restores the legacy client-side backpressure
200+ behavior. By default, CephFS writes are not forced synchronous solely
201+ because of NEARFULL.
202+
197203 recover_session=<no|clean>
198204 Set auto reconnect mode in the case where the client is blocklisted. The
199205 available modes are "no" and "clean". The default is "no".
fs/ceph/addr.c+22−8
@@ -255,9 +255,12 @@ static void finish_netfs_read(struct ceph_osd_request *req) · 254 unmodified lines
255255 }
256256
257257 if (osd_data->type == CEPH_OSD_DATA_TYPE_PAGES) {
258− ceph_put_page_vector(osd_data->pages,
259− calc_pages_for(osd_data->alignment,
260− osd_data->length), false);
258+ int num_pages = calc_pages_for(osd_data->alignment,
259+ osd_data->length);
260+
261+ for (int i = 0; i < num_pages; i++)
262+ put_page(osd_data->pages[i]);
263+ kvfree(osd_data->pages);
261264 }
262265 if (err > 0) {
263266 ceph_subvolume_metrics_record_io(fsc->mdsc, ceph_inode(inode),
@@ -1426,6 +1429,16 @@ void ceph_shift_unused_folios_left(struct folio_batch *fbatch) · 1162 unmodified lines
14261429 fbatch->nr = n;
14271430 }
14281431
1432+static void ceph_undo_wrbuffer_claim(struct inode *inode, struct folio *folio)
1433+{
1434+ struct ceph_snap_context *snapc = folio_detach_private(folio);
1435+
1436+ if (!snapc)
1437+ return;
1438+ ceph_put_wrbuffer_cap_refs(ceph_inode(inode), 1, snapc);
1439+ ceph_put_snap_context(snapc);
1440+}
1441+
14291442 static
14301443 int ceph_submit_write(struct address_space *mapping,
14311444 struct writeback_control *wbc,
@@ -1489,6 +1502,7 @@ new_request: · 57 unmodified lines
14891502 if (!page)
14901503 continue;
14911504
1505+ ceph_undo_wrbuffer_claim(inode, page_folio(page));
14921506 redirty_page_for_writepage(wbc, page);
14931507 unlock_page(page);
14941508 }
@@ -2464,7 +2478,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, · 969 unmodified lines
24642478 }
24652479
24662480 rd_req = ceph_osdc_alloc_request(&fsc->client->osdc, NULL,
2467− 1, false, GFP_NOFS);
2481+ 1, false, GFP_KERNEL);
24682482 if (!rd_req) {
24692483 err = -ENOMEM;
24702484 goto out_unlock;
@@ -2477,12 +2491,12 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, · 6 unmodified lines
24772491 rd_req->r_base_oloc.pool_ns = ceph_get_string(pool_ns);
24782492 ceph_oid_printf(&rd_req->r_base_oid, "%llx.00000000", ci->i_vino.ino);
24792493
2480− err = ceph_osdc_alloc_messages(rd_req, GFP_NOFS);
2494+ err = ceph_osdc_alloc_messages(rd_req, GFP_KERNEL);
24812495 if (err)
24822496 goto out_unlock;
24832497
24842498 wr_req = ceph_osdc_alloc_request(&fsc->client->osdc, NULL,
2485− 1, false, GFP_NOFS);
2499+ 1, false, GFP_KERNEL);
24862500 if (!wr_req) {
24872501 err = -ENOMEM;
24882502 goto out_unlock;
@@ -2493,7 +2507,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, · 4 unmodified lines
24932507 ceph_oloc_copy(&wr_req->r_base_oloc, &rd_req->r_base_oloc);
24942508 ceph_oid_copy(&wr_req->r_base_oid, &rd_req->r_base_oid);
24952509
2496− err = ceph_osdc_alloc_messages(wr_req, GFP_NOFS);
2510+ err = ceph_osdc_alloc_messages(wr_req, GFP_KERNEL);
24972511 if (err)
24982512 goto out_unlock;
24992513
@@ -2532,7 +2546,7 @@ static int __ceph_pool_perm_get(struct ceph_inode_info *ci, · 32 unmodified lines
25322546 }
25332547
25342548 pool_ns_len = pool_ns ? pool_ns->len : 0;
2535− perm = kmalloc_flex(*perm, pool_ns, pool_ns_len + 1, GFP_NOFS);
2549+ perm = kmalloc_flex(*perm, pool_ns, pool_ns_len + 1, GFP_KERNEL);
25362550 if (!perm) {
25372551 err = -ENOMEM;
25382552 goto out_unlock;
fs/ceph/caps.c+116−50
@@ -785,9 +785,9 @@ void ceph_add_cap(struct inode *inode, · 784 unmodified lines
785785 * generation of the MDS session (i.e. has not gone 'stale' due to
786786 * us losing touch with the mds).
787787 */
788−static int __cap_is_valid(struct ceph_cap *cap)
788+static int __cap_is_valid(struct ceph_inode_info *ci, struct ceph_cap *cap)
789789 {
790− struct inode *inode = &cap->ci->netfs.inode;
790+ struct inode *inode = &ci->netfs.inode;
791791 struct ceph_client *cl = cap->session->s_mdsc->fsc->client;
792792 unsigned long ttl;
793793 u32 gen;
@@ -822,7 +822,7 @@ int __ceph_caps_issued(struct ceph_inode_info *ci, int *implemented) · 28 unmodified lines
822822 *implemented = 0;
823823 for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
824824 cap = rb_entry(p, struct ceph_cap, ci_node);
825− if (!__cap_is_valid(cap))
825+ if (!__cap_is_valid(ci, cap))
826826 continue;
827827 doutc(cl, "%p %llx.%llx cap %p issued %s\n", inode,
828828 ceph_vinop(inode), cap, ceph_cap_string(cap->issued));
@@ -855,7 +855,7 @@ int __ceph_caps_issued_other(struct ceph_inode_info *ci, struct ceph_cap *ocap) · 26 unmodified lines
855855 cap = rb_entry(p, struct ceph_cap, ci_node);
856856 if (cap == ocap)
857857 continue;
858− if (!__cap_is_valid(cap))
858+ if (!__cap_is_valid(ci, cap))
859859 continue;
860860 have |= cap->issued;
861861 }
@@ -866,11 +866,19 @@ int __ceph_caps_issued_other(struct ceph_inode_info *ci, struct ceph_cap *ocap) · 4 unmodified lines
866866 * Move a cap to the end of the LRU (oldest caps at list head, newest
867867 * at list tail).
868868 */
869−static void __touch_cap(struct ceph_cap *cap)
869+static void __touch_cap(struct ceph_inode_info *ci, struct ceph_cap *cap)
870870 {
871− struct inode *inode = &cap->ci->netfs.inode;
871+ struct inode *inode = &ci->netfs.inode;
872872 struct ceph_mds_session *s = cap->session;
873873 struct ceph_client *cl = s->s_mdsc->fsc->client;
874+ static u8 skip_counter;
875+
876+ if (data_race(++skip_counter))
877+ /* skip this call most of the time to reduce lock
878+ * contention; the LRU list is still accurate enough
879+ * for ceph_trim_caps()
880+ */
881+ return;
874882
875883 spin_lock(&s->s_cap_lock);
876884 if (!s->s_cap_iterator) {
@@ -906,7 +914,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) · 29 unmodified lines
906914
907915 for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
908916 cap = rb_entry(p, struct ceph_cap, ci_node);
909− if (!__cap_is_valid(cap))
917+ if (!__cap_is_valid(ci, cap))
910918 continue;
911919 if ((cap->issued & mask) == mask) {
912920 doutc(cl, "mask %p %llx.%llx cap %p issued %s (mask %s)\n",
@@ -914,7 +922,7 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) · 1 unmodified line
914922 ceph_cap_string(cap->issued),
915923 ceph_cap_string(mask));
916924 if (touch)
917− __touch_cap(cap);
925+ __touch_cap(ci, cap);
918926 return 1;
919927 }
920928
@@ -929,15 +937,15 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch) · 8 unmodified lines
929937 struct rb_node *q;
930938
931939 /* touch this + preceding caps */
932− __touch_cap(cap);
940+ __touch_cap(ci, cap);
933941 for (q = rb_first(&ci->i_caps); q != p;
934942 q = rb_next(q)) {
935943 cap = rb_entry(q, struct ceph_cap,
936944 ci_node);
937− if (!__cap_is_valid(cap))
945+ if (!__cap_is_valid(ci, cap))
938946 continue;
939947 if (cap->issued & mask)
940− __touch_cap(cap);
948+ __touch_cap(ci, cap);
941949 }
942950 }
943951 return 1;
@@ -979,6 +987,27 @@ int __ceph_caps_revoking_other(struct ceph_inode_info *ci, · 35 unmodified lines
979987 return 0;
980988 }
981989
990+/*
991+ * Return true if any cap of this inode holds caps which the MDS has
992+ * revoked, but which we have not released yet.
993+ */
994+static bool __ceph_is_any_revoking(const struct ceph_inode_info *ci)
995+{
996+ const struct rb_node *p;
997+
998+ lockdep_assert_held(&ci->i_ceph_lock);
999+
1000+ for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
1001+ const struct ceph_cap *cap =
1002+ rb_entry(p, struct ceph_cap, ci_node);
1003+
1004+ if (cap->implemented & ~cap->issued)
1005+ return true;
1006+ }
1007+
1008+ return false;
1009+}
1010+
9821011 int __ceph_caps_used(struct ceph_inode_info *ci)
9831012 {
9841013 int used = 0;
@@ -1091,7 +1120,7 @@ int __ceph_caps_mds_wanted(struct ceph_inode_info *ci, bool check) · 106 unmodified lines
10911120
10921121 for (p = rb_first(&ci->i_caps); p; p = rb_next(p)) {
10931122 cap = rb_entry(p, struct ceph_cap, ci_node);
1094− if (check && !__cap_is_valid(cap))
1123+ if (check && !__cap_is_valid(ci, cap))
10951124 continue;
10961125 if (cap == ci->i_auth_cap)
10971126 mds_wanted |= cap->mds_wanted;
@@ -1119,20 +1148,20 @@ int ceph_is_any_caps(struct inode *inode) · 21 unmodified lines
11191148 * caller should hold i_ceph_lock.
11201149 * caller will not hold session s_mutex if called from destroy_inode.
11211150 */
1122−void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release)
1151+static void __ceph_remove_cap(struct ceph_inode_info *ci, struct ceph_cap *cap, bool queue_release)
11231152 {
1124− struct ceph_mds_session *session = cap->session;
1125− struct ceph_client *cl = session->s_mdsc->fsc->client;
1126− struct ceph_inode_info *ci = cap->ci;
1127− struct inode *inode = &ci->netfs.inode;
1153+ struct ceph_mds_session *session;
1154+ struct ceph_client *cl;
1155+ struct inode *inode;
11281156 struct ceph_mds_client *mdsc;
11291157 int removed = 0;
11301158
1131− /* 'ci' being NULL means the remove have already occurred */
1132− if (!ci) {
1133− doutc(cl, "inode is NULL\n");
1159+ if (ceph_cap_is_removed(cap))
11341160 return;
1135− }
1161+
1162+ session = cap->session;
1163+ cl = session->s_mdsc->fsc->client;
1164+ inode = &ci->netfs.inode;
11361165
11371166 lockdep_assert_held(&ci->i_ceph_lock);
11381167
@@ -1158,8 +1187,11 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) · 19 unmodified lines
11581187 cap->session = NULL;
11591188 removed = 1;
11601189 }
1161− /* protect backpointer with s_cap_lock: see iterate_session_caps */
1162− cap->ci = NULL;
1190+
1191+ /* protect removal marker with both i_ceph_lock and
1192+ s_cap_lock, so either one can be used to check for
1193+ removal */
1194+ RB_CLEAR_NODE(&cap->ci_node);
11631195
11641196 /*
11651197 * s_cap_reconnect is protected by s_cap_lock. no one changes
@@ -1196,13 +1228,12 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) · 30 unmodified lines
11961228 }
11971229
11981230 void ceph_remove_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
1231+ struct ceph_inode_info *ci,
11991232 bool queue_release)
12001233 {
1201− struct ceph_inode_info *ci = cap->ci;
12021234 struct ceph_fs_client *fsc;
12031235
1204− /* 'ci' being NULL means the remove have already occurred */
1205− if (!ci) {
1236+ if (ceph_cap_is_removed(cap)) {
12061237 doutc(mdsc->fsc->client, "inode is NULL\n");
12071238 return;
12081239 }
@@ -1215,7 +1246,7 @@ void ceph_remove_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap, · 6 unmodified lines
12151246 !fsc->blocklisted &&
12161247 !ceph_inode_is_shutdown(&ci->netfs.inode));
12171248
1218− __ceph_remove_cap(cap, queue_release);
1249+ __ceph_remove_cap(ci, cap, queue_release);
12191250 }
12201251
12211252 struct cap_msg_args {
@@ -1375,7 +1406,7 @@ void __ceph_remove_caps(struct ceph_inode_info *ci) · 153 unmodified lines
13751406 while (p) {
13761407 struct ceph_cap *cap = rb_entry(p, struct ceph_cap, ci_node);
13771408 p = rb_next(p);
1378− ceph_remove_cap(mdsc, cap, true);
1409+ ceph_remove_cap(mdsc, cap, ci, true);
13791410 }
13801411 spin_unlock(&ci->i_ceph_lock);
13811412 }
@@ -1388,11 +1419,11 @@ void __ceph_remove_caps(struct ceph_inode_info *ci) · 6 unmodified lines
13881419 * Make note of max_size reported/requested from mds, revoked caps
13891420 * that have now been implemented.
13901421 */
1391−static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap,
1422+static void __prep_cap(struct cap_msg_args *arg, struct ceph_inode_info *ci,
1423+ struct ceph_cap *cap,
13921424 int op, int flags, int used, int want, int retain,
13931425 int flushing, u64 flush_tid, u64 oldest_flush_tid)
13941426 {
1395− struct ceph_inode_info *ci = cap->ci;
13961427 struct inode *inode = &ci->netfs.inode;
13971428 struct ceph_client *cl = ceph_inode_to_client(inode);
13981429 int held, revoking;
@@ -1421,6 +1452,9 @@ static void __prep_cap(struct cap_msg_args *arg, struct ceph_cap *cap, · 22 unmodified lines
14211452 cap->implemented &= cap->issued | used;
14221453 cap->mds_wanted = want;
14231454
1455+ if ((ci->i_ceph_flags & CEPH_I_FLUSH_FORCE) != 0 && !__ceph_is_any_revoking(ci))
1456+ clear_bit(CEPH_I_FLUSH_FORCE_BIT, &ci->i_ceph_flags);
1457+
14241458 arg->session = cap->session;
14251459 arg->ino = ceph_vino(inode).ino;
14261460 arg->cid = cap->cap_id;
@@ -1842,7 +1876,7 @@ struct ceph_cap_flush *ceph_alloc_cap_flush(void) · 415 unmodified lines
18421876 {
18431877 struct ceph_cap_flush *cf;
18441878
1845− cf = kmem_cache_alloc(ceph_cap_flush_cachep, GFP_KERNEL);
1879+ cf = kmem_cache_alloc(ceph_cap_flush_cachep, GFP_NOFS);
18461880 if (!cf)
18471881 return NULL;
18481882
@@ -2038,6 +2072,14 @@ void ceph_check_caps(struct ceph_inode_info *ci, int flags) · 189 unmodified lines
20382072
20392073 if (ci->i_ceph_flags & CEPH_I_FLUSH)
20402074 flags |= CHECK_CAPS_FLUSH;
2075+ /*
2076+ * A revoke whose response was deferred (see handle_cap_grant()) must
2077+ * still be acknowledged. Replay the forced flush here so that even a
2078+ * check triggered by writeback/invalidation completion sends a cap
2079+ * message to the MDS.
2080+ */
2081+ if (ci->i_ceph_flags & CEPH_I_FLUSH_FORCE)
2082+ flags |= CHECK_CAPS_FLUSH_FORCE;
20412083 retry:
20422084 /* Caps wanted by virtue of active open files. */
20432085 file_wanted = __ceph_caps_file_wanted(ci);
@@ -2210,7 +2252,7 @@ retry: · 166 unmodified lines
22102252 if (want & ~cap->mds_wanted) {
22112253 if (want & ~(cap->mds_wanted | cap->issued))
22122254 goto ack;
2213− if (!__cap_is_valid(cap))
2255+ if (!__cap_is_valid(ci, cap))
22142256 goto ack;
22152257 }
22162258
@@ -2252,7 +2294,7 @@ ack: · 35 unmodified lines
22522294
22532295 mds = cap->mds; /* remember mds, so we don't repeat */
22542296
2255− __prep_cap(&arg, cap, CEPH_CAP_OP_UPDATE, mflags, cap_used,
2297+ __prep_cap(&arg, ci, cap, CEPH_CAP_OP_UPDATE, mflags, cap_used,
22562298 want, retain, flushing, flush_tid, oldest_flush_tid);
22572299
22582300 spin_unlock(&ci->i_ceph_lock);
@@ -2314,7 +2356,7 @@ retry_locked: · 55 unmodified lines
23142356 flush_tid = __mark_caps_flushing(inode, session, true,
23152357 &oldest_flush_tid);
23162358
2317− __prep_cap(&arg, cap, CEPH_CAP_OP_FLUSH, CEPH_CLIENT_CAPS_SYNC,
2359+ __prep_cap(&arg, ci, cap, CEPH_CAP_OP_FLUSH, CEPH_CLIENT_CAPS_SYNC,
23182360 __ceph_caps_used(ci), __ceph_caps_wanted(ci),
23192361 (cap->issued | cap->implemented),
23202362 flushing, flush_tid, oldest_flush_tid);
@@ -2589,9 +2631,14 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, · 268 unmodified lines
25892631 }
25902632 }
25912633
2592− list_for_each_entry(cf, &ci->i_cap_flush_list, i_list) {
2593− if (cf->tid < first_tid)
2634+ cf = list_first_entry(&ci->i_cap_flush_list, struct ceph_cap_flush, i_list);
2635+ while (&cf->i_list != &ci->i_cap_flush_list) {
2636+ struct ceph_cap_flush *next;
2637+
2638+ if (cf->tid < first_tid) {
2639+ cf = list_next_entry(cf, i_list);
25942640 continue;
2641+ }
25952642
25962643 cap = ci->i_auth_cap;
25972644 if (!(cap && cap->session == session)) {
@@ -2601,6 +2648,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, · 3 unmodified lines
26012648 }
26022649
26032650 first_tid = cf->tid + 1;
2651+ next = list_next_entry(cf, i_list);
26042652
26052653 if (!cf->is_capsnap) {
26062654 struct cap_msg_args arg;
@@ -2608,7 +2656,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, · 1 unmodified line
26082656 doutc(cl, "%p %llx.%llx cap %p tid %llu %s\n",
26092657 inode, ceph_vinop(inode), cap, cf->tid,
26102658 ceph_cap_string(cf->caps));
2611− __prep_cap(&arg, cap, CEPH_CAP_OP_FLUSH,
2659+ __prep_cap(&arg, ci, cap, CEPH_CAP_OP_FLUSH,
26122660 (cf->tid < last_snap_flush ?
26132661 CEPH_CLIENT_CAPS_PENDING_CAPSNAP : 0),
26142662 __ceph_caps_used(ci),
@@ -2641,6 +2689,7 @@ static void __kick_flushing_caps(struct ceph_mds_client *mdsc, · 26 unmodified lines
26412689 }
26422690
26432691 spin_lock(&ci->i_ceph_lock);
2692+ cf = next;
26442693 }
26452694 }
26462695
@@ -3757,13 +3806,30 @@ static void handle_cap_grant(struct inode *inode, · 1110 unmodified lines
37573806 BUG_ON(cap->issued & ~cap->implemented);
37583807
37593808 /* don't let check_caps skip sending a response to MDS for revoke msgs */
3760− if (!revoke_wait && le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) {
3761− cap->mds_wanted = 0;
3762− flags |= CHECK_CAPS_FLUSH_FORCE;
3763− if (cap == ci->i_auth_cap)
3764− check_caps = 1; /* check auth cap only */
3765− else
3766− check_caps = 2; /* check all caps */
3809+ if (le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) {
3810+ if (revoke_wait) {
3811+ /*
3812+ * We can't ack the revoke yet: the response is deferred
3813+ * until the writeback or cache invalidation queued above
3814+ * completes. Set the CEPH_I_FLUSH_FORCE flag to remember
3815+ * that a forced cap message is owed so that deferred
3816+ * completion (ceph_put_wrbuffer_cap_refs() or the
3817+ * invalidate worker, both of which call ceph_check_caps())
3818+ * actually sends one, even if by then the revoked caps look
3819+ * unused, the inode is retaining caps, or the MDS has
3820+ * re-granted them. Without this, the cap message is never
3821+ * sent and the MDS hangs ("isn't responding to
3822+ * mclientcaps(revoke)").
3823+ */
3824+ set_bit(CEPH_I_FLUSH_FORCE_BIT, &ci->i_ceph_flags);
3825+ } else {
3826+ cap->mds_wanted = 0;
3827+ flags |= CHECK_CAPS_FLUSH_FORCE;
3828+ if (cap == ci->i_auth_cap)
3829+ check_caps = 1; /* check auth cap only */
3830+ else
3831+ check_caps = 2; /* check all caps */
3832+ }
37673833 }
37683834
37693835 if (extra_info->inline_version > 0 &&
@@ -4119,7 +4185,7 @@ retry: · 349 unmodified lines
41194185 goto out_unlock;
41204186
41214187 if (target < 0) {
4122− ceph_remove_cap(mdsc, cap, false);
4188+ ceph_remove_cap(mdsc, cap, ci, false);
41234189 goto out_unlock;
41244190 }
41254191
@@ -4156,7 +4222,7 @@ retry: · 30 unmodified lines
41564222 change_auth_cap_ses(ci, tcap->session);
41574223 }
41584224 }
4159− ceph_remove_cap(mdsc, cap, false);
4225+ ceph_remove_cap(mdsc, cap, ci, false);
41604226 goto out_unlock;
41614227 } else if (tsession) {
41624228 /* add placeholder for the export target */
@@ -4173,7 +4239,7 @@ retry: · 10 unmodified lines
41734239 spin_unlock(&mdsc->cap_dirty_lock);
41744240 }
41754241
4176− ceph_remove_cap(mdsc, cap, false);
4242+ ceph_remove_cap(mdsc, cap, ci, false);
41774243 goto out_unlock;
41784244 }
41794245
@@ -4289,7 +4355,7 @@ retry: · 109 unmodified lines
42894355 inode, ceph_vinop(inode), peer,
42904356 ocap->seq, ocap->mseq, mds, piseq, pmseq);
42914357 }
4292− ceph_remove_cap(mdsc, ocap, (ph->flags & CEPH_CAP_FLAG_RELEASE));
4358+ ceph_remove_cap(mdsc, ocap, ci, (ph->flags & CEPH_CAP_FLAG_RELEASE));
42934359 }
42944360
42954361 *old_issued = issued;
@@ -4887,7 +4953,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, · 591 unmodified lines
48874953 drop &= ~(used | dirty);
48884954
48894955 cap = __get_cap_for_mds(ci, mds);
4890− if (cap && __cap_is_valid(cap)) {
4956+ if (cap && __cap_is_valid(ci, cap)) {
48914957 unless &= cap->issued;
48924958 if (unless) {
48934959 if (unless & CEPH_CAP_AUTH_EXCL)
@@ -5046,7 +5112,7 @@ int ceph_purge_inode_cap(struct inode *inode, struct ceph_cap *cap, bool *invali · 152 unmodified lines
50465112 cap, ci, inode, ceph_vinop(inode));
50475113
50485114 is_auth = (cap == ci->i_auth_cap);
5049− __ceph_remove_cap(cap, false);
5115+ __ceph_remove_cap(ci, cap, false);
50505116 if (is_auth) {
50515117 struct ceph_cap_flush *cf;
50525118
fs/ceph/crypto.c+37−13
@@ -298,18 +298,26 @@ out: · 297 unmodified lines
298298 * Otherwise, base64 decode the string, and then ask fscrypt to format it
299299 * for userland presentation.
300300 *
301+ * Though the fscrypt/crypto subsystems broadly expect all buffers to be in the
302+ * linear-mapped region, this function slightly relaxes those requirements:
303+ * fname->ctext, fname->name, and oname->name may be vmalloc(), but not tname.
304+ *
301305 * Returns 0 on success or negative error code on error.
302306 */
303−int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
307+int ceph_fname_to_usr(const struct ceph_fname *fname, unsigned char *tname,
304308 struct fscrypt_str *oname, bool *is_nokey)
305309 {
306310 struct inode *dir = fname->dir;
307311 struct fscrypt_str _tname = FSTR_INIT(NULL, 0);
312+ struct fscrypt_str _oname;
308313 struct fscrypt_str iname;
309314 char *name = fname->name;
310315 int name_len = fname->name_len;
311316 int ret;
312317
318+ if (WARN_ON_ONCE(tname && is_vmalloc_addr(tname)))
319+ return -EIO;
320+
313321 /* Sanity check that the resulting name will fit in the buffer */
314322 if (fname->name_len > NAME_MAX || fname->ctext_len > NAME_MAX)
315323 return -EIO;
@@ -350,31 +358,47 @@ int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname, · 34 unmodified lines
350358 goto out_inode;
351359 }
352360
361+ if (!tname && (fname->ctext_len == 0 ||
362+ unlikely(is_vmalloc_addr(fname->ctext)) ||
363+ unlikely(is_vmalloc_addr(oname->name)))) {
364+ ret = fscrypt_fname_alloc_buffer(NAME_MAX, &_tname);
365+ if (ret)
366+ goto out_inode;
367+ tname = _tname.name;
368+ }
369+
353370 if (fname->ctext_len == 0) {
354371 int declen;
355372
356− if (!tname) {
357− ret = fscrypt_fname_alloc_buffer(NAME_MAX, &_tname);
358− if (ret)
359− goto out_inode;
360− tname = &_tname;
361− }
362−
363− declen = base64_decode(name, name_len,
364− tname->name, false, BASE64_IMAP);
373+ declen = base64_decode(name, name_len, tname, false, BASE64_IMAP);
365374 if (declen <= 0) {
366375 ret = -EIO;
367376 goto out;
368377 }
369− iname.name = tname->name;
378+ iname.name = tname;
370379 iname.len = declen;
380+ } else if (unlikely(is_vmalloc_addr(fname->ctext))) {
381+ memcpy(tname, fname->ctext, fname->ctext_len);
382+
383+ iname.name = tname;
384+ iname.len = fname->ctext_len;
371385 } else {
372386 iname.name = fname->ctext;
373387 iname.len = fname->ctext_len;
374388 }
375389
376− ret = fscrypt_fname_disk_to_usr(dir, 0, 0, &iname, oname);
377− if (!ret && (dir != fname->dir)) {
390+ _oname.name = unlikely(is_vmalloc_addr(oname->name)) ? tname : oname->name;
391+ _oname.len = oname->len;
392+
393+ ret = fscrypt_fname_disk_to_usr(dir, 0, 0, &iname, &_oname);
394+ if (ret)
395+ goto out;
396+
397+ if (unlikely(is_vmalloc_addr(oname->name)))
398+ memcpy(oname->name, _oname.name, _oname.len);
399+ oname->len = _oname.len;
400+
401+ if (dir != fname->dir) {
378402 char tmp_buf[BASE64_CHARS(NAME_MAX)];
379403
380404 name_len = snprintf(tmp_buf, sizeof(tmp_buf), "_%.*s_%llu",
fs/ceph/crypto.h+2−2
@@ -115,7 +115,7 @@ static inline void ceph_fname_free_buffer(struct inode *parent, · 114 unmodified lines
115115 fscrypt_fname_free_buffer(fname);
116116 }
117117
118−int ceph_fname_to_usr(const struct ceph_fname *fname, struct fscrypt_str *tname,
118+int ceph_fname_to_usr(const struct ceph_fname *fname, unsigned char *tname,
119119 struct fscrypt_str *oname, bool *is_nokey);
120120 int ceph_fscrypt_prepare_readdir(struct inode *dir);
121121
@@ -204,7 +204,7 @@ static inline void ceph_fname_free_buffer(struct inode *parent, · 82 unmodified lines
204204 }
205205
206206 static inline int ceph_fname_to_usr(const struct ceph_fname *fname,
207− struct fscrypt_str *tname,
207+ unsigned char *tname,
208208 struct fscrypt_str *oname, bool *is_nokey)
209209 {
210210 oname->name = fname->name;
fs/ceph/dir.c+16−6
@@ -774,8 +774,13 @@ struct dentry *ceph_finish_lookup(struct ceph_mds_request *req, · 773 unmodified lines
774774 d_drop(dentry);
775775 err = -ENOENT;
776776 } else {
777− if (d_unhashed(dentry))
778− d_add(dentry, NULL);
777+ if (d_unhashed(dentry)) {
778+ struct inode *parent =
779+ d_inode(dentry->d_parent);
780+ if (!parent ||
781+ ceph_snap(parent) == CEPH_NOSNAP)
782+ d_add(dentry, NULL);
783+ }
779784 }
780785 }
781786 }
@@ -840,6 +845,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, · 58 unmodified lines
840845 dentry->d_name.len) &&
841846 !is_root_ceph_dentry(dir, dentry) &&
842847 ceph_test_mount_opt(fsc, DCACHE) &&
848+ ceph_snap(dir) == CEPH_NOSNAP &&
843849 __ceph_dir_is_complete(ci) &&
844850 __ceph_caps_issued_mask_metric(ci, CEPH_CAP_FILE_SHARED, 1)) {
845851 __ceph_touch_fmode(ci, mdsc, CEPH_FILE_MODE_RD);
@@ -1173,7 +1179,7 @@ static struct dentry *ceph_mkdir(struct mnt_idmap *idmap, struct inode *dir, · 327 unmodified lines
11731179 !req->r_reply_info.head->is_target &&
11741180 !req->r_reply_info.head->is_dentry)
11751181 err = ceph_handle_notrace_create(dir, dentry);
1176− ret = ERR_PTR(err);
1182+ ret = err ? ERR_PTR(err) : NULL;
11771183 out_req:
11781184 if (!IS_ERR(ret) && req->r_dentry != dentry)
11791185 /* Some other dentry was spliced in */
@@ -1763,11 +1769,11 @@ static int __dir_lease_check(const struct dentry *dentry, · 583 unmodified lines
17631769 if (ret > 0) {
17641770 if (time_before(jiffies, di->time + lwc->dir_lease_ttl))
17651771 return STOP;
1772+ if (!lwc->expire_dir_lease)
1773+ return KEEP;
17661774 /* Move dentry to tail of dir lease list if we don't want
17671775 * to delete it. So dentries in the list are checked in a
17681776 * round robin manner */
1769− if (!lwc->expire_dir_lease)
1770− return TOUCH;
17711777 if (dentry->d_lockref.count > 0 ||
17721778 (di->flags & CEPH_DENTRY_REFERENCED))
17731779 return TOUCH;
@@ -1794,7 +1800,7 @@ int ceph_trim_dentries(struct ceph_mds_client *mdsc) · 20 unmodified lines
17941800 lwc.dir_lease = false;
17951801 lwc.nr_to_scan = CEPH_CAPS_PER_RELEASE * 2;
17961802 freed = __dentry_leases_walk(mdsc, &lwc);
1797− if (!lwc.nr_to_scan) /* more invalid leases */
1803+ if (freed > 0 && !lwc.nr_to_scan) /* more invalid leases */
17981804 return -EAGAIN;
17991805
18001806 if (lwc.nr_to_scan < CEPH_CAPS_PER_RELEASE)
@@ -1804,6 +1810,10 @@ int ceph_trim_dentries(struct ceph_mds_client *mdsc) · 3 unmodified lines
18041810 lwc.expire_dir_lease = freed < count;
18051811 lwc.dir_lease_ttl = mdsc->fsc->mount_options->caps_wanted_delay_max * HZ;
18061812 freed +=__dentry_leases_walk(mdsc, &lwc);
1813+ if (freed == 0 && count == 0)
1814+ /* no progress possible currently, retry futile */
1815+ return 0;
1816+
18071817 if (!lwc.nr_to_scan) /* more to check */
18081818 return -EAGAIN;
18091819
fs/ceph/export.c+17−9
@@ -442,6 +442,16 @@ static struct dentry *ceph_fh_to_parent(struct super_block *sb, · 441 unmodified lines
442442 return dentry;
443443 }
444444
445+static int ceph_export_copy_name(char *name, const char *src, u32 len)
446+{
447+ if (len > NAME_MAX)
448+ return -ENAMETOOLONG;
449+
450+ memcpy(name, src, len);
451+ name[len] = '\0';
452+ return 0;
453+}
454+
445455 static int __get_snap_name(struct dentry *parent, char *name,
446456 struct dentry *child)
447457 {
@@ -513,9 +523,8 @@ static int __get_snap_name(struct dentry *parent, char *name, · 65 unmodified lines
513523 BUG_ON(!rde->inode.in);
514524 if (ceph_snap(inode) ==
515525 le64_to_cpu(rde->inode.in->snapid)) {
516− memcpy(name, rde->name, rde->name_len);
517− name[rde->name_len] = '\0';
518− err = 0;
526+ err = ceph_export_copy_name(name, rde->name,
527+ rde->name_len);
519528 goto out;
520529 }
521530 }
@@ -580,8 +589,8 @@ static int ceph_get_name(struct dentry *parent, char *name, · 58 unmodified lines
580589
581590 rinfo = &req->r_reply_info;
582591 if (!IS_ENCRYPTED(dir)) {
583− memcpy(name, rinfo->dname, rinfo->dname_len);
584− name[rinfo->dname_len] = 0;
592+ err = ceph_export_copy_name(name, rinfo->dname,
593+ rinfo->dname_len);
585594 } else {
586595 struct fscrypt_str oname = FSTR_INIT(NULL, 0);
587596 struct ceph_fname fname = { .dir = dir,
@@ -595,10 +604,9 @@ static int ceph_get_name(struct dentry *parent, char *name, · 7 unmodified lines
595604 goto out;
596605
597606 err = ceph_fname_to_usr(&fname, NULL, &oname, NULL);
598− if (!err) {
599− memcpy(name, oname.name, oname.len);
600− name[oname.len] = 0;
601− }
607+ if (!err)
608+ err = ceph_export_copy_name(name, oname.name,
609+ oname.len);
602610 ceph_fname_free_buffer(dir, &oname);
603611 }
604612 out:
fs/ceph/file.c+53−3
@@ -2388,7 +2388,8 @@ out_end: · 2387 unmodified lines
23882388 * dropping our cap refs and allowing the pending snap to logically
23892389 * complete _before_ this write occurs.
23902390 *
2391− * If we are near ENOSPC, write synchronously.
2391+ * If requested, nearfull writes are synced to preserve the legacy
2392+ * client-side backpressure behavior.
23922393 */
23932394 static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
23942395 {
@@ -2477,6 +2478,54 @@ retry_snap: · 82 unmodified lines
24772478 if (err < 0)
24782479 goto out;
24792480
2481+ /*
2482+ * For O_APPEND writes we may have waited for Fwx exclusive caps
2483+ * while the previous Fwx holder (another client) extended the
2484+ * file. i_size has been updated via the cap grant message from
2485+ * the MDS, but ki_pos is still the old EOF. Re-read i_size here
2486+ * (no extra MDS round-trip needed) and adjust ki_pos to the true
2487+ * EOF. Since we hold Fwx, no other client can change the file.
2488+ */
2489+ if (iocb->ki_flags & IOCB_APPEND) {
2490+ loff_t cur_eof = i_size_read(inode);
2491+
2492+ if (cur_eof != pos) {
2493+ doutc(cl,
2494+ "%p %llx.%llx O_APPEND: pos adjusted %lld -> %lld\n",
2495+ inode, ceph_vinop(inode), pos, cur_eof);
2496+ iocb->ki_pos = cur_eof;
2497+ pos = cur_eof;
2498+ if (pos >= limit) {
2499+ err = -EFBIG;
2500+ goto out_caps;
2501+ }
2502+ iov_iter_truncate(from, limit - pos);
2503+ count = iov_iter_count(from);
2504+
2505+ /*
2506+ * ceph_get_caps() validated the old endoff
2507+ * against i_max_size; adjusting ki_pos forward
2508+ * may have shifted the write range beyond the
2509+ * granted max_size. Re-check and truncate if
2510+ * necessary.
2511+ */
2512+ spin_lock(&ci->i_ceph_lock);
2513+ if (pos + count > (loff_t)ci->i_max_size) {
2514+ loff_t max_size = ci->i_max_size;
2515+
2516+ spin_unlock(&ci->i_ceph_lock);
2517+ if (pos >= max_size) {
2518+ err = -EFBIG;
2519+ goto out_caps;
2520+ }
2521+ iov_iter_truncate(from, max_size - pos);
2522+ count = iov_iter_count(from);
2523+ } else {
2524+ spin_unlock(&ci->i_ceph_lock);
2525+ }
2526+ }
2527+ }
2528+
24802529 err = file_update_time(file);
24812530 if (err)
24822531 goto out_caps;
@@ -2556,8 +2605,9 @@ retry_snap: · 73 unmodified lines
25562605 }
25572606
25582607 if (written >= 0) {
2559− if ((map_flags & CEPH_OSDMAP_NEARFULL) ||
2560− (pool_flags & CEPH_POOL_FLAG_NEARFULL))
2608+ if (ceph_test_mount_opt(fsc, NEARFULL_SYNC) &&
2609+ ((map_flags & CEPH_OSDMAP_NEARFULL) ||
2610+ (pool_flags & CEPH_POOL_FLAG_NEARFULL)))
25612611 iocb->ki_flags |= IOCB_DSYNC;
25622612 written = generic_write_sync(iocb, written);
25632613 }
fs/ceph/inode.c+2−1
@@ -1814,7 +1814,8 @@ retry_lookup: · 1813 unmodified lines
18141814 ceph_dir_clear_ordered(dir);
18151815 d_delete(dn);
18161816 } else if (have_lease) {
1817− if (d_unhashed(dn))
1817+ if (d_unhashed(dn) &&
1818+ ceph_snap(dir) == CEPH_NOSNAP)
18181819 d_add(dn, NULL);
18191820 }
18201821
fs/ceph/mds_client.c+89−21
@@ -491,11 +491,11 @@ static int parse_reply_info_readdir(void **p, void *end, · 490 unmodified lines
491491 struct inode *inode = d_inode(req->r_dentry);
492492 struct ceph_inode_info *ci = ceph_inode(inode);
493493 struct ceph_mds_reply_dir_entry *rde = info->dir_entries + i;
494− struct fscrypt_str tname = FSTR_INIT(NULL, 0);
495494 struct fscrypt_str oname = FSTR_INIT(NULL, 0);
496495 struct ceph_fname fname;
497496 u32 altname_len, _name_len;
498497 u8 *altname, *_name;
498+ u8 *tname = NULL;
499499
500500 /* dentry */
501501 ceph_decode_32_safe(p, end, _name_len, bad);
@@ -541,9 +541,13 @@ static int parse_reply_info_readdir(void **p, void *end, · 39 unmodified lines
541541 * to do the base64_decode in-place. It's
542542 * safe because the decoded string should
543543 * always be shorter, which is 3/4 of origin
544− * string.
544+ * string. If this message was allocated with
545+ * vmalloc() (happens, but rarely), leave it
546+ * NULL and let ceph_fname_to_usr() allocate
547+ * suitable temporary working space instead.
545548 */
546− tname.name = _name;
549+ if (likely(!is_vmalloc_addr(_name)))
550+ tname = _name;
547551
548552 /*
549553 * Set oname to _name too, and this will be
@@ -560,7 +564,7 @@ static int parse_reply_info_readdir(void **p, void *end, · 10 unmodified lines
560564 oname.len = altname_len;
561565 }
562566 rde->is_nokey = false;
563− err = ceph_fname_to_usr(&fname, &tname, &oname, &rde->is_nokey);
567+ err = ceph_fname_to_usr(&fname, tname, &oname, &rde->is_nokey);
564568 if (err) {
565569 pr_err_client(cl, "unable to decode %.*s, got %d\n",
566570 _name_len, _name, err);
@@ -615,10 +619,36 @@ bad: · 48 unmodified lines
615619
616620 #define DELEGATED_INO_AVAILABLE xa_mk_value(1)
617621
622+static int ceph_insert_deleg_ino(struct ceph_mds_session *s, u64 ino)
623+{
624+ struct ceph_client *cl = s->s_mdsc->fsc->client;
625+ int err;
626+
627+ /*
628+ * Cap how many delegated inodes a single session may hold. This is
629+ * the only place that grows the count, so atomic_add_unless() bounds
630+ * it at exactly CEPH_MAX_DELEG_INOS; s_num_deleg_inos can never exceed
631+ * that.
632+ */
633+ if (!atomic_add_unless(&s->s_num_deleg_inos, 1, CEPH_MAX_DELEG_INOS)) {
634+ pr_warn_ratelimited_client(cl,
635+ "MDS session already holds %d delegated inodes\n",
636+ CEPH_MAX_DELEG_INOS);
637+ return -EOVERFLOW;
638+ }
639+
640+ err = xa_insert(&s->s_delegated_inos, ino, DELEGATED_INO_AVAILABLE,
641+ GFP_KERNEL);
642+ if (err)
643+ atomic_dec(&s->s_num_deleg_inos);
644+ return err;
645+}
646+
618647 static int ceph_parse_deleg_inos(void **p, void *end,
619648 struct ceph_mds_session *s)
620649 {
621650 struct ceph_client *cl = s->s_mdsc->fsc->client;
651+ u64 msg_deleg_inos = 0;
622652 u32 sets;
623653
624654 ceph_decode_32_safe(p, end, sets, bad);
@@ -636,16 +666,34 @@ static int ceph_parse_deleg_inos(void **p, void *end, · 11 unmodified lines
636666 start, len);
637667 continue;
638668 }
669+
670+ /*
671+ * Bound the number of inodes one reply may delegate.
672+ * ceph_insert_deleg_ino() separately caps the per-session
673+ * population, so this only has to stop one reply from spinning
674+ * the insert loop under an attacker-controlled len.
675+ */
676+ if (len > (u64)CEPH_MAX_DELEG_INOS ||
677+ msg_deleg_inos > (u64)CEPH_MAX_DELEG_INOS - len) {
678+ pr_warn_ratelimited_client(cl,
679+ "MDS reply delegates too many inodes (have %llu, +%llu, max %d)\n",
680+ msg_deleg_inos, len, CEPH_MAX_DELEG_INOS);
681+ return -EIO;
682+ }
683+ msg_deleg_inos += len;
684+
639685 while (len--) {
640− int err = xa_insert(&s->s_delegated_inos, start++,
641− DELEGATED_INO_AVAILABLE,
642− GFP_KERNEL);
686+ int err = ceph_insert_deleg_ino(s, start++);
687+
643688 if (!err) {
644689 doutc(cl, "added delegated inode 0x%llx\n", start - 1);
645690 } else if (err == -EBUSY) {
646691 pr_warn_client(cl,
647692 "MDS delegated inode 0x%llx more than once.\n",
648693 start - 1);
694+ } else if (err == -EOVERFLOW) {
695+ /* ceph_insert_deleg_ino() already warned. */
696+ return -EIO;
649697 } else {
650698 return err;
651699 }
@@ -663,16 +711,17 @@ u64 ceph_get_deleg_ino(struct ceph_mds_session *s) · 11 unmodified lines
663711
664712 xa_for_each(&s->s_delegated_inos, ino, val) {
665713 val = xa_erase(&s->s_delegated_inos, ino);
666− if (val == DELEGATED_INO_AVAILABLE)
714+ if (val == DELEGATED_INO_AVAILABLE) {
715+ atomic_dec(&s->s_num_deleg_inos);
667716 return ino;
717+ }
668718 }
669719 return 0;
670720 }
671721
672722 int ceph_restore_deleg_ino(struct ceph_mds_session *s, u64 ino)
673723 {
674− return xa_insert(&s->s_delegated_inos, ino, DELEGATED_INO_AVAILABLE,
675− GFP_KERNEL);
724+ return ceph_insert_deleg_ino(s, ino);
676725 }
677726 #else /* BITS_PER_LONG == 64 */
678727 /*
@@ -1059,6 +1108,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc, · 380 unmodified lines
10591108 INIT_LIST_HEAD(&s->s_waiting);
10601109 INIT_LIST_HEAD(&s->s_unsafe);
10611110 xa_init(&s->s_delegated_inos);
1111+ atomic_set(&s->s_num_deleg_inos, 0);
10621112 INIT_LIST_HEAD(&s->s_cap_releases);
10631113 INIT_WORK(&s->s_cap_release_work, ceph_cap_release_work);
10641114
@@ -1800,16 +1850,19 @@ static void __open_export_target_sessions(struct ceph_mds_client *mdsc, · 735 unmodified lines
18001850 * session caps
18011851 */
18021852
1803−static void detach_cap_releases(struct ceph_mds_session *session,
1804− struct list_head *target)
1853+static int detach_cap_releases(struct ceph_mds_session *session,
1854+ struct list_head *target)
18051855 {
18061856 struct ceph_client *cl = session->s_mdsc->fsc->client;
1857+ const int num_cap_releases = session->s_num_cap_releases;
18071858
18081859 lockdep_assert_held(&session->s_cap_lock);
18091860
18101861 list_splice_init(&session->s_cap_releases, target);
18111862 session->s_num_cap_releases = 0;
18121863 doutc(cl, "mds%d\n", session->s_mds);
1864+
1865+ return num_cap_releases;
18131866 }
18141867
18151868 static void dispose_cap_releases(struct ceph_mds_client *mdsc,
@@ -1903,7 +1956,7 @@ int ceph_iterate_session_caps(struct ceph_mds_session *session, · 87 unmodified lines
19031956
19041957 spin_lock(&session->s_cap_lock);
19051958 p = p->next;
1906− if (!cap->ci) {
1959+ if (ceph_cap_is_removed(cap)) {
19071960 doutc(cl, "finishing cap %p removal\n", cap);
19081961 BUG_ON(cap->session != session);
19091962 cap->session = NULL;
@@ -2259,7 +2312,7 @@ static int trim_caps_cb(struct inode *inode, int mds, void *arg) · 349 unmodified lines
22592312
22602313 if (oissued) {
22612314 /* we aren't the only cap.. just remove us */
2262− ceph_remove_cap(mdsc, cap, true);
2315+ ceph_remove_cap(mdsc, cap, ci, true);
22632316 (*remaining)--;
22642317 } else {
22652318 struct dentry *dentry;
@@ -2465,9 +2518,7 @@ static void ceph_send_cap_releases(struct ceph_mds_client *mdsc, · 199 unmodified lines
24652518
24662519 spin_lock(&session->s_cap_lock);
24672520 again:
2468− list_splice_init(&session->s_cap_releases, &tmp_list);
2469− num_cap_releases = session->s_num_cap_releases;
2470− session->s_num_cap_releases = 0;
2521+ num_cap_releases = detach_cap_releases(session, &tmp_list);
24712522 spin_unlock(&session->s_cap_lock);
24722523
24732524 while (!list_empty(&tmp_list)) {
@@ -4091,13 +4142,19 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg) · 1617 unmodified lines
40914142 list_add_tail(&req->r_unsafe_item, &req->r_session->s_unsafe);
40924143 }
40934144
4145+ /*
4146+ * Now that all mutex-protected state has been updated above
4147+ * (the request has been unregistered or added to the
4148+ * session's unsafe list), we can unlock it.
4149+ */
4150+ mutex_unlock(&mdsc->mutex);
4151+
40944152 doutc(cl, "tid %lld result %d\n", tid, result);
40954153 if (test_bit(CEPHFS_FEATURE_REPLY_ENCODING, &session->s_features))
40964154 err = parse_reply_info(session, msg, req, (u64)-1);
40974155 else
40984156 err = parse_reply_info(session, msg, req,
40994157 session->s_con.peer_features);
4100− mutex_unlock(&mdsc->mutex);
41014158
41024159 /* Must find target inode outside of mutexes to avoid deadlocks */
41034160 rinfo = &req->r_reply_info;
@@ -4441,7 +4498,9 @@ static void handle_session(struct ceph_mds_session *session, · 337 unmodified lines
44414498 pr_err_client(cl, "No memory for path\n");
44424499 goto fail;
44434500 }
4444− ceph_decode_copy(&p, cap_auths[i].match.path, _len);
4501+ ceph_decode_copy_safe(&p, end,
4502+ cap_auths[i].match.path,
4503+ _len, bad);
44454504
44464505 /* Remove the tailing '/' */
44474506 while (_len && cap_auths[i].match.path[_len - 1] == '/') {
@@ -4458,7 +4517,9 @@ static void handle_session(struct ceph_mds_session *session, · 10 unmodified lines
44584517 pr_err_client(cl, "No memory for fs_name\n");
44594518 goto fail;
44604519 }
4461− ceph_decode_copy(&p, cap_auths[i].match.fs_name, _len);
4520+ ceph_decode_copy_safe(&p, end,
4521+ cap_auths[i].match.fs_name,
4522+ _len, bad);
44624523 }
44634524
44644525 ceph_decode_8_safe(&p, end, cap_auths[i].match.root_squash, bad);
@@ -5106,6 +5167,7 @@ static int send_mds_reconnect(struct ceph_mds_client *mdsc, · 641 unmodified lines
51065167
51075168 /* Serialized by s_mutex against concurrent ceph_get_deleg_ino(). */
51085169 xa_destroy(&session->s_delegated_inos);
5170+ atomic_set(&session->s_num_deleg_inos, 0);
51095171 if (session->s_state == CEPH_MDS_SESSION_CLOSED ||
51105172 session->s_state == CEPH_MDS_SESSION_REJECTED) {
51115173 pr_info_client(cl, "mds%d skipping reconnect, session %s\n",
@@ -5753,7 +5815,7 @@ int ceph_mdsc_schedule_reset(struct ceph_mds_client *mdsc, · 641 unmodified lines
57535815 strscpy(st->last_reason, msg, sizeof(st->last_reason));
57545816 spin_unlock(&st->lock);
57555817
5756− if (WARN_ON_ONCE(!queue_work(system_unbound_wq, &mdsc->reset_work))) {
5818+ if (WARN_ON_ONCE(!queue_work(system_dfl_wq, &mdsc->reset_work))) {
57575819 spin_lock(&st->lock);
57585820 st->phase = CEPH_CLIENT_RESET_IDLE;
57595821 st->last_errno = -EALREADY;
@@ -5834,9 +5896,11 @@ static void check_new_map(struct ceph_mds_client *mdsc, · 74 unmodified lines
58345896 ceph_mdsmap_get_addr(newmap, i),
58355897 sizeof(struct ceph_entity_addr))) {
58365898 /* just close it */
5899+ ceph_get_mds_session(s);
58375900 mutex_unlock(&mdsc->mutex);
58385901 mutex_lock(&s->s_mutex);
58395902 mutex_lock(&mdsc->mutex);
5903+ ceph_put_mds_session(s);
58405904 ceph_con_close(&s->s_con);
58415905 mutex_unlock(&s->s_mutex);
58425906 s->s_state = CEPH_MDS_SESSION_RESTARTING;
@@ -5851,6 +5915,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, · 8 unmodified lines
58515915 newstate >= CEPH_MDS_STATE_RECONNECT) {
58525916 int rc;
58535917
5918+ ceph_get_mds_session(s);
58545919 mutex_unlock(&mdsc->mutex);
58555920 clear_bit(i, targets);
58565921 rc = send_mds_reconnect(mdsc, s);
@@ -5859,6 +5924,7 @@ static void check_new_map(struct ceph_mds_client *mdsc, · 2 unmodified lines
58595924 "mds%d reconnect failed: %d\n",
58605925 i, rc);
58615926 mutex_lock(&mdsc->mutex);
5927+ ceph_put_mds_session(s);
58625928 }
58635929
58645930 /*
@@ -5871,9 +5937,11 @@ static void check_new_map(struct ceph_mds_client *mdsc, · 6 unmodified lines
58715937 pr_info_client(cl, "mds%d recovery completed\n",
58725938 s->s_mds);
58735939 kick_requests(mdsc, i);
5940+ ceph_get_mds_session(s);
58745941 mutex_unlock(&mdsc->mutex);
58755942 mutex_lock(&s->s_mutex);
58765943 mutex_lock(&mdsc->mutex);
5944+ ceph_put_mds_session(s);
58775945 ceph_kick_flushing_caps(mdsc, s);
58785946 mutex_unlock(&s->s_mutex);
58795947 wake_up_session_caps(s, RECONNECT);
fs/ceph/mds_client.h+1−0
@@ -300,6 +300,7 @@ struct ceph_mds_session { · 299 unmodified lines
300300 struct list_head s_waiting; /* waiting requests */
301301 struct list_head s_unsafe; /* unsafe requests */
302302 struct xarray s_delegated_inos;
303+ atomic_t s_num_deleg_inos;
303304 };
304305
305306 /*
fs/ceph/mdsmap.c+10−1
@@ -3,6 +3,7 @@ · 2 unmodified lines
33
44 #include <linux/bug.h>
55 #include <linux/err.h>
6+#include <linux/overflow.h>
67 #include <linux/random.h>
78 #include <linux/slab.h>
89 #include <linux/types.h>
@@ -126,6 +127,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, · 117 unmodified lines
126127 u8 mdsmap_v;
127128 u16 mdsmap_ev;
128129 u32 target;
130+ size_t export_targets_len;
129131
130132 m = kzalloc_obj(*m, GFP_NOFS);
131133 if (!m)
@@ -224,8 +226,11 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, · 92 unmodified lines
224226 *p += namelen;
225227 if (info_v >= 2) {
226228 ceph_decode_32_safe(p, end, num_export_targets, bad);
229+ export_targets_len = size_mul(num_export_targets,
230+ sizeof(u32));
231+ ceph_decode_need(p, end, export_targets_len, bad);
227232 pexport_targets = *p;
228− *p += num_export_targets * sizeof(u32);
233+ *p += export_targets_len;
229234 } else {
230235 num_export_targets = 0;
231236 }
@@ -264,6 +269,10 @@ struct ceph_mdsmap *ceph_mdsmap_decode(struct ceph_mds_client *mdsc, void **p, · 32 unmodified lines
264269 goto nomem;
265270 for (j = 0; j < num_export_targets; j++) {
266271 target = ceph_decode_32(&pexport_targets);
272+ if (target >= CEPH_MAX_MDS) {
273+ err = -EIO;
274+ goto corrupt;
275+ }
267276 info->export_targets[j] = target;
268277 }
269278 } else {
fs/ceph/super.c+10−0
@@ -177,6 +177,7 @@ enum { · 176 unmodified lines
177177 Opt_wsync,
178178 Opt_pagecache,
179179 Opt_sparseread,
180+ Opt_nearfull_sync,
180181 };
181182
182183 enum ceph_recover_session_mode {
@@ -205,6 +206,7 @@ static const struct fs_parameter_spec ceph_mount_parameters[] = { · 22 unmodified lines
205206 fsparam_flag_no ("ino32", Opt_ino32),
206207 fsparam_string ("mds_namespace", Opt_mds_namespace),
207208 fsparam_string ("mon_addr", Opt_mon_addr),
209+ fsparam_flag_no ("nearfull_sync", Opt_nearfull_sync),
208210 fsparam_flag_no ("poolperm", Opt_poolperm),
209211 fsparam_flag_no ("quotadf", Opt_quotadf),
210212 fsparam_u32 ("rasize", Opt_rasize),
@@ -593,6 +595,12 @@ static int ceph_parse_mount_param(struct fs_context *fc, · 382 unmodified lines
593595 else
594596 fsopt->flags |= CEPH_MOUNT_OPT_SPARSEREAD;
595597 break;
598+ case Opt_nearfull_sync:
599+ if (result.negated)
600+ fsopt->flags &= ~CEPH_MOUNT_OPT_NEARFULL_SYNC;
601+ else
602+ fsopt->flags |= CEPH_MOUNT_OPT_NEARFULL_SYNC;
603+ break;
596604 case Opt_test_dummy_encryption:
597605 #ifdef CONFIG_FS_ENCRYPTION
598606 fscrypt_free_dummy_policy(&fsopt->dummy_enc_policy);
@@ -749,6 +757,8 @@ static int ceph_show_options(struct seq_file *m, struct dentry *root) · 150 unmodified lines
749757 seq_puts(m, ",nopagecache");
750758 if (fsopt->flags & CEPH_MOUNT_OPT_SPARSEREAD)
751759 seq_puts(m, ",sparseread");
760+ if (fsopt->flags & CEPH_MOUNT_OPT_NEARFULL_SYNC)
761+ seq_puts(m, ",nearfull_sync");
752762
753763 fscrypt_show_test_dummy_encryption(m, ',', root->d_sb);
754764
fs/ceph/super.h+43−2
@@ -45,6 +45,7 @@ · 44 unmodified lines
4545 #define CEPH_MOUNT_OPT_ASYNC_DIROPS (1<<15) /* allow async directory ops */
4646 #define CEPH_MOUNT_OPT_NOPAGECACHE (1<<16) /* bypass pagecache altogether */
4747 #define CEPH_MOUNT_OPT_SPARSEREAD (1<<17) /* always do sparse reads */
48+#define CEPH_MOUNT_OPT_NEARFULL_SYNC (1<<18) /* sync writes when nearfull */
4849
4950 #define CEPH_MOUNT_OPT_DEFAULT \
5051 (CEPH_MOUNT_OPT_DCACHE | \
@@ -203,7 +204,19 @@ struct ceph_fs_client { · 152 unmodified lines
203204 */
204205 struct ceph_cap {
205206 struct ceph_inode_info *ci;
206− struct rb_node ci_node; /* per-ci cap tree */
207+
208+ /**
209+ * Per-ci cap tree. Protected with
210+ * `ceph_inode_info.i_ceph_lock`.
211+ *
212+ * Clearing this field with RB_CLEAR_NODE() requires holding
213+ * both `ceph_inode_info.i_ceph_lock` and
214+ * `ceph_mds_session->s_cap_lock`. Calling RB_EMPTY_NODE()
215+ * (via ceph_cap_is_removed()) requires holding at least one
216+ * of these.
217+ */
218+ struct rb_node ci_node;
219+
207220 struct ceph_mds_session *session;
208221 struct list_head session_caps; /* per-session caplist */
209222 u64 cap_id; /* unique cap id (mds provided) */
@@ -641,6 +654,15 @@ static inline int ceph_ino_compare(struct inode *inode, void *data) · 431 unmodified lines
641654 #define CEPH_MDS_INO_LOG_OFFSET (2 * CEPH_MAX_MDS)
642655 #define CEPH_INO_SYSTEM_BASE ((6*CEPH_MAX_MDS) + (CEPH_MAX_MDS * CEPH_NUM_STRAY))
643656
657+/*
658+ * Upper bound on the number of delegated inodes a single MDS session may
659+ * hold. The MDS normally hands out a small preallocation window (the
660+ * userspace mds_client_prealloc_inos option defaults to 1000) and refills
661+ * it as the client consumes entries. This leaves generous headroom while
662+ * bounding the CPU and memory a malformed delegation interval can consume.
663+ */
664+#define CEPH_MAX_DELEG_INOS 8192
665+
644666 static inline bool ceph_vino_is_reserved(const struct ceph_vino vino)
645667 {
646668 if (vino.ino >= CEPH_INO_SYSTEM_BASE ||
@@ -687,6 +709,10 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, · 40 unmodified lines
687709 #define CEPH_I_ASYNC_CREATE_BIT (12) /* async create in flight for this */
688710 #define CEPH_I_SHUTDOWN_BIT (13) /* inode is no longer usable */
689711 #define CEPH_I_ASYNC_CHECK_CAPS_BIT (14) /* check caps after async creating finishes */
712+#define CEPH_I_FLUSH_FORCE_BIT (15) /* a revoke's response was deferred;
713+ * force a cap message to the MDS once
714+ * the deferred work completes
715+ */
690716
691717 #define CEPH_I_DIR_ORDERED (1 << CEPH_I_DIR_ORDERED_BIT)
692718 #define CEPH_I_FLUSH (1 << CEPH_I_FLUSH_BIT)
@@ -699,6 +725,7 @@ static inline struct inode *ceph_find_inode(struct super_block *sb, · 6 unmodified lines
699725 #define CEPH_I_ODIRECT (1 << CEPH_I_ODIRECT_BIT)
700726 #define CEPH_I_ASYNC_CREATE (1 << CEPH_I_ASYNC_CREATE_BIT)
701727 #define CEPH_I_SHUTDOWN (1 << CEPH_I_SHUTDOWN_BIT)
728+#define CEPH_I_FLUSH_FORCE (1 << CEPH_I_FLUSH_FORCE_BIT)
702729
703730 /*
704731 * Masks of ceph inode work.
@@ -1269,8 +1296,22 @@ extern void ceph_add_cap(struct inode *inode, · 564 unmodified lines
12691296 unsigned issued, unsigned wanted,
12701297 unsigned cap, unsigned seq, u64 realmino, int flags,
12711298 struct ceph_cap **new_cap);
1272−extern void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release);
1299+
1300+/**
1301+ * Determine whether __ceph_remove_cap() has been called on this #cap
1302+ * (but the object has not yet been freed because it is protected by
1303+ * `ceph_mds_session.s_cap_iterator`).
1304+ *
1305+ * Caller must lock either `ceph_inode_info.i_ceph_lock` or
1306+ * `ceph_mds_session.s_cap_lock`.
1307+ */
1308+static inline bool ceph_cap_is_removed(const struct ceph_cap *cap)
1309+{
1310+ return RB_EMPTY_NODE(&cap->ci_node);
1311+}
1312+
12731313 extern void ceph_remove_cap(struct ceph_mds_client *mdsc, struct ceph_cap *cap,
1314+ struct ceph_inode_info *ci,
12741315 bool queue_release);
12751316 extern void __ceph_remove_caps(struct ceph_inode_info *ci);
12761317 extern void ceph_put_cap(struct ceph_mds_client *mdsc,
fs/ceph/xattr.c+1−0
@@ -848,6 +848,7 @@ start: · 847 unmodified lines
848848 name = p;
849849 p += len;
850850 ceph_decode_32_safe(&p, end, len, bad);
851+ ceph_decode_need(&p, end, len, bad);
851852 val = p;
852853 p += len;
853854
include/linux/ceph/libceph.h+0−2
@@ -313,8 +313,6 @@ int ceph_wait_for_latest_osdmap(struct ceph_client *client, · 312 unmodified lines
313313
314314 /* pagevec.c */
315315 extern void ceph_release_page_vector(struct page **pages, int num_pages);
316−extern void ceph_put_page_vector(struct page **pages, int num_pages,
317− bool dirty);
318316 extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
319317 extern void ceph_copy_from_page_vector(struct page **pages,
320318 void *data,
net/ceph/messenger_v2.c+5−0
@@ -2142,6 +2142,11 @@ static int process_banner_prefix(struct ceph_connection *con) · 2141 unmodified lines
21422142 payload_len = ceph_decode_16(&p);
21432143 dout("%s con %p payload_len %d\n", __func__, con, payload_len);
21442144
2145+ if (payload_len < sizeof(u64) + sizeof(u64)) {
2146+ con->error_msg = "protocol error, bad banner payload len";
2147+ return -EINVAL;
2148+ }
2149+
21452150 return prepare_read_banner_payload(con, payload_len);
21462151 }
21472152
net/ceph/osd_client.c+30−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 #include <linux/err.h>
77 #include <linux/highmem.h>
88 #include <linux/mm.h>
9+#include <linux/overflow.h>
910 #include <linux/pagemap.h>
1011 #include <linux/slab.h>
1112 #include <linux/uaccess.h>
@@ -5802,6 +5803,31 @@ static inline void convert_extent_map(struct ceph_sparse_read *sr) · 5790 unmodified lines
58025803 }
58035804 #endif
58045805
5806+static bool sparse_extent_map_valid(struct ceph_sparse_read *sr)
5807+{
5808+ u64 req_end, pos;
5809+ int i;
5810+
5811+ if (check_add_overflow(sr->sr_req_off, sr->sr_req_len, &req_end))
5812+ return false;
5813+
5814+ pos = sr->sr_req_off;
5815+ for (i = 0; i < sr->sr_count; i++) {
5816+ struct ceph_sparse_extent *ext = &sr->sr_extent[i];
5817+ u64 end;
5818+
5819+ if (ext->off < pos)
5820+ return false;
5821+ if (check_add_overflow(ext->off, ext->len, &end))
5822+ return false;
5823+ if (end > req_end)
5824+ return false;
5825+ pos = end;
5826+ }
5827+
5828+ return true;
5829+}
5830+
58055831 static int osd_sparse_read(struct ceph_connection *con,
58065832 struct ceph_msg_data_cursor *cursor,
58075833 char **pbuf)
@@ -5852,6 +5878,10 @@ next_op: · 44 unmodified lines
58525878 fallthrough;
58535879 case CEPH_SPARSE_READ_DATA_LEN:
58545880 convert_extent_map(sr);
5881+ if (!sparse_extent_map_valid(sr)) {
5882+ pr_warn_ratelimited("invalid sparse extent map\n");
5883+ return -EREMOTEIO;
5884+ }
58555885 ret = sizeof(sr->sr_datalen);
58565886 *pbuf = (char *)&sr->sr_datalen;
58575887 sr->sr_state = CEPH_SPARSE_READ_DATA_PRE;
net/ceph/osdmap.c+2−0
@@ -517,6 +517,8 @@ static struct crush_map *crush_decode(void *pbyval, void *end) · 516 unmodified lines
517517
518518 ceph_decode_need(p, end, 4*sizeof(u32), bad);
519519 b->id = ceph_decode_32(p);
520+ if (b->id != -1 - i)
521+ goto bad;
520522 b->type = ceph_decode_16(p);
521523 if (b->type == 0)
522524 goto bad;
net/ceph/pagevec.c+0−13
@@ -10,19 +10,6 @@ · 9 unmodified lines
1010
1111 #include <linux/ceph/libceph.h>
1212
13−void ceph_put_page_vector(struct page **pages, int num_pages, bool dirty)
14−{
15− int i;
16−
17− for (i = 0; i < num_pages; i++) {
18− if (dirty)
19− set_page_dirty_lock(pages[i]);
20− put_page(pages[i]);
21− }
22− kvfree(pages);
23−}
24−EXPORT_SYMBOL(ceph_put_page_vector);
25−
2613 void ceph_release_page_vector(struct page **pages, int num_pages)
2714 {
2815 int i;