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_MMAP_RA_FLUSH) 77 return "OP_MMAP_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 } 101 return "OP_UNKNOWN?"; 102 } 103 104 void orangefs_new_tag(struct orangefs_kernel_op_s *op) 105 { 106 spin_lock(&next_tag_value_lock); 107 op->tag = next_tag_value++; 108 if (next_tag_value == 0) 109 next_tag_value = 100; 110 spin_unlock(&next_tag_value_lock); 111 } 112 113 struct orangefs_kernel_op_s *op_alloc(__s32 type) 114 { 115 struct orangefs_kernel_op_s *new_op = NULL; 116 117 new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL); 118 if (new_op) { 119 INIT_LIST_HEAD(&new_op->list); 120 spin_lock_init(&new_op->lock); 121 init_completion(&new_op->waitq); 122 123 new_op->upcall.type = ORANGEFS_VFS_OP_INVALID; 124 new_op->downcall.type = ORANGEFS_VFS_OP_INVALID; 125 new_op->downcall.status = -1; 126 127 new_op->op_state = OP_VFS_STATE_UNKNOWN; 128 129 /* initialize the op specific tag and upcall credentials */ 130 orangefs_new_tag(new_op); 131 new_op->upcall.type = type; 132 new_op->attempts = 0; 133 gossip_debug(GOSSIP_CACHE_DEBUG, 134 "Alloced OP (%p: %llu %s)\n", 135 new_op, 136 llu(new_op->tag), 137 get_opname_string(new_op)); 138 139 new_op->upcall.uid = from_kuid(current_user_ns(), 140 current_fsuid()); 141 142 new_op->upcall.gid = from_kgid(current_user_ns(), 143 current_fsgid()); 144 } else { 145 gossip_err("op_alloc: kmem_cache_zalloc failed!\n"); 146 } 147 return new_op; 148 } 149 150 void op_release(struct orangefs_kernel_op_s *orangefs_op) 151 { 152 if (orangefs_op) { 153 gossip_debug(GOSSIP_CACHE_DEBUG, 154 "Releasing OP (%p: %llu)\n", 155 orangefs_op, 156 llu(orangefs_op->tag)); 157 kmem_cache_free(op_cache, orangefs_op); 158 } else { 159 gossip_err("NULL pointer in op_release\n"); 160 } 161 } 162