Merge tag 'armsoc-arm64' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[cascardo/linux.git] / fs / orangefs / devorangefs-req.c
1 /*
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"
11 #include "orangefs-kernel.h"
12 #include "orangefs-dev-proto.h"
13 #include "orangefs-bufmap.h"
14
15 #include <linux/debugfs.h>
16 #include <linux/slab.h>
17
18 /* this file implements the /dev/pvfs2-req device node */
19
20 static int open_access_count;
21
22 #define DUMP_DEVICE_ERROR()                                                   \
23 do {                                                                          \
24         gossip_err("*****************************************************\n");\
25         gossip_err("ORANGEFS Device Error:  You cannot open the device file ");  \
26         gossip_err("\n/dev/%s more than once.  Please make sure that\nthere " \
27                    "are no ", ORANGEFS_REQDEVICE_NAME);                          \
28         gossip_err("instances of a program using this device\ncurrently "     \
29                    "running. (You must verify this!)\n");                     \
30         gossip_err("For example, you can use the lsof program as follows:\n");\
31         gossip_err("'lsof | grep %s' (run this as root)\n",                   \
32                    ORANGEFS_REQDEVICE_NAME);                                     \
33         gossip_err("  open_access_count = %d\n", open_access_count);          \
34         gossip_err("*****************************************************\n");\
35 } while (0)
36
37 static int hash_func(__u64 tag, int table_size)
38 {
39         return do_div(tag, (unsigned int)table_size);
40 }
41
42 static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op)
43 {
44         int index = hash_func(op->tag, hash_table_size);
45
46         list_add_tail(&op->list, &htable_ops_in_progress[index]);
47 }
48
49 /*
50  * find the op with this tag and remove it from the in progress
51  * hash table.
52  */
53 static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag)
54 {
55         struct orangefs_kernel_op_s *op, *next;
56         int index;
57
58         index = hash_func(tag, hash_table_size);
59
60         spin_lock(&htable_ops_in_progress_lock);
61         list_for_each_entry_safe(op,
62                                  next,
63                                  &htable_ops_in_progress[index],
64                                  list) {
65                 if (op->tag == tag && !op_state_purged(op) &&
66                     !op_state_given_up(op)) {
67                         list_del_init(&op->list);
68                         spin_unlock(&htable_ops_in_progress_lock);
69                         return op;
70                 }
71         }
72
73         spin_unlock(&htable_ops_in_progress_lock);
74         return NULL;
75 }
76
77 /* Returns whether any FS are still pending remounted */
78 static int mark_all_pending_mounts(void)
79 {
80         int unmounted = 1;
81         struct orangefs_sb_info_s *orangefs_sb = NULL;
82
83         spin_lock(&orangefs_superblocks_lock);
84         list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
85                 /* All of these file system require a remount */
86                 orangefs_sb->mount_pending = 1;
87                 unmounted = 0;
88         }
89         spin_unlock(&orangefs_superblocks_lock);
90         return unmounted;
91 }
92
93 /*
94  * Determine if a given file system needs to be remounted or not
95  *  Returns -1 on error
96  *           0 if already mounted
97  *           1 if needs remount
98  */
99 static int fs_mount_pending(__s32 fsid)
100 {
101         int mount_pending = -1;
102         struct orangefs_sb_info_s *orangefs_sb = NULL;
103
104         spin_lock(&orangefs_superblocks_lock);
105         list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
106                 if (orangefs_sb->fs_id == fsid) {
107                         mount_pending = orangefs_sb->mount_pending;
108                         break;
109                 }
110         }
111         spin_unlock(&orangefs_superblocks_lock);
112         return mount_pending;
113 }
114
115 static int orangefs_devreq_open(struct inode *inode, struct file *file)
116 {
117         int ret = -EINVAL;
118
119         /* in order to ensure that the filesystem driver sees correct UIDs */
120         if (file->f_cred->user_ns != &init_user_ns) {
121                 gossip_err("%s: device cannot be opened outside init_user_ns\n",
122                            __func__);
123                 goto out;
124         }
125
126         if (!(file->f_flags & O_NONBLOCK)) {
127                 gossip_err("%s: device cannot be opened in blocking mode\n",
128                            __func__);
129                 goto out;
130         }
131         ret = -EACCES;
132         gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n");
133         mutex_lock(&devreq_mutex);
134
135         if (open_access_count == 0) {
136                 open_access_count = 1;
137                 ret = 0;
138         } else {
139                 DUMP_DEVICE_ERROR();
140         }
141         mutex_unlock(&devreq_mutex);
142
143 out:
144
145         gossip_debug(GOSSIP_DEV_DEBUG,
146                      "pvfs2-client-core: open device complete (ret = %d)\n",
147                      ret);
148         return ret;
149 }
150
151 /* Function for read() callers into the device */
152 static ssize_t orangefs_devreq_read(struct file *file,
153                                  char __user *buf,
154                                  size_t count, loff_t *offset)
155 {
156         struct orangefs_kernel_op_s *op, *temp;
157         __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION;
158         static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
159         struct orangefs_kernel_op_s *cur_op = NULL;
160         unsigned long ret;
161
162         /* We do not support blocking IO. */
163         if (!(file->f_flags & O_NONBLOCK)) {
164                 gossip_err("%s: blocking read from client-core.\n",
165                            __func__);
166                 return -EINVAL;
167         }
168
169         /*
170          * The client will do an ioctl to find MAX_DEV_REQ_UPSIZE, then
171          * always read with that size buffer.
172          */
173         if (count != MAX_DEV_REQ_UPSIZE) {
174                 gossip_err("orangefs: client-core tried to read wrong size\n");
175                 return -EINVAL;
176         }
177
178 restart:
179         /* Get next op (if any) from top of list. */
180         spin_lock(&orangefs_request_list_lock);
181         list_for_each_entry_safe(op, temp, &orangefs_request_list, list) {
182                 __s32 fsid;
183                 /* This lock is held past the end of the loop when we break. */
184                 spin_lock(&op->lock);
185                 if (unlikely(op_state_purged(op) || op_state_given_up(op))) {
186                         spin_unlock(&op->lock);
187                         continue;
188                 }
189
190                 fsid = fsid_of_op(op);
191                 if (fsid != ORANGEFS_FS_ID_NULL) {
192                         int ret;
193                         /* Skip ops whose filesystem needs to be mounted. */
194                         ret = fs_mount_pending(fsid);
195                         if (ret == 1) {
196                                 gossip_debug(GOSSIP_DEV_DEBUG,
197                                     "%s: mount pending, skipping op tag "
198                                     "%llu %s\n",
199                                     __func__,
200                                     llu(op->tag),
201                                     get_opname_string(op));
202                                 spin_unlock(&op->lock);
203                                 continue;
204                         /*
205                          * Skip ops whose filesystem we don't know about unless
206                          * it is being mounted.
207                          */
208                         /* XXX: is there a better way to detect this? */
209                         } else if (ret == -1 &&
210                                    !(op->upcall.type ==
211                                         ORANGEFS_VFS_OP_FS_MOUNT ||
212                                      op->upcall.type ==
213                                         ORANGEFS_VFS_OP_GETATTR)) {
214                                 gossip_debug(GOSSIP_DEV_DEBUG,
215                                     "orangefs: skipping op tag %llu %s\n",
216                                     llu(op->tag), get_opname_string(op));
217                                 gossip_err(
218                                     "orangefs: ERROR: fs_mount_pending %d\n",
219                                     fsid);
220                                 spin_unlock(&op->lock);
221                                 continue;
222                         }
223                 }
224                 /*
225                  * Either this op does not pertain to a filesystem, is mounting
226                  * a filesystem, or pertains to a mounted filesystem. Let it
227                  * through.
228                  */
229                 cur_op = op;
230                 break;
231         }
232
233         /*
234          * At this point we either have a valid op and can continue or have not
235          * found an op and must ask the client to try again later.
236          */
237         if (!cur_op) {
238                 spin_unlock(&orangefs_request_list_lock);
239                 return -EAGAIN;
240         }
241
242         gossip_debug(GOSSIP_DEV_DEBUG, "%s: reading op tag %llu %s\n",
243                      __func__,
244                      llu(cur_op->tag),
245                      get_opname_string(cur_op));
246
247         /*
248          * Such an op should never be on the list in the first place. If so, we
249          * will abort.
250          */
251         if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
252                 gossip_err("orangefs: ERROR: Current op already queued.\n");
253                 list_del_init(&cur_op->list);
254                 spin_unlock(&cur_op->lock);
255                 spin_unlock(&orangefs_request_list_lock);
256                 return -EAGAIN;
257         }
258
259         list_del_init(&cur_op->list);
260         spin_unlock(&orangefs_request_list_lock);
261
262         spin_unlock(&cur_op->lock);
263
264         /* Push the upcall out. */
265         ret = copy_to_user(buf, &proto_ver, sizeof(__s32));
266         if (ret != 0)
267                 goto error;
268         ret = copy_to_user(buf+sizeof(__s32), &magic, sizeof(__s32));
269         if (ret != 0)
270                 goto error;
271         ret = copy_to_user(buf+2 * sizeof(__s32), &cur_op->tag, sizeof(__u64));
272         if (ret != 0)
273                 goto error;
274         ret = copy_to_user(buf+2*sizeof(__s32)+sizeof(__u64), &cur_op->upcall,
275                            sizeof(struct orangefs_upcall_s));
276         if (ret != 0)
277                 goto error;
278
279         spin_lock(&htable_ops_in_progress_lock);
280         spin_lock(&cur_op->lock);
281         if (unlikely(op_state_given_up(cur_op))) {
282                 spin_unlock(&cur_op->lock);
283                 spin_unlock(&htable_ops_in_progress_lock);
284                 complete(&cur_op->waitq);
285                 goto restart;
286         }
287
288         /*
289          * Set the operation to be in progress and move it between lists since
290          * it has been sent to the client.
291          */
292         set_op_state_inprogress(cur_op);
293         gossip_debug(GOSSIP_DEV_DEBUG,
294                      "%s: 1 op:%s: op_state:%d: process:%s:\n",
295                      __func__,
296                      get_opname_string(cur_op),
297                      cur_op->op_state,
298                      current->comm);
299         orangefs_devreq_add_op(cur_op);
300         spin_unlock(&cur_op->lock);
301         spin_unlock(&htable_ops_in_progress_lock);
302
303         /* The client only asks to read one size buffer. */
304         return MAX_DEV_REQ_UPSIZE;
305 error:
306         /*
307          * We were unable to copy the op data to the client. Put the op back in
308          * list. If client has crashed, the op will be purged later when the
309          * device is released.
310          */
311         gossip_err("orangefs: Failed to copy data to user space\n");
312         spin_lock(&orangefs_request_list_lock);
313         spin_lock(&cur_op->lock);
314         if (likely(!op_state_given_up(cur_op))) {
315                 set_op_state_waiting(cur_op);
316                 gossip_debug(GOSSIP_DEV_DEBUG,
317                              "%s: 2 op:%s: op_state:%d: process:%s:\n",
318                              __func__,
319                              get_opname_string(cur_op),
320                              cur_op->op_state,
321                              current->comm);
322                 list_add(&cur_op->list, &orangefs_request_list);
323                 spin_unlock(&cur_op->lock);
324         } else {
325                 spin_unlock(&cur_op->lock);
326                 complete(&cur_op->waitq);
327         }
328         spin_unlock(&orangefs_request_list_lock);
329         return -EFAULT;
330 }
331
332 /*
333  * Function for writev() callers into the device.
334  *
335  * Userspace should have written:
336  *  - __u32 version
337  *  - __u32 magic
338  *  - __u64 tag
339  *  - struct orangefs_downcall_s
340  *  - trailer buffer (in the case of READDIR operations)
341  */
342 static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
343                                       struct iov_iter *iter)
344 {
345         ssize_t ret;
346         struct orangefs_kernel_op_s *op = NULL;
347         struct {
348                 __u32 version;
349                 __u32 magic;
350                 __u64 tag;
351         } head;
352         int total = ret = iov_iter_count(iter);
353         int n;
354         int downcall_size = sizeof(struct orangefs_downcall_s);
355         int head_size = sizeof(head);
356
357         gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n",
358                      __func__,
359                      total,
360                      ret);
361
362         if (total < MAX_DEV_REQ_DOWNSIZE) {
363                 gossip_err("%s: total:%d: must be at least:%u:\n",
364                            __func__,
365                            total,
366                            (unsigned int) MAX_DEV_REQ_DOWNSIZE);
367                 return -EFAULT;
368         }
369      
370         n = copy_from_iter(&head, head_size, iter);
371         if (n < head_size) {
372                 gossip_err("%s: failed to copy head.\n", __func__);
373                 return -EFAULT;
374         }
375
376         if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) {
377                 gossip_err("%s: userspace claims version"
378                            "%d, minimum version required: %d.\n",
379                            __func__,
380                            head.version,
381                            ORANGEFS_MINIMUM_USERSPACE_VERSION);
382                 return -EPROTO;
383         }
384
385         if (head.magic != ORANGEFS_DEVREQ_MAGIC) {
386                 gossip_err("Error: Device magic number does not match.\n");
387                 return -EPROTO;
388         }
389
390         /* remove the op from the in progress hash table */
391         op = orangefs_devreq_remove_op(head.tag);
392         if (!op) {
393                 gossip_err("WARNING: No one's waiting for tag %llu\n",
394                            llu(head.tag));
395                 return ret;
396         }
397
398         n = copy_from_iter(&op->downcall, downcall_size, iter);
399         if (n != downcall_size) {
400                 gossip_err("%s: failed to copy downcall.\n", __func__);
401                 goto Efault;
402         }
403
404         if (op->downcall.status)
405                 goto wakeup;
406
407         /*
408          * We've successfully peeled off the head and the downcall. 
409          * Something has gone awry if total doesn't equal the
410          * sum of head_size, downcall_size and trailer_size.
411          */
412         if ((head_size + downcall_size + op->downcall.trailer_size) != total) {
413                 gossip_err("%s: funky write, head_size:%d"
414                            ": downcall_size:%d: trailer_size:%lld"
415                            ": total size:%d:\n",
416                            __func__,
417                            head_size,
418                            downcall_size,
419                            op->downcall.trailer_size,
420                            total);
421                 goto Efault;
422         }
423
424         /* Only READDIR operations should have trailers. */
425         if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) &&
426             (op->downcall.trailer_size != 0)) {
427                 gossip_err("%s: %x operation with trailer.",
428                            __func__,
429                            op->downcall.type);
430                 goto Efault;
431         }
432
433         /* READDIR operations should always have trailers. */
434         if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) &&
435             (op->downcall.trailer_size == 0)) {
436                 gossip_err("%s: %x operation with no trailer.",
437                            __func__,
438                            op->downcall.type);
439                 goto Efault;
440         }
441
442         if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
443                 goto wakeup;
444
445         op->downcall.trailer_buf =
446                 vmalloc(op->downcall.trailer_size);
447         if (op->downcall.trailer_buf == NULL) {
448                 gossip_err("%s: failed trailer vmalloc.\n",
449                            __func__);
450                 goto Enomem;
451         }
452         memset(op->downcall.trailer_buf, 0, op->downcall.trailer_size);
453         n = copy_from_iter(op->downcall.trailer_buf,
454                            op->downcall.trailer_size,
455                            iter);
456         if (n != op->downcall.trailer_size) {
457                 gossip_err("%s: failed to copy trailer.\n", __func__);
458                 vfree(op->downcall.trailer_buf);
459                 goto Efault;
460         }
461
462 wakeup:
463         /*
464          * Return to vfs waitqueue, and back to service_operation
465          * through wait_for_matching_downcall. 
466          */
467         spin_lock(&op->lock);
468         if (unlikely(op_is_cancel(op))) {
469                 spin_unlock(&op->lock);
470                 put_cancel(op);
471         } else if (unlikely(op_state_given_up(op))) {
472                 spin_unlock(&op->lock);
473                 complete(&op->waitq);
474         } else {
475                 set_op_state_serviced(op);
476                 gossip_debug(GOSSIP_DEV_DEBUG,
477                              "%s: op:%s: op_state:%d: process:%s:\n",
478                              __func__,
479                              get_opname_string(op),
480                              op->op_state,
481                              current->comm);
482                 spin_unlock(&op->lock);
483         }
484         return ret;
485
486 Efault:
487         op->downcall.status = -(ORANGEFS_ERROR_BIT | 9);
488         ret = -EFAULT;
489         goto wakeup;
490
491 Enomem:
492         op->downcall.status = -(ORANGEFS_ERROR_BIT | 8);
493         ret = -ENOMEM;
494         goto wakeup;
495 }
496
497 /*
498  * NOTE: gets called when the last reference to this device is dropped.
499  * Using the open_access_count variable, we enforce a reference count
500  * on this file so that it can be opened by only one process at a time.
501  * the devreq_mutex is used to make sure all i/o has completed
502  * before we call orangefs_bufmap_finalize, and similar such tricky
503  * situations
504  */
505 static int orangefs_devreq_release(struct inode *inode, struct file *file)
506 {
507         int unmounted = 0;
508
509         gossip_debug(GOSSIP_DEV_DEBUG,
510                      "%s:pvfs2-client-core: exiting, closing device\n",
511                      __func__);
512
513         mutex_lock(&devreq_mutex);
514         orangefs_bufmap_finalize();
515
516         open_access_count = -1;
517
518         unmounted = mark_all_pending_mounts();
519         gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n",
520                      (unmounted ? "UNMOUNTED" : "MOUNTED"));
521
522         purge_waiting_ops();
523         purge_inprogress_ops();
524
525         orangefs_bufmap_run_down();
526
527         gossip_debug(GOSSIP_DEV_DEBUG,
528                      "pvfs2-client-core: device close complete\n");
529         open_access_count = 0;
530         mutex_unlock(&devreq_mutex);
531         return 0;
532 }
533
534 int is_daemon_in_service(void)
535 {
536         int in_service;
537
538         /*
539          * What this function does is checks if client-core is alive
540          * based on the access count we maintain on the device.
541          */
542         mutex_lock(&devreq_mutex);
543         in_service = open_access_count == 1 ? 0 : -EIO;
544         mutex_unlock(&devreq_mutex);
545         return in_service;
546 }
547
548 bool __is_daemon_in_service(void)
549 {
550         return open_access_count == 1;
551 }
552
553 static inline long check_ioctl_command(unsigned int command)
554 {
555         /* Check for valid ioctl codes */
556         if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) {
557                 gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
558                         command,
559                         _IOC_TYPE(command),
560                         ORANGEFS_DEV_MAGIC);
561                 return -EINVAL;
562         }
563         /* and valid ioctl commands */
564         if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
565                 gossip_err("Invalid ioctl command number [%d >= %d]\n",
566                            _IOC_NR(command), ORANGEFS_DEV_MAXNR);
567                 return -ENOIOCTLCMD;
568         }
569         return 0;
570 }
571
572 static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
573 {
574         static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
575         static __s32 max_up_size = MAX_DEV_REQ_UPSIZE;
576         static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE;
577         struct ORANGEFS_dev_map_desc user_desc;
578         int ret = 0;
579         struct dev_mask_info_s mask_info = { 0 };
580         struct dev_mask2_info_s mask2_info = { 0, 0 };
581         int upstream_kmod = 1;
582         struct orangefs_sb_info_s *orangefs_sb;
583
584         /* mtmoore: add locking here */
585
586         switch (command) {
587         case ORANGEFS_DEV_GET_MAGIC:
588                 return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
589                         -EIO :
590                         0);
591         case ORANGEFS_DEV_GET_MAX_UPSIZE:
592                 return ((put_user(max_up_size,
593                                   (__s32 __user *) arg) == -EFAULT) ?
594                                         -EIO :
595                                         0);
596         case ORANGEFS_DEV_GET_MAX_DOWNSIZE:
597                 return ((put_user(max_down_size,
598                                   (__s32 __user *) arg) == -EFAULT) ?
599                                         -EIO :
600                                         0);
601         case ORANGEFS_DEV_MAP:
602                 ret = copy_from_user(&user_desc,
603                                      (struct ORANGEFS_dev_map_desc __user *)
604                                      arg,
605                                      sizeof(struct ORANGEFS_dev_map_desc));
606                 /* WTF -EIO and not -EFAULT? */
607                 return ret ? -EIO : orangefs_bufmap_initialize(&user_desc);
608         case ORANGEFS_DEV_REMOUNT_ALL:
609                 gossip_debug(GOSSIP_DEV_DEBUG,
610                              "%s: got ORANGEFS_DEV_REMOUNT_ALL\n",
611                              __func__);
612
613                 /*
614                  * remount all mounted orangefs volumes to regain the lost
615                  * dynamic mount tables (if any) -- NOTE: this is done
616                  * without keeping the superblock list locked due to the
617                  * upcall/downcall waiting.  also, the request mutex is
618                  * used to ensure that no operations will be serviced until
619                  * all of the remounts are serviced (to avoid ops between
620                  * mounts to fail)
621                  */
622                 ret = mutex_lock_interruptible(&request_mutex);
623                 if (ret < 0)
624                         return ret;
625                 gossip_debug(GOSSIP_DEV_DEBUG,
626                              "%s: priority remount in progress\n",
627                              __func__);
628                 spin_lock(&orangefs_superblocks_lock);
629                 list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
630                         /*
631                          * We have to drop the spinlock, so entries can be
632                          * removed.  They can't be freed, though, so we just
633                          * keep the forward pointers and zero the back ones -
634                          * that way we can get to the rest of the list.
635                          */
636                         if (!orangefs_sb->list.prev)
637                                 continue;
638                         gossip_debug(GOSSIP_DEV_DEBUG,
639                                      "%s: Remounting SB %p\n",
640                                      __func__,
641                                      orangefs_sb);
642
643                         spin_unlock(&orangefs_superblocks_lock);
644                         ret = orangefs_remount(orangefs_sb);
645                         spin_lock(&orangefs_superblocks_lock);
646                         if (ret) {
647                                 gossip_debug(GOSSIP_DEV_DEBUG,
648                                              "SB %p remount failed\n",
649                                              orangefs_sb);
650                                 break;
651                         }
652                 }
653                 spin_unlock(&orangefs_superblocks_lock);
654                 gossip_debug(GOSSIP_DEV_DEBUG,
655                              "%s: priority remount complete\n",
656                              __func__);
657                 mutex_unlock(&request_mutex);
658                 return ret;
659
660         case ORANGEFS_DEV_UPSTREAM:
661                 ret = copy_to_user((void __user *)arg,
662                                     &upstream_kmod,
663                                     sizeof(upstream_kmod));
664
665                 if (ret != 0)
666                         return -EIO;
667                 else
668                         return ret;
669
670         case ORANGEFS_DEV_CLIENT_MASK:
671                 ret = copy_from_user(&mask2_info,
672                                      (void __user *)arg,
673                                      sizeof(struct dev_mask2_info_s));
674
675                 if (ret != 0)
676                         return -EIO;
677
678                 client_debug_mask.mask1 = mask2_info.mask1_value;
679                 client_debug_mask.mask2 = mask2_info.mask2_value;
680
681                 pr_info("%s: client debug mask has been been received "
682                         ":%llx: :%llx:\n",
683                         __func__,
684                         (unsigned long long)client_debug_mask.mask1,
685                         (unsigned long long)client_debug_mask.mask2);
686
687                 return ret;
688
689         case ORANGEFS_DEV_CLIENT_STRING:
690                 ret = copy_from_user(&client_debug_array_string,
691                                      (void __user *)arg,
692                                      ORANGEFS_MAX_DEBUG_STRING_LEN);
693                 /*
694                  * The real client-core makes an effort to ensure
695                  * that actual strings that aren't too long to fit in
696                  * this buffer is what we get here. We're going to use
697                  * string functions on the stuff we got, so we'll make
698                  * this extra effort to try and keep from
699                  * flowing out of this buffer when we use the string
700                  * functions, even if somehow the stuff we end up
701                  * with here is garbage.
702                  */
703                 client_debug_array_string[ORANGEFS_MAX_DEBUG_STRING_LEN - 1] =
704                         '\0';
705                 
706                 if (ret != 0) {
707                         pr_info("%s: CLIENT_STRING: copy_from_user failed\n",
708                                 __func__);
709                         return -EIO;
710                 }
711
712                 pr_info("%s: client debug array string has been received.\n",
713                         __func__);
714
715                 if (!help_string_initialized) {
716
717                         /* Free the "we don't know yet" default string... */
718                         kfree(debug_help_string);
719
720                         /* build a proper debug help string */
721                         if (orangefs_prepare_debugfs_help_string(0)) {
722                                 gossip_err("%s: no debug help string \n",
723                                            __func__);
724                                 return -EIO;
725                         }
726
727                         /* Replace the boilerplate boot-time debug-help file. */
728                         debugfs_remove(help_file_dentry);
729
730                         help_file_dentry =
731                                 debugfs_create_file(
732                                         ORANGEFS_KMOD_DEBUG_HELP_FILE,
733                                         0444,
734                                         debug_dir,
735                                         debug_help_string,
736                                         &debug_help_fops);
737
738                         if (!help_file_dentry) {
739                                 gossip_err("%s: debugfs_create_file failed for"
740                                            " :%s:!\n",
741                                            __func__,
742                                            ORANGEFS_KMOD_DEBUG_HELP_FILE);
743                                 return -EIO;
744                         }
745                 }
746
747                 debug_mask_to_string(&client_debug_mask, 1);
748
749                 debugfs_remove(client_debug_dentry);
750
751                 orangefs_client_debug_init();
752
753                 help_string_initialized++;
754
755                 return ret;
756
757         case ORANGEFS_DEV_DEBUG:
758                 ret = copy_from_user(&mask_info,
759                                      (void __user *)arg,
760                                      sizeof(mask_info));
761
762                 if (ret != 0)
763                         return -EIO;
764
765                 if (mask_info.mask_type == KERNEL_MASK) {
766                         if ((mask_info.mask_value == 0)
767                             && (kernel_mask_set_mod_init)) {
768                                 /*
769                                  * the kernel debug mask was set when the
770                                  * kernel module was loaded; don't override
771                                  * it if the client-core was started without
772                                  * a value for ORANGEFS_KMODMASK.
773                                  */
774                                 return 0;
775                         }
776                         debug_mask_to_string(&mask_info.mask_value,
777                                              mask_info.mask_type);
778                         gossip_debug_mask = mask_info.mask_value;
779                         pr_info("%s: kernel debug mask has been modified to "
780                                 ":%s: :%llx:\n",
781                                 __func__,
782                                 kernel_debug_string,
783                                 (unsigned long long)gossip_debug_mask);
784                 } else if (mask_info.mask_type == CLIENT_MASK) {
785                         debug_mask_to_string(&mask_info.mask_value,
786                                              mask_info.mask_type);
787                         pr_info("%s: client debug mask has been modified to"
788                                 ":%s: :%llx:\n",
789                                 __func__,
790                                 client_debug_string,
791                                 llu(mask_info.mask_value));
792                 } else {
793                         gossip_lerr("Invalid mask type....\n");
794                         return -EINVAL;
795                 }
796
797                 return ret;
798
799         default:
800                 return -ENOIOCTLCMD;
801         }
802         return -ENOIOCTLCMD;
803 }
804
805 static long orangefs_devreq_ioctl(struct file *file,
806                                unsigned int command, unsigned long arg)
807 {
808         long ret;
809
810         /* Check for properly constructed commands */
811         ret = check_ioctl_command(command);
812         if (ret < 0)
813                 return (int)ret;
814
815         return (int)dispatch_ioctl_command(command, arg);
816 }
817
818 #ifdef CONFIG_COMPAT            /* CONFIG_COMPAT is in .config */
819
820 /*  Compat structure for the ORANGEFS_DEV_MAP ioctl */
821 struct ORANGEFS_dev_map_desc32 {
822         compat_uptr_t ptr;
823         __s32 total_size;
824         __s32 size;
825         __s32 count;
826 };
827
828 static unsigned long translate_dev_map26(unsigned long args, long *error)
829 {
830         struct ORANGEFS_dev_map_desc32 __user *p32 = (void __user *)args;
831         /*
832          * Depending on the architecture, allocate some space on the
833          * user-call-stack based on our expected layout.
834          */
835         struct ORANGEFS_dev_map_desc __user *p =
836             compat_alloc_user_space(sizeof(*p));
837         compat_uptr_t addr;
838
839         *error = 0;
840         /* get the ptr from the 32 bit user-space */
841         if (get_user(addr, &p32->ptr))
842                 goto err;
843         /* try to put that into a 64-bit layout */
844         if (put_user(compat_ptr(addr), &p->ptr))
845                 goto err;
846         /* copy the remaining fields */
847         if (copy_in_user(&p->total_size, &p32->total_size, sizeof(__s32)))
848                 goto err;
849         if (copy_in_user(&p->size, &p32->size, sizeof(__s32)))
850                 goto err;
851         if (copy_in_user(&p->count, &p32->count, sizeof(__s32)))
852                 goto err;
853         return (unsigned long)p;
854 err:
855         *error = -EFAULT;
856         return 0;
857 }
858
859 /*
860  * 32 bit user-space apps' ioctl handlers when kernel modules
861  * is compiled as a 64 bit one
862  */
863 static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
864                                       unsigned long args)
865 {
866         long ret;
867         unsigned long arg = args;
868
869         /* Check for properly constructed commands */
870         ret = check_ioctl_command(cmd);
871         if (ret < 0)
872                 return ret;
873         if (cmd == ORANGEFS_DEV_MAP) {
874                 /*
875                  * convert the arguments to what we expect internally
876                  * in kernel space
877                  */
878                 arg = translate_dev_map26(args, &ret);
879                 if (ret < 0) {
880                         gossip_err("Could not translate dev map\n");
881                         return ret;
882                 }
883         }
884         /* no other ioctl requires translation */
885         return dispatch_ioctl_command(cmd, arg);
886 }
887
888 #endif /* CONFIG_COMPAT is in .config */
889
890 /* the assigned character device major number */
891 static int orangefs_dev_major;
892
893 /*
894  * Initialize orangefs device specific state:
895  * Must be called at module load time only
896  */
897 int orangefs_dev_init(void)
898 {
899         /* register orangefs-req device  */
900         orangefs_dev_major = register_chrdev(0,
901                                           ORANGEFS_REQDEVICE_NAME,
902                                           &orangefs_devreq_file_operations);
903         if (orangefs_dev_major < 0) {
904                 gossip_debug(GOSSIP_DEV_DEBUG,
905                              "Failed to register /dev/%s (error %d)\n",
906                              ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
907                 return orangefs_dev_major;
908         }
909
910         gossip_debug(GOSSIP_DEV_DEBUG,
911                      "*** /dev/%s character device registered ***\n",
912                      ORANGEFS_REQDEVICE_NAME);
913         gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
914                      ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
915         return 0;
916 }
917
918 void orangefs_dev_cleanup(void)
919 {
920         unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME);
921         gossip_debug(GOSSIP_DEV_DEBUG,
922                      "*** /dev/%s character device unregistered ***\n",
923                      ORANGEFS_REQDEVICE_NAME);
924 }
925
926 static unsigned int orangefs_devreq_poll(struct file *file,
927                                       struct poll_table_struct *poll_table)
928 {
929         int poll_revent_mask = 0;
930
931         poll_wait(file, &orangefs_request_list_waitq, poll_table);
932
933         if (!list_empty(&orangefs_request_list))
934                 poll_revent_mask |= POLL_IN;
935         return poll_revent_mask;
936 }
937
938 const struct file_operations orangefs_devreq_file_operations = {
939         .owner = THIS_MODULE,
940         .read = orangefs_devreq_read,
941         .write_iter = orangefs_devreq_write_iter,
942         .open = orangefs_devreq_open,
943         .release = orangefs_devreq_release,
944         .unlocked_ioctl = orangefs_devreq_ioctl,
945
946 #ifdef CONFIG_COMPAT            /* CONFIG_COMPAT is in .config */
947         .compat_ioctl = orangefs_devreq_compat_ioctl,
948 #endif
949         .poll = orangefs_devreq_poll
950 };