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

Configure Feed

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

Merge tag 'ceph-for-6.11-rc2' of https://github.com/ceph/ceph-client

Pull ceph fix from Ilya Dryomov:
"A fix for a potential hang in the MDS when cap revocation races with
the client releasing the caps in question, marked for stable"

* tag 'ceph-for-6.11-rc2' of https://github.com/ceph/ceph-client:
ceph: force sending a cap update msg back to MDS for revoke op

+28 -14
+24 -11
fs/ceph/caps.c
··· 2016 2016 * CHECK_CAPS_AUTHONLY - we should only check the auth cap 2017 2017 * CHECK_CAPS_FLUSH - we should flush any dirty caps immediately, without 2018 2018 * further delay. 2019 + * CHECK_CAPS_FLUSH_FORCE - we should flush any caps immediately, without 2020 + * further delay. 2019 2021 */ 2020 2022 void ceph_check_caps(struct ceph_inode_info *ci, int flags) 2021 2023 { ··· 2099 2097 } 2100 2098 2101 2099 doutc(cl, "%p %llx.%llx file_want %s used %s dirty %s " 2102 - "flushing %s issued %s revoking %s retain %s %s%s%s\n", 2100 + "flushing %s issued %s revoking %s retain %s %s%s%s%s\n", 2103 2101 inode, ceph_vinop(inode), ceph_cap_string(file_wanted), 2104 2102 ceph_cap_string(used), ceph_cap_string(ci->i_dirty_caps), 2105 2103 ceph_cap_string(ci->i_flushing_caps), ··· 2107 2105 ceph_cap_string(retain), 2108 2106 (flags & CHECK_CAPS_AUTHONLY) ? " AUTHONLY" : "", 2109 2107 (flags & CHECK_CAPS_FLUSH) ? " FLUSH" : "", 2110 - (flags & CHECK_CAPS_NOINVAL) ? " NOINVAL" : ""); 2108 + (flags & CHECK_CAPS_NOINVAL) ? " NOINVAL" : "", 2109 + (flags & CHECK_CAPS_FLUSH_FORCE) ? " FLUSH_FORCE" : ""); 2111 2110 2112 2111 /* 2113 2112 * If we no longer need to hold onto old our caps, and we may ··· 2181 2178 if (S_ISREG(inode->i_mode) && ci->i_wrbuffer_ref && 2182 2179 (revoking & CEPH_CAP_FILE_BUFFER)) 2183 2180 queue_writeback = true; 2181 + } 2182 + 2183 + if (flags & CHECK_CAPS_FLUSH_FORCE) { 2184 + doutc(cl, "force to flush caps\n"); 2185 + goto ack; 2184 2186 } 2185 2187 2186 2188 if (cap == ci->i_auth_cap && ··· 3518 3510 bool queue_invalidate = false; 3519 3511 bool deleted_inode = false; 3520 3512 bool fill_inline = false; 3513 + bool revoke_wait = false; 3514 + int flags = 0; 3521 3515 3522 3516 /* 3523 3517 * If there is at least one crypto block then we'll trust ··· 3715 3705 ceph_cap_string(cap->issued), ceph_cap_string(newcaps), 3716 3706 ceph_cap_string(revoking)); 3717 3707 if (S_ISREG(inode->i_mode) && 3718 - (revoking & used & CEPH_CAP_FILE_BUFFER)) 3708 + (revoking & used & CEPH_CAP_FILE_BUFFER)) { 3719 3709 writeback = true; /* initiate writeback; will delay ack */ 3720 - else if (queue_invalidate && 3710 + revoke_wait = true; 3711 + } else if (queue_invalidate && 3721 3712 revoking == CEPH_CAP_FILE_CACHE && 3722 - (newcaps & CEPH_CAP_FILE_LAZYIO) == 0) 3723 - ; /* do nothing yet, invalidation will be queued */ 3724 - else if (cap == ci->i_auth_cap) 3713 + (newcaps & CEPH_CAP_FILE_LAZYIO) == 0) { 3714 + revoke_wait = true; /* do nothing yet, invalidation will be queued */ 3715 + } else if (cap == ci->i_auth_cap) { 3725 3716 check_caps = 1; /* check auth cap only */ 3726 - else 3717 + } else { 3727 3718 check_caps = 2; /* check all caps */ 3719 + } 3728 3720 /* If there is new caps, try to wake up the waiters */ 3729 3721 if (~cap->issued & newcaps) 3730 3722 wake = true; ··· 3753 3741 BUG_ON(cap->issued & ~cap->implemented); 3754 3742 3755 3743 /* don't let check_caps skip sending a response to MDS for revoke msgs */ 3756 - if (le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) { 3744 + if (!revoke_wait && le32_to_cpu(grant->op) == CEPH_CAP_OP_REVOKE) { 3757 3745 cap->mds_wanted = 0; 3746 + flags |= CHECK_CAPS_FLUSH_FORCE; 3758 3747 if (cap == ci->i_auth_cap) 3759 3748 check_caps = 1; /* check auth cap only */ 3760 3749 else ··· 3811 3798 3812 3799 mutex_unlock(&session->s_mutex); 3813 3800 if (check_caps == 1) 3814 - ceph_check_caps(ci, CHECK_CAPS_AUTHONLY | CHECK_CAPS_NOINVAL); 3801 + ceph_check_caps(ci, flags | CHECK_CAPS_AUTHONLY | CHECK_CAPS_NOINVAL); 3815 3802 else if (check_caps == 2) 3816 - ceph_check_caps(ci, CHECK_CAPS_NOINVAL); 3803 + ceph_check_caps(ci, flags | CHECK_CAPS_NOINVAL); 3817 3804 } 3818 3805 3819 3806 /*
+4 -3
fs/ceph/super.h
··· 200 200 struct list_head caps_item; 201 201 }; 202 202 203 - #define CHECK_CAPS_AUTHONLY 1 /* only check auth cap */ 204 - #define CHECK_CAPS_FLUSH 2 /* flush any dirty caps */ 205 - #define CHECK_CAPS_NOINVAL 4 /* don't invalidate pagecache */ 203 + #define CHECK_CAPS_AUTHONLY 1 /* only check auth cap */ 204 + #define CHECK_CAPS_FLUSH 2 /* flush any dirty caps */ 205 + #define CHECK_CAPS_NOINVAL 4 /* don't invalidate pagecache */ 206 + #define CHECK_CAPS_FLUSH_FORCE 8 /* force flush any caps */ 206 207 207 208 struct ceph_cap_flush { 208 209 u64 tid;