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