blob: 7c40e653e526ca8d20165822c627c57ef6415c5c [file] [log] [blame]
Mike Marshall5db11c22015-07-17 10:38:12 -04001/*
2 * (C) 2001 Clemson University and The University of Chicago
3 *
4 * Changes by Acxiom Corporation to add protocol version to kernel
5 * communication, Copyright Acxiom Corporation, 2005.
6 *
7 * See COPYING in top-level directory.
8 */
9
10#include "protocol.h"
Mike Marshall575e9462015-12-04 12:56:14 -050011#include "orangefs-kernel.h"
12#include "orangefs-dev-proto.h"
13#include "orangefs-bufmap.h"
Mike Marshall5db11c22015-07-17 10:38:12 -040014
15#include <linux/debugfs.h>
16#include <linux/slab.h>
17
18/* this file implements the /dev/pvfs2-req device node */
19
Martin Brandenburgf2ee3b72016-08-09 15:59:26 -040020uint32_t userspace_version;
21
Mike Marshall5db11c22015-07-17 10:38:12 -040022static int open_access_count;
23
24#define DUMP_DEVICE_ERROR() \
25do { \
26 gossip_err("*****************************************************\n");\
Yi Liu8bb8aef2015-11-24 15:12:14 -050027 gossip_err("ORANGEFS Device Error: You cannot open the device file "); \
Mike Marshall5db11c22015-07-17 10:38:12 -040028 gossip_err("\n/dev/%s more than once. Please make sure that\nthere " \
Yi Liu8bb8aef2015-11-24 15:12:14 -050029 "are no ", ORANGEFS_REQDEVICE_NAME); \
Mike Marshall5db11c22015-07-17 10:38:12 -040030 gossip_err("instances of a program using this device\ncurrently " \
31 "running. (You must verify this!)\n"); \
32 gossip_err("For example, you can use the lsof program as follows:\n");\
33 gossip_err("'lsof | grep %s' (run this as root)\n", \
Yi Liu8bb8aef2015-11-24 15:12:14 -050034 ORANGEFS_REQDEVICE_NAME); \
Mike Marshall5db11c22015-07-17 10:38:12 -040035 gossip_err(" open_access_count = %d\n", open_access_count); \
36 gossip_err("*****************************************************\n");\
37} while (0)
38
39static int hash_func(__u64 tag, int table_size)
40{
Mike Marshall2c590d52015-07-24 10:37:15 -040041 return do_div(tag, (unsigned int)table_size);
Mike Marshall5db11c22015-07-17 10:38:12 -040042}
43
Yi Liu8bb8aef2015-11-24 15:12:14 -050044static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op)
Mike Marshall5db11c22015-07-17 10:38:12 -040045{
46 int index = hash_func(op->tag, hash_table_size);
47
Mike Marshall5db11c22015-07-17 10:38:12 -040048 list_add_tail(&op->list, &htable_ops_in_progress[index]);
Mike Marshall5db11c22015-07-17 10:38:12 -040049}
50
Mike Marshallca9f5182016-02-26 10:21:12 -050051/*
52 * find the op with this tag and remove it from the in progress
53 * hash table.
54 */
Yi Liu8bb8aef2015-11-24 15:12:14 -050055static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag)
Mike Marshall5db11c22015-07-17 10:38:12 -040056{
Yi Liu8bb8aef2015-11-24 15:12:14 -050057 struct orangefs_kernel_op_s *op, *next;
Mike Marshall5db11c22015-07-17 10:38:12 -040058 int index;
59
60 index = hash_func(tag, hash_table_size);
61
62 spin_lock(&htable_ops_in_progress_lock);
63 list_for_each_entry_safe(op,
64 next,
65 &htable_ops_in_progress[index],
66 list) {
Al Viro05a50a52016-02-18 18:59:44 -050067 if (op->tag == tag && !op_state_purged(op) &&
68 !op_state_given_up(op)) {
Al Viroed42fe02016-01-22 19:47:47 -050069 list_del_init(&op->list);
Mike Marshall5db11c22015-07-17 10:38:12 -040070 spin_unlock(&htable_ops_in_progress_lock);
71 return op;
72 }
73 }
74
75 spin_unlock(&htable_ops_in_progress_lock);
76 return NULL;
77}
78
Martin Brandenburgacfcbaf2016-03-05 13:17:39 -050079/* Returns whether any FS are still pending remounted */
80static int mark_all_pending_mounts(void)
81{
82 int unmounted = 1;
83 struct orangefs_sb_info_s *orangefs_sb = NULL;
84
85 spin_lock(&orangefs_superblocks_lock);
86 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
87 /* All of these file system require a remount */
88 orangefs_sb->mount_pending = 1;
89 unmounted = 0;
90 }
91 spin_unlock(&orangefs_superblocks_lock);
92 return unmounted;
93}
94
95/*
96 * Determine if a given file system needs to be remounted or not
97 * Returns -1 on error
98 * 0 if already mounted
99 * 1 if needs remount
100 */
101static int fs_mount_pending(__s32 fsid)
102{
103 int mount_pending = -1;
104 struct orangefs_sb_info_s *orangefs_sb = NULL;
105
106 spin_lock(&orangefs_superblocks_lock);
107 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
108 if (orangefs_sb->fs_id == fsid) {
109 mount_pending = orangefs_sb->mount_pending;
110 break;
111 }
112 }
113 spin_unlock(&orangefs_superblocks_lock);
114 return mount_pending;
115}
116
Yi Liu8bb8aef2015-11-24 15:12:14 -0500117static int orangefs_devreq_open(struct inode *inode, struct file *file)
Mike Marshall5db11c22015-07-17 10:38:12 -0400118{
119 int ret = -EINVAL;
120
Jann Horn78fee0b2016-06-25 01:51:52 +0200121 /* in order to ensure that the filesystem driver sees correct UIDs */
122 if (file->f_cred->user_ns != &init_user_ns) {
123 gossip_err("%s: device cannot be opened outside init_user_ns\n",
124 __func__);
125 goto out;
126 }
127
Mike Marshall5db11c22015-07-17 10:38:12 -0400128 if (!(file->f_flags & O_NONBLOCK)) {
Mike Marshall97f10022015-12-11 16:45:03 -0500129 gossip_err("%s: device cannot be opened in blocking mode\n",
130 __func__);
Mike Marshall5db11c22015-07-17 10:38:12 -0400131 goto out;
132 }
133 ret = -EACCES;
Mike Marshall97f10022015-12-11 16:45:03 -0500134 gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n");
Mike Marshall5db11c22015-07-17 10:38:12 -0400135 mutex_lock(&devreq_mutex);
136
137 if (open_access_count == 0) {
Al Virofee25ce2016-01-22 19:46:08 -0500138 open_access_count = 1;
Al Virofb6d2522016-01-19 12:00:26 -0500139 ret = 0;
Mike Marshall5db11c22015-07-17 10:38:12 -0400140 } else {
141 DUMP_DEVICE_ERROR();
142 }
143 mutex_unlock(&devreq_mutex);
144
145out:
146
147 gossip_debug(GOSSIP_DEV_DEBUG,
148 "pvfs2-client-core: open device complete (ret = %d)\n",
149 ret);
150 return ret;
151}
152
Mike Marshall97f10022015-12-11 16:45:03 -0500153/* Function for read() callers into the device */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500154static ssize_t orangefs_devreq_read(struct file *file,
Mike Marshall5db11c22015-07-17 10:38:12 -0400155 char __user *buf,
156 size_t count, loff_t *offset)
157{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500158 struct orangefs_kernel_op_s *op, *temp;
159 __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION;
160 static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
161 struct orangefs_kernel_op_s *cur_op = NULL;
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500162 unsigned long ret;
Mike Marshall5db11c22015-07-17 10:38:12 -0400163
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500164 /* We do not support blocking IO. */
Mike Marshall5db11c22015-07-17 10:38:12 -0400165 if (!(file->f_flags & O_NONBLOCK)) {
Mike Marshall97f10022015-12-11 16:45:03 -0500166 gossip_err("%s: blocking read from client-core.\n",
167 __func__);
Mike Marshall5db11c22015-07-17 10:38:12 -0400168 return -EINVAL;
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500169 }
170
171 /*
Martin Brandenburga762ae62015-12-15 14:22:06 -0500172 * The client will do an ioctl to find MAX_DEV_REQ_UPSIZE, then
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500173 * always read with that size buffer.
174 */
Martin Brandenburga762ae62015-12-15 14:22:06 -0500175 if (count != MAX_DEV_REQ_UPSIZE) {
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500176 gossip_err("orangefs: client-core tried to read wrong size\n");
177 return -EINVAL;
178 }
179
Al Viroed42fe02016-01-22 19:47:47 -0500180restart:
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500181 /* Get next op (if any) from top of list. */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500182 spin_lock(&orangefs_request_list_lock);
183 list_for_each_entry_safe(op, temp, &orangefs_request_list, list) {
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500184 __s32 fsid;
185 /* This lock is held past the end of the loop when we break. */
186 spin_lock(&op->lock);
Al Viro05a50a52016-02-18 18:59:44 -0500187 if (unlikely(op_state_purged(op) || op_state_given_up(op))) {
Al Viroed42fe02016-01-22 19:47:47 -0500188 spin_unlock(&op->lock);
189 continue;
190 }
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500191
192 fsid = fsid_of_op(op);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500193 if (fsid != ORANGEFS_FS_ID_NULL) {
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500194 int ret;
195 /* Skip ops whose filesystem needs to be mounted. */
196 ret = fs_mount_pending(fsid);
197 if (ret == 1) {
Mike Marshall5db11c22015-07-17 10:38:12 -0400198 gossip_debug(GOSSIP_DEV_DEBUG,
Mike Marshall5090c962016-02-04 13:29:27 -0500199 "%s: mount pending, skipping op tag "
200 "%llu %s\n",
201 __func__,
202 llu(op->tag),
203 get_opname_string(op));
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500204 spin_unlock(&op->lock);
Mike Marshall5db11c22015-07-17 10:38:12 -0400205 continue;
Mike Marshall97f10022015-12-11 16:45:03 -0500206 /*
207 * Skip ops whose filesystem we don't know about unless
208 * it is being mounted.
209 */
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500210 /* XXX: is there a better way to detect this? */
211 } else if (ret == -1 &&
Mike Marshall97f10022015-12-11 16:45:03 -0500212 !(op->upcall.type ==
213 ORANGEFS_VFS_OP_FS_MOUNT ||
214 op->upcall.type ==
215 ORANGEFS_VFS_OP_GETATTR)) {
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500216 gossip_debug(GOSSIP_DEV_DEBUG,
217 "orangefs: skipping op tag %llu %s\n",
218 llu(op->tag), get_opname_string(op));
219 gossip_err(
220 "orangefs: ERROR: fs_mount_pending %d\n",
221 fsid);
222 spin_unlock(&op->lock);
223 continue;
Mike Marshall5db11c22015-07-17 10:38:12 -0400224 }
225 }
Mike Marshall5db11c22015-07-17 10:38:12 -0400226 /*
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500227 * Either this op does not pertain to a filesystem, is mounting
228 * a filesystem, or pertains to a mounted filesystem. Let it
229 * through.
Mike Marshall5db11c22015-07-17 10:38:12 -0400230 */
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500231 cur_op = op;
232 break;
Mike Marshall5db11c22015-07-17 10:38:12 -0400233 }
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500234
235 /*
236 * At this point we either have a valid op and can continue or have not
237 * found an op and must ask the client to try again later.
238 */
239 if (!cur_op) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500240 spin_unlock(&orangefs_request_list_lock);
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500241 return -EAGAIN;
242 }
243
Mike Marshallca9f5182016-02-26 10:21:12 -0500244 gossip_debug(GOSSIP_DEV_DEBUG, "%s: reading op tag %llu %s\n",
245 __func__,
246 llu(cur_op->tag),
247 get_opname_string(cur_op));
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500248
249 /*
250 * Such an op should never be on the list in the first place. If so, we
251 * will abort.
252 */
253 if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
254 gossip_err("orangefs: ERROR: Current op already queued.\n");
Al Viro05a50a52016-02-18 18:59:44 -0500255 list_del_init(&cur_op->list);
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500256 spin_unlock(&cur_op->lock);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500257 spin_unlock(&orangefs_request_list_lock);
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500258 return -EAGAIN;
259 }
Mike Marshallca9f5182016-02-26 10:21:12 -0500260
Al Viroed42fe02016-01-22 19:47:47 -0500261 list_del_init(&cur_op->list);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500262 spin_unlock(&orangefs_request_list_lock);
Al Viroed42fe02016-01-22 19:47:47 -0500263
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500264 spin_unlock(&cur_op->lock);
265
266 /* Push the upcall out. */
267 ret = copy_to_user(buf, &proto_ver, sizeof(__s32));
268 if (ret != 0)
269 goto error;
270 ret = copy_to_user(buf+sizeof(__s32), &magic, sizeof(__s32));
271 if (ret != 0)
272 goto error;
273 ret = copy_to_user(buf+2 * sizeof(__s32), &cur_op->tag, sizeof(__u64));
274 if (ret != 0)
275 goto error;
276 ret = copy_to_user(buf+2*sizeof(__s32)+sizeof(__u64), &cur_op->upcall,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500277 sizeof(struct orangefs_upcall_s));
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500278 if (ret != 0)
279 goto error;
280
Al Viroed42fe02016-01-22 19:47:47 -0500281 spin_lock(&htable_ops_in_progress_lock);
282 spin_lock(&cur_op->lock);
283 if (unlikely(op_state_given_up(cur_op))) {
284 spin_unlock(&cur_op->lock);
285 spin_unlock(&htable_ops_in_progress_lock);
Al Viro05a50a52016-02-18 18:59:44 -0500286 complete(&cur_op->waitq);
Al Viroed42fe02016-01-22 19:47:47 -0500287 goto restart;
288 }
289
290 /*
291 * Set the operation to be in progress and move it between lists since
292 * it has been sent to the client.
293 */
294 set_op_state_inprogress(cur_op);
Mike Marshall9d9e7ba2016-03-03 13:46:48 -0500295 gossip_debug(GOSSIP_DEV_DEBUG,
296 "%s: 1 op:%s: op_state:%d: process:%s:\n",
297 __func__,
298 get_opname_string(cur_op),
299 cur_op->op_state,
300 current->comm);
Al Viroed42fe02016-01-22 19:47:47 -0500301 orangefs_devreq_add_op(cur_op);
302 spin_unlock(&cur_op->lock);
303 spin_unlock(&htable_ops_in_progress_lock);
Al Viroed42fe02016-01-22 19:47:47 -0500304
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500305 /* The client only asks to read one size buffer. */
Martin Brandenburga762ae62015-12-15 14:22:06 -0500306 return MAX_DEV_REQ_UPSIZE;
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500307error:
308 /*
309 * We were unable to copy the op data to the client. Put the op back in
310 * list. If client has crashed, the op will be purged later when the
311 * device is released.
312 */
313 gossip_err("orangefs: Failed to copy data to user space\n");
Yi Liu8bb8aef2015-11-24 15:12:14 -0500314 spin_lock(&orangefs_request_list_lock);
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500315 spin_lock(&cur_op->lock);
Al Viroed42fe02016-01-22 19:47:47 -0500316 if (likely(!op_state_given_up(cur_op))) {
317 set_op_state_waiting(cur_op);
Mike Marshall9d9e7ba2016-03-03 13:46:48 -0500318 gossip_debug(GOSSIP_DEV_DEBUG,
319 "%s: 2 op:%s: op_state:%d: process:%s:\n",
320 __func__,
321 get_opname_string(cur_op),
322 cur_op->op_state,
323 current->comm);
Al Viroed42fe02016-01-22 19:47:47 -0500324 list_add(&cur_op->list, &orangefs_request_list);
Al Viro05a50a52016-02-18 18:59:44 -0500325 spin_unlock(&cur_op->lock);
326 } else {
327 spin_unlock(&cur_op->lock);
328 complete(&cur_op->waitq);
Al Viroed42fe02016-01-22 19:47:47 -0500329 }
Yi Liu8bb8aef2015-11-24 15:12:14 -0500330 spin_unlock(&orangefs_request_list_lock);
Martin Brandenburg24c8d082015-11-13 14:26:10 -0500331 return -EFAULT;
Mike Marshall5db11c22015-07-17 10:38:12 -0400332}
333
Mike Marshall97f10022015-12-11 16:45:03 -0500334/*
Mike Marshallb3ae4752016-01-13 11:18:12 -0500335 * Function for writev() callers into the device.
336 *
337 * Userspace should have written:
338 * - __u32 version
339 * - __u32 magic
340 * - __u64 tag
341 * - struct orangefs_downcall_s
342 * - trailer buffer (in the case of READDIR operations)
Mike Marshall97f10022015-12-11 16:45:03 -0500343 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500344static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
Mike Marshall5db11c22015-07-17 10:38:12 -0400345 struct iov_iter *iter)
346{
Mike Marshallb3ae4752016-01-13 11:18:12 -0500347 ssize_t ret;
348 struct orangefs_kernel_op_s *op = NULL;
349 struct {
350 __u32 version;
351 __u32 magic;
352 __u64 tag;
353 } head;
354 int total = ret = iov_iter_count(iter);
355 int n;
356 int downcall_size = sizeof(struct orangefs_downcall_s);
357 int head_size = sizeof(head);
358
359 gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n",
360 __func__,
361 total,
362 ret);
363
364 if (total < MAX_DEV_REQ_DOWNSIZE) {
Mike Marshallcf0c2772016-01-19 12:04:40 -0500365 gossip_err("%s: total:%d: must be at least:%u:\n",
Mike Marshallb3ae4752016-01-13 11:18:12 -0500366 __func__,
367 total,
Mike Marshallcf0c2772016-01-19 12:04:40 -0500368 (unsigned int) MAX_DEV_REQ_DOWNSIZE);
Al Viroed42fe02016-01-22 19:47:47 -0500369 return -EFAULT;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500370 }
371
372 n = copy_from_iter(&head, head_size, iter);
373 if (n < head_size) {
374 gossip_err("%s: failed to copy head.\n", __func__);
Al Viroed42fe02016-01-22 19:47:47 -0500375 return -EFAULT;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500376 }
377
378 if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) {
379 gossip_err("%s: userspace claims version"
380 "%d, minimum version required: %d.\n",
381 __func__,
382 head.version,
383 ORANGEFS_MINIMUM_USERSPACE_VERSION);
Al Viroed42fe02016-01-22 19:47:47 -0500384 return -EPROTO;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500385 }
386
387 if (head.magic != ORANGEFS_DEVREQ_MAGIC) {
388 gossip_err("Error: Device magic number does not match.\n");
Al Viroed42fe02016-01-22 19:47:47 -0500389 return -EPROTO;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500390 }
391
Martin Brandenburgf2ee3b72016-08-09 15:59:26 -0400392 if (!userspace_version) {
393 userspace_version = head.version;
394 } else if (userspace_version != head.version) {
395 gossip_err("Error: userspace version changes\n");
396 return -EPROTO;
397 }
398
Mike Marshallca9f5182016-02-26 10:21:12 -0500399 /* remove the op from the in progress hash table */
Mike Marshallb3ae4752016-01-13 11:18:12 -0500400 op = orangefs_devreq_remove_op(head.tag);
401 if (!op) {
402 gossip_err("WARNING: No one's waiting for tag %llu\n",
403 llu(head.tag));
Al Viroed42fe02016-01-22 19:47:47 -0500404 return ret;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500405 }
406
Mike Marshallb3ae4752016-01-13 11:18:12 -0500407 n = copy_from_iter(&op->downcall, downcall_size, iter);
408 if (n != downcall_size) {
409 gossip_err("%s: failed to copy downcall.\n", __func__);
Al Viro5964c1b2016-02-18 18:53:41 -0500410 goto Efault;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500411 }
412
413 if (op->downcall.status)
414 goto wakeup;
415
416 /*
417 * We've successfully peeled off the head and the downcall.
418 * Something has gone awry if total doesn't equal the
419 * sum of head_size, downcall_size and trailer_size.
420 */
421 if ((head_size + downcall_size + op->downcall.trailer_size) != total) {
422 gossip_err("%s: funky write, head_size:%d"
423 ": downcall_size:%d: trailer_size:%lld"
424 ": total size:%d:\n",
425 __func__,
426 head_size,
427 downcall_size,
428 op->downcall.trailer_size,
429 total);
Al Viro5964c1b2016-02-18 18:53:41 -0500430 goto Efault;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500431 }
432
433 /* Only READDIR operations should have trailers. */
434 if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) &&
435 (op->downcall.trailer_size != 0)) {
436 gossip_err("%s: %x operation with trailer.",
437 __func__,
438 op->downcall.type);
Al Viro5964c1b2016-02-18 18:53:41 -0500439 goto Efault;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500440 }
441
442 /* READDIR operations should always have trailers. */
443 if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) &&
444 (op->downcall.trailer_size == 0)) {
445 gossip_err("%s: %x operation with no trailer.",
446 __func__,
447 op->downcall.type);
Al Viro5964c1b2016-02-18 18:53:41 -0500448 goto Efault;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500449 }
450
451 if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
452 goto wakeup;
453
454 op->downcall.trailer_buf =
455 vmalloc(op->downcall.trailer_size);
456 if (op->downcall.trailer_buf == NULL) {
457 gossip_err("%s: failed trailer vmalloc.\n",
458 __func__);
Al Viro5964c1b2016-02-18 18:53:41 -0500459 goto Enomem;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500460 }
461 memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size);
462 n = copy_from_iter(op->downcall.trailer_buf,
463 op->downcall.trailer_size,
464 iter);
465 if (n != op->downcall.trailer_size) {
466 gossip_err("%s: failed to copy trailer.\n", __func__);
467 vfree(op->downcall.trailer_buf);
Al Viro5964c1b2016-02-18 18:53:41 -0500468 goto Efault;
Mike Marshallb3ae4752016-01-13 11:18:12 -0500469 }
470
471wakeup:
Al Viro2a9e5c22016-01-23 13:45:46 -0500472 /*
Mike Marshall9f08cfe92016-02-26 14:39:08 -0500473 * Return to vfs waitqueue, and back to service_operation
474 * through wait_for_matching_downcall.
Al Viro2a9e5c22016-01-23 13:45:46 -0500475 */
476 spin_lock(&op->lock);
Al Viro5964c1b2016-02-18 18:53:41 -0500477 if (unlikely(op_is_cancel(op))) {
Al Viro2a9e5c22016-01-23 13:45:46 -0500478 spin_unlock(&op->lock);
Al Viro78699e22016-02-11 23:07:19 -0500479 put_cancel(op);
Al Viro5964c1b2016-02-18 18:53:41 -0500480 } else if (unlikely(op_state_given_up(op))) {
481 spin_unlock(&op->lock);
Al Viro05a50a52016-02-18 18:59:44 -0500482 complete(&op->waitq);
Al Viro5964c1b2016-02-18 18:53:41 -0500483 } else {
484 set_op_state_serviced(op);
Mike Marshall9d9e7ba2016-03-03 13:46:48 -0500485 gossip_debug(GOSSIP_DEV_DEBUG,
486 "%s: op:%s: op_state:%d: process:%s:\n",
487 __func__,
488 get_opname_string(op),
489 op->op_state,
490 current->comm);
Al Viro5964c1b2016-02-18 18:53:41 -0500491 spin_unlock(&op->lock);
492 }
Mike Marshallb3ae4752016-01-13 11:18:12 -0500493 return ret;
Al Viroed42fe02016-01-22 19:47:47 -0500494
Al Viro5964c1b2016-02-18 18:53:41 -0500495Efault:
496 op->downcall.status = -(ORANGEFS_ERROR_BIT | 9);
497 ret = -EFAULT;
498 goto wakeup;
499
500Enomem:
501 op->downcall.status = -(ORANGEFS_ERROR_BIT | 8);
502 ret = -ENOMEM;
503 goto wakeup;
Mike Marshall5db11c22015-07-17 10:38:12 -0400504}
505
Mike Marshall5db11c22015-07-17 10:38:12 -0400506/*
507 * NOTE: gets called when the last reference to this device is dropped.
508 * Using the open_access_count variable, we enforce a reference count
509 * on this file so that it can be opened by only one process at a time.
510 * the devreq_mutex is used to make sure all i/o has completed
Yi Liu8bb8aef2015-11-24 15:12:14 -0500511 * before we call orangefs_bufmap_finalize, and similar such tricky
Mike Marshall5db11c22015-07-17 10:38:12 -0400512 * situations
513 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500514static int orangefs_devreq_release(struct inode *inode, struct file *file)
Mike Marshall5db11c22015-07-17 10:38:12 -0400515{
516 int unmounted = 0;
517
518 gossip_debug(GOSSIP_DEV_DEBUG,
519 "%s:pvfs2-client-core: exiting, closing device\n",
520 __func__);
521
522 mutex_lock(&devreq_mutex);
Al Viroea2c9c92016-02-13 21:01:21 -0500523 orangefs_bufmap_finalize();
Mike Marshall5db11c22015-07-17 10:38:12 -0400524
Al Virofee25ce2016-01-22 19:46:08 -0500525 open_access_count = -1;
Mike Marshall5db11c22015-07-17 10:38:12 -0400526
527 unmounted = mark_all_pending_mounts();
Yi Liu8bb8aef2015-11-24 15:12:14 -0500528 gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n",
Mike Marshall5db11c22015-07-17 10:38:12 -0400529 (unmounted ? "UNMOUNTED" : "MOUNTED"));
Mike Marshall5db11c22015-07-17 10:38:12 -0400530
Mike Marshall5db11c22015-07-17 10:38:12 -0400531 purge_waiting_ops();
Mike Marshall5db11c22015-07-17 10:38:12 -0400532 purge_inprogress_ops();
Al Viroea2c9c92016-02-13 21:01:21 -0500533
534 orangefs_bufmap_run_down();
535
Mike Marshall5db11c22015-07-17 10:38:12 -0400536 gossip_debug(GOSSIP_DEV_DEBUG,
537 "pvfs2-client-core: device close complete\n");
Al Virofee25ce2016-01-22 19:46:08 -0500538 open_access_count = 0;
Martin Brandenburgf2ee3b72016-08-09 15:59:26 -0400539 userspace_version = 0;
Al Virofee25ce2016-01-22 19:46:08 -0500540 mutex_unlock(&devreq_mutex);
Mike Marshall5db11c22015-07-17 10:38:12 -0400541 return 0;
542}
543
544int is_daemon_in_service(void)
545{
546 int in_service;
547
548 /*
549 * What this function does is checks if client-core is alive
550 * based on the access count we maintain on the device.
551 */
552 mutex_lock(&devreq_mutex);
553 in_service = open_access_count == 1 ? 0 : -EIO;
554 mutex_unlock(&devreq_mutex);
555 return in_service;
556}
557
Al Viro78699e22016-02-11 23:07:19 -0500558bool __is_daemon_in_service(void)
559{
560 return open_access_count == 1;
561}
562
Mike Marshall5db11c22015-07-17 10:38:12 -0400563static inline long check_ioctl_command(unsigned int command)
564{
565 /* Check for valid ioctl codes */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500566 if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) {
Mike Marshall5db11c22015-07-17 10:38:12 -0400567 gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
568 command,
569 _IOC_TYPE(command),
Yi Liu8bb8aef2015-11-24 15:12:14 -0500570 ORANGEFS_DEV_MAGIC);
Mike Marshall5db11c22015-07-17 10:38:12 -0400571 return -EINVAL;
572 }
573 /* and valid ioctl commands */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500574 if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
Mike Marshall5db11c22015-07-17 10:38:12 -0400575 gossip_err("Invalid ioctl command number [%d >= %d]\n",
Yi Liu8bb8aef2015-11-24 15:12:14 -0500576 _IOC_NR(command), ORANGEFS_DEV_MAXNR);
Mike Marshall5db11c22015-07-17 10:38:12 -0400577 return -ENOIOCTLCMD;
578 }
579 return 0;
580}
581
582static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
583{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500584 static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
Martin Brandenburga762ae62015-12-15 14:22:06 -0500585 static __s32 max_up_size = MAX_DEV_REQ_UPSIZE;
586 static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500587 struct ORANGEFS_dev_map_desc user_desc;
Mike Marshall5db11c22015-07-17 10:38:12 -0400588 int ret = 0;
589 struct dev_mask_info_s mask_info = { 0 };
590 struct dev_mask2_info_s mask2_info = { 0, 0 };
591 int upstream_kmod = 1;
Al Viro45996492016-03-25 19:56:34 -0400592 struct orangefs_sb_info_s *orangefs_sb;
Mike Marshall5db11c22015-07-17 10:38:12 -0400593
594 /* mtmoore: add locking here */
595
596 switch (command) {
Yi Liu8bb8aef2015-11-24 15:12:14 -0500597 case ORANGEFS_DEV_GET_MAGIC:
Mike Marshall5db11c22015-07-17 10:38:12 -0400598 return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
599 -EIO :
600 0);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500601 case ORANGEFS_DEV_GET_MAX_UPSIZE:
Mike Marshall5db11c22015-07-17 10:38:12 -0400602 return ((put_user(max_up_size,
603 (__s32 __user *) arg) == -EFAULT) ?
604 -EIO :
605 0);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500606 case ORANGEFS_DEV_GET_MAX_DOWNSIZE:
Mike Marshall5db11c22015-07-17 10:38:12 -0400607 return ((put_user(max_down_size,
608 (__s32 __user *) arg) == -EFAULT) ?
609 -EIO :
610 0);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500611 case ORANGEFS_DEV_MAP:
Mike Marshall5db11c22015-07-17 10:38:12 -0400612 ret = copy_from_user(&user_desc,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500613 (struct ORANGEFS_dev_map_desc __user *)
Mike Marshall5db11c22015-07-17 10:38:12 -0400614 arg,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500615 sizeof(struct ORANGEFS_dev_map_desc));
Al Viroea2c9c92016-02-13 21:01:21 -0500616 /* WTF -EIO and not -EFAULT? */
617 return ret ? -EIO : orangefs_bufmap_initialize(&user_desc);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500618 case ORANGEFS_DEV_REMOUNT_ALL:
Mike Marshall5db11c22015-07-17 10:38:12 -0400619 gossip_debug(GOSSIP_DEV_DEBUG,
Mike Marshall97f10022015-12-11 16:45:03 -0500620 "%s: got ORANGEFS_DEV_REMOUNT_ALL\n",
621 __func__);
Mike Marshall5db11c22015-07-17 10:38:12 -0400622
623 /*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500624 * remount all mounted orangefs volumes to regain the lost
Mike Marshall5db11c22015-07-17 10:38:12 -0400625 * dynamic mount tables (if any) -- NOTE: this is done
626 * without keeping the superblock list locked due to the
Mike Marshalladcf34a2016-02-24 16:54:27 -0500627 * upcall/downcall waiting. also, the request mutex is
Mike Marshall5db11c22015-07-17 10:38:12 -0400628 * used to ensure that no operations will be serviced until
629 * all of the remounts are serviced (to avoid ops between
630 * mounts to fail)
631 */
632 ret = mutex_lock_interruptible(&request_mutex);
633 if (ret < 0)
634 return ret;
635 gossip_debug(GOSSIP_DEV_DEBUG,
Mike Marshall97f10022015-12-11 16:45:03 -0500636 "%s: priority remount in progress\n",
637 __func__);
Al Viro45996492016-03-25 19:56:34 -0400638 spin_lock(&orangefs_superblocks_lock);
639 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
640 /*
641 * We have to drop the spinlock, so entries can be
642 * removed. They can't be freed, though, so we just
643 * keep the forward pointers and zero the back ones -
644 * that way we can get to the rest of the list.
645 */
646 if (!orangefs_sb->list.prev)
647 continue;
648 gossip_debug(GOSSIP_DEV_DEBUG,
649 "%s: Remounting SB %p\n",
650 __func__,
651 orangefs_sb);
Mike Marshall5db11c22015-07-17 10:38:12 -0400652
Al Viro45996492016-03-25 19:56:34 -0400653 spin_unlock(&orangefs_superblocks_lock);
654 ret = orangefs_remount(orangefs_sb);
655 spin_lock(&orangefs_superblocks_lock);
656 if (ret) {
657 gossip_debug(GOSSIP_DEV_DEBUG,
658 "SB %p remount failed\n",
659 orangefs_sb);
660 break;
Mike Marshall5db11c22015-07-17 10:38:12 -0400661 }
662 }
Al Viro45996492016-03-25 19:56:34 -0400663 spin_unlock(&orangefs_superblocks_lock);
Mike Marshall5db11c22015-07-17 10:38:12 -0400664 gossip_debug(GOSSIP_DEV_DEBUG,
Mike Marshall97f10022015-12-11 16:45:03 -0500665 "%s: priority remount complete\n",
666 __func__);
Mike Marshall5db11c22015-07-17 10:38:12 -0400667 mutex_unlock(&request_mutex);
668 return ret;
669
Yi Liu8bb8aef2015-11-24 15:12:14 -0500670 case ORANGEFS_DEV_UPSTREAM:
Mike Marshall5db11c22015-07-17 10:38:12 -0400671 ret = copy_to_user((void __user *)arg,
672 &upstream_kmod,
673 sizeof(upstream_kmod));
674
675 if (ret != 0)
676 return -EIO;
677 else
678 return ret;
679
Yi Liu8bb8aef2015-11-24 15:12:14 -0500680 case ORANGEFS_DEV_CLIENT_MASK:
Mike Marshall5db11c22015-07-17 10:38:12 -0400681 ret = copy_from_user(&mask2_info,
682 (void __user *)arg,
683 sizeof(struct dev_mask2_info_s));
684
685 if (ret != 0)
686 return -EIO;
687
688 client_debug_mask.mask1 = mask2_info.mask1_value;
689 client_debug_mask.mask2 = mask2_info.mask2_value;
690
691 pr_info("%s: client debug mask has been been received "
692 ":%llx: :%llx:\n",
693 __func__,
694 (unsigned long long)client_debug_mask.mask1,
695 (unsigned long long)client_debug_mask.mask2);
696
697 return ret;
698
Yi Liu8bb8aef2015-11-24 15:12:14 -0500699 case ORANGEFS_DEV_CLIENT_STRING:
Mike Marshall5db11c22015-07-17 10:38:12 -0400700 ret = copy_from_user(&client_debug_array_string,
701 (void __user *)arg,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500702 ORANGEFS_MAX_DEBUG_STRING_LEN);
Mike Marshall53f57fe2016-03-14 15:28:34 -0400703 /*
704 * The real client-core makes an effort to ensure
705 * that actual strings that aren't too long to fit in
706 * this buffer is what we get here. We're going to use
707 * string functions on the stuff we got, so we'll make
708 * this extra effort to try and keep from
709 * flowing out of this buffer when we use the string
710 * functions, even if somehow the stuff we end up
711 * with here is garbage.
712 */
713 client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] =
714 '\0';
715
Mike Marshall5db11c22015-07-17 10:38:12 -0400716 if (ret != 0) {
Mike Marshall97f10022015-12-11 16:45:03 -0500717 pr_info("%s: CLIENT_STRING: copy_from_user failed\n",
Mike Marshall5db11c22015-07-17 10:38:12 -0400718 __func__);
719 return -EIO;
720 }
721
Mike Marshall97f10022015-12-11 16:45:03 -0500722 pr_info("%s: client debug array string has been received.\n",
Mike Marshall5db11c22015-07-17 10:38:12 -0400723 __func__);
724
725 if (!help_string_initialized) {
726
727 /* Free the "we don't know yet" default string... */
728 kfree(debug_help_string);
729
730 /* build a proper debug help string */
731 if (orangefs_prepare_debugfs_help_string(0)) {
Mike Marshall97f10022015-12-11 16:45:03 -0500732 gossip_err("%s: no debug help string \n",
Mike Marshall5db11c22015-07-17 10:38:12 -0400733 __func__);
734 return -EIO;
735 }
736
737 /* Replace the boilerplate boot-time debug-help file. */
738 debugfs_remove(help_file_dentry);
739
740 help_file_dentry =
741 debugfs_create_file(
742 ORANGEFS_KMOD_DEBUG_HELP_FILE,
743 0444,
744 debug_dir,
745 debug_help_string,
746 &debug_help_fops);
747
748 if (!help_file_dentry) {
749 gossip_err("%s: debugfs_create_file failed for"
750 " :%s:!\n",
751 __func__,
752 ORANGEFS_KMOD_DEBUG_HELP_FILE);
753 return -EIO;
754 }
755 }
756
757 debug_mask_to_string(&client_debug_mask, 1);
758
759 debugfs_remove(client_debug_dentry);
760
Yi Liu8bb8aef2015-11-24 15:12:14 -0500761 orangefs_client_debug_init();
Mike Marshall5db11c22015-07-17 10:38:12 -0400762
763 help_string_initialized++;
764
765 return ret;
766
Yi Liu8bb8aef2015-11-24 15:12:14 -0500767 case ORANGEFS_DEV_DEBUG:
Mike Marshall5db11c22015-07-17 10:38:12 -0400768 ret = copy_from_user(&mask_info,
769 (void __user *)arg,
770 sizeof(mask_info));
771
772 if (ret != 0)
773 return -EIO;
774
775 if (mask_info.mask_type == KERNEL_MASK) {
776 if ((mask_info.mask_value == 0)
777 && (kernel_mask_set_mod_init)) {
778 /*
779 * the kernel debug mask was set when the
780 * kernel module was loaded; don't override
781 * it if the client-core was started without
Yi Liu8bb8aef2015-11-24 15:12:14 -0500782 * a value for ORANGEFS_KMODMASK.
Mike Marshall5db11c22015-07-17 10:38:12 -0400783 */
784 return 0;
785 }
786 debug_mask_to_string(&mask_info.mask_value,
787 mask_info.mask_type);
788 gossip_debug_mask = mask_info.mask_value;
Mike Marshall97f10022015-12-11 16:45:03 -0500789 pr_info("%s: kernel debug mask has been modified to "
Mike Marshall5db11c22015-07-17 10:38:12 -0400790 ":%s: :%llx:\n",
Mike Marshall97f10022015-12-11 16:45:03 -0500791 __func__,
Mike Marshall5db11c22015-07-17 10:38:12 -0400792 kernel_debug_string,
793 (unsigned long long)gossip_debug_mask);
794 } else if (mask_info.mask_type == CLIENT_MASK) {
795 debug_mask_to_string(&mask_info.mask_value,
796 mask_info.mask_type);
Mike Marshall97f10022015-12-11 16:45:03 -0500797 pr_info("%s: client debug mask has been modified to"
Mike Marshall5db11c22015-07-17 10:38:12 -0400798 ":%s: :%llx:\n",
Mike Marshall97f10022015-12-11 16:45:03 -0500799 __func__,
Mike Marshall5db11c22015-07-17 10:38:12 -0400800 client_debug_string,
801 llu(mask_info.mask_value));
802 } else {
803 gossip_lerr("Invalid mask type....\n");
804 return -EINVAL;
805 }
806
807 return ret;
808
809 default:
810 return -ENOIOCTLCMD;
811 }
812 return -ENOIOCTLCMD;
813}
814
Yi Liu8bb8aef2015-11-24 15:12:14 -0500815static long orangefs_devreq_ioctl(struct file *file,
Mike Marshall5db11c22015-07-17 10:38:12 -0400816 unsigned int command, unsigned long arg)
817{
818 long ret;
819
820 /* Check for properly constructed commands */
821 ret = check_ioctl_command(command);
822 if (ret < 0)
823 return (int)ret;
824
825 return (int)dispatch_ioctl_command(command, arg);
826}
827
828#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
829
Yi Liu8bb8aef2015-11-24 15:12:14 -0500830/* Compat structure for the ORANGEFS_DEV_MAP ioctl */
831struct ORANGEFS_dev_map_desc32 {
Mike Marshall5db11c22015-07-17 10:38:12 -0400832 compat_uptr_t ptr;
833 __s32 total_size;
834 __s32 size;
835 __s32 count;
836};
837
838static unsigned long translate_dev_map26(unsigned long args, long *error)
839{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500840 struct ORANGEFS_dev_map_desc32 __user *p32 = (void __user *)args;
Mike Marshall5db11c22015-07-17 10:38:12 -0400841 /*
842 * Depending on the architecture, allocate some space on the
843 * user-call-stack based on our expected layout.
844 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500845 struct ORANGEFS_dev_map_desc __user *p =
Mike Marshall5db11c22015-07-17 10:38:12 -0400846 compat_alloc_user_space(sizeof(*p));
Mike Marshall84d02152015-07-28 13:27:51 -0400847 compat_uptr_t addr;
Mike Marshall5db11c22015-07-17 10:38:12 -0400848
849 *error = 0;
850 /* get the ptr from the 32 bit user-space */
851 if (get_user(addr, &p32->ptr))
852 goto err;
853 /* try to put that into a 64-bit layout */
854 if (put_user(compat_ptr(addr), &p->ptr))
855 goto err;
856 /* copy the remaining fields */
857 if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32)))
858 goto err;
859 if (copy_in_user(&p->size, &p32->size, sizeof(__s32)))
860 goto err;
861 if (copy_in_user(&p->count, &p32->count, sizeof(__s32)))
862 goto err;
863 return (unsigned long)p;
864err:
865 *error = -EFAULT;
866 return 0;
867}
868
869/*
870 * 32 bit user-space apps' ioctl handlers when kernel modules
871 * is compiled as a 64 bit one
872 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500873static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
Mike Marshall5db11c22015-07-17 10:38:12 -0400874 unsigned long args)
875{
876 long ret;
877 unsigned long arg = args;
878
879 /* Check for properly constructed commands */
880 ret = check_ioctl_command(cmd);
881 if (ret < 0)
882 return ret;
Yi Liu8bb8aef2015-11-24 15:12:14 -0500883 if (cmd == ORANGEFS_DEV_MAP) {
Mike Marshall5db11c22015-07-17 10:38:12 -0400884 /*
885 * convert the arguments to what we expect internally
886 * in kernel space
887 */
888 arg = translate_dev_map26(args, &ret);
889 if (ret < 0) {
890 gossip_err("Could not translate dev map\n");
891 return ret;
892 }
893 }
894 /* no other ioctl requires translation */
895 return dispatch_ioctl_command(cmd, arg);
896}
897
Mike Marshall2c590d52015-07-24 10:37:15 -0400898#endif /* CONFIG_COMPAT is in .config */
899
Mike Marshall5db11c22015-07-17 10:38:12 -0400900/* the assigned character device major number */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500901static int orangefs_dev_major;
Mike Marshall5db11c22015-07-17 10:38:12 -0400902
903/*
Yi Liu8bb8aef2015-11-24 15:12:14 -0500904 * Initialize orangefs device specific state:
Mike Marshall5db11c22015-07-17 10:38:12 -0400905 * Must be called at module load time only
906 */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500907int orangefs_dev_init(void)
Mike Marshall5db11c22015-07-17 10:38:12 -0400908{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500909 /* register orangefs-req device */
910 orangefs_dev_major = register_chrdev(0,
911 ORANGEFS_REQDEVICE_NAME,
912 &orangefs_devreq_file_operations);
913 if (orangefs_dev_major < 0) {
Mike Marshall5db11c22015-07-17 10:38:12 -0400914 gossip_debug(GOSSIP_DEV_DEBUG,
915 "Failed to register /dev/%s (error %d)\n",
Yi Liu8bb8aef2015-11-24 15:12:14 -0500916 ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
Yi Liu8bb8aef2015-11-24 15:12:14 -0500917 return orangefs_dev_major;
Mike Marshall5db11c22015-07-17 10:38:12 -0400918 }
919
920 gossip_debug(GOSSIP_DEV_DEBUG,
921 "*** /dev/%s character device registered ***\n",
Yi Liu8bb8aef2015-11-24 15:12:14 -0500922 ORANGEFS_REQDEVICE_NAME);
Mike Marshall5db11c22015-07-17 10:38:12 -0400923 gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
Yi Liu8bb8aef2015-11-24 15:12:14 -0500924 ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
Mike Marshall5db11c22015-07-17 10:38:12 -0400925 return 0;
926}
927
Yi Liu8bb8aef2015-11-24 15:12:14 -0500928void orangefs_dev_cleanup(void)
Mike Marshall5db11c22015-07-17 10:38:12 -0400929{
Yi Liu8bb8aef2015-11-24 15:12:14 -0500930 unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME);
Mike Marshall5db11c22015-07-17 10:38:12 -0400931 gossip_debug(GOSSIP_DEV_DEBUG,
932 "*** /dev/%s character device unregistered ***\n",
Yi Liu8bb8aef2015-11-24 15:12:14 -0500933 ORANGEFS_REQDEVICE_NAME);
Mike Marshall5db11c22015-07-17 10:38:12 -0400934}
935
Yi Liu8bb8aef2015-11-24 15:12:14 -0500936static unsigned int orangefs_devreq_poll(struct file *file,
Mike Marshall5db11c22015-07-17 10:38:12 -0400937 struct poll_table_struct *poll_table)
938{
939 int poll_revent_mask = 0;
940
Al Viro83595db2016-01-19 12:03:05 -0500941 poll_wait(file, &orangefs_request_list_waitq, poll_table);
Mike Marshall5db11c22015-07-17 10:38:12 -0400942
Al Viro83595db2016-01-19 12:03:05 -0500943 if (!list_empty(&orangefs_request_list))
944 poll_revent_mask |= POLL_IN;
Mike Marshall5db11c22015-07-17 10:38:12 -0400945 return poll_revent_mask;
946}
947
Yi Liu8bb8aef2015-11-24 15:12:14 -0500948const struct file_operations orangefs_devreq_file_operations = {
Mike Marshall5db11c22015-07-17 10:38:12 -0400949 .owner = THIS_MODULE,
Yi Liu8bb8aef2015-11-24 15:12:14 -0500950 .read = orangefs_devreq_read,
951 .write_iter = orangefs_devreq_write_iter,
952 .open = orangefs_devreq_open,
953 .release = orangefs_devreq_release,
954 .unlocked_ioctl = orangefs_devreq_ioctl,
Mike Marshall5db11c22015-07-17 10:38:12 -0400955
956#ifdef CONFIG_COMPAT /* CONFIG_COMPAT is in .config */
Yi Liu8bb8aef2015-11-24 15:12:14 -0500957 .compat_ioctl = orangefs_devreq_compat_ioctl,
Mike Marshall5db11c22015-07-17 10:38:12 -0400958#endif
Yi Liu8bb8aef2015-11-24 15:12:14 -0500959 .poll = orangefs_devreq_poll
Mike Marshall5db11c22015-07-17 10:38:12 -0400960};