Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }