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