hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/fs/dlm/lock.c
....@@ -1,11 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /******************************************************************************
23 *******************************************************************************
34 **
45 ** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved.
56 **
6
-** This copyrighted material is made available to anyone wishing to use,
7
-** modify, copy, or redistribute it subject to the terms and conditions
8
-** of the GNU General Public License v.2.
97 **
108 *******************************************************************************
119 ******************************************************************************/
....@@ -1553,6 +1551,7 @@
15531551 lkb->lkb_wait_type = 0;
15541552 lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
15551553 lkb->lkb_wait_count--;
1554
+ unhold_lkb(lkb);
15561555 goto out_del;
15571556 }
15581557
....@@ -1579,6 +1578,7 @@
15791578 log_error(ls, "remwait error %x reply %d wait_type %d overlap",
15801579 lkb->lkb_id, mstype, lkb->lkb_wait_type);
15811580 lkb->lkb_wait_count--;
1581
+ unhold_lkb(lkb);
15821582 lkb->lkb_wait_type = 0;
15831583 }
15841584
....@@ -1856,7 +1856,7 @@
18561856 void dlm_scan_timeout(struct dlm_ls *ls)
18571857 {
18581858 struct dlm_rsb *r;
1859
- struct dlm_lkb *lkb;
1859
+ struct dlm_lkb *lkb = NULL, *iter;
18601860 int do_cancel, do_warn;
18611861 s64 wait_us;
18621862
....@@ -1867,27 +1867,28 @@
18671867 do_cancel = 0;
18681868 do_warn = 0;
18691869 mutex_lock(&ls->ls_timeout_mutex);
1870
- list_for_each_entry(lkb, &ls->ls_timeout, lkb_time_list) {
1870
+ list_for_each_entry(iter, &ls->ls_timeout, lkb_time_list) {
18711871
18721872 wait_us = ktime_to_us(ktime_sub(ktime_get(),
1873
- lkb->lkb_timestamp));
1873
+ iter->lkb_timestamp));
18741874
1875
- if ((lkb->lkb_exflags & DLM_LKF_TIMEOUT) &&
1876
- wait_us >= (lkb->lkb_timeout_cs * 10000))
1875
+ if ((iter->lkb_exflags & DLM_LKF_TIMEOUT) &&
1876
+ wait_us >= (iter->lkb_timeout_cs * 10000))
18771877 do_cancel = 1;
18781878
1879
- if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
1879
+ if ((iter->lkb_flags & DLM_IFL_WATCH_TIMEWARN) &&
18801880 wait_us >= dlm_config.ci_timewarn_cs * 10000)
18811881 do_warn = 1;
18821882
18831883 if (!do_cancel && !do_warn)
18841884 continue;
1885
- hold_lkb(lkb);
1885
+ hold_lkb(iter);
1886
+ lkb = iter;
18861887 break;
18871888 }
18881889 mutex_unlock(&ls->ls_timeout_mutex);
18891890
1890
- if (!do_cancel && !do_warn)
1891
+ if (!lkb)
18911892 break;
18921893
18931894 r = lkb->lkb_resource;
....@@ -2888,17 +2889,9 @@
28882889 static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb,
28892890 struct dlm_args *args)
28902891 {
2891
- int rv = -EINVAL;
2892
+ int rv = -EBUSY;
28922893
28932894 if (args->flags & DLM_LKF_CONVERT) {
2894
- if (lkb->lkb_flags & DLM_IFL_MSTCPY)
2895
- goto out;
2896
-
2897
- if (args->flags & DLM_LKF_QUECVT &&
2898
- !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
2899
- goto out;
2900
-
2901
- rv = -EBUSY;
29022895 if (lkb->lkb_status != DLM_LKSTS_GRANTED)
29032896 goto out;
29042897
....@@ -2906,6 +2899,14 @@
29062899 goto out;
29072900
29082901 if (is_overlap(lkb))
2902
+ goto out;
2903
+
2904
+ rv = -EINVAL;
2905
+ if (lkb->lkb_flags & DLM_IFL_MSTCPY)
2906
+ goto out;
2907
+
2908
+ if (args->flags & DLM_LKF_QUECVT &&
2909
+ !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1])
29092910 goto out;
29102911 }
29112912
....@@ -4067,13 +4068,14 @@
40674068 rv = _create_message(ls, sizeof(struct dlm_message) + len,
40684069 dir_nodeid, DLM_MSG_REMOVE, &ms, &mh);
40694070 if (rv)
4070
- return;
4071
+ goto out;
40714072
40724073 memcpy(ms->m_extra, name, len);
40734074 ms->m_hash = hash;
40744075
40754076 send_message(mh, ms);
40764077
4078
+out:
40774079 spin_lock(&ls->ls_remove_spin);
40784080 ls->ls_remove_len = 0;
40794081 memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN);
....@@ -5240,21 +5242,18 @@
52405242
52415243 static struct dlm_lkb *find_resend_waiter(struct dlm_ls *ls)
52425244 {
5243
- struct dlm_lkb *lkb;
5244
- int found = 0;
5245
+ struct dlm_lkb *lkb = NULL, *iter;
52455246
52465247 mutex_lock(&ls->ls_waiters_mutex);
5247
- list_for_each_entry(lkb, &ls->ls_waiters, lkb_wait_reply) {
5248
- if (lkb->lkb_flags & DLM_IFL_RESEND) {
5249
- hold_lkb(lkb);
5250
- found = 1;
5248
+ list_for_each_entry(iter, &ls->ls_waiters, lkb_wait_reply) {
5249
+ if (iter->lkb_flags & DLM_IFL_RESEND) {
5250
+ hold_lkb(iter);
5251
+ lkb = iter;
52515252 break;
52525253 }
52535254 }
52545255 mutex_unlock(&ls->ls_waiters_mutex);
52555256
5256
- if (!found)
5257
- lkb = NULL;
52585257 return lkb;
52595258 }
52605259
....@@ -5314,11 +5313,16 @@
53145313 lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK;
53155314 lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL;
53165315 lkb->lkb_wait_type = 0;
5317
- lkb->lkb_wait_count = 0;
5316
+ /* drop all wait_count references we still
5317
+ * hold a reference for this iteration.
5318
+ */
5319
+ while (lkb->lkb_wait_count) {
5320
+ lkb->lkb_wait_count--;
5321
+ unhold_lkb(lkb);
5322
+ }
53185323 mutex_lock(&ls->ls_waiters_mutex);
53195324 list_del_init(&lkb->lkb_wait_reply);
53205325 mutex_unlock(&ls->ls_waiters_mutex);
5321
- unhold_lkb(lkb); /* for waiters list */
53225326
53235327 if (oc || ou) {
53245328 /* do an unlock or cancel instead of resending */
....@@ -5828,7 +5832,7 @@
58285832 break;
58295833 case -EAGAIN:
58305834 error = 0;
5831
- /* fall through */
5835
+ fallthrough;
58325836 default:
58335837 __put_lkb(ls, lkb);
58345838 goto out;
....@@ -5908,37 +5912,36 @@
59085912 int mode, uint32_t flags, void *name, unsigned int namelen,
59095913 unsigned long timeout_cs, uint32_t *lkid)
59105914 {
5911
- struct dlm_lkb *lkb;
5915
+ struct dlm_lkb *lkb = NULL, *iter;
59125916 struct dlm_user_args *ua;
59135917 int found_other_mode = 0;
5914
- int found = 0;
59155918 int rv = 0;
59165919
59175920 mutex_lock(&ls->ls_orphans_mutex);
5918
- list_for_each_entry(lkb, &ls->ls_orphans, lkb_ownqueue) {
5919
- if (lkb->lkb_resource->res_length != namelen)
5921
+ list_for_each_entry(iter, &ls->ls_orphans, lkb_ownqueue) {
5922
+ if (iter->lkb_resource->res_length != namelen)
59205923 continue;
5921
- if (memcmp(lkb->lkb_resource->res_name, name, namelen))
5924
+ if (memcmp(iter->lkb_resource->res_name, name, namelen))
59225925 continue;
5923
- if (lkb->lkb_grmode != mode) {
5926
+ if (iter->lkb_grmode != mode) {
59245927 found_other_mode = 1;
59255928 continue;
59265929 }
59275930
5928
- found = 1;
5929
- list_del_init(&lkb->lkb_ownqueue);
5930
- lkb->lkb_flags &= ~DLM_IFL_ORPHAN;
5931
- *lkid = lkb->lkb_id;
5931
+ lkb = iter;
5932
+ list_del_init(&iter->lkb_ownqueue);
5933
+ iter->lkb_flags &= ~DLM_IFL_ORPHAN;
5934
+ *lkid = iter->lkb_id;
59325935 break;
59335936 }
59345937 mutex_unlock(&ls->ls_orphans_mutex);
59355938
5936
- if (!found && found_other_mode) {
5939
+ if (!lkb && found_other_mode) {
59375940 rv = -EAGAIN;
59385941 goto out;
59395942 }
59405943
5941
- if (!found) {
5944
+ if (!lkb) {
59425945 rv = -ENOENT;
59435946 goto out;
59445947 }