Commit | Line | Data |
---|---|---|
b2441318 | 1 | // SPDX-License-Identifier: GPL-2.0 |
274dcf55 MM |
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" | |
575e9461 | 9 | #include "orangefs-kernel.h" |
274dcf55 MM |
10 | |
11 | /* tags assigned to kernel upcall operations */ | |
12 | static __u64 next_tag_value; | |
13 | static DEFINE_SPINLOCK(next_tag_value_lock); | |
14 | ||
8bb8aefd | 15 | /* the orangefs memory caches */ |
274dcf55 | 16 | |
8bb8aefd | 17 | /* a cache for orangefs upcall/downcall operations */ |
274dcf55 MM |
18 | static struct kmem_cache *op_cache; |
19 | ||
274dcf55 MM |
20 | int op_cache_initialize(void) |
21 | { | |
8bb8aefd YL |
22 | op_cache = kmem_cache_create("orangefs_op_cache", |
23 | sizeof(struct orangefs_kernel_op_s), | |
274dcf55 | 24 | 0, |
8bb8aefd | 25 | ORANGEFS_CACHE_CREATE_FLAGS, |
274dcf55 MM |
26 | NULL); |
27 | ||
28 | if (!op_cache) { | |
8bb8aefd | 29 | gossip_err("Cannot create orangefs_op_cache\n"); |
274dcf55 MM |
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 | ||
8bb8aefd | 46 | char *get_opname_string(struct orangefs_kernel_op_s *new_op) |
274dcf55 MM |
47 | { |
48 | if (new_op) { | |
49 | __s32 type = new_op->upcall.type; | |
50 | ||
8bb8aefd | 51 | if (type == ORANGEFS_VFS_OP_FILE_IO) |
274dcf55 | 52 | return "OP_FILE_IO"; |
8bb8aefd | 53 | else if (type == ORANGEFS_VFS_OP_LOOKUP) |
274dcf55 | 54 | return "OP_LOOKUP"; |
8bb8aefd | 55 | else if (type == ORANGEFS_VFS_OP_CREATE) |
274dcf55 | 56 | return "OP_CREATE"; |
8bb8aefd | 57 | else if (type == ORANGEFS_VFS_OP_GETATTR) |
274dcf55 | 58 | return "OP_GETATTR"; |
8bb8aefd | 59 | else if (type == ORANGEFS_VFS_OP_REMOVE) |
274dcf55 | 60 | return "OP_REMOVE"; |
8bb8aefd | 61 | else if (type == ORANGEFS_VFS_OP_MKDIR) |
274dcf55 | 62 | return "OP_MKDIR"; |
8bb8aefd | 63 | else if (type == ORANGEFS_VFS_OP_READDIR) |
274dcf55 | 64 | return "OP_READDIR"; |
8bb8aefd | 65 | else if (type == ORANGEFS_VFS_OP_READDIRPLUS) |
274dcf55 | 66 | return "OP_READDIRPLUS"; |
8bb8aefd | 67 | else if (type == ORANGEFS_VFS_OP_SETATTR) |
274dcf55 | 68 | return "OP_SETATTR"; |
8bb8aefd | 69 | else if (type == ORANGEFS_VFS_OP_SYMLINK) |
274dcf55 | 70 | return "OP_SYMLINK"; |
8bb8aefd | 71 | else if (type == ORANGEFS_VFS_OP_RENAME) |
274dcf55 | 72 | return "OP_RENAME"; |
8bb8aefd | 73 | else if (type == ORANGEFS_VFS_OP_STATFS) |
274dcf55 | 74 | return "OP_STATFS"; |
8bb8aefd | 75 | else if (type == ORANGEFS_VFS_OP_TRUNCATE) |
274dcf55 | 76 | return "OP_TRUNCATE"; |
6eaff8c7 MB |
77 | else if (type == ORANGEFS_VFS_OP_RA_FLUSH) |
78 | return "OP_RA_FLUSH"; | |
8bb8aefd | 79 | else if (type == ORANGEFS_VFS_OP_FS_MOUNT) |
274dcf55 | 80 | return "OP_FS_MOUNT"; |
8bb8aefd | 81 | else if (type == ORANGEFS_VFS_OP_FS_UMOUNT) |
274dcf55 | 82 | return "OP_FS_UMOUNT"; |
8bb8aefd | 83 | else if (type == ORANGEFS_VFS_OP_GETXATTR) |
274dcf55 | 84 | return "OP_GETXATTR"; |
8bb8aefd | 85 | else if (type == ORANGEFS_VFS_OP_SETXATTR) |
274dcf55 | 86 | return "OP_SETXATTR"; |
8bb8aefd | 87 | else if (type == ORANGEFS_VFS_OP_LISTXATTR) |
274dcf55 | 88 | return "OP_LISTXATTR"; |
8bb8aefd | 89 | else if (type == ORANGEFS_VFS_OP_REMOVEXATTR) |
274dcf55 | 90 | return "OP_REMOVEXATTR"; |
8bb8aefd | 91 | else if (type == ORANGEFS_VFS_OP_PARAM) |
274dcf55 | 92 | return "OP_PARAM"; |
8bb8aefd | 93 | else if (type == ORANGEFS_VFS_OP_PERF_COUNT) |
274dcf55 | 94 | return "OP_PERF_COUNT"; |
8bb8aefd | 95 | else if (type == ORANGEFS_VFS_OP_CANCEL) |
274dcf55 | 96 | return "OP_CANCEL"; |
8bb8aefd | 97 | else if (type == ORANGEFS_VFS_OP_FSYNC) |
274dcf55 | 98 | return "OP_FSYNC"; |
8bb8aefd | 99 | else if (type == ORANGEFS_VFS_OP_FSKEY) |
274dcf55 | 100 | return "OP_FSKEY"; |
482664dd MB |
101 | else if (type == ORANGEFS_VFS_OP_FEATURES) |
102 | return "OP_FEATURES"; | |
274dcf55 MM |
103 | } |
104 | return "OP_UNKNOWN?"; | |
105 | } | |
106 | ||
78699e29 AV |
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 | ||
8bb8aefd | 116 | struct orangefs_kernel_op_s *op_alloc(__s32 type) |
274dcf55 | 117 | { |
8bb8aefd | 118 | struct orangefs_kernel_op_s *new_op = NULL; |
274dcf55 | 119 | |
2d4cae0d | 120 | new_op = kmem_cache_zalloc(op_cache, GFP_KERNEL); |
274dcf55 | 121 | if (new_op) { |
274dcf55 MM |
122 | INIT_LIST_HEAD(&new_op->list); |
123 | spin_lock_init(&new_op->lock); | |
d2d87a3b | 124 | init_completion(&new_op->waitq); |
274dcf55 | 125 | |
115b93a8 AV |
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; | |
274dcf55 MM |
131 | |
132 | /* initialize the op specific tag and upcall credentials */ | |
78699e29 | 133 | orangefs_new_tag(new_op); |
274dcf55 MM |
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 | ||
78fee0b6 | 142 | new_op->upcall.uid = from_kuid(&init_user_ns, |
274dcf55 MM |
143 | current_fsuid()); |
144 | ||
78fee0b6 | 145 | new_op->upcall.gid = from_kgid(&init_user_ns, |
274dcf55 | 146 | current_fsgid()); |
274dcf55 | 147 | } else { |
2d4cae0d | 148 | gossip_err("op_alloc: kmem_cache_zalloc failed!\n"); |
274dcf55 MM |
149 | } |
150 | return new_op; | |
151 | } | |
152 | ||
c1223ca4 | 153 | void op_release(struct orangefs_kernel_op_s *orangefs_op) |
274dcf55 | 154 | { |
8bb8aefd | 155 | if (orangefs_op) { |
274dcf55 MM |
156 | gossip_debug(GOSSIP_CACHE_DEBUG, |
157 | "Releasing OP (%p: %llu)\n", | |
8bb8aefd YL |
158 | orangefs_op, |
159 | llu(orangefs_op->tag)); | |
8bb8aefd | 160 | kmem_cache_free(op_cache, orangefs_op); |
274dcf55 MM |
161 | } else { |
162 | gossip_err("NULL pointer in op_release\n"); | |
163 | } | |
164 | } |