^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2006-2010 Red Hat, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/dlm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/dlm_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sched/signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "dlm_internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "lockspace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "lock.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "lvb_table.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "user.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "ast.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "config.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static const char name_prefix[] = "dlm";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) static const struct file_operations device_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static atomic_t dlm_monitor_opened;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static int dlm_monitor_unused = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct dlm_lock_params32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) __u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) __u8 namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) __u16 unused;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) __u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) __u32 lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) __u32 parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) __u64 xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) __u64 timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) __u32 castparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) __u32 castaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) __u32 bastparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __u32 bastaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) __u32 lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) char lvb[DLM_USER_LVB_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) char name[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) struct dlm_write_request32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) __u32 version[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) __u8 cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __u8 is64bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) __u8 unused[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) union {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) struct dlm_lock_params32 lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) struct dlm_lspace_params lspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) struct dlm_purge_params purge;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) } i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct dlm_lksb32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __u32 sb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __u32 sb_lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) __u8 sb_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __u32 sb_lvbptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct dlm_lock_result32 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) __u32 version[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) __u32 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) __u32 user_astaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) __u32 user_astparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __u32 user_lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct dlm_lksb32 lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) __u8 bast_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) __u8 unused[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Offsets may be zero if no data is present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) __u32 lvb_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) static void compat_input(struct dlm_write_request *kb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) struct dlm_write_request32 *kb32,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) int namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) kb->version[0] = kb32->version[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) kb->version[1] = kb32->version[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) kb->version[2] = kb32->version[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) kb->cmd = kb32->cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) kb->is64bit = kb32->is64bit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (kb->cmd == DLM_USER_CREATE_LOCKSPACE ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) kb->cmd == DLM_USER_REMOVE_LOCKSPACE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) kb->i.lspace.flags = kb32->i.lspace.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) kb->i.lspace.minor = kb32->i.lspace.minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) memcpy(kb->i.lspace.name, kb32->i.lspace.name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) } else if (kb->cmd == DLM_USER_PURGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) kb->i.purge.nodeid = kb32->i.purge.nodeid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) kb->i.purge.pid = kb32->i.purge.pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) kb->i.lock.mode = kb32->i.lock.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) kb->i.lock.namelen = kb32->i.lock.namelen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) kb->i.lock.flags = kb32->i.lock.flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) kb->i.lock.lkid = kb32->i.lock.lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) kb->i.lock.parent = kb32->i.lock.parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) kb->i.lock.xid = kb32->i.lock.xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) kb->i.lock.timeout = kb32->i.lock.timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) kb->i.lock.castparam = (void *)(long)kb32->i.lock.castparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) kb->i.lock.castaddr = (void *)(long)kb32->i.lock.castaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) kb->i.lock.bastparam = (void *)(long)kb32->i.lock.bastparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) kb->i.lock.bastaddr = (void *)(long)kb32->i.lock.bastaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) kb->i.lock.lksb = (void *)(long)kb32->i.lock.lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) memcpy(kb->i.lock.lvb, kb32->i.lock.lvb, DLM_USER_LVB_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) memcpy(kb->i.lock.name, kb32->i.lock.name, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) static void compat_output(struct dlm_lock_result *res,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct dlm_lock_result32 *res32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) memset(res32, 0, sizeof(*res32));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) res32->version[0] = res->version[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) res32->version[1] = res->version[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) res32->version[2] = res->version[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) res32->user_astaddr = (__u32)(long)res->user_astaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) res32->user_astparam = (__u32)(long)res->user_astparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) res32->user_lksb = (__u32)(long)res->user_lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) res32->bast_mode = res->bast_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) res32->lvb_offset = res->lvb_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) res32->length = res->length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) res32->lksb.sb_status = res->lksb.sb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) res32->lksb.sb_flags = res->lksb.sb_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) res32->lksb.sb_lkid = res->lksb.sb_lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) res32->lksb.sb_lvbptr = (__u32)(long)res->lksb.sb_lvbptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Figure out if this lock is at the end of its life and no longer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) available for the application to use. The lkb still exists until
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) the final ast is read. A lock becomes EOL in three situations:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 1. a noqueue request fails with EAGAIN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 2. an unlock completes with EUNLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 3. a cancel of a waiting request completes with ECANCEL/EDEADLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) An EOL lock needs to be removed from the process's list of locks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) And we can't allow any new operation on an EOL lock. This is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) not related to the lifetime of the lkb struct which is managed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) entirely by refcount. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static int lkb_is_endoflife(int mode, int status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) case -DLM_EUNLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) case -DLM_ECANCEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) case -ETIMEDOUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) case -EDEADLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (mode == DLM_LOCK_IV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) /* we could possibly check if the cancel of an orphan has resulted in the lkb
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) being removed and then remove that lkb from the orphans list and free it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) void dlm_user_add_ast(struct dlm_lkb *lkb, uint32_t flags, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) int status, uint32_t sbflags, uint64_t seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct dlm_user_args *ua;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct dlm_user_proc *proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ls = lkb->lkb_resource->res_ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) mutex_lock(&ls->ls_clear_proc_locks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* If ORPHAN/DEAD flag is set, it means the process is dead so an ast
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) can't be delivered. For ORPHAN's, dlm_clear_proc_locks() freed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) lkb->ua so we can't try to use it. This second check is necessary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) for cases where a completion ast is received for an operation that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) began before clear_proc_locks did its cancel/unlock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (lkb->lkb_flags & (DLM_IFL_ORPHAN | DLM_IFL_DEAD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) DLM_ASSERT(lkb->lkb_ua, dlm_print_lkb(lkb););
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ua = lkb->lkb_ua;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) proc = ua->proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if ((flags & DLM_CB_BAST) && ua->bastaddr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if ((flags & DLM_CB_CAST) && lkb_is_endoflife(mode, status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) lkb->lkb_flags |= DLM_IFL_ENDOFLIFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) spin_lock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) rv = dlm_add_lkb_callback(lkb, flags, mode, status, sbflags, seq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (rv < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (list_empty(&lkb->lkb_cb_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) kref_get(&lkb->lkb_ref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) list_add_tail(&lkb->lkb_cb_list, &proc->asts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) wake_up_interruptible(&proc->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (lkb->lkb_flags & DLM_IFL_ENDOFLIFE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* N.B. spin_lock locks_spin, not asts_spin */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) spin_lock(&proc->locks_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (!list_empty(&lkb->lkb_ownqueue)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) list_del_init(&lkb->lkb_ownqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) dlm_put_lkb(lkb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) spin_unlock(&proc->locks_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mutex_unlock(&ls->ls_clear_proc_locks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int device_user_lock(struct dlm_user_proc *proc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct dlm_lock_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct dlm_user_args *ua;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) uint32_t lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) int error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ls = dlm_find_lockspace_local(proc->lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!params->castaddr || !params->lksb) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (!ua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) ua->proc = proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) ua->user_lksb = params->lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) ua->castparam = params->castparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ua->castaddr = params->castaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) ua->bastparam = params->bastparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) ua->bastaddr = params->bastaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ua->xid = params->xid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (params->flags & DLM_LKF_CONVERT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) error = dlm_user_convert(ls, ua,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) params->mode, params->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) params->lkid, params->lvb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) (unsigned long) params->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) } else if (params->flags & DLM_LKF_ORPHAN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) error = dlm_user_adopt_orphan(ls, ua,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) params->mode, params->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) params->name, params->namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) (unsigned long) params->timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) &lkid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) error = lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) error = dlm_user_request(ls, ua,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) params->mode, params->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) params->name, params->namelen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) (unsigned long) params->timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) error = ua->lksb.sb_lkid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static int device_user_unlock(struct dlm_user_proc *proc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct dlm_lock_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) struct dlm_user_args *ua;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) int error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) ls = dlm_find_lockspace_local(proc->lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) ua = kzalloc(sizeof(struct dlm_user_args), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (!ua)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) ua->proc = proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) ua->user_lksb = params->lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) ua->castparam = params->castparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) ua->castaddr = params->castaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (params->flags & DLM_LKF_CANCEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) error = dlm_user_cancel(ls, ua, params->flags, params->lkid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) error = dlm_user_unlock(ls, ua, params->flags, params->lkid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) params->lvb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) static int device_user_deadlock(struct dlm_user_proc *proc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) struct dlm_lock_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) ls = dlm_find_lockspace_local(proc->lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) error = dlm_user_deadlock(ls, params->flags, params->lkid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static int dlm_device_register(struct dlm_ls *ls, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) int error, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) /* The device is already registered. This happens when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) lockspace is created multiple times from userspace. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (ls->ls_device.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) len = strlen(name) + strlen(name_prefix) + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) ls->ls_device.name = kzalloc(len, GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (!ls->ls_device.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) goto fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) snprintf((char *)ls->ls_device.name, len, "%s_%s", name_prefix,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) ls->ls_device.fops = &device_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) ls->ls_device.minor = MISC_DYNAMIC_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) error = misc_register(&ls->ls_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) kfree(ls->ls_device.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* this has to be set to NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * to avoid a double-free in dlm_device_deregister
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) ls->ls_device.name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) int dlm_device_deregister(struct dlm_ls *ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /* The device is not registered. This happens when the lockspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) was never used from userspace, or when device_create_lockspace()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) calls dlm_release_lockspace() after the register fails. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (!ls->ls_device.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) misc_deregister(&ls->ls_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) kfree(ls->ls_device.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) static int device_user_purge(struct dlm_user_proc *proc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) struct dlm_purge_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) ls = dlm_find_lockspace_local(proc->lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) error = dlm_user_purge(ls, proc, params->nodeid, params->pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int device_create_lockspace(struct dlm_lspace_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) dlm_lockspace_t *lockspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) error = dlm_new_lockspace(params->name, dlm_config.ci_cluster_name, params->flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) DLM_USER_LVB_LEN, NULL, NULL, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) &lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) ls = dlm_find_lockspace_local(lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) error = dlm_device_register(ls, params->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) dlm_release_lockspace(lockspace, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) error = ls->ls_device.minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int device_remove_lockspace(struct dlm_lspace_params *params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) dlm_lockspace_t *lockspace;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int error, force = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (!capable(CAP_SYS_ADMIN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) ls = dlm_find_lockspace_device(params->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) if (params->flags & DLM_USER_LSFLG_FORCEFREE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) force = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) lockspace = ls->ls_local_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* The final dlm_release_lockspace waits for references to go to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) zero, so all processes will need to close their device for the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) ls before the release will proceed. release also calls the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) device_deregister above. Converting a positive return value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) from release to zero means that userspace won't know when its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) release was the final one, but it shouldn't need to know. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) error = dlm_release_lockspace(lockspace, force);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (error > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* Check the user's version matches ours */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static int check_version(struct dlm_write_request *req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (req->version[0] != DLM_DEVICE_VERSION_MAJOR ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) (req->version[0] == DLM_DEVICE_VERSION_MAJOR &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) req->version[1] > DLM_DEVICE_VERSION_MINOR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) printk(KERN_DEBUG "dlm: process %s (%d) version mismatch "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) "user (%d.%d.%d) kernel (%d.%d.%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) current->comm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) task_pid_nr(current),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) req->version[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) req->version[1],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) req->version[2],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) DLM_DEVICE_VERSION_MAJOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) DLM_DEVICE_VERSION_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) DLM_DEVICE_VERSION_PATCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) * device_write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * device_user_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * dlm_user_request -> request_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) * dlm_user_convert -> convert_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * device_user_unlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * dlm_user_unlock -> unlock_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * dlm_user_cancel -> cancel_lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * device_create_lockspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) * dlm_new_lockspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) * device_remove_lockspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) * dlm_release_lockspace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* a write to a lockspace device is a lock or unlock request, a write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) to the control device is to create/remove a lockspace */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static ssize_t device_write(struct file *file, const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) size_t count, loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) struct dlm_user_proc *proc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) struct dlm_write_request *kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) if (count < sizeof(struct dlm_write_request32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) if (count < sizeof(struct dlm_write_request))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * can't compare against COMPAT/dlm_write_request32 because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * we don't yet know if is64bit is zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) if (count > sizeof(struct dlm_write_request) + DLM_RESNAME_MAXLEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) kbuf = memdup_user_nul(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (IS_ERR(kbuf))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) return PTR_ERR(kbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) if (check_version(kbuf)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) error = -EBADE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) if (!kbuf->is64bit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) struct dlm_write_request32 *k32buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) int namelen = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (count > sizeof(struct dlm_write_request32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) namelen = count - sizeof(struct dlm_write_request32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) k32buf = (struct dlm_write_request32 *)kbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* add 1 after namelen so that the name string is terminated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) kbuf = kzalloc(sizeof(struct dlm_write_request) + namelen + 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!kbuf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) kfree(k32buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (proc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) set_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) compat_input(kbuf, k32buf, namelen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) kfree(k32buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* do we really need this? can a write happen after a close? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if ((kbuf->cmd == DLM_USER_LOCK || kbuf->cmd == DLM_USER_UNLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) (proc && test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) switch (kbuf->cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) case DLM_USER_LOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) log_print("no locking on control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) error = device_user_lock(proc, &kbuf->i.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) case DLM_USER_UNLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (!proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) log_print("no locking on control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) error = device_user_unlock(proc, &kbuf->i.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) case DLM_USER_DEADLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) if (!proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) log_print("no locking on control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) error = device_user_deadlock(proc, &kbuf->i.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) case DLM_USER_CREATE_LOCKSPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) if (proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) log_print("create/remove only on control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) error = device_create_lockspace(&kbuf->i.lspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) case DLM_USER_REMOVE_LOCKSPACE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) log_print("create/remove only on control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) error = device_remove_lockspace(&kbuf->i.lspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) case DLM_USER_PURGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) if (!proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) log_print("no locking on control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) error = device_user_purge(proc, &kbuf->i.purge);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) log_print("Unknown command passed to DLM device : %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) kbuf->cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) kfree(kbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /* Every process that opens the lockspace device has its own "proc" structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) hanging off the open file that's used to keep track of locks owned by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) process and asts that need to be delivered to the process. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static int device_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct dlm_user_proc *proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) ls = dlm_find_lockspace_device(iminor(inode));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) proc = kzalloc(sizeof(struct dlm_user_proc), GFP_NOFS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) proc->lockspace = ls->ls_local_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) INIT_LIST_HEAD(&proc->asts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) INIT_LIST_HEAD(&proc->locks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) INIT_LIST_HEAD(&proc->unlocking);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) spin_lock_init(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) spin_lock_init(&proc->locks_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) init_waitqueue_head(&proc->wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) file->private_data = proc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) static int device_close(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) struct dlm_user_proc *proc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) struct dlm_ls *ls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) ls = dlm_find_lockspace_local(proc->lockspace);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) if (!ls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) set_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dlm_clear_proc_locks(ls, proc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /* at this point no more lkb's should exist for this lockspace,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) so there's no chance of dlm_user_add_ast() being called and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) looking for lkb->ua->proc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) kfree(proc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) dlm_put_lockspace(ls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) dlm_put_lockspace(ls); /* for the find in device_open() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* FIXME: AUTOFREE: if this ls is no longer used do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) device_remove_lockspace() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) static int copy_result_to_user(struct dlm_user_args *ua, int compat,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) uint32_t flags, int mode, int copy_lvb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) struct dlm_lock_result32 result32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct dlm_lock_result result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) void *resultptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) int error=0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) int struct_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) memset(&result, 0, sizeof(struct dlm_lock_result));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) result.version[0] = DLM_DEVICE_VERSION_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) result.version[1] = DLM_DEVICE_VERSION_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) result.version[2] = DLM_DEVICE_VERSION_PATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) memcpy(&result.lksb, &ua->lksb, offsetof(struct dlm_lksb, sb_lvbptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) result.user_lksb = ua->user_lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /* FIXME: dlm1 provides for the user's bastparam/addr to not be updated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) in a conversion unless the conversion is successful. See code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) in dlm_user_convert() for updating ua from ua_tmp. OpenVMS, though,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) notes that a new blocking AST address and parameter are set even if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) the conversion fails, so maybe we should just do that. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) if (flags & DLM_CB_BAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) result.user_astaddr = ua->bastaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) result.user_astparam = ua->bastparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) result.bast_mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) result.user_astaddr = ua->castaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) result.user_astparam = ua->castparam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) if (compat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) len = sizeof(struct dlm_lock_result32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) len = sizeof(struct dlm_lock_result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct_len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* copy lvb to userspace if there is one, it's been updated, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) the user buffer has space for it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (copy_lvb && ua->lksb.sb_lvbptr && count >= len + DLM_USER_LVB_LEN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (copy_to_user(buf+len, ua->lksb.sb_lvbptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) DLM_USER_LVB_LEN)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) result.lvb_offset = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) len += DLM_USER_LVB_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) result.length = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) resultptr = &result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (compat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) compat_output(&result, &result32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) resultptr = &result32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (copy_to_user(buf, resultptr, struct_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) error = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) error = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static int copy_version_to_user(char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) struct dlm_device_version ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) memset(&ver, 0, sizeof(struct dlm_device_version));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ver.version[0] = DLM_DEVICE_VERSION_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ver.version[1] = DLM_DEVICE_VERSION_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) ver.version[2] = DLM_DEVICE_VERSION_PATCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (copy_to_user(buf, &ver, sizeof(struct dlm_device_version)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) return sizeof(struct dlm_device_version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* a read returns a single ast described in a struct dlm_lock_result */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) static ssize_t device_read(struct file *file, char __user *buf, size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) struct dlm_user_proc *proc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) struct dlm_lkb *lkb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) DECLARE_WAITQUEUE(wait, current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct dlm_callback cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) int rv, resid, copy_lvb = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) int old_mode, new_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (count == sizeof(struct dlm_device_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) rv = copy_version_to_user(buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) if (!proc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) log_print("non-version read from control device %zu", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) #ifdef CONFIG_COMPAT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) if (count < sizeof(struct dlm_lock_result32))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) if (count < sizeof(struct dlm_lock_result))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) try_another:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* do we really need this? can a read happen after a close? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) if (test_bit(DLM_PROC_FLAGS_CLOSING, &proc->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) spin_lock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (list_empty(&proc->asts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (file->f_flags & O_NONBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) add_wait_queue(&proc->wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) repeat:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) set_current_state(TASK_INTERRUPTIBLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) if (list_empty(&proc->asts) && !signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) schedule();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) spin_lock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) goto repeat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) set_current_state(TASK_RUNNING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) remove_wait_queue(&proc->wait, &wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) if (signal_pending(current)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return -ERESTARTSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* if we empty lkb_callbacks, we don't want to unlock the spinlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) without removing lkb_cb_list; so empty lkb_cb_list is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) consistent with empty lkb_callbacks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) lkb = list_entry(proc->asts.next, struct dlm_lkb, lkb_cb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) /* rem_lkb_callback sets a new lkb_last_cast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) old_mode = lkb->lkb_last_cast.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) rv = dlm_rem_lkb_callback(lkb->lkb_resource->res_ls, lkb, &cb, &resid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) if (rv < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /* this shouldn't happen; lkb should have been removed from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) list when resid was zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) log_print("dlm_rem_lkb_callback empty %x", lkb->lkb_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) list_del_init(&lkb->lkb_cb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) /* removes ref for proc->asts, may cause lkb to be freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) dlm_put_lkb(lkb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) goto try_another;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) if (!resid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) list_del_init(&lkb->lkb_cb_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) if (cb.flags & DLM_CB_SKIP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* removes ref for proc->asts, may cause lkb to be freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) if (!resid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) dlm_put_lkb(lkb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) goto try_another;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) if (cb.flags & DLM_CB_CAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) new_mode = cb.mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (!cb.sb_status && lkb->lkb_lksb->sb_lvbptr &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) dlm_lvb_operations[old_mode + 1][new_mode + 1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) copy_lvb = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) lkb->lkb_lksb->sb_status = cb.sb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) lkb->lkb_lksb->sb_flags = cb.sb_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) rv = copy_result_to_user(lkb->lkb_ua,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) test_bit(DLM_PROC_FLAGS_COMPAT, &proc->flags),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) cb.flags, cb.mode, copy_lvb, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) /* removes ref for proc->asts, may cause lkb to be freed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) if (!resid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) dlm_put_lkb(lkb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) return rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static __poll_t device_poll(struct file *file, poll_table *wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct dlm_user_proc *proc = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) poll_wait(file, &proc->wait, wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) spin_lock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) if (!list_empty(&proc->asts)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return EPOLLIN | EPOLLRDNORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) spin_unlock(&proc->asts_spin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int dlm_user_daemon_available(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* dlm_controld hasn't started (or, has started, but not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) properly populated configfs) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (!dlm_our_nodeid())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* This is to deal with versions of dlm_controld that don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) know about the monitor device. We assume that if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) dlm_controld was started (above), but the monitor device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) was never opened, that it's an old version. dlm_controld
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) should open the monitor device before populating configfs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) if (dlm_monitor_unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) return atomic_read(&dlm_monitor_opened) ? 1 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) static int ctl_device_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static int ctl_device_close(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static int monitor_device_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) atomic_inc(&dlm_monitor_opened);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) dlm_monitor_unused = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) static int monitor_device_close(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (atomic_dec_and_test(&dlm_monitor_opened))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) dlm_stop_lockspaces();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) static const struct file_operations device_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) .open = device_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) .release = device_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) .read = device_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) .write = device_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) .poll = device_poll,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) static const struct file_operations ctl_device_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) .open = ctl_device_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) .release = ctl_device_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) .read = device_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) .write = device_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) static struct miscdevice ctl_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .name = "dlm-control",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .fops = &ctl_device_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .minor = MISC_DYNAMIC_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) static const struct file_operations monitor_device_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) .open = monitor_device_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) .release = monitor_device_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) .llseek = noop_llseek,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) static struct miscdevice monitor_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) .name = "dlm-monitor",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) .fops = &monitor_device_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) .minor = MISC_DYNAMIC_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int __init dlm_user_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) atomic_set(&dlm_monitor_opened, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) error = misc_register(&ctl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) log_print("misc_register failed for control device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) error = misc_register(&monitor_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) log_print("misc_register failed for monitor device");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) misc_deregister(&ctl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) void dlm_user_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) misc_deregister(&ctl_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) misc_deregister(&monitor_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012)