user.c (d3e4dc5d68c8fef719291cc9f3dc907aac494c55) | user.c (61bed0baa4dba17dd06cdfe20481a580718d6c7c) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved. 4 */ 5 6#include <linux/miscdevice.h> 7#include <linux/init.h> 8#include <linux/wait.h> --- 11 unchanged lines hidden (view full) --- 20 21#include "dlm_internal.h" 22#include "lockspace.h" 23#include "lock.h" 24#include "lvb_table.h" 25#include "user.h" 26#include "ast.h" 27#include "config.h" | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved. 4 */ 5 6#include <linux/miscdevice.h> 7#include <linux/init.h> 8#include <linux/wait.h> --- 11 unchanged lines hidden (view full) --- 20 21#include "dlm_internal.h" 22#include "lockspace.h" 23#include "lock.h" 24#include "lvb_table.h" 25#include "user.h" 26#include "ast.h" 27#include "config.h" |
28#include "memory.h" |
|
28 29static const char name_prefix[] = "dlm"; 30static const struct file_operations device_fops; 31static atomic_t dlm_monitor_opened; 32static int dlm_monitor_unused = 1; 33 34#ifdef CONFIG_COMPAT 35 --- 134 unchanged lines hidden (view full) --- 170 } 171 return 0; 172} 173 174/* we could possibly check if the cancel of an orphan has resulted in the lkb 175 being removed and then remove that lkb from the orphans list and free it */ 176 177void dlm_user_add_ast(struct dlm_lkb *lkb, uint32_t flags, int mode, | 29 30static const char name_prefix[] = "dlm"; 31static const struct file_operations device_fops; 32static atomic_t dlm_monitor_opened; 33static int dlm_monitor_unused = 1; 34 35#ifdef CONFIG_COMPAT 36 --- 134 unchanged lines hidden (view full) --- 171 } 172 return 0; 173} 174 175/* we could possibly check if the cancel of an orphan has resulted in the lkb 176 being removed and then remove that lkb from the orphans list and free it */ 177 178void dlm_user_add_ast(struct dlm_lkb *lkb, uint32_t flags, int mode, |
178 int status, uint32_t sbflags, uint64_t seq) | 179 int status, uint32_t sbflags) |
179{ 180 struct dlm_ls *ls; 181 struct dlm_user_args *ua; 182 struct dlm_user_proc *proc; 183 int rv; 184 185 if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) 186 return; --- 17 unchanged lines hidden (view full) --- 204 if ((flags & DLM_CB_BAST) && ua->bastaddr == NULL) 205 goto out; 206 207 if ((flags & DLM_CB_CAST) && lkb_is_endoflife(mode, status)) 208 lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; 209 210 spin_lock(&proc->asts_spin); 211 | 180{ 181 struct dlm_ls *ls; 182 struct dlm_user_args *ua; 183 struct dlm_user_proc *proc; 184 int rv; 185 186 if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD)) 187 return; --- 17 unchanged lines hidden (view full) --- 205 if ((flags & DLM_CB_BAST) && ua->bastaddr == NULL) 206 goto out; 207 208 if ((flags & DLM_CB_CAST) && lkb_is_endoflife(mode, status)) 209 lkb->lkb_flags |= DLM_IFL_ENDOFLIFE; 210 211 spin_lock(&proc->asts_spin); 212 |
212 rv = dlm_add_lkb_callback(lkb, flags, mode, status, sbflags, seq); 213 if (rv < 0) { | 213 rv = dlm_enqueue_lkb_callback(lkb, flags, mode, status, sbflags); 214 switch (rv) { 215 case DLM_ENQUEUE_CALLBACK_FAILURE: |
214 spin_unlock(&proc->asts_spin); | 216 spin_unlock(&proc->asts_spin); |
217 WARN_ON(1); |
|
215 goto out; | 218 goto out; |
216 } 217 218 if (list_empty(&lkb->lkb_cb_list)) { | 219 case DLM_ENQUEUE_CALLBACK_NEED_SCHED: |
219 kref_get(&lkb->lkb_ref); 220 list_add_tail(&lkb->lkb_cb_list, &proc->asts); 221 wake_up_interruptible(&proc->wait); | 220 kref_get(&lkb->lkb_ref); 221 list_add_tail(&lkb->lkb_cb_list, &proc->asts); 222 wake_up_interruptible(&proc->wait); |
223 break; 224 case DLM_ENQUEUE_CALLBACK_SUCCESS: 225 break; 226 default: 227 WARN_ON(1); 228 break; |
|
222 } 223 spin_unlock(&proc->asts_spin); 224 225 if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) { 226 /* N.B. spin_lock locks_spin, not asts_spin */ 227 spin_lock(&proc->locks_spin); 228 if (!list_empty(&lkb->lkb_ownqueue)) { 229 list_del_init(&lkb->lkb_ownqueue); --- 565 unchanged lines hidden (view full) --- 795/* a read returns a single ast described in a struct dlm_lock_result */ 796 797static ssize_t device_read(struct file *file, char __user *buf, size_t count, 798 loff_t *ppos) 799{ 800 struct dlm_user_proc *proc = file->private_data; 801 struct dlm_lkb *lkb; 802 DECLARE_WAITQUEUE(wait, current); | 229 } 230 spin_unlock(&proc->asts_spin); 231 232 if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) { 233 /* N.B. spin_lock locks_spin, not asts_spin */ 234 spin_lock(&proc->locks_spin); 235 if (!list_empty(&lkb->lkb_ownqueue)) { 236 list_del_init(&lkb->lkb_ownqueue); --- 565 unchanged lines hidden (view full) --- 802/* a read returns a single ast described in a struct dlm_lock_result */ 803 804static ssize_t device_read(struct file *file, char __user *buf, size_t count, 805 loff_t *ppos) 806{ 807 struct dlm_user_proc *proc = file->private_data; 808 struct dlm_lkb *lkb; 809 DECLARE_WAITQUEUE(wait, current); |
803 struct dlm_callback cb; 804 int rv, resid, copy_lvb = 0; | 810 struct dlm_callback *cb; 811 int rv, copy_lvb = 0; |
805 int old_mode, new_mode; 806 807 if (count == sizeof(struct dlm_device_version)) { 808 rv = copy_version_to_user(buf, count); 809 return rv; 810 } 811 812 if (!proc) { --- 42 unchanged lines hidden (view full) --- 855 856 /* if we empty lkb_callbacks, we don't want to unlock the spinlock 857 without removing lkb_cb_list; so empty lkb_cb_list is always 858 consistent with empty lkb_callbacks */ 859 860 lkb = list_first_entry(&proc->asts, struct dlm_lkb, lkb_cb_list); 861 862 /* rem_lkb_callback sets a new lkb_last_cast */ | 812 int old_mode, new_mode; 813 814 if (count == sizeof(struct dlm_device_version)) { 815 rv = copy_version_to_user(buf, count); 816 return rv; 817 } 818 819 if (!proc) { --- 42 unchanged lines hidden (view full) --- 862 863 /* if we empty lkb_callbacks, we don't want to unlock the spinlock 864 without removing lkb_cb_list; so empty lkb_cb_list is always 865 consistent with empty lkb_callbacks */ 866 867 lkb = list_first_entry(&proc->asts, struct dlm_lkb, lkb_cb_list); 868 869 /* rem_lkb_callback sets a new lkb_last_cast */ |
863 old_mode = lkb->lkb_last_cast.mode; | 870 old_mode = lkb->lkb_last_cast->mode; |
864 | 871 |
865 rv = dlm_rem_lkb_callback(lkb->lkb_resource->res_ls, lkb, &cb, &resid); 866 if (rv < 0) { | 872 rv = dlm_dequeue_lkb_callback(lkb, &cb); 873 switch (rv) { 874 case DLM_DEQUEUE_CALLBACK_EMPTY: |
867 /* this shouldn't happen; lkb should have been removed from | 875 /* this shouldn't happen; lkb should have been removed from |
868 list when resid was zero */ | 876 * list when last item was dequeued 877 */ |
869 log_print("dlm_rem_lkb_callback empty %x", lkb->lkb_id); 870 list_del_init(&lkb->lkb_cb_list); 871 spin_unlock(&proc->asts_spin); 872 /* removes ref for proc->asts, may cause lkb to be freed */ 873 dlm_put_lkb(lkb); | 878 log_print("dlm_rem_lkb_callback empty %x", lkb->lkb_id); 879 list_del_init(&lkb->lkb_cb_list); 880 spin_unlock(&proc->asts_spin); 881 /* removes ref for proc->asts, may cause lkb to be freed */ 882 dlm_put_lkb(lkb); |
883 WARN_ON(1); |
|
874 goto try_another; | 884 goto try_another; |
875 } 876 if (!resid) | 885 case DLM_DEQUEUE_CALLBACK_LAST: |
877 list_del_init(&lkb->lkb_cb_list); | 886 list_del_init(&lkb->lkb_cb_list); |
887 /* TODO */ 888 lkb->lkb_flags &= ~DLM_IFL_NEED_SCHED; 889 break; 890 case DLM_DEQUEUE_CALLBACK_SUCCESS: 891 break; 892 default: 893 WARN_ON(1); 894 break; 895 } |
|
878 spin_unlock(&proc->asts_spin); 879 | 896 spin_unlock(&proc->asts_spin); 897 |
880 if (cb.flags & DLM_CB_SKIP) { 881 /* removes ref for proc->asts, may cause lkb to be freed */ 882 if (!resid) 883 dlm_put_lkb(lkb); 884 goto try_another; 885 } | 898 if (cb->flags & DLM_CB_BAST) { 899 trace_dlm_bast(lkb->lkb_resource->res_ls, lkb, cb->mode); 900 } else if (cb->flags & DLM_CB_CAST) { 901 new_mode = cb->mode; |
886 | 902 |
887 if (cb.flags & DLM_CB_BAST) { 888 trace_dlm_bast(lkb->lkb_resource->res_ls, lkb, cb.mode); 889 } else if (cb.flags & DLM_CB_CAST) { 890 new_mode = cb.mode; 891 892 if (!cb.sb_status && lkb->lkb_lksb->sb_lvbptr && | 903 if (!cb->sb_status && lkb->lkb_lksb->sb_lvbptr && |
893 dlm_lvb_operations[old_mode + 1][new_mode + 1]) 894 copy_lvb = 1; 895 | 904 dlm_lvb_operations[old_mode + 1][new_mode + 1]) 905 copy_lvb = 1; 906 |
896 lkb->lkb_lksb->sb_status = cb.sb_status; 897 lkb->lkb_lksb->sb_flags = cb.sb_flags; | 907 lkb->lkb_lksb->sb_status = cb->sb_status; 908 lkb->lkb_lksb->sb_flags = cb->sb_flags; |
898 trace_dlm_ast(lkb->lkb_resource->res_ls, lkb); 899 } 900 901 rv = copy_result_to_user(lkb->lkb_ua, 902 test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), | 909 trace_dlm_ast(lkb->lkb_resource->res_ls, lkb); 910 } 911 912 rv = copy_result_to_user(lkb->lkb_ua, 913 test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags), |
903 cb.flags, cb.mode, copy_lvb, buf, count); | 914 cb->flags, cb->mode, copy_lvb, buf, count); |
904 | 915 |
916 kref_put(&cb->ref, dlm_release_callback); 917 |
|
905 /* removes ref for proc->asts, may cause lkb to be freed */ | 918 /* removes ref for proc->asts, may cause lkb to be freed */ |
906 if (!resid) | 919 if (rv == DLM_DEQUEUE_CALLBACK_LAST) |
907 dlm_put_lkb(lkb); 908 909 return rv; 910} 911 912static __poll_t device_poll(struct file *file, poll_table *wait) 913{ 914 struct dlm_user_proc *proc = file->private_data; --- 122 unchanged lines hidden --- | 920 dlm_put_lkb(lkb); 921 922 return rv; 923} 924 925static __poll_t device_poll(struct file *file, poll_table *wait) 926{ 927 struct dlm_user_proc *proc = file->private_data; --- 122 unchanged lines hidden --- |