Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * (C) 2001 Clemson University and The University of Chicago
0004  *
0005  * Changes by Acxiom Corporation to add protocol version to kernel
0006  * communication, Copyright Acxiom Corporation, 2005.
0007  *
0008  * See COPYING in top-level directory.
0009  */
0010 
0011 #include "protocol.h"
0012 #include "orangefs-kernel.h"
0013 #include "orangefs-dev-proto.h"
0014 #include "orangefs-bufmap.h"
0015 #include "orangefs-debugfs.h"
0016 
0017 #include <linux/debugfs.h>
0018 #include <linux/slab.h>
0019 
0020 /* this file implements the /dev/pvfs2-req device node */
0021 
0022 uint32_t orangefs_userspace_version;
0023 
0024 static int open_access_count;
0025 
0026 static DEFINE_MUTEX(devreq_mutex);
0027 
0028 #define DUMP_DEVICE_ERROR()                                                   \
0029 do {                                                                          \
0030     gossip_err("*****************************************************\n");\
0031     gossip_err("ORANGEFS Device Error:  You cannot open the device file ");  \
0032     gossip_err("\n/dev/%s more than once.  Please make sure that\nthere " \
0033            "are no ", ORANGEFS_REQDEVICE_NAME);                          \
0034     gossip_err("instances of a program using this device\ncurrently "     \
0035            "running. (You must verify this!)\n");                     \
0036     gossip_err("For example, you can use the lsof program as follows:\n");\
0037     gossip_err("'lsof | grep %s' (run this as root)\n",                   \
0038            ORANGEFS_REQDEVICE_NAME);                                     \
0039     gossip_err("  open_access_count = %d\n", open_access_count);          \
0040     gossip_err("*****************************************************\n");\
0041 } while (0)
0042 
0043 static int hash_func(__u64 tag, int table_size)
0044 {
0045     return do_div(tag, (unsigned int)table_size);
0046 }
0047 
0048 static void orangefs_devreq_add_op(struct orangefs_kernel_op_s *op)
0049 {
0050     int index = hash_func(op->tag, hash_table_size);
0051 
0052     list_add_tail(&op->list, &orangefs_htable_ops_in_progress[index]);
0053 }
0054 
0055 /*
0056  * find the op with this tag and remove it from the in progress
0057  * hash table.
0058  */
0059 static struct orangefs_kernel_op_s *orangefs_devreq_remove_op(__u64 tag)
0060 {
0061     struct orangefs_kernel_op_s *op, *next;
0062     int index;
0063 
0064     index = hash_func(tag, hash_table_size);
0065 
0066     spin_lock(&orangefs_htable_ops_in_progress_lock);
0067     list_for_each_entry_safe(op,
0068                  next,
0069                  &orangefs_htable_ops_in_progress[index],
0070                  list) {
0071         if (op->tag == tag && !op_state_purged(op) &&
0072             !op_state_given_up(op)) {
0073             list_del_init(&op->list);
0074             spin_unlock(&orangefs_htable_ops_in_progress_lock);
0075             return op;
0076         }
0077     }
0078 
0079     spin_unlock(&orangefs_htable_ops_in_progress_lock);
0080     return NULL;
0081 }
0082 
0083 /* Returns whether any FS are still pending remounted */
0084 static int mark_all_pending_mounts(void)
0085 {
0086     int unmounted = 1;
0087     struct orangefs_sb_info_s *orangefs_sb = NULL;
0088 
0089     spin_lock(&orangefs_superblocks_lock);
0090     list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
0091         /* All of these file system require a remount */
0092         orangefs_sb->mount_pending = 1;
0093         unmounted = 0;
0094     }
0095     spin_unlock(&orangefs_superblocks_lock);
0096     return unmounted;
0097 }
0098 
0099 /*
0100  * Determine if a given file system needs to be remounted or not
0101  *  Returns -1 on error
0102  *           0 if already mounted
0103  *           1 if needs remount
0104  */
0105 static int fs_mount_pending(__s32 fsid)
0106 {
0107     int mount_pending = -1;
0108     struct orangefs_sb_info_s *orangefs_sb = NULL;
0109 
0110     spin_lock(&orangefs_superblocks_lock);
0111     list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
0112         if (orangefs_sb->fs_id == fsid) {
0113             mount_pending = orangefs_sb->mount_pending;
0114             break;
0115         }
0116     }
0117     spin_unlock(&orangefs_superblocks_lock);
0118     return mount_pending;
0119 }
0120 
0121 static int orangefs_devreq_open(struct inode *inode, struct file *file)
0122 {
0123     int ret = -EINVAL;
0124 
0125     /* in order to ensure that the filesystem driver sees correct UIDs */
0126     if (file->f_cred->user_ns != &init_user_ns) {
0127         gossip_err("%s: device cannot be opened outside init_user_ns\n",
0128                __func__);
0129         goto out;
0130     }
0131 
0132     if (!(file->f_flags & O_NONBLOCK)) {
0133         gossip_err("%s: device cannot be opened in blocking mode\n",
0134                __func__);
0135         goto out;
0136     }
0137     ret = -EACCES;
0138     gossip_debug(GOSSIP_DEV_DEBUG, "client-core: opening device\n");
0139     mutex_lock(&devreq_mutex);
0140 
0141     if (open_access_count == 0) {
0142         open_access_count = 1;
0143         ret = 0;
0144     } else {
0145         DUMP_DEVICE_ERROR();
0146     }
0147     mutex_unlock(&devreq_mutex);
0148 
0149 out:
0150 
0151     gossip_debug(GOSSIP_DEV_DEBUG,
0152              "pvfs2-client-core: open device complete (ret = %d)\n",
0153              ret);
0154     return ret;
0155 }
0156 
0157 /* Function for read() callers into the device */
0158 static ssize_t orangefs_devreq_read(struct file *file,
0159                  char __user *buf,
0160                  size_t count, loff_t *offset)
0161 {
0162     struct orangefs_kernel_op_s *op, *temp;
0163     __s32 proto_ver = ORANGEFS_KERNEL_PROTO_VERSION;
0164     static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
0165     struct orangefs_kernel_op_s *cur_op;
0166     unsigned long ret;
0167 
0168     /* We do not support blocking IO. */
0169     if (!(file->f_flags & O_NONBLOCK)) {
0170         gossip_err("%s: blocking read from client-core.\n",
0171                __func__);
0172         return -EINVAL;
0173     }
0174 
0175     /*
0176      * The client will do an ioctl to find MAX_DEV_REQ_UPSIZE, then
0177      * always read with that size buffer.
0178      */
0179     if (count != MAX_DEV_REQ_UPSIZE) {
0180         gossip_err("orangefs: client-core tried to read wrong size\n");
0181         return -EINVAL;
0182     }
0183 
0184     /* Check for an empty list before locking. */
0185     if (list_empty(&orangefs_request_list))
0186         return -EAGAIN;
0187 
0188 restart:
0189     cur_op = NULL;
0190     /* Get next op (if any) from top of list. */
0191     spin_lock(&orangefs_request_list_lock);
0192     list_for_each_entry_safe(op, temp, &orangefs_request_list, list) {
0193         __s32 fsid;
0194         /* This lock is held past the end of the loop when we break. */
0195         spin_lock(&op->lock);
0196         if (unlikely(op_state_purged(op) || op_state_given_up(op))) {
0197             spin_unlock(&op->lock);
0198             continue;
0199         }
0200 
0201         fsid = fsid_of_op(op);
0202         if (fsid != ORANGEFS_FS_ID_NULL) {
0203             int ret;
0204             /* Skip ops whose filesystem needs to be mounted. */
0205             ret = fs_mount_pending(fsid);
0206             if (ret == 1) {
0207                 gossip_debug(GOSSIP_DEV_DEBUG,
0208                     "%s: mount pending, skipping op tag "
0209                     "%llu %s\n",
0210                     __func__,
0211                     llu(op->tag),
0212                     get_opname_string(op));
0213                 spin_unlock(&op->lock);
0214                 continue;
0215             /*
0216              * Skip ops whose filesystem we don't know about unless
0217              * it is being mounted or unmounted.  It is possible for
0218              * a filesystem we don't know about to be unmounted if
0219              * it fails to mount in the kernel after userspace has
0220              * been sent the mount request.
0221              */
0222             /* XXX: is there a better way to detect this? */
0223             } else if (ret == -1 &&
0224                    !(op->upcall.type ==
0225                     ORANGEFS_VFS_OP_FS_MOUNT ||
0226                      op->upcall.type ==
0227                     ORANGEFS_VFS_OP_GETATTR ||
0228                      op->upcall.type ==
0229                     ORANGEFS_VFS_OP_FS_UMOUNT)) {
0230                 gossip_debug(GOSSIP_DEV_DEBUG,
0231                     "orangefs: skipping op tag %llu %s\n",
0232                     llu(op->tag), get_opname_string(op));
0233                 gossip_err(
0234                     "orangefs: ERROR: fs_mount_pending %d\n",
0235                     fsid);
0236                 spin_unlock(&op->lock);
0237                 continue;
0238             }
0239         }
0240         /*
0241          * Either this op does not pertain to a filesystem, is mounting
0242          * a filesystem, or pertains to a mounted filesystem. Let it
0243          * through.
0244          */
0245         cur_op = op;
0246         break;
0247     }
0248 
0249     /*
0250      * At this point we either have a valid op and can continue or have not
0251      * found an op and must ask the client to try again later.
0252      */
0253     if (!cur_op) {
0254         spin_unlock(&orangefs_request_list_lock);
0255         return -EAGAIN;
0256     }
0257 
0258     gossip_debug(GOSSIP_DEV_DEBUG, "%s: reading op tag %llu %s\n",
0259              __func__,
0260              llu(cur_op->tag),
0261              get_opname_string(cur_op));
0262 
0263     /*
0264      * Such an op should never be on the list in the first place. If so, we
0265      * will abort.
0266      */
0267     if (op_state_in_progress(cur_op) || op_state_serviced(cur_op)) {
0268         gossip_err("orangefs: ERROR: Current op already queued.\n");
0269         list_del_init(&cur_op->list);
0270         spin_unlock(&cur_op->lock);
0271         spin_unlock(&orangefs_request_list_lock);
0272         return -EAGAIN;
0273     }
0274 
0275     list_del_init(&cur_op->list);
0276     spin_unlock(&orangefs_request_list_lock);
0277 
0278     spin_unlock(&cur_op->lock);
0279 
0280     /* Push the upcall out. */
0281     ret = copy_to_user(buf, &proto_ver, sizeof(__s32));
0282     if (ret != 0)
0283         goto error;
0284     ret = copy_to_user(buf + sizeof(__s32), &magic, sizeof(__s32));
0285     if (ret != 0)
0286         goto error;
0287     ret = copy_to_user(buf + 2 * sizeof(__s32),
0288         &cur_op->tag,
0289         sizeof(__u64));
0290     if (ret != 0)
0291         goto error;
0292     ret = copy_to_user(buf + 2 * sizeof(__s32) + sizeof(__u64),
0293         &cur_op->upcall,
0294         sizeof(struct orangefs_upcall_s));
0295     if (ret != 0)
0296         goto error;
0297 
0298     spin_lock(&orangefs_htable_ops_in_progress_lock);
0299     spin_lock(&cur_op->lock);
0300     if (unlikely(op_state_given_up(cur_op))) {
0301         spin_unlock(&cur_op->lock);
0302         spin_unlock(&orangefs_htable_ops_in_progress_lock);
0303         complete(&cur_op->waitq);
0304         goto restart;
0305     }
0306 
0307     /*
0308      * Set the operation to be in progress and move it between lists since
0309      * it has been sent to the client.
0310      */
0311     set_op_state_inprogress(cur_op);
0312     gossip_debug(GOSSIP_DEV_DEBUG,
0313              "%s: 1 op:%s: op_state:%d: process:%s:\n",
0314              __func__,
0315              get_opname_string(cur_op),
0316              cur_op->op_state,
0317              current->comm);
0318     orangefs_devreq_add_op(cur_op);
0319     spin_unlock(&cur_op->lock);
0320     spin_unlock(&orangefs_htable_ops_in_progress_lock);
0321 
0322     /* The client only asks to read one size buffer. */
0323     return MAX_DEV_REQ_UPSIZE;
0324 error:
0325     /*
0326      * We were unable to copy the op data to the client. Put the op back in
0327      * list. If client has crashed, the op will be purged later when the
0328      * device is released.
0329      */
0330     gossip_err("orangefs: Failed to copy data to user space\n");
0331     spin_lock(&orangefs_request_list_lock);
0332     spin_lock(&cur_op->lock);
0333     if (likely(!op_state_given_up(cur_op))) {
0334         set_op_state_waiting(cur_op);
0335         gossip_debug(GOSSIP_DEV_DEBUG,
0336                  "%s: 2 op:%s: op_state:%d: process:%s:\n",
0337                  __func__,
0338                  get_opname_string(cur_op),
0339                  cur_op->op_state,
0340                  current->comm);
0341         list_add(&cur_op->list, &orangefs_request_list);
0342         spin_unlock(&cur_op->lock);
0343     } else {
0344         spin_unlock(&cur_op->lock);
0345         complete(&cur_op->waitq);
0346     }
0347     spin_unlock(&orangefs_request_list_lock);
0348     return -EFAULT;
0349 }
0350 
0351 /*
0352  * Function for writev() callers into the device.
0353  *
0354  * Userspace should have written:
0355  *  - __u32 version
0356  *  - __u32 magic
0357  *  - __u64 tag
0358  *  - struct orangefs_downcall_s
0359  *  - trailer buffer (in the case of READDIR operations)
0360  */
0361 static ssize_t orangefs_devreq_write_iter(struct kiocb *iocb,
0362                       struct iov_iter *iter)
0363 {
0364     ssize_t ret;
0365     struct orangefs_kernel_op_s *op = NULL;
0366     struct {
0367         __u32 version;
0368         __u32 magic;
0369         __u64 tag;
0370     } head;
0371     int total = ret = iov_iter_count(iter);
0372     int downcall_size = sizeof(struct orangefs_downcall_s);
0373     int head_size = sizeof(head);
0374 
0375     gossip_debug(GOSSIP_DEV_DEBUG, "%s: total:%d: ret:%zd:\n",
0376              __func__,
0377              total,
0378              ret);
0379 
0380         if (total < MAX_DEV_REQ_DOWNSIZE) {
0381         gossip_err("%s: total:%d: must be at least:%u:\n",
0382                __func__,
0383                total,
0384                (unsigned int) MAX_DEV_REQ_DOWNSIZE);
0385         return -EFAULT;
0386     }
0387 
0388     if (!copy_from_iter_full(&head, head_size, iter)) {
0389         gossip_err("%s: failed to copy head.\n", __func__);
0390         return -EFAULT;
0391     }
0392 
0393     if (head.version < ORANGEFS_MINIMUM_USERSPACE_VERSION) {
0394         gossip_err("%s: userspace claims version"
0395                "%d, minimum version required: %d.\n",
0396                __func__,
0397                head.version,
0398                ORANGEFS_MINIMUM_USERSPACE_VERSION);
0399         return -EPROTO;
0400     }
0401 
0402     if (head.magic != ORANGEFS_DEVREQ_MAGIC) {
0403         gossip_err("Error: Device magic number does not match.\n");
0404         return -EPROTO;
0405     }
0406 
0407     if (!orangefs_userspace_version) {
0408         orangefs_userspace_version = head.version;
0409     } else if (orangefs_userspace_version != head.version) {
0410         gossip_err("Error: userspace version changes\n");
0411         return -EPROTO;
0412     }
0413 
0414     /* remove the op from the in progress hash table */
0415     op = orangefs_devreq_remove_op(head.tag);
0416     if (!op) {
0417         gossip_debug(GOSSIP_DEV_DEBUG,
0418                  "%s: No one's waiting for tag %llu\n",
0419                  __func__, llu(head.tag));
0420         return ret;
0421     }
0422 
0423     if (!copy_from_iter_full(&op->downcall, downcall_size, iter)) {
0424         gossip_err("%s: failed to copy downcall.\n", __func__);
0425         goto Efault;
0426     }
0427 
0428     if (op->downcall.status)
0429         goto wakeup;
0430 
0431     /*
0432      * We've successfully peeled off the head and the downcall.
0433      * Something has gone awry if total doesn't equal the
0434      * sum of head_size, downcall_size and trailer_size.
0435      */
0436     if ((head_size + downcall_size + op->downcall.trailer_size) != total) {
0437         gossip_err("%s: funky write, head_size:%d"
0438                ": downcall_size:%d: trailer_size:%lld"
0439                ": total size:%d:\n",
0440                __func__,
0441                head_size,
0442                downcall_size,
0443                op->downcall.trailer_size,
0444                total);
0445         goto Efault;
0446     }
0447 
0448     /* Only READDIR operations should have trailers. */
0449     if ((op->downcall.type != ORANGEFS_VFS_OP_READDIR) &&
0450         (op->downcall.trailer_size != 0)) {
0451         gossip_err("%s: %x operation with trailer.",
0452                __func__,
0453                op->downcall.type);
0454         goto Efault;
0455     }
0456 
0457     /* READDIR operations should always have trailers. */
0458     if ((op->downcall.type == ORANGEFS_VFS_OP_READDIR) &&
0459         (op->downcall.trailer_size == 0)) {
0460         gossip_err("%s: %x operation with no trailer.",
0461                __func__,
0462                op->downcall.type);
0463         goto Efault;
0464     }
0465 
0466     if (op->downcall.type != ORANGEFS_VFS_OP_READDIR)
0467         goto wakeup;
0468 
0469     op->downcall.trailer_buf = vzalloc(op->downcall.trailer_size);
0470     if (!op->downcall.trailer_buf)
0471         goto Enomem;
0472 
0473     if (!copy_from_iter_full(op->downcall.trailer_buf,
0474                      op->downcall.trailer_size, iter)) {
0475         gossip_err("%s: failed to copy trailer.\n", __func__);
0476         vfree(op->downcall.trailer_buf);
0477         goto Efault;
0478     }
0479 
0480 wakeup:
0481     /*
0482      * Return to vfs waitqueue, and back to service_operation
0483      * through wait_for_matching_downcall.
0484      */
0485     spin_lock(&op->lock);
0486     if (unlikely(op_is_cancel(op))) {
0487         spin_unlock(&op->lock);
0488         put_cancel(op);
0489     } else if (unlikely(op_state_given_up(op))) {
0490         spin_unlock(&op->lock);
0491         complete(&op->waitq);
0492     } else {
0493         set_op_state_serviced(op);
0494         gossip_debug(GOSSIP_DEV_DEBUG,
0495                  "%s: op:%s: op_state:%d: process:%s:\n",
0496                  __func__,
0497                  get_opname_string(op),
0498                  op->op_state,
0499                  current->comm);
0500         spin_unlock(&op->lock);
0501     }
0502     return ret;
0503 
0504 Efault:
0505     op->downcall.status = -(ORANGEFS_ERROR_BIT | 9);
0506     ret = -EFAULT;
0507     goto wakeup;
0508 
0509 Enomem:
0510     op->downcall.status = -(ORANGEFS_ERROR_BIT | 8);
0511     ret = -ENOMEM;
0512     goto wakeup;
0513 }
0514 
0515 /*
0516  * NOTE: gets called when the last reference to this device is dropped.
0517  * Using the open_access_count variable, we enforce a reference count
0518  * on this file so that it can be opened by only one process at a time.
0519  * the devreq_mutex is used to make sure all i/o has completed
0520  * before we call orangefs_bufmap_finalize, and similar such tricky
0521  * situations
0522  */
0523 static int orangefs_devreq_release(struct inode *inode, struct file *file)
0524 {
0525     int unmounted = 0;
0526 
0527     gossip_debug(GOSSIP_DEV_DEBUG,
0528              "%s:pvfs2-client-core: exiting, closing device\n",
0529              __func__);
0530 
0531     mutex_lock(&devreq_mutex);
0532     orangefs_bufmap_finalize();
0533 
0534     open_access_count = -1;
0535 
0536     unmounted = mark_all_pending_mounts();
0537     gossip_debug(GOSSIP_DEV_DEBUG, "ORANGEFS Device Close: Filesystem(s) %s\n",
0538              (unmounted ? "UNMOUNTED" : "MOUNTED"));
0539 
0540     purge_waiting_ops();
0541     purge_inprogress_ops();
0542 
0543     orangefs_bufmap_run_down();
0544 
0545     gossip_debug(GOSSIP_DEV_DEBUG,
0546              "pvfs2-client-core: device close complete\n");
0547     open_access_count = 0;
0548     orangefs_userspace_version = 0;
0549     mutex_unlock(&devreq_mutex);
0550     return 0;
0551 }
0552 
0553 int is_daemon_in_service(void)
0554 {
0555     int in_service;
0556 
0557     /*
0558      * What this function does is checks if client-core is alive
0559      * based on the access count we maintain on the device.
0560      */
0561     mutex_lock(&devreq_mutex);
0562     in_service = open_access_count == 1 ? 0 : -EIO;
0563     mutex_unlock(&devreq_mutex);
0564     return in_service;
0565 }
0566 
0567 bool __is_daemon_in_service(void)
0568 {
0569     return open_access_count == 1;
0570 }
0571 
0572 static inline long check_ioctl_command(unsigned int command)
0573 {
0574     /* Check for valid ioctl codes */
0575     if (_IOC_TYPE(command) != ORANGEFS_DEV_MAGIC) {
0576         gossip_err("device ioctl magic numbers don't match! Did you rebuild pvfs2-client-core/libpvfs2? [cmd %x, magic %x != %x]\n",
0577             command,
0578             _IOC_TYPE(command),
0579             ORANGEFS_DEV_MAGIC);
0580         return -EINVAL;
0581     }
0582     /* and valid ioctl commands */
0583     if (_IOC_NR(command) >= ORANGEFS_DEV_MAXNR || _IOC_NR(command) <= 0) {
0584         gossip_err("Invalid ioctl command number [%d >= %d]\n",
0585                _IOC_NR(command), ORANGEFS_DEV_MAXNR);
0586         return -ENOIOCTLCMD;
0587     }
0588     return 0;
0589 }
0590 
0591 static long dispatch_ioctl_command(unsigned int command, unsigned long arg)
0592 {
0593     static __s32 magic = ORANGEFS_DEVREQ_MAGIC;
0594     static __s32 max_up_size = MAX_DEV_REQ_UPSIZE;
0595     static __s32 max_down_size = MAX_DEV_REQ_DOWNSIZE;
0596     struct ORANGEFS_dev_map_desc user_desc;
0597     int ret = 0;
0598     int upstream_kmod = 1;
0599     struct orangefs_sb_info_s *orangefs_sb;
0600 
0601     /* mtmoore: add locking here */
0602 
0603     switch (command) {
0604     case ORANGEFS_DEV_GET_MAGIC:
0605         return ((put_user(magic, (__s32 __user *) arg) == -EFAULT) ?
0606             -EIO :
0607             0);
0608     case ORANGEFS_DEV_GET_MAX_UPSIZE:
0609         return ((put_user(max_up_size,
0610                   (__s32 __user *) arg) == -EFAULT) ?
0611                     -EIO :
0612                     0);
0613     case ORANGEFS_DEV_GET_MAX_DOWNSIZE:
0614         return ((put_user(max_down_size,
0615                   (__s32 __user *) arg) == -EFAULT) ?
0616                     -EIO :
0617                     0);
0618     case ORANGEFS_DEV_MAP:
0619         ret = copy_from_user(&user_desc,
0620                      (struct ORANGEFS_dev_map_desc __user *)
0621                      arg,
0622                      sizeof(struct ORANGEFS_dev_map_desc));
0623         /* WTF -EIO and not -EFAULT? */
0624         return ret ? -EIO : orangefs_bufmap_initialize(&user_desc);
0625     case ORANGEFS_DEV_REMOUNT_ALL:
0626         gossip_debug(GOSSIP_DEV_DEBUG,
0627                  "%s: got ORANGEFS_DEV_REMOUNT_ALL\n",
0628                  __func__);
0629 
0630         /*
0631          * remount all mounted orangefs volumes to regain the lost
0632          * dynamic mount tables (if any) -- NOTE: this is done
0633          * without keeping the superblock list locked due to the
0634          * upcall/downcall waiting.  also, the request mutex is
0635          * used to ensure that no operations will be serviced until
0636          * all of the remounts are serviced (to avoid ops between
0637          * mounts to fail)
0638          */
0639         ret = mutex_lock_interruptible(&orangefs_request_mutex);
0640         if (ret < 0)
0641             return ret;
0642         gossip_debug(GOSSIP_DEV_DEBUG,
0643                  "%s: priority remount in progress\n",
0644                  __func__);
0645         spin_lock(&orangefs_superblocks_lock);
0646         list_for_each_entry(orangefs_sb, &orangefs_superblocks, list) {
0647             /*
0648              * We have to drop the spinlock, so entries can be
0649              * removed.  They can't be freed, though, so we just
0650              * keep the forward pointers and zero the back ones -
0651              * that way we can get to the rest of the list.
0652              */
0653             if (!orangefs_sb->list.prev)
0654                 continue;
0655             gossip_debug(GOSSIP_DEV_DEBUG,
0656                      "%s: Remounting SB %p\n",
0657                      __func__,
0658                      orangefs_sb);
0659 
0660             spin_unlock(&orangefs_superblocks_lock);
0661             ret = orangefs_remount(orangefs_sb);
0662             spin_lock(&orangefs_superblocks_lock);
0663             if (ret) {
0664                 gossip_debug(GOSSIP_DEV_DEBUG,
0665                          "SB %p remount failed\n",
0666                          orangefs_sb);
0667                 break;
0668             }
0669         }
0670         spin_unlock(&orangefs_superblocks_lock);
0671         gossip_debug(GOSSIP_DEV_DEBUG,
0672                  "%s: priority remount complete\n",
0673                  __func__);
0674         mutex_unlock(&orangefs_request_mutex);
0675         return ret;
0676 
0677     case ORANGEFS_DEV_UPSTREAM:
0678         ret = copy_to_user((void __user *)arg,
0679                     &upstream_kmod,
0680                     sizeof(upstream_kmod));
0681 
0682         if (ret != 0)
0683             return -EIO;
0684         else
0685             return ret;
0686 
0687     case ORANGEFS_DEV_CLIENT_MASK:
0688         return orangefs_debugfs_new_client_mask((void __user *)arg);
0689     case ORANGEFS_DEV_CLIENT_STRING:
0690         return orangefs_debugfs_new_client_string((void __user *)arg);
0691     case ORANGEFS_DEV_DEBUG:
0692         return orangefs_debugfs_new_debug((void __user *)arg);
0693     default:
0694         return -ENOIOCTLCMD;
0695     }
0696     return -ENOIOCTLCMD;
0697 }
0698 
0699 static long orangefs_devreq_ioctl(struct file *file,
0700                    unsigned int command, unsigned long arg)
0701 {
0702     long ret;
0703 
0704     /* Check for properly constructed commands */
0705     ret = check_ioctl_command(command);
0706     if (ret < 0)
0707         return (int)ret;
0708 
0709     return (int)dispatch_ioctl_command(command, arg);
0710 }
0711 
0712 #ifdef CONFIG_COMPAT        /* CONFIG_COMPAT is in .config */
0713 
0714 /*  Compat structure for the ORANGEFS_DEV_MAP ioctl */
0715 struct ORANGEFS_dev_map_desc32 {
0716     compat_uptr_t ptr;
0717     __s32 total_size;
0718     __s32 size;
0719     __s32 count;
0720 };
0721 
0722 /*
0723  * 32 bit user-space apps' ioctl handlers when kernel modules
0724  * is compiled as a 64 bit one
0725  */
0726 static long orangefs_devreq_compat_ioctl(struct file *filp, unsigned int cmd,
0727                       unsigned long args)
0728 {
0729     long ret;
0730 
0731     /* Check for properly constructed commands */
0732     ret = check_ioctl_command(cmd);
0733     if (ret < 0)
0734         return ret;
0735     if (cmd == ORANGEFS_DEV_MAP) {
0736         struct ORANGEFS_dev_map_desc desc;
0737         struct ORANGEFS_dev_map_desc32 d32;
0738 
0739         if (copy_from_user(&d32, (void __user *)args, sizeof(d32)))
0740             return -EFAULT;
0741 
0742         desc.ptr = compat_ptr(d32.ptr);
0743         desc.total_size = d32.total_size;
0744         desc.size = d32.size;
0745         desc.count = d32.count;
0746         return orangefs_bufmap_initialize(&desc);
0747     }
0748     /* no other ioctl requires translation */
0749     return dispatch_ioctl_command(cmd, args);
0750 }
0751 
0752 #endif /* CONFIG_COMPAT is in .config */
0753 
0754 static __poll_t orangefs_devreq_poll(struct file *file,
0755                       struct poll_table_struct *poll_table)
0756 {
0757     __poll_t poll_revent_mask = 0;
0758 
0759     poll_wait(file, &orangefs_request_list_waitq, poll_table);
0760 
0761     if (!list_empty(&orangefs_request_list))
0762         poll_revent_mask |= EPOLLIN;
0763     return poll_revent_mask;
0764 }
0765 
0766 /* the assigned character device major number */
0767 static int orangefs_dev_major;
0768 
0769 static const struct file_operations orangefs_devreq_file_operations = {
0770     .owner = THIS_MODULE,
0771     .read = orangefs_devreq_read,
0772     .write_iter = orangefs_devreq_write_iter,
0773     .open = orangefs_devreq_open,
0774     .release = orangefs_devreq_release,
0775     .unlocked_ioctl = orangefs_devreq_ioctl,
0776 
0777 #ifdef CONFIG_COMPAT        /* CONFIG_COMPAT is in .config */
0778     .compat_ioctl = orangefs_devreq_compat_ioctl,
0779 #endif
0780     .poll = orangefs_devreq_poll
0781 };
0782 
0783 /*
0784  * Initialize orangefs device specific state:
0785  * Must be called at module load time only
0786  */
0787 int orangefs_dev_init(void)
0788 {
0789     /* register orangefs-req device  */
0790     orangefs_dev_major = register_chrdev(0,
0791                       ORANGEFS_REQDEVICE_NAME,
0792                       &orangefs_devreq_file_operations);
0793     if (orangefs_dev_major < 0) {
0794         gossip_debug(GOSSIP_DEV_DEBUG,
0795                  "Failed to register /dev/%s (error %d)\n",
0796                  ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
0797         return orangefs_dev_major;
0798     }
0799 
0800     gossip_debug(GOSSIP_DEV_DEBUG,
0801              "*** /dev/%s character device registered ***\n",
0802              ORANGEFS_REQDEVICE_NAME);
0803     gossip_debug(GOSSIP_DEV_DEBUG, "'mknod /dev/%s c %d 0'.\n",
0804              ORANGEFS_REQDEVICE_NAME, orangefs_dev_major);
0805     return 0;
0806 }
0807 
0808 void orangefs_dev_cleanup(void)
0809 {
0810     unregister_chrdev(orangefs_dev_major, ORANGEFS_REQDEVICE_NAME);
0811     gossip_debug(GOSSIP_DEV_DEBUG,
0812              "*** /dev/%s character device unregistered ***\n",
0813              ORANGEFS_REQDEVICE_NAME);
0814 }