0001
0002
0003
0004
0005
0006
0007
0008 #include "protocol.h"
0009 #include "orangefs-kernel.h"
0010
0011
0012 static __u64 next_tag_value;
0013 static DEFINE_SPINLOCK(next_tag_value_lock);
0014
0015
0016
0017
0018 static struct kmem_cache *op_cache;
0019
0020 int op_cache_initialize(void)
0021 {
0022 op_cache = kmem_cache_create("orangefs_op_cache",
0023 sizeof(struct orangefs_kernel_op_s),
0024 0,
0025 ORANGEFS_CACHE_CREATE_FLAGS,
0026 NULL);
0027
0028 if (!op_cache) {
0029 gossip_err("Cannot create orangefs_op_cache\n");
0030 return -ENOMEM;
0031 }
0032
0033
0034 spin_lock(&next_tag_value_lock);
0035 next_tag_value = 100;
0036 spin_unlock(&next_tag_value_lock);
0037 return 0;
0038 }
0039
0040 int op_cache_finalize(void)
0041 {
0042 kmem_cache_destroy(op_cache);
0043 return 0;
0044 }
0045
0046 char *get_opname_string(struct orangefs_kernel_op_s *new_op)
0047 {
0048 if (new_op) {
0049 __s32 type = new_op->upcall.type;
0050
0051 if (type == ORANGEFS_VFS_OP_FILE_IO)
0052 return "OP_FILE_IO";
0053 else if (type == ORANGEFS_VFS_OP_LOOKUP)
0054 return "OP_LOOKUP";
0055 else if (type == ORANGEFS_VFS_OP_CREATE)
0056 return "OP_CREATE";
0057 else if (type == ORANGEFS_VFS_OP_GETATTR)
0058 return "OP_GETATTR";
0059 else if (type == ORANGEFS_VFS_OP_REMOVE)
0060 return "OP_REMOVE";
0061 else if (type == ORANGEFS_VFS_OP_MKDIR)
0062 return "OP_MKDIR";
0063 else if (type == ORANGEFS_VFS_OP_READDIR)
0064 return "OP_READDIR";
0065 else if (type == ORANGEFS_VFS_OP_READDIRPLUS)
0066 return "OP_READDIRPLUS";
0067 else if (type == ORANGEFS_VFS_OP_SETATTR)
0068 return "OP_SETATTR";
0069 else if (type == ORANGEFS_VFS_OP_SYMLINK)
0070 return "OP_SYMLINK";
0071 else if (type == ORANGEFS_VFS_OP_RENAME)
0072 return "OP_RENAME";
0073 else if (type == ORANGEFS_VFS_OP_STATFS)
0074 return "OP_STATFS";
0075 else if (type == ORANGEFS_VFS_OP_TRUNCATE)
0076 return "OP_TRUNCATE";
0077 else if (type == ORANGEFS_VFS_OP_RA_FLUSH)
0078 return "OP_RA_FLUSH";
0079 else if (type == ORANGEFS_VFS_OP_FS_MOUNT)
0080 return "OP_FS_MOUNT";
0081 else if (type == ORANGEFS_VFS_OP_FS_UMOUNT)
0082 return "OP_FS_UMOUNT";
0083 else if (type == ORANGEFS_VFS_OP_GETXATTR)
0084 return "OP_GETXATTR";
0085 else if (type == ORANGEFS_VFS_OP_SETXATTR)
0086 return "OP_SETXATTR";
0087 else if (type == ORANGEFS_VFS_OP_LISTXATTR)
0088 return "OP_LISTXATTR";
0089 else if (type == ORANGEFS_VFS_OP_REMOVEXATTR)
0090 return "OP_REMOVEXATTR";
0091 else if (type == ORANGEFS_VFS_OP_PARAM)
0092 return "OP_PARAM";
0093 else if (type == ORANGEFS_VFS_OP_PERF_COUNT)
0094 return "OP_PERF_COUNT";
0095 else if (type == ORANGEFS_VFS_OP_CANCEL)
0096 return "OP_CANCEL";
0097 else if (type == ORANGEFS_VFS_OP_FSYNC)
0098 return "OP_FSYNC";
0099 else if (type == ORANGEFS_VFS_OP_FSKEY)
0100 return "OP_FSKEY";
0101 else if (type == ORANGEFS_VFS_OP_FEATURES)
0102 return "OP_FEATURES";
0103 }
0104 return "OP_UNKNOWN?";
0105 }
0106
0107 void orangefs_new_tag(struct orangefs_kernel_op_s *op)
0108 {
0109 spin_lock(&next_tag_value_lock);
0110 op->tag = next_tag_value++;
0111 if (next_tag_value == 0)
0112 next_tag_value = 100;
0113 spin_unlock(&next_tag_value_lock);
0114 }
0115
0116 struct orangefs_kernel_op_s *op_alloc(__s32 type)
0117 {
0118 struct orangefs_kernel_op_s *new_op = NULL;
0119
0120 new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL);
0121 if (new_op) {
0122 INIT_LIST_HEAD(&new_op->list);
0123 spin_lock_init(&new_op->lock);
0124 init_completion(&new_op->waitq);
0125
0126 new_op->upcall.type = ORANGEFS_VFS_OP_INVALID;
0127 new_op->downcall.type = ORANGEFS_VFS_OP_INVALID;
0128 new_op->downcall.status = -1;
0129
0130 new_op->op_state = OP_VFS_STATE_UNKNOWN;
0131
0132
0133 orangefs_new_tag(new_op);
0134 new_op->upcall.type = type;
0135 new_op->attempts = 0;
0136 gossip_debug(GOSSIP_CACHE_DEBUG,
0137 "Alloced OP (%p: %llu %s)\n",
0138 new_op,
0139 llu(new_op->tag),
0140 get_opname_string(new_op));
0141
0142 new_op->upcall.uid = from_kuid(&init_user_ns,
0143 current_fsuid());
0144
0145 new_op->upcall.gid = from_kgid(&init_user_ns,
0146 current_fsgid());
0147 } else {
0148 gossip_err("op_alloc: kmem_cache_zalloc failed!\n");
0149 }
0150 return new_op;
0151 }
0152
0153 void op_release(struct orangefs_kernel_op_s *orangefs_op)
0154 {
0155 if (orangefs_op) {
0156 gossip_debug(GOSSIP_CACHE_DEBUG,
0157 "Releasing OP (%p: %llu)\n",
0158 orangefs_op,
0159 llu(orangefs_op->tag));
0160 kmem_cache_free(op_cache, orangefs_op);
0161 } else {
0162 gossip_err("NULL pointer in op_release\n");
0163 }
0164 }