Whamcloud - gitweb
LU-8277 scripts: add missing commas in checkpatch.pl
[fs/lustre-release.git] / lustre / llite / llite_rmtacl.c
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
19  *
20  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
21  * CA 95054 USA or visit www.sun.com if you need additional information or
22  * have any questions.
23  *
24  * GPL HEADER END
25  */
26 /*
27  * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
28  * Use is subject to license terms.
29  *
30  * Copyright (c) 2012, 2014, Intel Corporation.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  *
36  * lustre/llite/llite_rmtacl.c
37  *
38  * Lustre Remote User Access Control List.
39  *
40  * Author: Fan Yong <fanyong@clusterfs.com>
41  */
42
43 #define DEBUG_SUBSYSTEM S_LLITE
44
45 #ifdef CONFIG_FS_POSIX_ACL
46
47 #include <lustre_eacl.h>
48 #include "llite_internal.h"
49
50 static inline __u32 rce_hashfunc(uid_t id)
51 {
52         return id & (RCE_HASHES - 1);
53 }
54
55 static inline __u32 ee_hashfunc(uid_t id)
56 {
57         return id & (EE_HASHES - 1);
58 }
59
60 u64 rce_ops2valid(int ops)
61 {
62         switch (ops) {
63         case RMT_LSETFACL:
64                 return OBD_MD_FLRMTLSETFACL;
65         case RMT_LGETFACL:
66                 return OBD_MD_FLRMTLGETFACL;
67         case RMT_RSETFACL:
68                 return OBD_MD_FLRMTRSETFACL;
69         case RMT_RGETFACL:
70                 return OBD_MD_FLRMTRGETFACL;
71         default:
72                 return 0;
73         }
74 }
75
76 static struct rmtacl_ctl_entry *rce_alloc(pid_t key, int ops)
77 {
78         struct rmtacl_ctl_entry *rce;
79
80         OBD_ALLOC_PTR(rce);
81         if (!rce)
82                 return NULL;
83
84         INIT_LIST_HEAD(&rce->rce_list);
85         rce->rce_key = key;
86         rce->rce_ops = ops;
87
88         return rce;
89 }
90
91 static void rce_free(struct rmtacl_ctl_entry *rce)
92 {
93         if (!list_empty(&rce->rce_list))
94                 list_del(&rce->rce_list);
95
96         OBD_FREE_PTR(rce);
97 }
98
99 static struct rmtacl_ctl_entry *__rct_search(struct rmtacl_ctl_table *rct,
100                                            pid_t key)
101 {
102         struct rmtacl_ctl_entry *rce;
103         struct list_head *head = &rct->rct_entries[rce_hashfunc(key)];
104
105         list_for_each_entry(rce, head, rce_list)
106                 if (rce->rce_key == key)
107                         return rce;
108
109         return NULL;
110 }
111
112 struct rmtacl_ctl_entry *rct_search(struct rmtacl_ctl_table *rct, pid_t key)
113 {
114         struct rmtacl_ctl_entry *rce;
115
116         spin_lock(&rct->rct_lock);
117         rce = __rct_search(rct, key);
118         spin_unlock(&rct->rct_lock);
119         return rce;
120 }
121
122 int rct_add(struct rmtacl_ctl_table *rct, pid_t key, int ops)
123 {
124         struct rmtacl_ctl_entry *rce, *e;
125
126         rce = rce_alloc(key, ops);
127         if (rce == NULL)
128                 return -ENOMEM;
129
130         spin_lock(&rct->rct_lock);
131         e = __rct_search(rct, key);
132         if (unlikely(e != NULL)) {
133                 CWARN("Unexpected stale rmtacl_entry found: "
134                       "[key: %d] [ops: %d]\n", (int)key, ops);
135                 rce_free(e);
136         }
137         list_add_tail(&rce->rce_list, &rct->rct_entries[rce_hashfunc(key)]);
138         spin_unlock(&rct->rct_lock);
139
140         return 0;
141 }
142
143 int rct_del(struct rmtacl_ctl_table *rct, pid_t key)
144 {
145         struct rmtacl_ctl_entry *rce;
146
147         spin_lock(&rct->rct_lock);
148         rce = __rct_search(rct, key);
149         if (rce)
150                 rce_free(rce);
151         spin_unlock(&rct->rct_lock);
152
153         return rce ? 0 : -ENOENT;
154 }
155
156 void rct_init(struct rmtacl_ctl_table *rct)
157 {
158         int i;
159
160         spin_lock_init(&rct->rct_lock);
161         for (i = 0; i < RCE_HASHES; i++)
162                 INIT_LIST_HEAD(&rct->rct_entries[i]);
163 }
164
165 void rct_fini(struct rmtacl_ctl_table *rct)
166 {
167         struct rmtacl_ctl_entry *rce;
168         int i;
169
170         spin_lock(&rct->rct_lock);
171         for (i = 0; i < RCE_HASHES; i++)
172                 while (!list_empty(&rct->rct_entries[i])) {
173                         rce = list_entry(rct->rct_entries[i].next,
174                                              struct rmtacl_ctl_entry, rce_list);
175                         rce_free(rce);
176                 }
177         spin_unlock(&rct->rct_lock);
178 }
179
180
181 static struct eacl_entry *ee_alloc(pid_t key, struct lu_fid *fid, int type,
182                                    ext_acl_xattr_header *header)
183 {
184         struct eacl_entry *ee;
185
186         OBD_ALLOC_PTR(ee);
187         if (!ee)
188                 return NULL;
189
190         INIT_LIST_HEAD(&ee->ee_list);
191         ee->ee_key = key;
192         ee->ee_fid = *fid;
193         ee->ee_type = type;
194         ee->ee_acl = header;
195
196         return ee;
197 }
198
199 void ee_free(struct eacl_entry *ee)
200 {
201         if (!list_empty(&ee->ee_list))
202                 list_del(&ee->ee_list);
203
204         if (ee->ee_acl)
205                 lustre_ext_acl_xattr_free(ee->ee_acl);
206
207         OBD_FREE_PTR(ee);
208 }
209
210 static struct eacl_entry *__et_search_del(struct eacl_table *et, pid_t key,
211                                         struct lu_fid *fid, int type)
212 {
213         struct eacl_entry *ee;
214         struct list_head *head = &et->et_entries[ee_hashfunc(key)];
215
216         LASSERT(fid != NULL);
217         list_for_each_entry(ee, head, ee_list)
218                 if (ee->ee_key == key) {
219                         if (lu_fid_eq(&ee->ee_fid, fid) &&
220                             ee->ee_type == type) {
221                                 list_del_init(&ee->ee_list);
222                                 return ee;
223                         }
224                 }
225
226         return NULL;
227 }
228
229 struct eacl_entry *et_search_del(struct eacl_table *et, pid_t key,
230                                  struct lu_fid *fid, int type)
231 {
232         struct eacl_entry *ee;
233
234         spin_lock(&et->et_lock);
235         ee = __et_search_del(et, key, fid, type);
236         spin_unlock(&et->et_lock);
237         return ee;
238 }
239
240 void et_search_free(struct eacl_table *et, pid_t key)
241 {
242         struct eacl_entry *ee, *next;
243         struct list_head *head = &et->et_entries[ee_hashfunc(key)];
244
245         spin_lock(&et->et_lock);
246         list_for_each_entry_safe(ee, next, head, ee_list)
247                 if (ee->ee_key == key)
248                         ee_free(ee);
249
250         spin_unlock(&et->et_lock);
251 }
252
253 int ee_add(struct eacl_table *et, pid_t key, struct lu_fid *fid, int type,
254            ext_acl_xattr_header *header)
255 {
256         struct eacl_entry *ee, *e;
257
258         ee = ee_alloc(key, fid, type, header);
259         if (ee == NULL)
260                 return -ENOMEM;
261
262         spin_lock(&et->et_lock);
263         e = __et_search_del(et, key, fid, type);
264         if (unlikely(e != NULL)) {
265                 CWARN("Unexpected stale eacl_entry found: "
266                       "[key: %d] [fid: "DFID"] [type: %d]\n",
267                       (int)key, PFID(fid), type);
268                 ee_free(e);
269         }
270         list_add_tail(&ee->ee_list, &et->et_entries[ee_hashfunc(key)]);
271         spin_unlock(&et->et_lock);
272
273         return 0;
274 }
275
276 void et_init(struct eacl_table *et)
277 {
278         int i;
279
280         spin_lock_init(&et->et_lock);
281         for (i = 0; i < EE_HASHES; i++)
282                 INIT_LIST_HEAD(&et->et_entries[i]);
283 }
284
285 void et_fini(struct eacl_table *et)
286 {
287         struct eacl_entry *ee;
288         int i;
289
290         spin_lock(&et->et_lock);
291         for (i = 0; i < EE_HASHES; i++)
292                 while (!list_empty(&et->et_entries[i])) {
293                         ee = list_entry(et->et_entries[i].next,
294                                         struct eacl_entry, ee_list);
295                         ee_free(ee);
296                 }
297         spin_unlock(&et->et_lock);
298 }
299
300 #endif