]> git.karo-electronics.de Git - karo-tx-linux.git/blob - fs/ocfs2/stack_user.c
ocfs2: Add the ocfs2_control misc device.
[karo-tx-linux.git] / fs / ocfs2 / stack_user.c
1 /* -*- mode: c; c-basic-offset: 8; -*-
2  * vim: noexpandtab sw=8 ts=8 sts=0:
3  *
4  * stack_user.c
5  *
6  * Code which interfaces ocfs2 with fs/dlm and a userspace stack.
7  *
8  * Copyright (C) 2007 Oracle.  All rights reserved.
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public
12  * License as published by the Free Software Foundation, version 2.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  * General Public License for more details.
18  */
19
20 #include <linux/module.h>
21 #include <linux/fs.h>
22 #include <linux/miscdevice.h>
23 #include <linux/mutex.h>
24 #include <linux/reboot.h>
25
26 #include "stackglue.h"
27
28
29 /*
30  * The control protocol starts with a handshake.  Until the handshake
31  * is complete, the control device will fail all write(2)s.
32  *
33  * The handshake is simple.  First, the client reads until EOF.  Each line
34  * of output is a supported protocol tag.  All protocol tags are a single
35  * character followed by a two hex digit version number.  Currently the
36  * only things supported is T01, for "Text-base version 0x01".  Next, the
37  * client writes the version they would like to use.  If the version tag
38  * written is unknown, -EINVAL is returned.  Once the negotiation is
39  * complete, the client can start sending messages.
40  */
41
42 /*
43  * ocfs2_live_connection is refcounted because the filesystem and
44  * miscdevice sides can detach in different order.  Let's just be safe.
45  */
46 struct ocfs2_live_connection {
47         struct list_head                oc_list;
48         struct ocfs2_cluster_connection *oc_conn;
49 };
50
51 static atomic_t ocfs2_control_opened;
52
53 static LIST_HEAD(ocfs2_live_connection_list);
54 static DEFINE_MUTEX(ocfs2_control_lock);
55
56 static struct ocfs2_live_connection *ocfs2_connection_find(const char *name)
57 {
58         size_t len = strlen(name);
59         struct ocfs2_live_connection *c;
60
61         BUG_ON(!mutex_is_locked(&ocfs2_control_lock));
62
63         list_for_each_entry(c, &ocfs2_live_connection_list, oc_list) {
64                 if ((c->oc_conn->cc_namelen == len) &&
65                     !strncmp(c->oc_conn->cc_name, name, len))
66                         return c;
67         }
68
69         return c;
70 }
71
72 /*
73  * ocfs2_live_connection structures are created underneath the ocfs2
74  * mount path.  Since the VFS prevents multiple calls to
75  * fill_super(), we can't get dupes here.
76  */
77 static int ocfs2_live_connection_new(struct ocfs2_cluster_connection *conn,
78                                      struct ocfs2_live_connection **c_ret)
79 {
80         int rc = 0;
81         struct ocfs2_live_connection *c;
82
83         c = kzalloc(sizeof(struct ocfs2_live_connection), GFP_KERNEL);
84         if (!c)
85                 return -ENOMEM;
86
87         mutex_lock(&ocfs2_control_lock);
88         c->oc_conn = conn;
89
90         if (atomic_read(&ocfs2_control_opened))
91                 list_add(&c->oc_list, &ocfs2_live_connection_list);
92         else {
93                 printk(KERN_ERR
94                        "ocfs2: Userspace control daemon is not present\n");
95                 rc = -ESRCH;
96         }
97
98         mutex_unlock(&ocfs2_control_lock);
99
100         if (!rc)
101                 *c_ret = c;
102         else
103                 kfree(c);
104
105         return rc;
106 }
107
108 /*
109  * This function disconnects the cluster connection from ocfs2_control.
110  * Afterwards, userspace can't affect the cluster connection.
111  */
112 static void ocfs2_live_connection_drop(struct ocfs2_live_connection *c)
113 {
114         mutex_lock(&ocfs2_control_lock);
115         list_del_init(&c->oc_list);
116         c->oc_conn = NULL;
117         mutex_unlock(&ocfs2_control_lock);
118
119         kfree(c);
120 }
121
122
123 static ssize_t ocfs2_control_write(struct file *file,
124                                    const char __user *buf,
125                                    size_t count,
126                                    loff_t *ppos)
127 {
128         return 0;
129 }
130
131 static ssize_t ocfs2_control_read(struct file *file,
132                                   char __user *buf,
133                                   size_t count,
134                                   loff_t *ppos)
135 {
136         return 0;
137 }
138
139 static int ocfs2_control_release(struct inode *inode, struct file *file)
140 {
141         if (atomic_dec_and_test(&ocfs2_control_opened)) {
142                 mutex_lock(&ocfs2_control_lock);
143                 if (!list_empty(&ocfs2_live_connection_list)) {
144                         /* XXX: Do bad things! */
145                         printk(KERN_ERR
146                                "ocfs2: Unexpected release of ocfs2_control!\n"
147                                "       Loss of cluster connection requires "
148                                "an emergency restart!\n");
149                         emergency_restart();
150                 }
151                 mutex_unlock(&ocfs2_control_lock);
152         }
153
154         return 0;
155 }
156
157 static int ocfs2_control_open(struct inode *inode, struct file *file)
158 {
159         atomic_inc(&ocfs2_control_opened);
160
161         return 0;
162 }
163
164 static const struct file_operations ocfs2_control_fops = {
165         .open    = ocfs2_control_open,
166         .release = ocfs2_control_release,
167         .read    = ocfs2_control_read,
168         .write   = ocfs2_control_write,
169         .owner   = THIS_MODULE,
170 };
171
172 struct miscdevice ocfs2_control_device = {
173         .minor          = MISC_DYNAMIC_MINOR,
174         .name           = "ocfs2_control",
175         .fops           = &ocfs2_control_fops,
176 };
177
178 static int ocfs2_control_init(void)
179 {
180         int rc;
181
182         atomic_set(&ocfs2_control_opened, 0);
183
184         rc = misc_register(&ocfs2_control_device);
185         if (rc)
186                 printk(KERN_ERR
187                        "ocfs2: Unable to register ocfs2_control device "
188                        "(errno %d)\n",
189                        -rc);
190
191         return rc;
192 }
193
194 static void ocfs2_control_exit(void)
195 {
196         int rc;
197
198         rc = misc_deregister(&ocfs2_control_device);
199         if (rc)
200                 printk(KERN_ERR
201                        "ocfs2: Unable to deregister ocfs2_control device "
202                        "(errno %d)\n",
203                        -rc);
204 }
205
206 static int __init user_stack_init(void)
207 {
208         return ocfs2_control_init();
209 }
210
211 static void __exit user_stack_exit(void)
212 {
213         ocfs2_control_exit();
214 }
215
216 MODULE_AUTHOR("Oracle");
217 MODULE_DESCRIPTION("ocfs2 driver for userspace cluster stacks");
218 MODULE_LICENSE("GPL");
219 module_init(user_stack_init);
220 module_exit(user_stack_exit);