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 'dlm-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm

Pull dlm updates from David Teigland:

- Fix a couple races found with a new torture test

- Improve errors when api functions are used incorrectly

- Improve tracing for lock requests from user space

- Fix use after free in recently added tracing cod.

- Small internal code cleanups

* tag 'dlm-6.1' of git://git.kernel.org/pub/scm/linux/kernel/git/teigland/linux-dlm:
fs: dlm: fix possible use after free if tracing
fs: dlm: const void resource name parameter
fs: dlm: LSFL_CB_DELAY only for kernel lockspaces
fs: dlm: remove DLM_LSFL_FS from uapi
fs: dlm: trace user space callbacks
fs: dlm: change ls_clear_proc_locks to spinlock
fs: dlm: remove dlm_del_ast prototype
fs: dlm: handle rcom in else if branch
fs: dlm: allow lockspaces have zero lvblen
fs: dlm: fix invalid derefence of sb_lvbptr
fs: dlm: handle -EINVAL as log_error()
fs: dlm: use __func__ for function name
fs: dlm: handle -EBUSY first in unlock validation
fs: dlm: handle -EBUSY first in lock arg validation
fs: dlm: fix race between test_bit() and queue_work()
fs: dlm: fix race in lowcomms

+193 -100
+2 -2
drivers/md/md-cluster.c
··· 876 876 memset(str, 0, 64); 877 877 sprintf(str, "%pU", mddev->uuid); 878 878 ret = dlm_new_lockspace(str, mddev->bitmap_info.cluster_name, 879 - DLM_LSFL_FS, LVB_SIZE, 880 - &md_ls_ops, mddev, &ops_rv, &cinfo->lockspace); 879 + 0, LVB_SIZE, &md_ls_ops, mddev, 880 + &ops_rv, &cinfo->lockspace); 881 881 if (ret) 882 882 goto err; 883 883 wait_for_completion(&cinfo->completion);
+9 -6
fs/dlm/ast.c
··· 200 200 if (!prev_seq) { 201 201 kref_get(&lkb->lkb_ref); 202 202 203 + mutex_lock(&ls->ls_cb_mutex); 203 204 if (test_bit(LSFL_CB_DELAY, &ls->ls_flags)) { 204 - mutex_lock(&ls->ls_cb_mutex); 205 205 list_add(&lkb->lkb_cb_list, &ls->ls_cb_delay); 206 - mutex_unlock(&ls->ls_cb_mutex); 207 206 } else { 208 207 queue_work(ls->ls_callback_wq, &lkb->lkb_cb_work); 209 208 } 209 + mutex_unlock(&ls->ls_cb_mutex); 210 210 } 211 211 out: 212 212 mutex_unlock(&lkb->lkb_cb_mutex); ··· 288 288 289 289 void dlm_callback_suspend(struct dlm_ls *ls) 290 290 { 291 - set_bit(LSFL_CB_DELAY, &ls->ls_flags); 291 + if (ls->ls_callback_wq) { 292 + mutex_lock(&ls->ls_cb_mutex); 293 + set_bit(LSFL_CB_DELAY, &ls->ls_flags); 294 + mutex_unlock(&ls->ls_cb_mutex); 292 295 293 - if (ls->ls_callback_wq) 294 296 flush_workqueue(ls->ls_callback_wq); 297 + } 295 298 } 296 299 297 300 #define MAX_CB_QUEUE 25 ··· 305 302 int count = 0, sum = 0; 306 303 bool empty; 307 304 308 - clear_bit(LSFL_CB_DELAY, &ls->ls_flags); 309 - 310 305 if (!ls->ls_callback_wq) 311 306 return; 307 + 308 + clear_bit(LSFL_CB_DELAY, &ls->ls_flags); 312 309 313 310 more: 314 311 mutex_lock(&ls->ls_cb_mutex);
-1
fs/dlm/ast.h
··· 11 11 #ifndef __ASTD_DOT_H__ 12 12 #define __ASTD_DOT_H__ 13 13 14 - void dlm_del_ast(struct dlm_lkb *lkb); 15 14 int dlm_add_lkb_callback(struct dlm_lkb *lkb, uint32_t flags, int mode, 16 15 int status, uint32_t sbflags, uint64_t seq); 17 16 int dlm_rem_lkb_callback(struct dlm_ls *ls, struct dlm_lkb *lkb,
+1 -1
fs/dlm/dlm_internal.h
··· 661 661 spinlock_t ls_recover_idr_lock; 662 662 wait_queue_head_t ls_wait_general; 663 663 wait_queue_head_t ls_recover_lock_wait; 664 - struct mutex ls_clear_proc_locks; 664 + spinlock_t ls_clear_proc_locks; 665 665 666 666 struct list_head ls_root_list; /* root resources */ 667 667 struct rw_semaphore ls_root_sem; /* protect root_list */
+109 -58
fs/dlm/lock.c
··· 401 401 unlock any spinlocks, go back and call pre_rsb_struct again. 402 402 Otherwise, take an rsb off the list and return it. */ 403 403 404 - static int get_rsb_struct(struct dlm_ls *ls, char *name, int len, 404 + static int get_rsb_struct(struct dlm_ls *ls, const void *name, int len, 405 405 struct dlm_rsb **r_ret) 406 406 { 407 407 struct dlm_rsb *r; ··· 412 412 count = ls->ls_new_rsb_count; 413 413 spin_unlock(&ls->ls_new_rsb_spin); 414 414 log_debug(ls, "find_rsb retry %d %d %s", 415 - count, dlm_config.ci_new_rsb_count, name); 415 + count, dlm_config.ci_new_rsb_count, 416 + (const char *)name); 416 417 return -EAGAIN; 417 418 } 418 419 ··· 449 448 return memcmp(r->res_name, maxname, DLM_RESNAME_MAXLEN); 450 449 } 451 450 452 - int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len, 451 + int dlm_search_rsb_tree(struct rb_root *tree, const void *name, int len, 453 452 struct dlm_rsb **r_ret) 454 453 { 455 454 struct rb_node *node = tree->rb_node; ··· 547 546 * while that rsb has a potentially stale master.) 548 547 */ 549 548 550 - static int find_rsb_dir(struct dlm_ls *ls, char *name, int len, 549 + static int find_rsb_dir(struct dlm_ls *ls, const void *name, int len, 551 550 uint32_t hash, uint32_t b, 552 551 int dir_nodeid, int from_nodeid, 553 552 unsigned int flags, struct dlm_rsb **r_ret) ··· 725 724 dlm_recover_locks) before we've made ourself master (in 726 725 dlm_recover_masters). */ 727 726 728 - static int find_rsb_nodir(struct dlm_ls *ls, char *name, int len, 727 + static int find_rsb_nodir(struct dlm_ls *ls, const void *name, int len, 729 728 uint32_t hash, uint32_t b, 730 729 int dir_nodeid, int from_nodeid, 731 730 unsigned int flags, struct dlm_rsb **r_ret) ··· 819 818 return error; 820 819 } 821 820 822 - static int find_rsb(struct dlm_ls *ls, char *name, int len, int from_nodeid, 823 - unsigned int flags, struct dlm_rsb **r_ret) 821 + static int find_rsb(struct dlm_ls *ls, const void *name, int len, 822 + int from_nodeid, unsigned int flags, 823 + struct dlm_rsb **r_ret) 824 824 { 825 825 uint32_t hash, b; 826 826 int dir_nodeid; ··· 2866 2864 static int validate_lock_args(struct dlm_ls *ls, struct dlm_lkb *lkb, 2867 2865 struct dlm_args *args) 2868 2866 { 2869 - int rv = -EINVAL; 2867 + int rv = -EBUSY; 2870 2868 2871 2869 if (args->flags & DLM_LKF_CONVERT) { 2872 - if (lkb->lkb_flags & DLM_IFL_MSTCPY) 2873 - goto out; 2874 - 2875 - if (args->flags & DLM_LKF_QUECVT && 2876 - !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1]) 2877 - goto out; 2878 - 2879 - rv = -EBUSY; 2880 2870 if (lkb->lkb_status != DLM_LKSTS_GRANTED) 2881 2871 goto out; 2882 2872 ··· 2877 2883 goto out; 2878 2884 2879 2885 if (is_overlap(lkb)) 2886 + goto out; 2887 + 2888 + rv = -EINVAL; 2889 + if (lkb->lkb_flags & DLM_IFL_MSTCPY) 2890 + goto out; 2891 + 2892 + if (args->flags & DLM_LKF_QUECVT && 2893 + !__quecvt_compat_matrix[lkb->lkb_grmode+1][args->mode+1]) 2880 2894 goto out; 2881 2895 } 2882 2896 ··· 2902 2900 #endif 2903 2901 rv = 0; 2904 2902 out: 2905 - if (rv) 2906 - log_debug(ls, "validate_lock_args %d %x %x %x %d %d %s", 2903 + switch (rv) { 2904 + case 0: 2905 + break; 2906 + case -EINVAL: 2907 + /* annoy the user because dlm usage is wrong */ 2908 + WARN_ON(1); 2909 + log_error(ls, "%s %d %x %x %x %d %d %s", __func__, 2907 2910 rv, lkb->lkb_id, lkb->lkb_flags, args->flags, 2908 2911 lkb->lkb_status, lkb->lkb_wait_type, 2909 2912 lkb->lkb_resource->res_name); 2913 + break; 2914 + default: 2915 + log_debug(ls, "%s %d %x %x %x %d %d %s", __func__, 2916 + rv, lkb->lkb_id, lkb->lkb_flags, args->flags, 2917 + lkb->lkb_status, lkb->lkb_wait_type, 2918 + lkb->lkb_resource->res_name); 2919 + break; 2920 + } 2921 + 2910 2922 return rv; 2911 2923 } 2912 2924 ··· 2934 2918 static int validate_unlock_args(struct dlm_lkb *lkb, struct dlm_args *args) 2935 2919 { 2936 2920 struct dlm_ls *ls = lkb->lkb_resource->res_ls; 2937 - int rv = -EINVAL; 2921 + int rv = -EBUSY; 2938 2922 2939 - if (lkb->lkb_flags & DLM_IFL_MSTCPY) { 2940 - log_error(ls, "unlock on MSTCPY %x", lkb->lkb_id); 2941 - dlm_print_lkb(lkb); 2923 + /* normal unlock not allowed if there's any op in progress */ 2924 + if (!(args->flags & (DLM_LKF_CANCEL | DLM_LKF_FORCEUNLOCK)) && 2925 + (lkb->lkb_wait_type || lkb->lkb_wait_count)) 2942 2926 goto out; 2943 - } 2944 - 2945 - /* an lkb may still exist even though the lock is EOL'ed due to a 2946 - cancel, unlock or failed noqueue request; an app can't use these 2947 - locks; return same error as if the lkid had not been found at all */ 2948 - 2949 - if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) { 2950 - log_debug(ls, "unlock on ENDOFLIFE %x", lkb->lkb_id); 2951 - rv = -ENOENT; 2952 - goto out; 2953 - } 2954 2927 2955 2928 /* an lkb may be waiting for an rsb lookup to complete where the 2956 2929 lookup was initiated by another lock */ ··· 2954 2949 unhold_lkb(lkb); /* undoes create_lkb() */ 2955 2950 } 2956 2951 /* caller changes -EBUSY to 0 for CANCEL and FORCEUNLOCK */ 2957 - rv = -EBUSY; 2952 + goto out; 2953 + } 2954 + 2955 + rv = -EINVAL; 2956 + if (lkb->lkb_flags & DLM_IFL_MSTCPY) { 2957 + log_error(ls, "unlock on MSTCPY %x", lkb->lkb_id); 2958 + dlm_print_lkb(lkb); 2959 + goto out; 2960 + } 2961 + 2962 + /* an lkb may still exist even though the lock is EOL'ed due to a 2963 + * cancel, unlock or failed noqueue request; an app can't use these 2964 + * locks; return same error as if the lkid had not been found at all 2965 + */ 2966 + 2967 + if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) { 2968 + log_debug(ls, "unlock on ENDOFLIFE %x", lkb->lkb_id); 2969 + rv = -ENOENT; 2958 2970 goto out; 2959 2971 } 2960 2972 ··· 3044 3022 goto out; 3045 3023 } 3046 3024 /* add_to_waiters() will set OVERLAP_UNLOCK */ 3047 - goto out_ok; 3048 3025 } 3049 - 3050 - /* normal unlock not allowed if there's any op in progress */ 3051 - rv = -EBUSY; 3052 - if (lkb->lkb_wait_type || lkb->lkb_wait_count) 3053 - goto out; 3054 3026 3055 3027 out_ok: 3056 3028 /* an overlapping op shouldn't blow away exflags from other op */ ··· 3053 3037 lkb->lkb_astparam = args->astparam; 3054 3038 rv = 0; 3055 3039 out: 3056 - if (rv) 3057 - log_debug(ls, "validate_unlock_args %d %x %x %x %x %d %s", rv, 3040 + switch (rv) { 3041 + case 0: 3042 + break; 3043 + case -EINVAL: 3044 + /* annoy the user because dlm usage is wrong */ 3045 + WARN_ON(1); 3046 + log_error(ls, "%s %d %x %x %x %x %d %s", __func__, rv, 3058 3047 lkb->lkb_id, lkb->lkb_flags, lkb->lkb_exflags, 3059 3048 args->flags, lkb->lkb_wait_type, 3060 3049 lkb->lkb_resource->res_name); 3050 + break; 3051 + default: 3052 + log_debug(ls, "%s %d %x %x %x %x %d %s", __func__, rv, 3053 + lkb->lkb_id, lkb->lkb_flags, lkb->lkb_exflags, 3054 + args->flags, lkb->lkb_wait_type, 3055 + lkb->lkb_resource->res_name); 3056 + break; 3057 + } 3058 + 3061 3059 return rv; 3062 3060 } 3063 3061 ··· 3322 3292 * request_lock(), convert_lock(), unlock_lock(), cancel_lock() 3323 3293 */ 3324 3294 3325 - static int request_lock(struct dlm_ls *ls, struct dlm_lkb *lkb, char *name, 3326 - int len, struct dlm_args *args) 3295 + static int request_lock(struct dlm_ls *ls, struct dlm_lkb *lkb, 3296 + const void *name, int len, 3297 + struct dlm_args *args) 3327 3298 { 3328 3299 struct dlm_rsb *r; 3329 3300 int error; ··· 3423 3392 int mode, 3424 3393 struct dlm_lksb *lksb, 3425 3394 uint32_t flags, 3426 - void *name, 3395 + const void *name, 3427 3396 unsigned int namelen, 3428 3397 uint32_t parent_lkid, 3429 3398 void (*ast) (void *astarg), ··· 3469 3438 if (error == -EINPROGRESS) 3470 3439 error = 0; 3471 3440 out_put: 3472 - trace_dlm_lock_end(ls, lkb, name, namelen, mode, flags, error); 3441 + trace_dlm_lock_end(ls, lkb, name, namelen, mode, flags, error, true); 3473 3442 3474 3443 if (convert || error) 3475 3444 __put_lkb(ls, lkb); ··· 3654 3623 case cpu_to_le32(DLM_MSG_REQUEST_REPLY): 3655 3624 case cpu_to_le32(DLM_MSG_CONVERT_REPLY): 3656 3625 case cpu_to_le32(DLM_MSG_GRANT): 3657 - if (!lkb->lkb_lvbptr) 3626 + if (!lkb->lkb_lvbptr || !(lkb->lkb_exflags & DLM_LKF_VALBLK)) 3658 3627 break; 3659 3628 memcpy(ms->m_extra, lkb->lkb_lvbptr, r->res_ls->ls_lvblen); 3660 3629 break; ··· 5111 5080 down_read(&ls->ls_recv_active); 5112 5081 if (hd->h_cmd == DLM_MSG) 5113 5082 dlm_receive_message(ls, &p->message, nodeid); 5114 - else 5083 + else if (hd->h_cmd == DLM_RCOM) 5115 5084 dlm_receive_rcom(ls, &p->rcom, nodeid); 5085 + else 5086 + log_error(ls, "invalid h_cmd %d from %d lockspace %x", 5087 + hd->h_cmd, nodeid, le32_to_cpu(hd->u.h_lockspace)); 5116 5088 up_read(&ls->ls_recv_active); 5117 5089 5118 5090 dlm_put_lockspace(ls); ··· 5835 5801 { 5836 5802 struct dlm_lkb *lkb; 5837 5803 struct dlm_args args; 5804 + bool do_put = true; 5838 5805 int error; 5839 5806 5840 5807 dlm_lock_recovery(ls); ··· 5846 5811 goto out; 5847 5812 } 5848 5813 5814 + trace_dlm_lock_start(ls, lkb, name, namelen, mode, flags); 5815 + 5849 5816 if (flags & DLM_LKF_VALBLK) { 5850 5817 ua->lksb.sb_lvbptr = kzalloc(DLM_USER_LVB_LEN, GFP_NOFS); 5851 5818 if (!ua->lksb.sb_lvbptr) { 5852 5819 kfree(ua); 5853 - __put_lkb(ls, lkb); 5854 5820 error = -ENOMEM; 5855 - goto out; 5821 + goto out_put; 5856 5822 } 5857 5823 } 5858 5824 #ifdef CONFIG_DLM_DEPRECATED_API ··· 5867 5831 kfree(ua->lksb.sb_lvbptr); 5868 5832 ua->lksb.sb_lvbptr = NULL; 5869 5833 kfree(ua); 5870 - __put_lkb(ls, lkb); 5871 - goto out; 5834 + goto out_put; 5872 5835 } 5873 5836 5874 5837 /* After ua is attached to lkb it will be freed by dlm_free_lkb(). ··· 5886 5851 error = 0; 5887 5852 fallthrough; 5888 5853 default: 5889 - __put_lkb(ls, lkb); 5890 - goto out; 5854 + goto out_put; 5891 5855 } 5892 5856 5893 5857 /* add this new lkb to the per-process list of locks */ ··· 5894 5860 hold_lkb(lkb); 5895 5861 list_add_tail(&lkb->lkb_ownqueue, &ua->proc->locks); 5896 5862 spin_unlock(&ua->proc->locks_spin); 5863 + do_put = false; 5864 + out_put: 5865 + trace_dlm_lock_end(ls, lkb, name, namelen, mode, flags, error, false); 5866 + if (do_put) 5867 + __put_lkb(ls, lkb); 5897 5868 out: 5898 5869 dlm_unlock_recovery(ls); 5899 5870 return error; ··· 5923 5884 error = find_lkb(ls, lkid, &lkb); 5924 5885 if (error) 5925 5886 goto out; 5887 + 5888 + trace_dlm_lock_start(ls, lkb, NULL, 0, mode, flags); 5926 5889 5927 5890 /* user can change the params on its lock when it converts it, or 5928 5891 add an lvb that didn't exist before */ ··· 5963 5922 if (error == -EINPROGRESS || error == -EAGAIN || error == -EDEADLK) 5964 5923 error = 0; 5965 5924 out_put: 5925 + trace_dlm_lock_end(ls, lkb, NULL, 0, mode, flags, error, false); 5966 5926 dlm_put_lkb(lkb); 5967 5927 out: 5968 5928 dlm_unlock_recovery(ls); ··· 6056 6014 if (error) 6057 6015 goto out; 6058 6016 6017 + trace_dlm_unlock_start(ls, lkb, flags); 6018 + 6059 6019 ua = lkb->lkb_ua; 6060 6020 6061 6021 if (lvb_in && ua->lksb.sb_lvbptr) ··· 6086 6042 list_move(&lkb->lkb_ownqueue, &ua->proc->unlocking); 6087 6043 spin_unlock(&ua->proc->locks_spin); 6088 6044 out_put: 6045 + trace_dlm_unlock_end(ls, lkb, flags, error); 6089 6046 dlm_put_lkb(lkb); 6090 6047 out: 6091 6048 dlm_unlock_recovery(ls); ··· 6108 6063 if (error) 6109 6064 goto out; 6110 6065 6066 + trace_dlm_unlock_start(ls, lkb, flags); 6067 + 6111 6068 ua = lkb->lkb_ua; 6112 6069 if (ua_tmp->castparam) 6113 6070 ua->castparam = ua_tmp->castparam; ··· 6127 6080 if (error == -EBUSY) 6128 6081 error = 0; 6129 6082 out_put: 6083 + trace_dlm_unlock_end(ls, lkb, flags, error); 6130 6084 dlm_put_lkb(lkb); 6131 6085 out: 6132 6086 dlm_unlock_recovery(ls); ··· 6148 6100 error = find_lkb(ls, lkid, &lkb); 6149 6101 if (error) 6150 6102 goto out; 6103 + 6104 + trace_dlm_unlock_start(ls, lkb, flags); 6151 6105 6152 6106 ua = lkb->lkb_ua; 6153 6107 ··· 6179 6129 if (error == -EBUSY) 6180 6130 error = 0; 6181 6131 out_put: 6132 + trace_dlm_unlock_end(ls, lkb, flags, error); 6182 6133 dlm_put_lkb(lkb); 6183 6134 out: 6184 6135 dlm_unlock_recovery(ls); ··· 6235 6184 { 6236 6185 struct dlm_lkb *lkb = NULL; 6237 6186 6238 - mutex_lock(&ls->ls_clear_proc_locks); 6187 + spin_lock(&ls->ls_clear_proc_locks); 6239 6188 if (list_empty(&proc->locks)) 6240 6189 goto out; 6241 6190 ··· 6247 6196 else 6248 6197 lkb->lkb_flags |= DLM_IFL_DEAD; 6249 6198 out: 6250 - mutex_unlock(&ls->ls_clear_proc_locks); 6199 + spin_unlock(&ls->ls_clear_proc_locks); 6251 6200 return lkb; 6252 6201 } 6253 6202 ··· 6284 6233 dlm_put_lkb(lkb); 6285 6234 } 6286 6235 6287 - mutex_lock(&ls->ls_clear_proc_locks); 6236 + spin_lock(&ls->ls_clear_proc_locks); 6288 6237 6289 6238 /* in-progress unlocks */ 6290 6239 list_for_each_entry_safe(lkb, safe, &proc->unlocking, lkb_ownqueue) { ··· 6300 6249 dlm_put_lkb(lkb); 6301 6250 } 6302 6251 6303 - mutex_unlock(&ls->ls_clear_proc_locks); 6252 + spin_unlock(&ls->ls_clear_proc_locks); 6304 6253 dlm_unlock_recovery(ls); 6305 6254 } 6306 6255
+1 -1
fs/dlm/lock.h
··· 36 36 int dlm_master_lookup(struct dlm_ls *ls, int nodeid, char *name, int len, 37 37 unsigned int flags, int *r_nodeid, int *result); 38 38 39 - int dlm_search_rsb_tree(struct rb_root *tree, char *name, int len, 39 + int dlm_search_rsb_tree(struct rb_root *tree, const void *name, int len, 40 40 struct dlm_rsb **r_ret); 41 41 42 42 void dlm_recover_purge(struct dlm_ls *ls);
+26 -6
fs/dlm/lockspace.c
··· 416 416 if (namelen > DLM_LOCKSPACE_LEN || namelen == 0) 417 417 return -EINVAL; 418 418 419 - if (!lvblen || (lvblen % 8)) 419 + if (lvblen % 8) 420 420 return -EINVAL; 421 421 422 422 if (!try_module_get(THIS_MODULE)) ··· 584 584 atomic_set(&ls->ls_requestqueue_cnt, 0); 585 585 init_waitqueue_head(&ls->ls_requestqueue_wait); 586 586 mutex_init(&ls->ls_requestqueue_mutex); 587 - mutex_init(&ls->ls_clear_proc_locks); 587 + spin_lock_init(&ls->ls_clear_proc_locks); 588 588 589 589 /* Due backwards compatibility with 3.1 we need to use maximum 590 590 * possible dlm message size to be sure the message will fit and ··· 703 703 return error; 704 704 } 705 705 706 - int dlm_new_lockspace(const char *name, const char *cluster, 707 - uint32_t flags, int lvblen, 708 - const struct dlm_lockspace_ops *ops, void *ops_arg, 709 - int *ops_result, dlm_lockspace_t **lockspace) 706 + static int __dlm_new_lockspace(const char *name, const char *cluster, 707 + uint32_t flags, int lvblen, 708 + const struct dlm_lockspace_ops *ops, 709 + void *ops_arg, int *ops_result, 710 + dlm_lockspace_t **lockspace) 710 711 { 711 712 int error = 0; 712 713 ··· 731 730 out: 732 731 mutex_unlock(&ls_lock); 733 732 return error; 733 + } 734 + 735 + int dlm_new_lockspace(const char *name, const char *cluster, uint32_t flags, 736 + int lvblen, const struct dlm_lockspace_ops *ops, 737 + void *ops_arg, int *ops_result, 738 + dlm_lockspace_t **lockspace) 739 + { 740 + return __dlm_new_lockspace(name, cluster, flags | DLM_LSFL_FS, lvblen, 741 + ops, ops_arg, ops_result, lockspace); 742 + } 743 + 744 + int dlm_new_user_lockspace(const char *name, const char *cluster, 745 + uint32_t flags, int lvblen, 746 + const struct dlm_lockspace_ops *ops, 747 + void *ops_arg, int *ops_result, 748 + dlm_lockspace_t **lockspace) 749 + { 750 + return __dlm_new_lockspace(name, cluster, flags, lvblen, ops, 751 + ops_arg, ops_result, lockspace); 734 752 } 735 753 736 754 static int lkb_idr_is_local(int id, void *p, void *data)
+13
fs/dlm/lockspace.h
··· 12 12 #ifndef __LOCKSPACE_DOT_H__ 13 13 #define __LOCKSPACE_DOT_H__ 14 14 15 + /* DLM_LSFL_FS 16 + * The lockspace user is in the kernel (i.e. filesystem). Enables 17 + * direct bast/cast callbacks. 18 + * 19 + * internal lockspace flag - will be removed in future 20 + */ 21 + #define DLM_LSFL_FS 0x00000004 22 + 15 23 int dlm_lockspace_init(void); 16 24 void dlm_lockspace_exit(void); 17 25 struct dlm_ls *dlm_find_lockspace_global(uint32_t id); ··· 28 20 void dlm_put_lockspace(struct dlm_ls *ls); 29 21 void dlm_stop_lockspaces(void); 30 22 void dlm_stop_lockspaces_check(void); 23 + int dlm_new_user_lockspace(const char *name, const char *cluster, 24 + uint32_t flags, int lvblen, 25 + const struct dlm_lockspace_ops *ops, 26 + void *ops_arg, int *ops_result, 27 + dlm_lockspace_t **lockspace); 31 28 32 29 #endif /* __LOCKSPACE_DOT_H__ */ 33 30
+4
fs/dlm/lowcomms.c
··· 1336 1336 return NULL; 1337 1337 } 1338 1338 1339 + /* for dlm_lowcomms_commit_msg() */ 1340 + kref_get(&msg->ref); 1339 1341 /* we assume if successful commit must called */ 1340 1342 msg->idx = idx; 1341 1343 return msg; ··· 1377 1375 { 1378 1376 _dlm_lowcomms_commit_msg(msg); 1379 1377 srcu_read_unlock(&connections_srcu, msg->idx); 1378 + /* because dlm_lowcomms_new_msg() */ 1379 + kref_put(&msg->ref, dlm_msg_release); 1380 1380 } 1381 1381 #endif 1382 1382
+11 -6
fs/dlm/user.c
··· 16 16 #include <linux/slab.h> 17 17 #include <linux/sched/signal.h> 18 18 19 + #include <trace/events/dlm.h> 20 + 19 21 #include "dlm_internal.h" 20 22 #include "lockspace.h" 21 23 #include "lock.h" ··· 186 184 return; 187 185 188 186 ls = lkb->lkb_resource->res_ls; 189 - mutex_lock(&ls->ls_clear_proc_locks); 187 + spin_lock(&ls->ls_clear_proc_locks); 190 188 191 189 /* If ORPHAN/DEAD flag is set, it means the process is dead so an ast 192 190 can't be delivered. For ORPHAN's, dlm_clear_proc_locks() freed ··· 232 230 spin_unlock(&proc->locks_spin); 233 231 } 234 232 out: 235 - mutex_unlock(&ls->ls_clear_proc_locks); 233 + spin_unlock(&ls->ls_clear_proc_locks); 236 234 } 237 235 238 236 static int device_user_lock(struct dlm_user_proc *proc, ··· 423 421 if (!capable(CAP_SYS_ADMIN)) 424 422 return -EPERM; 425 423 426 - error = dlm_new_lockspace(params->name, dlm_config.ci_cluster_name, params->flags, 427 - DLM_USER_LVB_LEN, NULL, NULL, NULL, 428 - &lockspace); 424 + error = dlm_new_user_lockspace(params->name, dlm_config.ci_cluster_name, 425 + params->flags, DLM_USER_LVB_LEN, NULL, 426 + NULL, NULL, &lockspace); 429 427 if (error) 430 428 return error; 431 429 ··· 884 882 goto try_another; 885 883 } 886 884 887 - if (cb.flags & DLM_CB_CAST) { 885 + if (cb.flags & DLM_CB_BAST) { 886 + trace_dlm_bast(lkb->lkb_resource->res_ls, lkb, cb.mode); 887 + } else if (cb.flags & DLM_CB_CAST) { 888 888 new_mode = cb.mode; 889 889 890 890 if (!cb.sb_status && lkb->lkb_lksb->sb_lvbptr && ··· 895 891 896 892 lkb->lkb_lksb->sb_status = cb.sb_status; 897 893 lkb->lkb_lksb->sb_flags = cb.sb_flags; 894 + trace_dlm_ast(lkb->lkb_resource->res_ls, lkb); 898 895 } 899 896 900 897 rv = copy_result_to_user(lkb->lkb_ua,
+1 -1
fs/gfs2/lock_dlm.c
··· 1302 1302 memcpy(cluster, table, strlen(table) - strlen(fsname)); 1303 1303 fsname++; 1304 1304 1305 - flags = DLM_LSFL_FS | DLM_LSFL_NEWEXCL; 1305 + flags = DLM_LSFL_NEWEXCL; 1306 1306 1307 1307 /* 1308 1308 * create/join lockspace
+1 -1
fs/ocfs2/stack_user.c
··· 991 991 lc->oc_type = NO_CONTROLD; 992 992 993 993 rc = dlm_new_lockspace(conn->cc_name, conn->cc_cluster_name, 994 - DLM_LSFL_FS | DLM_LSFL_NEWEXCL, DLM_LVB_LEN, 994 + DLM_LSFL_NEWEXCL, DLM_LVB_LEN, 995 995 &ocfs2_ls_ops, conn, &ops_rv, &fsdlm); 996 996 if (rc) { 997 997 if (rc == -EEXIST || rc == -EPROTO)
+1 -4
include/linux/dlm.h
··· 56 56 * DLM_LSFL_TIMEWARN 57 57 * The dlm should emit netlink messages if locks have been waiting 58 58 * for a configurable amount of time. (Unused.) 59 - * DLM_LSFL_FS 60 - * The lockspace user is in the kernel (i.e. filesystem). Enables 61 - * direct bast/cast callbacks. 62 59 * DLM_LSFL_NEWEXCL 63 60 * dlm_new_lockspace() should return -EEXIST if the lockspace exists. 64 61 * ··· 131 134 int mode, 132 135 struct dlm_lksb *lksb, 133 136 uint32_t flags, 134 - void *name, 137 + const void *name, 135 138 unsigned int namelen, 136 139 uint32_t parent_lkid, 137 140 void (*lockast) (void *astarg),
+14 -12
include/trace/events/dlm.h
··· 49 49 /* note: we begin tracing dlm_lock_start() only if ls and lkb are found */ 50 50 TRACE_EVENT(dlm_lock_start, 51 51 52 - TP_PROTO(struct dlm_ls *ls, struct dlm_lkb *lkb, void *name, 52 + TP_PROTO(struct dlm_ls *ls, struct dlm_lkb *lkb, const void *name, 53 53 unsigned int namelen, int mode, __u32 flags), 54 54 55 55 TP_ARGS(ls, lkb, name, namelen, mode, flags), ··· 91 91 92 92 TRACE_EVENT(dlm_lock_end, 93 93 94 - TP_PROTO(struct dlm_ls *ls, struct dlm_lkb *lkb, void *name, 95 - unsigned int namelen, int mode, __u32 flags, int error), 94 + TP_PROTO(struct dlm_ls *ls, struct dlm_lkb *lkb, const void *name, 95 + unsigned int namelen, int mode, __u32 flags, int error, 96 + bool kernel_lock), 96 97 97 - TP_ARGS(ls, lkb, name, namelen, mode, flags, error), 98 + TP_ARGS(ls, lkb, name, namelen, mode, flags, error, kernel_lock), 98 99 99 100 TP_STRUCT__entry( 100 101 __field(__u32, ls_id) ··· 114 113 __entry->lkb_id = lkb->lkb_id; 115 114 __entry->mode = mode; 116 115 __entry->flags = flags; 116 + __entry->error = error; 117 117 118 118 r = lkb->lkb_resource; 119 119 if (r) ··· 124 122 memcpy(__get_dynamic_array(res_name), name, 125 123 __get_dynamic_array_len(res_name)); 126 124 127 - /* return value will be zeroed in those cases by dlm_lock() 128 - * we do it here again to not introduce more overhead if 129 - * trace isn't running and error reflects the return value. 130 - */ 131 - if (error == -EAGAIN || error == -EDEADLK) 132 - __entry->error = 0; 133 - else 134 - __entry->error = error; 125 + if (kernel_lock) { 126 + /* return value will be zeroed in those cases by dlm_lock() 127 + * we do it here again to not introduce more overhead if 128 + * trace isn't running and error reflects the return value. 129 + */ 130 + if (error == -EAGAIN || error == -EDEADLK) 131 + __entry->error = 0; 132 + } 135 133 136 134 ), 137 135
-1
include/uapi/linux/dlm.h
··· 69 69 /* dlm_new_lockspace() flags */ 70 70 71 71 #define DLM_LSFL_TIMEWARN 0x00000002 72 - #define DLM_LSFL_FS 0x00000004 73 72 #define DLM_LSFL_NEWEXCL 0x00000008 74 73 75 74