1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * (C) 2001 Clemson University and The University of Chicago 4 * 5 * See COPYING in top-level directory. 6 */ 7 8 #include "protocol.h" 9 #include "orangefs-kernel.h" 10 11 /* tags assigned to kernel upcall operations */ 12 static __u64 next_tag_value; 13 static DEFINE_SPINLOCK(next_tag_value_lock); 14 15 /* the orangefs memory caches */ 16 17 /* a cache for orangefs upcall/downcall operations */ 18 static struct kmem_cache *op_cache; 19 20 int op_cache_initialize(void) 21 { 22 op_cache = kmem_cache_create("orangefs_op_cache", 23 sizeof(struct orangefs_kernel_op_s), 24 0, 25 ORANGEFS_CACHE_CREATE_FLAGS, 26 NULL); 27 28 if (!op_cache) { 29 gossip_err("Cannot create orangefs_op_cache\n"); 30 return -ENOMEM; 31 } 32 33 /* initialize our atomic tag counter */ 34 spin_lock(&next_tag_value_lock); 35 next_tag_value = 100; 36 spin_unlock(&next_tag_value_lock); 37 return 0; 38 } 39 40 int op_cache_finalize(void) 41 { 42 kmem_cache_destroy(op_cache); 43 return 0; 44 } 45 46 char *get_opname_string(struct orangefs_kernel_op_s *new_op) 47 { 48 if (new_op) { 49 __s32 type = new_op->upcall.type; 50 51 if (type == ORANGEFS_VFS_OP_FILE_IO) 52 return "OP_FILE_IO"; 53 else if (type == ORANGEFS_VFS_OP_LOOKUP) 54 return "OP_LOOKUP"; 55 else if (type == ORANGEFS_VFS_OP_CREATE) 56 return "OP_CREATE"; 57 else if (type == ORANGEFS_VFS_OP_GETATTR) 58 return "OP_GETATTR"; 59 else if (type == ORANGEFS_VFS_OP_REMOVE) 60 return "OP_REMOVE"; 61 else if (type == ORANGEFS_VFS_OP_MKDIR) 62 return "OP_MKDIR"; 63 else if (type == ORANGEFS_VFS_OP_READDIR) 64 return "OP_READDIR"; 65 else if (type == ORANGEFS_VFS_OP_READDIRPLUS) 66 return "OP_READDIRPLUS"; 67 else if (type == ORANGEFS_VFS_OP_SETATTR) 68 return "OP_SETATTR"; 69 else if (type == ORANGEFS_VFS_OP_SYMLINK) 70 return "OP_SYMLINK"; 71 else if (type == ORANGEFS_VFS_OP_RENAME) 72 return "OP_RENAME"; 73 else if (type == ORANGEFS_VFS_OP_STATFS) 74 return "OP_STATFS"; 75 else if (type == ORANGEFS_VFS_OP_TRUNCATE) 76 return "OP_TRUNCATE"; 77 else if (type == ORANGEFS_VFS_OP_RA_FLUSH) 78 return "OP_RA_FLUSH"; 79 else if (type == ORANGEFS_VFS_OP_FS_MOUNT) 80 return "OP_FS_MOUNT"; 81 else if (type == ORANGEFS_VFS_OP_FS_UMOUNT) 82 return "OP_FS_UMOUNT"; 83 else if (type == ORANGEFS_VFS_OP_GETXATTR) 84 return "OP_GETXATTR"; 85 else if (type == ORANGEFS_VFS_OP_SETXATTR) 86 return "OP_SETXATTR"; 87 else if (type == ORANGEFS_VFS_OP_LISTXATTR) 88 return "OP_LISTXATTR"; 89 else if (type == ORANGEFS_VFS_OP_REMOVEXATTR) 90 return "OP_REMOVEXATTR"; 91 else if (type == ORANGEFS_VFS_OP_PARAM) 92 return "OP_PARAM"; 93 else if (type == ORANGEFS_VFS_OP_PERF_COUNT) 94 return "OP_PERF_COUNT"; 95 else if (type == ORANGEFS_VFS_OP_CANCEL) 96 return "OP_CANCEL"; 97 else if (type == ORANGEFS_VFS_OP_FSYNC) 98 return "OP_FSYNC"; 99 else if (type == ORANGEFS_VFS_OP_FSKEY) 100 return "OP_FSKEY"; 101 else if (type == ORANGEFS_VFS_OP_FEATURES) 102 return "OP_FEATURES"; 103 } 104 return "OP_UNKNOWN?"; 105 } 106 107 void orangefs_new_tag(struct orangefs_kernel_op_s *op) 108 { 109 spin_lock(&next_tag_value_lock); 110 op->tag = next_tag_value++; 111 if (next_tag_value == 0) 112 next_tag_value = 100; 113 spin_unlock(&next_tag_value_lock); 114 } 115 116 struct orangefs_kernel_op_s *op_alloc(__s32 type) 117 { 118 struct orangefs_kernel_op_s *new_op = NULL; 119 120 new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL); 121 if (new_op) { 122 INIT_LIST_HEAD(&new_op->list); 123 spin_lock_init(&new_op->lock); 124 init_completion(&new_op->waitq); 125 126 new_op->upcall.type = ORANGEFS_VFS_OP_INVALID; 127 new_op->downcall.type = ORANGEFS_VFS_OP_INVALID; 128 new_op->downcall.status = -1; 129 130 new_op->op_state = OP_VFS_STATE_UNKNOWN; 131 132 /* initialize the op specific tag and upcall credentials */ 133 orangefs_new_tag(new_op); 134 new_op->upcall.type = type; 135 new_op->attempts = 0; 136 gossip_debug(GOSSIP_CACHE_DEBUG, 137 "Alloced OP (%p: %llu %s)\n", 138 new_op, 139 llu(new_op->tag), 140 get_opname_string(new_op)); 141 142 new_op->upcall.uid = from_kuid(&init_user_ns, 143 current_fsuid()); 144 145 new_op->upcall.gid = from_kgid(&init_user_ns, 146 current_fsgid()); 147 } else { 148 gossip_err("op_alloc: kmem_cache_zalloc failed!\n"); 149 } 150 return new_op; 151 } 152 153 void op_release(struct orangefs_kernel_op_s *orangefs_op) 154 { 155 if (orangefs_op) { 156 gossip_debug(GOSSIP_CACHE_DEBUG, 157 "Releasing OP (%p: %llu)\n", 158 orangefs_op, 159 llu(orangefs_op->tag)); 160 kmem_cache_free(op_cache, orangefs_op); 161 } else { 162 gossip_err("NULL pointer in op_release\n"); 163 } 164 } 165