^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) /* -*- mode: c; c-basic-offset: 8; -*-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * vim: noexpandtab sw=8 ts=8 sts=0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * stack_user.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Code which interfaces ocfs2 with fs/dlm and a userspace stack.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (C) 2007 Oracle. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/miscdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/mutex.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/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/uaccess.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "stackglue.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/dlm_plock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * The control protocol starts with a handshake. Until the handshake
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * is complete, the control device will fail all write(2)s.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * The handshake is simple. First, the client reads until EOF. Each line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * of output is a supported protocol tag. All protocol tags are a single
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * character followed by a two hex digit version number. Currently the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * only things supported is T01, for "Text-base version 0x01". Next, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * client writes the version they would like to use, including the newline.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * Thus, the protocol tag is 'T01\n'. If the version tag written is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * unknown, -EINVAL is returned. Once the negotiation is complete, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * client can start sending messages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * The T01 protocol has three messages. First is the "SETN" message.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * It has the following syntax:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * SETN<space><8-char-hex-nodenum><newline>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * This is 14 characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * The "SETN" message must be the first message following the protocol.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * It tells ocfs2_control the local node number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * Next comes the "SETV" message. It has the following syntax:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * SETV<space><2-char-hex-major><space><2-char-hex-minor><newline>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * This is 11 characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * The "SETV" message sets the filesystem locking protocol version as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * negotiated by the client. The client negotiates based on the maximum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * version advertised in /sys/fs/ocfs2/max_locking_protocol. The major
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * number from the "SETV" message must match
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * ocfs2_user_plugin.sp_max_proto.pv_major, and the minor number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * must be less than or equal to ...sp_max_version.pv_minor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * Once this information has been set, mounts will be allowed. From this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * point on, the "DOWN" message can be sent for node down notification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * It has the following syntax:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * DOWN<space><32-char-cap-hex-uuid><space><8-char-hex-nodenum><newline>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * eg:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * DOWN 632A924FDD844190BDA93C0DF6B94899 00000001\n
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * This is 47 characters.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * Whether or not the client has done the handshake.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * For now, we have just one protocol version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define OCFS2_CONTROL_PROTO "T01\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define OCFS2_CONTROL_PROTO_LEN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* Handshake states */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define OCFS2_CONTROL_HANDSHAKE_INVALID (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define OCFS2_CONTROL_HANDSHAKE_READ (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define OCFS2_CONTROL_HANDSHAKE_PROTOCOL (2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define OCFS2_CONTROL_HANDSHAKE_VALID (3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Messages */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define OCFS2_CONTROL_MESSAGE_OP_LEN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define OCFS2_CONTROL_MESSAGE_SETNODE_OP "SETN"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN 14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define OCFS2_CONTROL_MESSAGE_SETVERSION_OP "SETV"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define OCFS2_CONTROL_MESSAGE_DOWN_OP "DOWN"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN 47
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define OCFS2_TEXT_UUID_LEN 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define OCFS2_CONTROL_MESSAGE_VERNUM_LEN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define OCFS2_CONTROL_MESSAGE_NODENUM_LEN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define VERSION_LOCK "version_lock"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) enum ocfs2_connection_type {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) WITH_CONTROLD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) NO_CONTROLD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * ocfs2_live_connection is refcounted because the filesystem and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * miscdevice sides can detach in different order. Let's just be safe.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) struct ocfs2_live_connection {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct list_head oc_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct ocfs2_cluster_connection *oc_conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) enum ocfs2_connection_type oc_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) atomic_t oc_this_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) int oc_our_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct dlm_lksb oc_version_lksb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) char oc_lvb[DLM_LVB_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct completion oc_sync_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) wait_queue_head_t oc_wait;
^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) struct ocfs2_control_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct list_head op_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) int op_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) int op_this_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) struct ocfs2_protocol_version op_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* SETN<space><8-char-hex-nodenum><newline> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct ocfs2_control_message_setn {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) char tag[OCFS2_CONTROL_MESSAGE_OP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) char space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) char nodestr[OCFS2_CONTROL_MESSAGE_NODENUM_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) char newline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /* SETV<space><2-char-hex-major><space><2-char-hex-minor><newline> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct ocfs2_control_message_setv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) char tag[OCFS2_CONTROL_MESSAGE_OP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) char space1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) char major[OCFS2_CONTROL_MESSAGE_VERNUM_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) char space2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) char minor[OCFS2_CONTROL_MESSAGE_VERNUM_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) char newline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* DOWN<space><32-char-cap-hex-uuid><space><8-char-hex-nodenum><newline> */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct ocfs2_control_message_down {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) char tag[OCFS2_CONTROL_MESSAGE_OP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) char space1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) char uuid[OCFS2_TEXT_UUID_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) char space2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) char nodestr[OCFS2_CONTROL_MESSAGE_NODENUM_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) char newline;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) union ocfs2_control_message {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) char tag[OCFS2_CONTROL_MESSAGE_OP_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct ocfs2_control_message_setn u_setn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct ocfs2_control_message_setv u_setv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct ocfs2_control_message_down u_down;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static struct ocfs2_stack_plugin ocfs2_user_plugin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) static atomic_t ocfs2_control_opened;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int ocfs2_control_this_node = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) static struct ocfs2_protocol_version running_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) static LIST_HEAD(ocfs2_live_connection_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static LIST_HEAD(ocfs2_control_private_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static DEFINE_MUTEX(ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) static inline void ocfs2_control_set_handshake_state(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct ocfs2_control_private *p = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) p->op_state = state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static inline int ocfs2_control_get_handshake_state(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) struct ocfs2_control_private *p = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) return p->op_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static struct ocfs2_live_connection *ocfs2_connection_find(const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) size_t len = strlen(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) struct ocfs2_live_connection *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) BUG_ON(!mutex_is_locked(&ocfs2_control_lock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) list_for_each_entry(c, &ocfs2_live_connection_list, oc_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if ((c->oc_conn->cc_namelen == len) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) !strncmp(c->oc_conn->cc_name, name, len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * ocfs2_live_connection structures are created underneath the ocfs2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * mount path. Since the VFS prevents multiple calls to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * fill_super(), we can't get dupes here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static int ocfs2_live_connection_attach(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct ocfs2_live_connection *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) c->oc_conn = conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if ((c->oc_type == NO_CONTROLD) || atomic_read(&ocfs2_control_opened))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) list_add(&c->oc_list, &ocfs2_live_connection_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) "ocfs2: Userspace control daemon is not present\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) rc = -ESRCH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * This function disconnects the cluster connection from ocfs2_control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * Afterwards, userspace can't affect the cluster connection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static void ocfs2_live_connection_drop(struct ocfs2_live_connection *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) list_del_init(&c->oc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) c->oc_conn = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) kfree(c);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int ocfs2_control_cfu(void *target, size_t target_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) const char __user *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) /* The T01 expects write(2) calls to have exactly one command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if ((count != target_len) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) (count > sizeof(union ocfs2_control_message)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) if (copy_from_user(target, buf, target_len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) static ssize_t ocfs2_control_validate_protocol(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) char kbuf[OCFS2_CONTROL_PROTO_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = ocfs2_control_cfu(kbuf, OCFS2_CONTROL_PROTO_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (strncmp(kbuf, OCFS2_CONTROL_PROTO, OCFS2_CONTROL_PROTO_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ocfs2_control_set_handshake_state(file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) OCFS2_CONTROL_HANDSHAKE_PROTOCOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) static void ocfs2_control_send_down(const char *uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) int nodenum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct ocfs2_live_connection *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) c = ocfs2_connection_find(uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) if (c) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) BUG_ON(c->oc_conn == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) c->oc_conn->cc_recovery_handler(nodenum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) c->oc_conn->cc_recovery_data);
^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) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * Called whenever configuration elements are sent to /dev/ocfs2_control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * If all configuration elements are present, try to set the global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * values. If there is a problem, return an error. Skip any missing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * elements, and only bump ocfs2_control_opened when we have all elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * and are successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) static int ocfs2_control_install_private(struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) int set_p = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct ocfs2_control_private *p = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) BUG_ON(p->op_state != OCFS2_CONTROL_HANDSHAKE_PROTOCOL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (p->op_this_node < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) set_p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) } else if ((ocfs2_control_this_node >= 0) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) (ocfs2_control_this_node != p->op_this_node)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!p->op_proto.pv_major) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) set_p = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) } else if (!list_empty(&ocfs2_live_connection_list) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) ((running_proto.pv_major != p->op_proto.pv_major) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) (running_proto.pv_minor != p->op_proto.pv_minor))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) goto out_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (set_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ocfs2_control_this_node = p->op_this_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) running_proto.pv_major = p->op_proto.pv_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) running_proto.pv_minor = p->op_proto.pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) out_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (!rc && set_p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* We set the global values successfully */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) atomic_inc(&ocfs2_control_opened);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) ocfs2_control_set_handshake_state(file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) OCFS2_CONTROL_HANDSHAKE_VALID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static int ocfs2_control_get_this_node(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) if (ocfs2_control_this_node < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) rc = ocfs2_control_this_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static int ocfs2_control_do_setnode_msg(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct ocfs2_control_message_setn *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) long nodenum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) char *ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct ocfs2_control_private *p = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (ocfs2_control_get_handshake_state(file) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) OCFS2_CONTROL_HANDSHAKE_PROTOCOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (strncmp(msg->tag, OCFS2_CONTROL_MESSAGE_SETNODE_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) OCFS2_CONTROL_MESSAGE_OP_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if ((msg->space != ' ') || (msg->newline != '\n'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) msg->space = msg->newline = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) nodenum = simple_strtol(msg->nodestr, &ptr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (!ptr || *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if ((nodenum == LONG_MIN) || (nodenum == LONG_MAX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) (nodenum > INT_MAX) || (nodenum < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) p->op_this_node = nodenum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return ocfs2_control_install_private(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static int ocfs2_control_do_setversion_msg(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct ocfs2_control_message_setv *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) long major, minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) char *ptr = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct ocfs2_control_private *p = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) struct ocfs2_protocol_version *max =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) &ocfs2_user_plugin.sp_max_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (ocfs2_control_get_handshake_state(file) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) OCFS2_CONTROL_HANDSHAKE_PROTOCOL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) if (strncmp(msg->tag, OCFS2_CONTROL_MESSAGE_SETVERSION_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) OCFS2_CONTROL_MESSAGE_OP_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if ((msg->space1 != ' ') || (msg->space2 != ' ') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) (msg->newline != '\n'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) msg->space1 = msg->space2 = msg->newline = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) major = simple_strtol(msg->major, &ptr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) if (!ptr || *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) minor = simple_strtol(msg->minor, &ptr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) if (!ptr || *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * The major must be between 1 and 255, inclusive. The minor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * must be between 0 and 255, inclusive. The version passed in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) * must be within the maximum version supported by the filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if ((major == LONG_MIN) || (major == LONG_MAX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) (major > (u8)-1) || (major < 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if ((minor == LONG_MIN) || (minor == LONG_MAX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) (minor > (u8)-1) || (minor < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) if ((major != max->pv_major) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) (minor > max->pv_minor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) p->op_proto.pv_major = major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) p->op_proto.pv_minor = minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) return ocfs2_control_install_private(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static int ocfs2_control_do_down_msg(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) struct ocfs2_control_message_down *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) long nodenum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) char *p = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) if (ocfs2_control_get_handshake_state(file) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) OCFS2_CONTROL_HANDSHAKE_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (strncmp(msg->tag, OCFS2_CONTROL_MESSAGE_DOWN_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) OCFS2_CONTROL_MESSAGE_OP_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if ((msg->space1 != ' ') || (msg->space2 != ' ') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) (msg->newline != '\n'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) msg->space1 = msg->space2 = msg->newline = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) nodenum = simple_strtol(msg->nodestr, &p, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (!p || *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) if ((nodenum == LONG_MIN) || (nodenum == LONG_MAX) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) (nodenum > INT_MAX) || (nodenum < 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) return -ERANGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) ocfs2_control_send_down(msg->uuid, nodenum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) static ssize_t ocfs2_control_message(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) union ocfs2_control_message msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* Try to catch padding issues */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) WARN_ON(offsetof(struct ocfs2_control_message_down, uuid) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) (sizeof(msg.u_down.tag) + sizeof(msg.u_down.space1)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) memset(&msg, 0, sizeof(union ocfs2_control_message));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) ret = ocfs2_control_cfu(&msg, count, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if ((count == OCFS2_CONTROL_MESSAGE_SETNODE_TOTAL_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) !strncmp(msg.tag, OCFS2_CONTROL_MESSAGE_SETNODE_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) OCFS2_CONTROL_MESSAGE_OP_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = ocfs2_control_do_setnode_msg(file, &msg.u_setn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) else if ((count == OCFS2_CONTROL_MESSAGE_SETVERSION_TOTAL_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) !strncmp(msg.tag, OCFS2_CONTROL_MESSAGE_SETVERSION_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) OCFS2_CONTROL_MESSAGE_OP_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ret = ocfs2_control_do_setversion_msg(file, &msg.u_setv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) else if ((count == OCFS2_CONTROL_MESSAGE_DOWN_TOTAL_LEN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) !strncmp(msg.tag, OCFS2_CONTROL_MESSAGE_DOWN_OP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) OCFS2_CONTROL_MESSAGE_OP_LEN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) ret = ocfs2_control_do_down_msg(file, &msg.u_down);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return ret ? ret : count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) static ssize_t ocfs2_control_write(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) const char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) switch (ocfs2_control_get_handshake_state(file)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) case OCFS2_CONTROL_HANDSHAKE_INVALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) case OCFS2_CONTROL_HANDSHAKE_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ret = ocfs2_control_validate_protocol(file, buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) case OCFS2_CONTROL_HANDSHAKE_PROTOCOL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) case OCFS2_CONTROL_HANDSHAKE_VALID:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ret = ocfs2_control_message(file, buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) * This is a naive version. If we ever have a new protocol, we'll expand
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) * it. Probably using seq_file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) static ssize_t ocfs2_control_read(struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) char __user *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) size_t count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) loff_t *ppos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) ssize_t ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = simple_read_from_buffer(buf, count, ppos,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) OCFS2_CONTROL_PROTO, OCFS2_CONTROL_PROTO_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* Have we read the whole protocol list? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (ret > 0 && *ppos >= OCFS2_CONTROL_PROTO_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) ocfs2_control_set_handshake_state(file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) OCFS2_CONTROL_HANDSHAKE_READ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) static int ocfs2_control_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct ocfs2_control_private *p = file->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (ocfs2_control_get_handshake_state(file) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) OCFS2_CONTROL_HANDSHAKE_VALID)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) if (atomic_dec_and_test(&ocfs2_control_opened)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (!list_empty(&ocfs2_live_connection_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* XXX: Do bad things! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) "ocfs2: Unexpected release of ocfs2_control!\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) " Loss of cluster connection requires "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) "an emergency restart!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) emergency_restart();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * Last valid close clears the node number and resets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * the locking protocol version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) ocfs2_control_this_node = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) running_proto.pv_major = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) running_proto.pv_minor = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) list_del_init(&p->op_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) file->private_data = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static int ocfs2_control_open(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) struct ocfs2_control_private *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) p = kzalloc(sizeof(struct ocfs2_control_private), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) p->op_this_node = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) mutex_lock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) file->private_data = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) list_add(&p->op_list, &ocfs2_control_private_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) mutex_unlock(&ocfs2_control_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static const struct file_operations ocfs2_control_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) .open = ocfs2_control_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) .release = ocfs2_control_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) .read = ocfs2_control_read,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) .write = ocfs2_control_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) .llseek = default_llseek,
^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) static struct miscdevice ocfs2_control_device = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) .minor = MISC_DYNAMIC_MINOR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) .name = "ocfs2_control",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) .fops = &ocfs2_control_fops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static int ocfs2_control_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) atomic_set(&ocfs2_control_opened, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) rc = misc_register(&ocfs2_control_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) "ocfs2: Unable to register ocfs2_control device "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) "(errno %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) -rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static void ocfs2_control_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) misc_deregister(&ocfs2_control_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static void fsdlm_lock_ast_wrapper(void *astarg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) struct ocfs2_dlm_lksb *lksb = astarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) int status = lksb->lksb_fsdlm.sb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * For now we're punting on the issue of other non-standard errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * where we can't tell if the unlock_ast or lock_ast should be called.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * The main "other error" that's possible is EINVAL which means the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * function was called with invalid args, which shouldn't be possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * since the caller here is under our control. Other non-standard
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) * errors probably fall into the same category, or otherwise are fatal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * which means we can't carry on anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (status == -DLM_EUNLOCK || status == -DLM_ECANCEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) lksb->lksb_conn->cc_proto->lp_unlock_ast(lksb, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) lksb->lksb_conn->cc_proto->lp_lock_ast(lksb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) static void fsdlm_blocking_ast_wrapper(void *astarg, int level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) struct ocfs2_dlm_lksb *lksb = astarg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) lksb->lksb_conn->cc_proto->lp_blocking_ast(lksb, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) static int user_dlm_lock(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) struct ocfs2_dlm_lksb *lksb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) u32 flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) void *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) unsigned int namelen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!lksb->lksb_fsdlm.sb_lvbptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) lksb->lksb_fsdlm.sb_lvbptr = (char *)lksb +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) sizeof(struct dlm_lksb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) ret = dlm_lock(conn->cc_lockspace, mode, &lksb->lksb_fsdlm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) flags|DLM_LKF_NODLCKWT, name, namelen, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) fsdlm_lock_ast_wrapper, lksb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) fsdlm_blocking_ast_wrapper);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) static int user_dlm_unlock(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) struct ocfs2_dlm_lksb *lksb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) u32 flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) ret = dlm_unlock(conn->cc_lockspace, lksb->lksb_fsdlm.sb_lkid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) flags, &lksb->lksb_fsdlm, lksb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static int user_dlm_lock_status(struct ocfs2_dlm_lksb *lksb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) return lksb->lksb_fsdlm.sb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static int user_dlm_lvb_valid(struct ocfs2_dlm_lksb *lksb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) int invalid = lksb->lksb_fsdlm.sb_flags & DLM_SBF_VALNOTVALID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return !invalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) static void *user_dlm_lvb(struct ocfs2_dlm_lksb *lksb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!lksb->lksb_fsdlm.sb_lvbptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) lksb->lksb_fsdlm.sb_lvbptr = (char *)lksb +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) sizeof(struct dlm_lksb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) return (void *)(lksb->lksb_fsdlm.sb_lvbptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) static void user_dlm_dump_lksb(struct ocfs2_dlm_lksb *lksb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static int user_plock(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) u64 ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) struct file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) struct file_lock *fl)
^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) * This more or less just demuxes the plock request into any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * one of three dlm calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * Internally, fs/dlm will pass these to a misc device, which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * a userspace daemon will read and write to.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * For now, cancel requests (which happen internally only),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * are turned into unlocks. Most of this function taken from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * gfs2_lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) if (cmd == F_CANCELLK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) cmd = F_SETLK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) fl->fl_type = F_UNLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (IS_GETLK(cmd))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) return dlm_posix_get(conn->cc_lockspace, ino, file, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) else if (fl->fl_type == F_UNLCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return dlm_posix_unlock(conn->cc_lockspace, ino, file, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) return dlm_posix_lock(conn->cc_lockspace, ino, file, cmd, fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * Compare a requested locking protocol version against the current one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * If the major numbers are different, they are incompatible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * If the current minor is greater than the request, they are incompatible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) * If the current minor is less than or equal to the request, they are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * compatible, and the requester should run at the current minor version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static int fs_protocol_compare(struct ocfs2_protocol_version *existing,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct ocfs2_protocol_version *request)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) if (existing->pv_major != request->pv_major)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (existing->pv_minor > request->pv_minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (existing->pv_minor < request->pv_minor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) request->pv_minor = existing->pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static void lvb_to_version(char *lvb, struct ocfs2_protocol_version *ver)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) struct ocfs2_protocol_version *pv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) (struct ocfs2_protocol_version *)lvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * ocfs2_protocol_version has two u8 variables, so we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * need any endian conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) ver->pv_major = pv->pv_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) ver->pv_minor = pv->pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static void version_to_lvb(struct ocfs2_protocol_version *ver, char *lvb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct ocfs2_protocol_version *pv =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) (struct ocfs2_protocol_version *)lvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) * ocfs2_protocol_version has two u8 variables, so we don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * need any endian conversion.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) pv->pv_major = ver->pv_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) pv->pv_minor = ver->pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static void sync_wait_cb(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) struct ocfs2_cluster_connection *conn = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) complete(&lc->oc_sync_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) static int sync_unlock(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) struct dlm_lksb *lksb, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) error = dlm_unlock(conn->cc_lockspace, lksb->sb_lkid, 0, lksb, conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) printk(KERN_ERR "%s lkid %x error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) name, lksb->sb_lkid, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return error;
^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) wait_for_completion(&lc->oc_sync_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) if (lksb->sb_status != -DLM_EUNLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) printk(KERN_ERR "%s lkid %x status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) name, lksb->sb_lkid, lksb->sb_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static int sync_lock(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) int mode, uint32_t flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) struct dlm_lksb *lksb, char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) int error, status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) error = dlm_lock(conn->cc_lockspace, mode, lksb, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) name, strlen(name),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 0, sync_wait_cb, conn, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) printk(KERN_ERR "%s lkid %x flags %x mode %d error %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) name, lksb->sb_lkid, flags, mode, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) wait_for_completion(&lc->oc_sync_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) status = lksb->sb_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (status && status != -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) printk(KERN_ERR "%s lkid %x flags %x mode %d status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) name, lksb->sb_lkid, flags, mode, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) static int version_lock(struct ocfs2_cluster_connection *conn, int mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return sync_lock(conn, mode, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) &lc->oc_version_lksb, VERSION_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static int version_unlock(struct ocfs2_cluster_connection *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) return sync_unlock(conn, &lc->oc_version_lksb, VERSION_LOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* get_protocol_version()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * To exchange ocfs2 versioning, we use the LVB of the version dlm lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) * The algorithm is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * 1. Attempt to take the lock in EX mode (non-blocking).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * 2. If successful (which means it is the first mount), write the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * version number and downconvert to PR lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * 3. If unsuccessful (returns -EAGAIN), read the version from the LVB after
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * taking the PR lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) static int get_protocol_version(struct ocfs2_cluster_connection *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) struct ocfs2_protocol_version pv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) running_proto.pv_major =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) ocfs2_user_plugin.sp_max_proto.pv_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) running_proto.pv_minor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) ocfs2_user_plugin.sp_max_proto.pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) lc->oc_version_lksb.sb_lvbptr = lc->oc_lvb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) ret = version_lock(conn, DLM_LOCK_EX,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) DLM_LKF_VALBLK|DLM_LKF_NOQUEUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) conn->cc_version.pv_major = running_proto.pv_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) conn->cc_version.pv_minor = running_proto.pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) version_to_lvb(&running_proto, lc->oc_lvb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) version_lock(conn, DLM_LOCK_PR, DLM_LKF_CONVERT|DLM_LKF_VALBLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) } else if (ret == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) ret = version_lock(conn, DLM_LOCK_PR, DLM_LKF_VALBLK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) lvb_to_version(lc->oc_lvb, &pv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if ((pv.pv_major != running_proto.pv_major) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) (pv.pv_minor > running_proto.pv_minor)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) goto out;
^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) conn->cc_version.pv_major = pv.pv_major;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) conn->cc_version.pv_minor = pv.pv_minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) static void user_recover_prep(void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) static void user_recover_slot(void *arg, struct dlm_slot *slot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) struct ocfs2_cluster_connection *conn = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) printk(KERN_INFO "ocfs2: Node %d/%d down. Initiating recovery.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) slot->nodeid, slot->slot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) conn->cc_recovery_handler(slot->nodeid, conn->cc_recovery_data);
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) static void user_recover_done(void *arg, struct dlm_slot *slots,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) int num_slots, int our_slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) uint32_t generation)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) struct ocfs2_cluster_connection *conn = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) for (i = 0; i < num_slots; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (slots[i].slot == our_slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) atomic_set(&lc->oc_this_node, slots[i].nodeid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) lc->oc_our_slot = our_slot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) wake_up(&lc->oc_wait);
^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 const struct dlm_lockspace_ops ocfs2_ls_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) .recover_prep = user_recover_prep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) .recover_slot = user_recover_slot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) .recover_done = user_recover_done,
^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 int user_cluster_disconnect(struct ocfs2_cluster_connection *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) version_unlock(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) dlm_release_lockspace(conn->cc_lockspace, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) conn->cc_lockspace = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) ocfs2_live_connection_drop(conn->cc_private);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) conn->cc_private = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static int user_cluster_connect(struct ocfs2_cluster_connection *conn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) dlm_lockspace_t *fsdlm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) struct ocfs2_live_connection *lc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) int rc, ops_rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) BUG_ON(conn == NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) lc = kzalloc(sizeof(struct ocfs2_live_connection), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) if (!lc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) init_waitqueue_head(&lc->oc_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) init_completion(&lc->oc_sync_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) atomic_set(&lc->oc_this_node, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) conn->cc_private = lc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) lc->oc_type = NO_CONTROLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) rc = dlm_new_lockspace(conn->cc_name, conn->cc_cluster_name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) DLM_LSFL_FS | DLM_LSFL_NEWEXCL, DLM_LVB_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) &ocfs2_ls_ops, conn, &ops_rv, &fsdlm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (rc == -EEXIST || rc == -EPROTO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) printk(KERN_ERR "ocfs2: Unable to create the "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) "lockspace %s (%d), because a ocfs2-tools "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) "program is running on this file system "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) "with the same name lockspace\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) conn->cc_name, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) if (ops_rv == -EOPNOTSUPP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) lc->oc_type = WITH_CONTROLD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) printk(KERN_NOTICE "ocfs2: You seem to be using an older "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) "version of dlm_controld and/or ocfs2-tools."
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) " Please consider upgrading.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) } else if (ops_rv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) rc = ops_rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) conn->cc_lockspace = fsdlm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) rc = ocfs2_live_connection_attach(conn, lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) if (lc->oc_type == NO_CONTROLD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) rc = get_protocol_version(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) printk(KERN_ERR "ocfs2: Could not determine"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) " locking version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) user_cluster_disconnect(conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) wait_event(lc->oc_wait, (atomic_read(&lc->oc_this_node) > 0));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * running_proto must have been set before we allowed any mounts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * to proceed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) if (fs_protocol_compare(&running_proto, &conn->cc_version)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) printk(KERN_ERR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) "Unable to mount with fs locking protocol version "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) "%u.%u because negotiated protocol is %u.%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) conn->cc_version.pv_major, conn->cc_version.pv_minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) running_proto.pv_major, running_proto.pv_minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) rc = -EPROTO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) ocfs2_live_connection_drop(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) lc = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) kfree(lc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) static int user_cluster_this_node(struct ocfs2_cluster_connection *conn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) unsigned int *this_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct ocfs2_live_connection *lc = conn->cc_private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) if (lc->oc_type == WITH_CONTROLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) rc = ocfs2_control_get_this_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) else if (lc->oc_type == NO_CONTROLD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) rc = atomic_read(&lc->oc_this_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) *this_node = rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) static struct ocfs2_stack_operations ocfs2_user_plugin_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) .connect = user_cluster_connect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) .disconnect = user_cluster_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) .this_node = user_cluster_this_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) .dlm_lock = user_dlm_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) .dlm_unlock = user_dlm_unlock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) .lock_status = user_dlm_lock_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) .lvb_valid = user_dlm_lvb_valid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) .lock_lvb = user_dlm_lvb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) .plock = user_plock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) .dump_lksb = user_dlm_dump_lksb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) static struct ocfs2_stack_plugin ocfs2_user_plugin = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) .sp_name = "user",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) .sp_ops = &ocfs2_user_plugin_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) .sp_owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static int __init ocfs2_user_plugin_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) rc = ocfs2_control_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) rc = ocfs2_stack_glue_register(&ocfs2_user_plugin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) ocfs2_control_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static void __exit ocfs2_user_plugin_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) ocfs2_stack_glue_unregister(&ocfs2_user_plugin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ocfs2_control_exit();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) MODULE_AUTHOR("Oracle");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) MODULE_DESCRIPTION("ocfs2 driver for userspace cluster stacks");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) module_init(ocfs2_user_plugin_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) module_exit(ocfs2_user_plugin_exit);