.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /****************************************************************************** |
---|
2 | 3 | ******************************************************************************* |
---|
3 | 4 | ** |
---|
4 | 5 | ** Copyright (C) 2005-2010 Red Hat, Inc. All rights reserved. |
---|
5 | 6 | ** |
---|
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. |
---|
9 | 7 | ** |
---|
10 | 8 | ******************************************************************************* |
---|
11 | 9 | ******************************************************************************/ |
---|
.. | .. |
---|
1553 | 1551 | lkb->lkb_wait_type = 0; |
---|
1554 | 1552 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; |
---|
1555 | 1553 | lkb->lkb_wait_count--; |
---|
| 1554 | + unhold_lkb(lkb); |
---|
1556 | 1555 | goto out_del; |
---|
1557 | 1556 | } |
---|
1558 | 1557 | |
---|
.. | .. |
---|
1579 | 1578 | log_error(ls, "remwait error %x reply %d wait_type %d overlap", |
---|
1580 | 1579 | lkb->lkb_id, mstype, lkb->lkb_wait_type); |
---|
1581 | 1580 | lkb->lkb_wait_count--; |
---|
| 1581 | + unhold_lkb(lkb); |
---|
1582 | 1582 | lkb->lkb_wait_type = 0; |
---|
1583 | 1583 | } |
---|
1584 | 1584 | |
---|
.. | .. |
---|
1856 | 1856 | void dlm_scan_timeout(struct dlm_ls *ls) |
---|
1857 | 1857 | { |
---|
1858 | 1858 | struct dlm_rsb *r; |
---|
1859 | | - struct dlm_lkb *lkb; |
---|
| 1859 | + struct dlm_lkb *lkb = NULL, *iter; |
---|
1860 | 1860 | int do_cancel, do_warn; |
---|
1861 | 1861 | s64 wait_us; |
---|
1862 | 1862 | |
---|
.. | .. |
---|
1867 | 1867 | do_cancel = 0; |
---|
1868 | 1868 | do_warn = 0; |
---|
1869 | 1869 | 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) { |
---|
1871 | 1871 | |
---|
1872 | 1872 | wait_us = ktime_to_us(ktime_sub(ktime_get(), |
---|
1873 | | - lkb->lkb_timestamp)); |
---|
| 1873 | + iter->lkb_timestamp)); |
---|
1874 | 1874 | |
---|
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)) |
---|
1877 | 1877 | do_cancel = 1; |
---|
1878 | 1878 | |
---|
1879 | | - if ((lkb->lkb_flags & DLM_IFL_WATCH_TIMEWARN) && |
---|
| 1879 | + if ((iter->lkb_flags & DLM_IFL_WATCH_TIMEWARN) && |
---|
1880 | 1880 | wait_us >= dlm_config.ci_timewarn_cs * 10000) |
---|
1881 | 1881 | do_warn = 1; |
---|
1882 | 1882 | |
---|
1883 | 1883 | if (!do_cancel && !do_warn) |
---|
1884 | 1884 | continue; |
---|
1885 | | - hold_lkb(lkb); |
---|
| 1885 | + hold_lkb(iter); |
---|
| 1886 | + lkb = iter; |
---|
1886 | 1887 | break; |
---|
1887 | 1888 | } |
---|
1888 | 1889 | mutex_unlock(&ls->ls_timeout_mutex); |
---|
1889 | 1890 | |
---|
1890 | | - if (!do_cancel && !do_warn) |
---|
| 1891 | + if (!lkb) |
---|
1891 | 1892 | break; |
---|
1892 | 1893 | |
---|
1893 | 1894 | r = lkb->lkb_resource; |
---|
.. | .. |
---|
2888 | 2889 | static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, |
---|
2889 | 2890 | struct dlm_args *args) |
---|
2890 | 2891 | { |
---|
2891 | | - int rv = -EINVAL; |
---|
| 2892 | + int rv = -EBUSY; |
---|
2892 | 2893 | |
---|
2893 | 2894 | 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; |
---|
2902 | 2895 | if (lkb->lkb_status != DLM_LKSTS_GRANTED) |
---|
2903 | 2896 | goto out; |
---|
2904 | 2897 | |
---|
.. | .. |
---|
2906 | 2899 | goto out; |
---|
2907 | 2900 | |
---|
2908 | 2901 | 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]) |
---|
2909 | 2910 | goto out; |
---|
2910 | 2911 | } |
---|
2911 | 2912 | |
---|
.. | .. |
---|
4067 | 4068 | rv = _create_message(ls, sizeof(struct dlm_message) + len, |
---|
4068 | 4069 | dir_nodeid, DLM_MSG_REMOVE, &ms, &mh); |
---|
4069 | 4070 | if (rv) |
---|
4070 | | - return; |
---|
| 4071 | + goto out; |
---|
4071 | 4072 | |
---|
4072 | 4073 | memcpy(ms->m_extra, name, len); |
---|
4073 | 4074 | ms->m_hash = hash; |
---|
4074 | 4075 | |
---|
4075 | 4076 | send_message(mh, ms); |
---|
4076 | 4077 | |
---|
| 4078 | +out: |
---|
4077 | 4079 | spin_lock(&ls->ls_remove_spin); |
---|
4078 | 4080 | ls->ls_remove_len = 0; |
---|
4079 | 4081 | memset(ls->ls_remove_name, 0, DLM_RESNAME_MAXLEN); |
---|
.. | .. |
---|
5240 | 5242 | |
---|
5241 | 5243 | static struct dlm_lkb *find_resend_waiter(struct dlm_ls *ls) |
---|
5242 | 5244 | { |
---|
5243 | | - struct dlm_lkb *lkb; |
---|
5244 | | - int found = 0; |
---|
| 5245 | + struct dlm_lkb *lkb = NULL, *iter; |
---|
5245 | 5246 | |
---|
5246 | 5247 | 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; |
---|
5251 | 5252 | break; |
---|
5252 | 5253 | } |
---|
5253 | 5254 | } |
---|
5254 | 5255 | mutex_unlock(&ls->ls_waiters_mutex); |
---|
5255 | 5256 | |
---|
5256 | | - if (!found) |
---|
5257 | | - lkb = NULL; |
---|
5258 | 5257 | return lkb; |
---|
5259 | 5258 | } |
---|
5260 | 5259 | |
---|
.. | .. |
---|
5314 | 5313 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK; |
---|
5315 | 5314 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; |
---|
5316 | 5315 | 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 | + } |
---|
5318 | 5323 | mutex_lock(&ls->ls_waiters_mutex); |
---|
5319 | 5324 | list_del_init(&lkb->lkb_wait_reply); |
---|
5320 | 5325 | mutex_unlock(&ls->ls_waiters_mutex); |
---|
5321 | | - unhold_lkb(lkb); /* for waiters list */ |
---|
5322 | 5326 | |
---|
5323 | 5327 | if (oc || ou) { |
---|
5324 | 5328 | /* do an unlock or cancel instead of resending */ |
---|
.. | .. |
---|
5828 | 5832 | break; |
---|
5829 | 5833 | case -EAGAIN: |
---|
5830 | 5834 | error = 0; |
---|
5831 | | - /* fall through */ |
---|
| 5835 | + fallthrough; |
---|
5832 | 5836 | default: |
---|
5833 | 5837 | __put_lkb(ls, lkb); |
---|
5834 | 5838 | goto out; |
---|
.. | .. |
---|
5908 | 5912 | int mode, uint32_t flags, void *name, unsigned int namelen, |
---|
5909 | 5913 | unsigned long timeout_cs, uint32_t *lkid) |
---|
5910 | 5914 | { |
---|
5911 | | - struct dlm_lkb *lkb; |
---|
| 5915 | + struct dlm_lkb *lkb = NULL, *iter; |
---|
5912 | 5916 | struct dlm_user_args *ua; |
---|
5913 | 5917 | int found_other_mode = 0; |
---|
5914 | | - int found = 0; |
---|
5915 | 5918 | int rv = 0; |
---|
5916 | 5919 | |
---|
5917 | 5920 | 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) |
---|
5920 | 5923 | continue; |
---|
5921 | | - if (memcmp(lkb->lkb_resource->res_name, name, namelen)) |
---|
| 5924 | + if (memcmp(iter->lkb_resource->res_name, name, namelen)) |
---|
5922 | 5925 | continue; |
---|
5923 | | - if (lkb->lkb_grmode != mode) { |
---|
| 5926 | + if (iter->lkb_grmode != mode) { |
---|
5924 | 5927 | found_other_mode = 1; |
---|
5925 | 5928 | continue; |
---|
5926 | 5929 | } |
---|
5927 | 5930 | |
---|
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; |
---|
5932 | 5935 | break; |
---|
5933 | 5936 | } |
---|
5934 | 5937 | mutex_unlock(&ls->ls_orphans_mutex); |
---|
5935 | 5938 | |
---|
5936 | | - if (!found && found_other_mode) { |
---|
| 5939 | + if (!lkb && found_other_mode) { |
---|
5937 | 5940 | rv = -EAGAIN; |
---|
5938 | 5941 | goto out; |
---|
5939 | 5942 | } |
---|
5940 | 5943 | |
---|
5941 | | - if (!found) { |
---|
| 5944 | + if (!lkb) { |
---|
5942 | 5945 | rv = -ENOENT; |
---|
5943 | 5946 | goto out; |
---|
5944 | 5947 | } |
---|