Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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)