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 ---