diff options
| -rw-r--r-- | fs/dlm/lock.c | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 01e7d39c5fba..8cb92046a584 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
| @@ -835,7 +835,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) | |||
| 835 | lkb->lkb_wait_count++; | 835 | lkb->lkb_wait_count++; |
| 836 | hold_lkb(lkb); | 836 | hold_lkb(lkb); |
| 837 | 837 | ||
| 838 | log_debug(ls, "add overlap %x cur %d new %d count %d flags %x", | 838 | log_debug(ls, "addwait %x cur %d overlap %d count %d f %x", |
| 839 | lkb->lkb_id, lkb->lkb_wait_type, mstype, | 839 | lkb->lkb_id, lkb->lkb_wait_type, mstype, |
| 840 | lkb->lkb_wait_count, lkb->lkb_flags); | 840 | lkb->lkb_wait_count, lkb->lkb_flags); |
| 841 | goto out; | 841 | goto out; |
| @@ -851,7 +851,7 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) | |||
| 851 | list_add(&lkb->lkb_wait_reply, &ls->ls_waiters); | 851 | list_add(&lkb->lkb_wait_reply, &ls->ls_waiters); |
| 852 | out: | 852 | out: |
| 853 | if (error) | 853 | if (error) |
| 854 | log_error(ls, "add_to_waiters %x error %d flags %x %d %d %s", | 854 | log_error(ls, "addwait error %x %d flags %x %d %d %s", |
| 855 | lkb->lkb_id, error, lkb->lkb_flags, mstype, | 855 | lkb->lkb_id, error, lkb->lkb_flags, mstype, |
| 856 | lkb->lkb_wait_type, lkb->lkb_resource->res_name); | 856 | lkb->lkb_wait_type, lkb->lkb_resource->res_name); |
| 857 | mutex_unlock(&ls->ls_waiters_mutex); | 857 | mutex_unlock(&ls->ls_waiters_mutex); |
| @@ -863,23 +863,55 @@ static int add_to_waiters(struct dlm_lkb *lkb, int mstype) | |||
| 863 | request reply on the requestqueue) between dlm_recover_waiters_pre() which | 863 | request reply on the requestqueue) between dlm_recover_waiters_pre() which |
| 864 | set RESEND and dlm_recover_waiters_post() */ | 864 | set RESEND and dlm_recover_waiters_post() */ |
| 865 | 865 | ||
| 866 | static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) | 866 | static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype, |
| 867 | struct dlm_message *ms) | ||
| 867 | { | 868 | { |
| 868 | struct dlm_ls *ls = lkb->lkb_resource->res_ls; | 869 | struct dlm_ls *ls = lkb->lkb_resource->res_ls; |
| 869 | int overlap_done = 0; | 870 | int overlap_done = 0; |
| 870 | 871 | ||
| 871 | if (is_overlap_unlock(lkb) && (mstype == DLM_MSG_UNLOCK_REPLY)) { | 872 | if (is_overlap_unlock(lkb) && (mstype == DLM_MSG_UNLOCK_REPLY)) { |
| 873 | log_debug(ls, "remwait %x unlock_reply overlap", lkb->lkb_id); | ||
| 872 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK; | 874 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_UNLOCK; |
| 873 | overlap_done = 1; | 875 | overlap_done = 1; |
| 874 | goto out_del; | 876 | goto out_del; |
| 875 | } | 877 | } |
| 876 | 878 | ||
| 877 | if (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL_REPLY)) { | 879 | if (is_overlap_cancel(lkb) && (mstype == DLM_MSG_CANCEL_REPLY)) { |
| 880 | log_debug(ls, "remwait %x cancel_reply overlap", lkb->lkb_id); | ||
| 878 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; | 881 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; |
| 879 | overlap_done = 1; | 882 | overlap_done = 1; |
| 880 | goto out_del; | 883 | goto out_del; |
| 881 | } | 884 | } |
| 882 | 885 | ||
| 886 | /* Cancel state was preemptively cleared by a successful convert, | ||
| 887 | see next comment, nothing to do. */ | ||
| 888 | |||
| 889 | if ((mstype == DLM_MSG_CANCEL_REPLY) && | ||
| 890 | (lkb->lkb_wait_type != DLM_MSG_CANCEL)) { | ||
| 891 | log_debug(ls, "remwait %x cancel_reply wait_type %d", | ||
| 892 | lkb->lkb_id, lkb->lkb_wait_type); | ||
| 893 | return -1; | ||
| 894 | } | ||
| 895 | |||
| 896 | /* Remove for the convert reply, and premptively remove for the | ||
| 897 | cancel reply. A convert has been granted while there's still | ||
| 898 | an outstanding cancel on it (the cancel is moot and the result | ||
| 899 | in the cancel reply should be 0). We preempt the cancel reply | ||
| 900 | because the app gets the convert result and then can follow up | ||
| 901 | with another op, like convert. This subsequent op would see the | ||
| 902 | lingering state of the cancel and fail with -EBUSY. */ | ||
| 903 | |||
| 904 | if ((mstype == DLM_MSG_CONVERT_REPLY) && | ||
| 905 | (lkb->lkb_wait_type == DLM_MSG_CONVERT) && | ||
| 906 | is_overlap_cancel(lkb) && ms && !ms->m_result) { | ||
| 907 | log_debug(ls, "remwait %x convert_reply zap overlap_cancel", | ||
| 908 | lkb->lkb_id); | ||
| 909 | lkb->lkb_wait_type = 0; | ||
| 910 | lkb->lkb_flags &= ~DLM_IFL_OVERLAP_CANCEL; | ||
| 911 | lkb->lkb_wait_count--; | ||
| 912 | goto out_del; | ||
| 913 | } | ||
| 914 | |||
| 883 | /* N.B. type of reply may not always correspond to type of original | 915 | /* N.B. type of reply may not always correspond to type of original |
| 884 | msg due to lookup->request optimization, verify others? */ | 916 | msg due to lookup->request optimization, verify others? */ |
| 885 | 917 | ||
| @@ -888,8 +920,8 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |||
| 888 | goto out_del; | 920 | goto out_del; |
| 889 | } | 921 | } |
| 890 | 922 | ||
| 891 | log_error(ls, "remove_from_waiters lkid %x flags %x types %d %d", | 923 | log_error(ls, "remwait error %x reply %d flags %x no wait_type", |
| 892 | lkb->lkb_id, lkb->lkb_flags, mstype, lkb->lkb_wait_type); | 924 | lkb->lkb_id, mstype, lkb->lkb_flags); |
| 893 | return -1; | 925 | return -1; |
| 894 | 926 | ||
| 895 | out_del: | 927 | out_del: |
| @@ -899,7 +931,7 @@ static int _remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |||
| 899 | this would happen */ | 931 | this would happen */ |
| 900 | 932 | ||
| 901 | if (overlap_done && lkb->lkb_wait_type) { | 933 | if (overlap_done && lkb->lkb_wait_type) { |
| 902 | log_error(ls, "remove_from_waiters %x reply %d give up on %d", | 934 | log_error(ls, "remwait error %x reply %d wait_type %d overlap", |
| 903 | lkb->lkb_id, mstype, lkb->lkb_wait_type); | 935 | lkb->lkb_id, mstype, lkb->lkb_wait_type); |
| 904 | lkb->lkb_wait_count--; | 936 | lkb->lkb_wait_count--; |
| 905 | lkb->lkb_wait_type = 0; | 937 | lkb->lkb_wait_type = 0; |
| @@ -921,7 +953,7 @@ static int remove_from_waiters(struct dlm_lkb *lkb, int mstype) | |||
| 921 | int error; | 953 | int error; |
| 922 | 954 | ||
| 923 | mutex_lock(&ls->ls_waiters_mutex); | 955 | mutex_lock(&ls->ls_waiters_mutex); |
| 924 | error = _remove_from_waiters(lkb, mstype); | 956 | error = _remove_from_waiters(lkb, mstype, NULL); |
| 925 | mutex_unlock(&ls->ls_waiters_mutex); | 957 | mutex_unlock(&ls->ls_waiters_mutex); |
| 926 | return error; | 958 | return error; |
| 927 | } | 959 | } |
| @@ -936,7 +968,7 @@ static int remove_from_waiters_ms(struct dlm_lkb *lkb, struct dlm_message *ms) | |||
| 936 | 968 | ||
| 937 | if (ms != &ls->ls_stub_ms) | 969 | if (ms != &ls->ls_stub_ms) |
| 938 | mutex_lock(&ls->ls_waiters_mutex); | 970 | mutex_lock(&ls->ls_waiters_mutex); |
| 939 | error = _remove_from_waiters(lkb, ms->m_type); | 971 | error = _remove_from_waiters(lkb, ms->m_type, ms); |
| 940 | if (ms != &ls->ls_stub_ms) | 972 | if (ms != &ls->ls_stub_ms) |
| 941 | mutex_unlock(&ls->ls_waiters_mutex); | 973 | mutex_unlock(&ls->ls_waiters_mutex); |
| 942 | return error; | 974 | return error; |
| @@ -2083,6 +2115,11 @@ static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, | |||
| 2083 | lkb->lkb_timeout_cs = args->timeout; | 2115 | lkb->lkb_timeout_cs = args->timeout; |
| 2084 | rv = 0; | 2116 | rv = 0; |
| 2085 | out: | 2117 | out: |
| 2118 | if (rv) | ||
| 2119 | log_debug(ls, "validate_lock_args %d %x %x %x %d %d %s", | ||
| 2120 | rv, lkb->lkb_id, lkb->lkb_flags, args->flags, | ||
| 2121 | lkb->lkb_status, lkb->lkb_wait_type, | ||
| 2122 | lkb->lkb_resource->res_name); | ||
| 2086 | return rv; | 2123 | return rv; |
| 2087 | } | 2124 | } |
| 2088 | 2125 | ||
