File: | xlators/features/locks/src/entrylk.c |
Location: | line 586, column 9 |
Description: | The left operand of '-' is a garbage value |
1 | /* | ||
2 | Copyright (c) 2006-2012 Red Hat, Inc. <http://www.redhat.com> | ||
3 | This file is part of GlusterFS. | ||
4 | |||
5 | This file is licensed to you under your choice of the GNU Lesser | ||
6 | General Public License, version 3 or any later version (LGPLv3 or | ||
7 | later), or the GNU General Public License, version 2 (GPLv2), in all | ||
8 | cases as published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef _CONFIG_H | ||
11 | #define _CONFIG_H | ||
12 | #include "config.h" | ||
13 | #endif | ||
14 | |||
15 | #include "glusterfs.h" | ||
16 | #include "compat.h" | ||
17 | #include "xlator.h" | ||
18 | #include "inode.h" | ||
19 | #include "logging.h" | ||
20 | #include "common-utils.h" | ||
21 | #include "list.h" | ||
22 | |||
23 | #include "locks.h" | ||
24 | #include "common.h" | ||
25 | |||
26 | static pl_entry_lock_t * | ||
27 | new_entrylk_lock (pl_inode_t *pinode, const char *basename, entrylk_type type, | ||
28 | void *trans, pid_t client_pid, gf_lkowner_t *owner, | ||
29 | const char *volume) | ||
30 | |||
31 | { | ||
32 | pl_entry_lock_t *newlock = NULL((void*)0); | ||
33 | |||
34 | newlock = GF_CALLOC (1, sizeof (pl_entry_lock_t),__gf_calloc (1, sizeof (pl_entry_lock_t), gf_locks_mt_pl_entry_lock_t ) | ||
35 | gf_locks_mt_pl_entry_lock_t)__gf_calloc (1, sizeof (pl_entry_lock_t), gf_locks_mt_pl_entry_lock_t ); | ||
36 | if (!newlock) { | ||
37 | goto out; | ||
38 | } | ||
39 | |||
40 | newlock->basename = basename ? gf_strdup (basename) : NULL((void*)0); | ||
41 | newlock->type = type; | ||
42 | newlock->trans = trans; | ||
43 | newlock->volume = volume; | ||
44 | newlock->client_pid = client_pid; | ||
45 | newlock->owner = *owner; | ||
46 | |||
47 | INIT_LIST_HEAD (&newlock->domain_list)do { (&newlock->domain_list)->next = (&newlock-> domain_list)->prev = &newlock->domain_list; } while (0); | ||
48 | INIT_LIST_HEAD (&newlock->blocked_locks)do { (&newlock->blocked_locks)->next = (&newlock ->blocked_locks)->prev = &newlock->blocked_locks ; } while (0); | ||
49 | |||
50 | out: | ||
51 | return newlock; | ||
52 | } | ||
53 | |||
54 | |||
55 | /** | ||
56 | * all_names - does a basename represent all names? | ||
57 | * @basename: name to check | ||
58 | */ | ||
59 | |||
60 | #define all_names(basename)((basename == ((void*)0)) ? 1 : 0) ((basename == NULL((void*)0)) ? 1 : 0) | ||
61 | |||
62 | /** | ||
63 | * names_conflict - do two names conflict? | ||
64 | * @n1: name | ||
65 | * @n2: name | ||
66 | */ | ||
67 | |||
68 | static int | ||
69 | names_conflict (const char *n1, const char *n2) | ||
70 | { | ||
71 | return all_names (n1)((n1 == ((void*)0)) ? 1 : 0) || all_names (n2)((n2 == ((void*)0)) ? 1 : 0) || !strcmp (n1, n2); | ||
72 | } | ||
73 | |||
74 | |||
75 | static inline int | ||
76 | __same_entrylk_owner (pl_entry_lock_t *l1, pl_entry_lock_t *l2) | ||
77 | { | ||
78 | |||
79 | return (is_same_lkowner (&l1->owner, &l2->owner) && | ||
80 | (l1->trans == l2->trans)); | ||
81 | } | ||
82 | |||
83 | |||
84 | /** | ||
85 | * lock_grantable - is this lock grantable? | ||
86 | * @inode: inode in which to look | ||
87 | * @basename: name we're trying to lock | ||
88 | * @type: type of lock | ||
89 | */ | ||
90 | static pl_entry_lock_t * | ||
91 | __lock_grantable (pl_dom_list_t *dom, const char *basename, entrylk_type type) | ||
92 | { | ||
93 | pl_entry_lock_t *lock = NULL((void*)0); | ||
94 | |||
95 | if (list_empty (&dom->entrylk_list)) | ||
96 | return NULL((void*)0); | ||
97 | |||
98 | list_for_each_entry (lock, &dom->entrylk_list, domain_list)for (lock = ((typeof(*lock) *)((char *)((&dom->entrylk_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->domain_list ))); &lock->domain_list != (&dom->entrylk_list) ; lock = ((typeof(*lock) *)((char *)(lock->domain_list.next )-(unsigned long)(&((typeof(*lock) *)0)->domain_list)) )) { | ||
99 | if (names_conflict (lock->basename, basename)) | ||
100 | return lock; | ||
101 | } | ||
102 | |||
103 | return NULL((void*)0); | ||
104 | } | ||
105 | |||
106 | static pl_entry_lock_t * | ||
107 | __blocked_lock_conflict (pl_dom_list_t *dom, const char *basename, entrylk_type type) | ||
108 | { | ||
109 | pl_entry_lock_t *lock = NULL((void*)0); | ||
110 | |||
111 | if (list_empty (&dom->blocked_entrylks)) | ||
112 | return NULL((void*)0); | ||
113 | |||
114 | list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&dom->blocked_entrylks )->next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&dom->blocked_entrylks ); lock = ((typeof(*lock) *)((char *)(lock->blocked_locks. next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks )))) { | ||
115 | if (names_conflict (lock->basename, basename)) | ||
116 | return lock; | ||
117 | } | ||
118 | |||
119 | return NULL((void*)0); | ||
120 | } | ||
121 | |||
122 | static int | ||
123 | __owner_has_lock (pl_dom_list_t *dom, pl_entry_lock_t *newlock) | ||
124 | { | ||
125 | pl_entry_lock_t *lock = NULL((void*)0); | ||
126 | |||
127 | list_for_each_entry (lock, &dom->entrylk_list, domain_list)for (lock = ((typeof(*lock) *)((char *)((&dom->entrylk_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->domain_list ))); &lock->domain_list != (&dom->entrylk_list) ; lock = ((typeof(*lock) *)((char *)(lock->domain_list.next )-(unsigned long)(&((typeof(*lock) *)0)->domain_list)) )) { | ||
128 | if (__same_entrylk_owner (lock, newlock)) | ||
129 | return 1; | ||
130 | } | ||
131 | |||
132 | list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&dom->blocked_entrylks )->next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&dom->blocked_entrylks ); lock = ((typeof(*lock) *)((char *)(lock->blocked_locks. next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks )))) { | ||
133 | if (__same_entrylk_owner (lock, newlock)) | ||
134 | return 1; | ||
135 | } | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static int | ||
141 | names_equal (const char *n1, const char *n2) | ||
142 | { | ||
143 | return (n1 == NULL((void*)0) && n2 == NULL((void*)0)) || (n1 && n2 && !strcmp (n1, n2)); | ||
144 | } | ||
145 | |||
146 | void | ||
147 | pl_print_entrylk (char *str, int size, entrylk_cmd cmd, entrylk_type type, | ||
148 | const char *basename, const char *domain) | ||
149 | { | ||
150 | char *cmd_str = NULL((void*)0); | ||
151 | char *type_str = NULL((void*)0); | ||
152 | |||
153 | switch (cmd) { | ||
154 | case ENTRYLK_LOCK: | ||
155 | cmd_str = "LOCK"; | ||
156 | break; | ||
157 | |||
158 | case ENTRYLK_LOCK_NB: | ||
159 | cmd_str = "LOCK_NB"; | ||
160 | break; | ||
161 | |||
162 | case ENTRYLK_UNLOCK: | ||
163 | cmd_str = "UNLOCK"; | ||
164 | break; | ||
165 | |||
166 | default: | ||
167 | cmd_str = "UNKNOWN"; | ||
168 | break; | ||
169 | } | ||
170 | |||
171 | switch (type) { | ||
172 | case ENTRYLK_RDLCK: | ||
173 | type_str = "READ"; | ||
174 | break; | ||
175 | case ENTRYLK_WRLCK: | ||
176 | type_str = "WRITE"; | ||
177 | break; | ||
178 | default: | ||
179 | type_str = "UNKNOWN"; | ||
180 | break; | ||
181 | } | ||
182 | |||
183 | snprintf (str, size, "lock=ENTRYLK, cmd=%s, type=%s, basename=%s, domain: %s", | ||
184 | cmd_str, type_str, basename, domain); | ||
185 | } | ||
186 | |||
187 | |||
188 | void | ||
189 | entrylk_trace_in (xlator_t *this, call_frame_t *frame, const char *domain, | ||
190 | fd_t *fd, loc_t *loc, const char *basename, | ||
191 | entrylk_cmd cmd, entrylk_type type) | ||
192 | { | ||
193 | posix_locks_private_t *priv = NULL((void*)0); | ||
194 | char pl_locker[256]; | ||
195 | char pl_lockee[256]; | ||
196 | char pl_entrylk[256]; | ||
197 | |||
198 | priv = this->private; | ||
199 | |||
200 | if (!priv->trace) | ||
201 | return; | ||
202 | |||
203 | pl_print_locker (pl_locker, 256, this, frame); | ||
204 | pl_print_lockee (pl_lockee, 256, fd, loc); | ||
205 | pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, domain); | ||
206 | |||
207 | gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this ->name, "entrylk.c", __FUNCTION__, 209, GF_LOG_INFO, "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0) | ||
208 | "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}",do { do { if (0) printf ("[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this ->name, "entrylk.c", __FUNCTION__, 209, GF_LOG_INFO, "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0) | ||
209 | pl_locker, pl_lockee, pl_entrylk)do { do { if (0) printf ("[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this ->name, "entrylk.c", __FUNCTION__, 209, GF_LOG_INFO, "[REQUEST] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); | ||
210 | } | ||
211 | |||
212 | |||
213 | void | ||
214 | entrylk_trace_out (xlator_t *this, call_frame_t *frame, const char *domain, | ||
215 | fd_t *fd, loc_t *loc, const char *basename, | ||
216 | entrylk_cmd cmd, entrylk_type type, int op_ret, int op_errno) | ||
217 | { | ||
218 | posix_locks_private_t *priv = NULL((void*)0); | ||
219 | char pl_locker[256]; | ||
220 | char pl_lockee[256]; | ||
221 | char pl_entrylk[256]; | ||
222 | char verdict[32]; | ||
223 | |||
224 | priv = this->private; | ||
225 | |||
226 | if (!priv->trace) | ||
227 | return; | ||
228 | |||
229 | pl_print_locker (pl_locker, 256, this, frame); | ||
230 | pl_print_lockee (pl_lockee, 256, fd, loc); | ||
231 | pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, domain); | ||
232 | pl_print_verdict (verdict, 32, op_ret, op_errno); | ||
233 | |||
234 | gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("[%s] Locker = {%s} Lockee = {%s} Lock = {%s}" , verdict, pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__, 236, GF_LOG_INFO, "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}", verdict, pl_locker , pl_lockee, pl_entrylk); } while (0) | ||
235 | "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}",do { do { if (0) printf ("[%s] Locker = {%s} Lockee = {%s} Lock = {%s}" , verdict, pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__, 236, GF_LOG_INFO, "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}", verdict, pl_locker , pl_lockee, pl_entrylk); } while (0) | ||
236 | verdict, pl_locker, pl_lockee, pl_entrylk)do { do { if (0) printf ("[%s] Locker = {%s} Lockee = {%s} Lock = {%s}" , verdict, pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__, 236, GF_LOG_INFO, "[%s] Locker = {%s} Lockee = {%s} Lock = {%s}", verdict, pl_locker , pl_lockee, pl_entrylk); } while (0); | ||
237 | } | ||
238 | |||
239 | |||
240 | void | ||
241 | entrylk_trace_block (xlator_t *this, call_frame_t *frame, const char *volume, | ||
242 | fd_t *fd, loc_t *loc, const char *basename, | ||
243 | entrylk_cmd cmd, entrylk_type type) | ||
244 | |||
245 | { | ||
246 | posix_locks_private_t *priv = NULL((void*)0); | ||
247 | char pl_locker[256]; | ||
248 | char pl_lockee[256]; | ||
249 | char pl_entrylk[256]; | ||
250 | |||
251 | priv = this->private; | ||
252 | |||
253 | if (!priv->trace) | ||
254 | return; | ||
255 | |||
256 | pl_print_locker (pl_locker, 256, this, frame); | ||
257 | pl_print_lockee (pl_lockee, 256, fd, loc); | ||
258 | pl_print_entrylk (pl_entrylk, 256, cmd, type, basename, volume); | ||
259 | |||
260 | gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this ->name, "entrylk.c", __FUNCTION__, 262, GF_LOG_INFO, "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0) | ||
261 | "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}",do { do { if (0) printf ("[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this ->name, "entrylk.c", __FUNCTION__, 262, GF_LOG_INFO, "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0) | ||
262 | pl_locker, pl_lockee, pl_entrylk)do { do { if (0) printf ("[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); _gf_log (this ->name, "entrylk.c", __FUNCTION__, 262, GF_LOG_INFO, "[BLOCKED] Locker = {%s} Lockee = {%s} Lock = {%s}" , pl_locker, pl_lockee, pl_entrylk); } while (0); | ||
263 | } | ||
264 | |||
265 | /** | ||
266 | * __find_most_matching_lock - find the lock struct which most matches in order of: | ||
267 | * lock on the exact basename || | ||
268 | * an all_names lock | ||
269 | * | ||
270 | * | ||
271 | * @inode: inode in which to look | ||
272 | * @basename: name to search for | ||
273 | */ | ||
274 | |||
275 | static pl_entry_lock_t * | ||
276 | __find_most_matching_lock (pl_dom_list_t *dom, const char *basename) | ||
277 | { | ||
278 | pl_entry_lock_t *lock; | ||
279 | pl_entry_lock_t *all = NULL((void*)0); | ||
280 | pl_entry_lock_t *exact = NULL((void*)0); | ||
281 | |||
282 | if (list_empty (&dom->entrylk_list)) | ||
283 | return NULL((void*)0); | ||
284 | |||
285 | list_for_each_entry (lock, &dom->entrylk_list, domain_list)for (lock = ((typeof(*lock) *)((char *)((&dom->entrylk_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->domain_list ))); &lock->domain_list != (&dom->entrylk_list) ; lock = ((typeof(*lock) *)((char *)(lock->domain_list.next )-(unsigned long)(&((typeof(*lock) *)0)->domain_list)) )) { | ||
286 | if (all_names (lock->basename)((lock->basename == ((void*)0)) ? 1 : 0)) | ||
287 | all = lock; | ||
288 | else if (names_equal (lock->basename, basename)) | ||
289 | exact = lock; | ||
290 | } | ||
291 | |||
292 | return (exact ? exact : all); | ||
293 | } | ||
294 | |||
295 | /** | ||
296 | * __lock_name - lock a name in a directory | ||
297 | * @inode: inode for the directory in which to lock | ||
298 | * @basename: name of the entry to lock | ||
299 | * if null, lock the entire directory | ||
300 | * | ||
301 | * the entire directory being locked is represented as: a single | ||
302 | * pl_entry_lock_t present in the entrylk_locks list with its | ||
303 | * basename = NULL | ||
304 | */ | ||
305 | |||
306 | int | ||
307 | __lock_name (pl_inode_t *pinode, const char *basename, entrylk_type type, | ||
308 | call_frame_t *frame, pl_dom_list_t *dom, xlator_t *this, int nonblock) | ||
309 | { | ||
310 | pl_entry_lock_t *lock = NULL((void*)0); | ||
311 | pl_entry_lock_t *conf = NULL((void*)0); | ||
312 | void *trans = NULL((void*)0); | ||
313 | pid_t client_pid = 0; | ||
314 | int ret = -EINVAL22; | ||
315 | |||
316 | trans = frame->root->trans; | ||
317 | client_pid = frame->root->pid; | ||
318 | |||
319 | lock = new_entrylk_lock (pinode, basename, type, trans, client_pid, | ||
320 | &frame->root->lk_owner, dom->domain); | ||
321 | if (!lock) { | ||
322 | ret = -ENOMEM12; | ||
323 | goto out; | ||
324 | } | ||
325 | |||
326 | lock->frame = frame; | ||
327 | lock->this = this; | ||
328 | lock->trans = trans; | ||
329 | |||
330 | conf = __lock_grantable (dom, basename, type); | ||
331 | if (conf) { | ||
332 | ret = -EAGAIN11; | ||
333 | if (nonblock){ | ||
334 | GF_FREE ((char *)lock->basename)__gf_free ((char *)lock->basename); | ||
335 | GF_FREE (lock)__gf_free (lock); | ||
336 | goto out; | ||
337 | |||
338 | } | ||
339 | |||
340 | gettimeofday (&lock->blkd_time, NULL((void*)0)); | ||
341 | list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks); | ||
342 | |||
343 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); _gf_log (this->name, "entrylk.c" , __FUNCTION__, 345, GF_LOG_TRACE, "Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0) | ||
344 | "Blocking lock: {pinode=%p, basename=%s}",do { do { if (0) printf ("Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); _gf_log (this->name, "entrylk.c" , __FUNCTION__, 345, GF_LOG_TRACE, "Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0) | ||
345 | pinode, basename)do { do { if (0) printf ("Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); _gf_log (this->name, "entrylk.c" , __FUNCTION__, 345, GF_LOG_TRACE, "Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); | ||
346 | |||
347 | goto out; | ||
348 | } | ||
349 | |||
350 | if ( __blocked_lock_conflict (dom, basename, type) && !(__owner_has_lock (dom, lock))) { | ||
351 | ret = -EAGAIN11; | ||
352 | if (nonblock) { | ||
353 | GF_FREE ((char *) lock->basename)__gf_free ((char *) lock->basename); | ||
354 | GF_FREE (lock)__gf_free (lock); | ||
355 | goto out; | ||
356 | |||
357 | } | ||
358 | lock->frame = frame; | ||
359 | lock->this = this; | ||
360 | |||
361 | gettimeofday (&lock->blkd_time, NULL((void*)0)); | ||
362 | list_add_tail (&lock->blocked_locks, &dom->blocked_entrylks); | ||
363 | |||
364 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("Lock is grantable, but blocking to prevent starvation" ); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 365, GF_LOG_TRACE, "Lock is grantable, but blocking to prevent starvation" ); } while (0) | ||
365 | "Lock is grantable, but blocking to prevent starvation")do { do { if (0) printf ("Lock is grantable, but blocking to prevent starvation" ); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 365, GF_LOG_TRACE, "Lock is grantable, but blocking to prevent starvation" ); } while (0); | ||
366 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); _gf_log (this->name, "entrylk.c" , __FUNCTION__, 368, GF_LOG_TRACE, "Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0) | ||
367 | "Blocking lock: {pinode=%p, basename=%s}",do { do { if (0) printf ("Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); _gf_log (this->name, "entrylk.c" , __FUNCTION__, 368, GF_LOG_TRACE, "Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0) | ||
368 | pinode, basename)do { do { if (0) printf ("Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); _gf_log (this->name, "entrylk.c" , __FUNCTION__, 368, GF_LOG_TRACE, "Blocking lock: {pinode=%p, basename=%s}" , pinode, basename); } while (0); | ||
369 | |||
370 | ret = -EAGAIN11; | ||
371 | goto out; | ||
372 | } | ||
373 | switch (type) { | ||
374 | |||
375 | case ENTRYLK_WRLCK: | ||
376 | gettimeofday (&lock->granted_time, NULL((void*)0)); | ||
377 | list_add_tail (&lock->domain_list, &dom->entrylk_list); | ||
378 | break; | ||
379 | |||
380 | default: | ||
381 | |||
382 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("Invalid type for entrylk specified: %d" , type); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 383, GF_LOG_DEBUG, "Invalid type for entrylk specified: %d" , type); } while (0) | ||
383 | "Invalid type for entrylk specified: %d", type)do { do { if (0) printf ("Invalid type for entrylk specified: %d" , type); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 383, GF_LOG_DEBUG, "Invalid type for entrylk specified: %d" , type); } while (0); | ||
384 | ret = -EINVAL22; | ||
385 | goto out; | ||
386 | } | ||
387 | |||
388 | ret = 0; | ||
389 | out: | ||
390 | return ret; | ||
391 | } | ||
392 | |||
393 | /** | ||
394 | * __unlock_name - unlock a name in a directory | ||
395 | * @inode: inode for the directory to unlock in | ||
396 | * @basename: name of the entry to unlock | ||
397 | * if null, unlock the entire directory | ||
398 | */ | ||
399 | |||
400 | pl_entry_lock_t * | ||
401 | __unlock_name (pl_dom_list_t *dom, const char *basename, entrylk_type type) | ||
402 | { | ||
403 | pl_entry_lock_t *lock = NULL((void*)0); | ||
404 | pl_entry_lock_t *ret_lock = NULL((void*)0); | ||
405 | |||
406 | lock = __find_most_matching_lock (dom, basename); | ||
407 | |||
408 | if (!lock) { | ||
409 | gf_log ("locks", GF_LOG_DEBUG,do { do { if (0) printf ("unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found" , basename); } while (0); _gf_log ("locks", "entrylk.c", __FUNCTION__ , 411, GF_LOG_DEBUG, "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found" , basename); } while (0) | ||
410 | "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found",do { do { if (0) printf ("unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found" , basename); } while (0); _gf_log ("locks", "entrylk.c", __FUNCTION__ , 411, GF_LOG_DEBUG, "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found" , basename); } while (0) | ||
411 | basename)do { do { if (0) printf ("unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found" , basename); } while (0); _gf_log ("locks", "entrylk.c", __FUNCTION__ , 411, GF_LOG_DEBUG, "unlock on %s (type=ENTRYLK_WRLCK) attempted but no matching lock found" , basename); } while (0); | ||
412 | goto out; | ||
413 | } | ||
414 | |||
415 | if (names_equal (lock->basename, basename) | ||
416 | && lock->type == type) { | ||
417 | |||
418 | if (type == ENTRYLK_WRLCK) { | ||
419 | list_del_init (&lock->domain_list); | ||
420 | ret_lock = lock; | ||
421 | } | ||
422 | } else { | ||
423 | gf_log ("locks", GF_LOG_DEBUG,do { do { if (0) printf ("Unlock for a non-existing lock!"); } while (0); _gf_log ("locks", "entrylk.c", __FUNCTION__, 424, GF_LOG_DEBUG, "Unlock for a non-existing lock!"); } while (0 ) | ||
424 | "Unlock for a non-existing lock!")do { do { if (0) printf ("Unlock for a non-existing lock!"); } while (0); _gf_log ("locks", "entrylk.c", __FUNCTION__, 424, GF_LOG_DEBUG, "Unlock for a non-existing lock!"); } while (0 ); | ||
425 | goto out; | ||
426 | } | ||
427 | |||
428 | out: | ||
429 | return ret_lock; | ||
430 | } | ||
431 | |||
432 | uint32_t | ||
433 | check_entrylk_on_basename (xlator_t *this, inode_t *parent, char *basename) | ||
434 | { | ||
435 | uint32_t entrylk = 0; | ||
436 | pl_inode_t *pinode = 0; | ||
437 | pl_dom_list_t *dom = NULL((void*)0); | ||
438 | pl_entry_lock_t *conf = NULL((void*)0); | ||
439 | |||
440 | pinode = pl_inode_get (this, parent); | ||
441 | if (!pinode) | ||
442 | goto out; | ||
443 | pthread_mutex_lock (&pinode->mutex); | ||
444 | { | ||
445 | list_for_each_entry (dom, &pinode->dom_list, inode_list)for (dom = ((typeof(*dom) *)((char *)((&pinode->dom_list )->next)-(unsigned long)(&((typeof(*dom) *)0)->inode_list ))); &dom->inode_list != (&pinode->dom_list); dom = ((typeof(*dom) *)((char *)(dom->inode_list.next)-(unsigned long)(&((typeof(*dom) *)0)->inode_list)))) { | ||
446 | conf = __lock_grantable (dom, basename, ENTRYLK_WRLCK); | ||
447 | if (conf && conf->basename) { | ||
448 | entrylk = 1; | ||
449 | break; | ||
450 | } | ||
451 | } | ||
452 | } | ||
453 | pthread_mutex_unlock (&pinode->mutex); | ||
454 | |||
455 | out: | ||
456 | return entrylk; | ||
457 | } | ||
458 | |||
459 | void | ||
460 | __grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, | ||
461 | pl_dom_list_t *dom, struct list_head *granted) | ||
462 | { | ||
463 | int bl_ret = 0; | ||
464 | pl_entry_lock_t *bl = NULL((void*)0); | ||
465 | pl_entry_lock_t *tmp = NULL((void*)0); | ||
466 | |||
467 | struct list_head blocked_list; | ||
468 | |||
469 | INIT_LIST_HEAD (&blocked_list)do { (&blocked_list)->next = (&blocked_list)->prev = &blocked_list; } while (0); | ||
470 | list_splice_init (&dom->blocked_entrylks, &blocked_list); | ||
471 | |||
472 | list_for_each_entry_safe (bl, tmp, &blocked_list,for (bl = ((typeof(*bl) *)((char *)((&blocked_list)->next )-(unsigned long)(&((typeof(*bl) *)0)->blocked_locks)) ), tmp = ((typeof(*bl) *)((char *)(bl->blocked_locks.next) -(unsigned long)(&((typeof(*bl) *)0)->blocked_locks))) ; &bl->blocked_locks != (&blocked_list); bl = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks.next) -(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks)) )) | ||
473 | blocked_locks)for (bl = ((typeof(*bl) *)((char *)((&blocked_list)->next )-(unsigned long)(&((typeof(*bl) *)0)->blocked_locks)) ), tmp = ((typeof(*bl) *)((char *)(bl->blocked_locks.next) -(unsigned long)(&((typeof(*bl) *)0)->blocked_locks))) ; &bl->blocked_locks != (&blocked_list); bl = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks.next) -(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks)) )) { | ||
474 | |||
475 | list_del_init (&bl->blocked_locks); | ||
476 | |||
477 | |||
478 | gf_log ("locks", GF_LOG_TRACE,do { do { if (0) printf ("Trying to unblock: {pinode=%p, basename=%s}" , pl_inode, bl->basename); } while (0); _gf_log ("locks", "entrylk.c" , __FUNCTION__, 480, GF_LOG_TRACE, "Trying to unblock: {pinode=%p, basename=%s}" , pl_inode, bl->basename); } while (0) | ||
479 | "Trying to unblock: {pinode=%p, basename=%s}",do { do { if (0) printf ("Trying to unblock: {pinode=%p, basename=%s}" , pl_inode, bl->basename); } while (0); _gf_log ("locks", "entrylk.c" , __FUNCTION__, 480, GF_LOG_TRACE, "Trying to unblock: {pinode=%p, basename=%s}" , pl_inode, bl->basename); } while (0) | ||
480 | pl_inode, bl->basename)do { do { if (0) printf ("Trying to unblock: {pinode=%p, basename=%s}" , pl_inode, bl->basename); } while (0); _gf_log ("locks", "entrylk.c" , __FUNCTION__, 480, GF_LOG_TRACE, "Trying to unblock: {pinode=%p, basename=%s}" , pl_inode, bl->basename); } while (0); | ||
481 | |||
482 | bl_ret = __lock_name (pl_inode, bl->basename, bl->type, | ||
483 | bl->frame, dom, bl->this, 0); | ||
484 | |||
485 | if (bl_ret == 0) { | ||
486 | list_add (&bl->blocked_locks, granted); | ||
487 | } else { | ||
488 | gf_log (this->name, GF_LOG_DEBUG,do { do { if (0) printf ("should never happen"); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__, 489, GF_LOG_DEBUG , "should never happen"); } while (0) | ||
489 | "should never happen")do { do { if (0) printf ("should never happen"); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__, 489, GF_LOG_DEBUG , "should never happen"); } while (0); | ||
490 | GF_FREE ((char *)bl->basename)__gf_free ((char *)bl->basename); | ||
491 | GF_FREE (bl)__gf_free (bl); | ||
492 | } | ||
493 | } | ||
494 | return; | ||
495 | } | ||
496 | |||
497 | /* Grants locks if possible which are blocked on a lock */ | ||
498 | void | ||
499 | grant_blocked_entry_locks (xlator_t *this, pl_inode_t *pl_inode, | ||
500 | pl_entry_lock_t *unlocked, pl_dom_list_t *dom) | ||
501 | { | ||
502 | struct list_head granted_list; | ||
503 | pl_entry_lock_t *tmp = NULL((void*)0); | ||
504 | pl_entry_lock_t *lock = NULL((void*)0); | ||
505 | |||
506 | INIT_LIST_HEAD (&granted_list)do { (&granted_list)->next = (&granted_list)->prev = &granted_list; } while (0); | ||
507 | |||
508 | pthread_mutex_lock (&pl_inode->mutex); | ||
509 | { | ||
510 | __grant_blocked_entry_locks (this, pl_inode, dom, &granted_list); | ||
511 | } | ||
512 | pthread_mutex_unlock (&pl_inode->mutex); | ||
513 | |||
514 | list_for_each_entry_safe (lock, tmp, &granted_list, blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&granted_list)-> next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))), tmp = ((typeof(*lock) *)((char *)(lock->blocked_locks .next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&granted_list); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks .next)-(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks )))) { | ||
515 | list_del_init (&lock->blocked_locks); | ||
516 | |||
517 | entrylk_trace_out (this, lock->frame, NULL((void*)0), NULL((void*)0), NULL((void*)0), | ||
518 | lock->basename, ENTRYLK_LOCK, lock->type, | ||
519 | 0, 0); | ||
520 | |||
521 | STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL)do { fop_entrylk_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!lock-> frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack", "entrylk.c", __FUNCTION__, 521, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_entrylk_cbk_t )lock->frame ->ret; _parent = lock->frame->parent; pthread_spin_lock (&lock->frame->root->stack_lock); { _parent-> ref_count--; } pthread_spin_unlock (&lock->frame->root ->stack_lock); old_THIS = (*__glusterfs_this_location()); ( *__glusterfs_this_location()) = _parent->this; lock->frame ->complete = _gf_true; lock->frame->unwind_from = __FUNCTION__ ; if (lock->frame->this->ctx->measure_latency) gf_latency_end (lock->frame); fn (_parent, lock->frame->cookie, _parent ->this, 0, 0, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); | ||
522 | |||
523 | } | ||
524 | |||
525 | GF_FREE ((char *)unlocked->basename)__gf_free ((char *)unlocked->basename); | ||
526 | GF_FREE (unlocked)__gf_free (unlocked); | ||
527 | |||
528 | return; | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * release_entry_locks_for_transport: release all entry locks from this | ||
533 | * transport for this loc_t | ||
534 | */ | ||
535 | |||
536 | static int | ||
537 | release_entry_locks_for_transport (xlator_t *this, pl_inode_t *pinode, | ||
538 | pl_dom_list_t *dom, void *trans) | ||
539 | { | ||
540 | pl_entry_lock_t *lock = NULL((void*)0); | ||
541 | pl_entry_lock_t *tmp = NULL((void*)0); | ||
542 | struct list_head granted; | ||
543 | struct list_head released; | ||
544 | |||
545 | INIT_LIST_HEAD (&granted)do { (&granted)->next = (&granted)->prev = & granted; } while (0); | ||
546 | INIT_LIST_HEAD (&released)do { (&released)->next = (&released)->prev = & released; } while (0); | ||
547 | |||
548 | pthread_mutex_lock (&pinode->mutex); | ||
549 | { | ||
550 | list_for_each_entry_safe (lock, tmp, &dom->blocked_entrylks,for (lock = ((typeof(*lock) *)((char *)((&dom->blocked_entrylks )->next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))), tmp = ((typeof(*lock) *)((char *)(lock->blocked_locks .next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&dom->blocked_entrylks ); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks .next)-(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks )))) | ||
551 | blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&dom->blocked_entrylks )->next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))), tmp = ((typeof(*lock) *)((char *)(lock->blocked_locks .next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&dom->blocked_entrylks ); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks .next)-(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks )))) { | ||
552 | if (lock->trans != trans) | ||
553 | continue; | ||
554 | |||
555 | list_del_init (&lock->blocked_locks); | ||
556 | |||
557 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("releasing lock on held by " "{transport=%p}" ,trans); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 559, GF_LOG_TRACE, "releasing lock on held by " "{transport=%p}" ,trans); } while (0) | ||
558 | "releasing lock on held by "do { do { if (0) printf ("releasing lock on held by " "{transport=%p}" ,trans); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 559, GF_LOG_TRACE, "releasing lock on held by " "{transport=%p}" ,trans); } while (0) | ||
559 | "{transport=%p}",trans)do { do { if (0) printf ("releasing lock on held by " "{transport=%p}" ,trans); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 559, GF_LOG_TRACE, "releasing lock on held by " "{transport=%p}" ,trans); } while (0); | ||
560 | |||
561 | list_add (&lock->blocked_locks, &released); | ||
562 | |||
563 | } | ||
564 | |||
565 | list_for_each_entry_safe (lock, tmp, &dom->entrylk_list,for (lock = ((typeof(*lock) *)((char *)((&dom->entrylk_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->domain_list ))), tmp = ((typeof(*lock) *)((char *)(lock->domain_list.next )-(unsigned long)(&((typeof(*lock) *)0)->domain_list)) ); &lock->domain_list != (&dom->entrylk_list); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->domain_list. next)-(unsigned long)(&((typeof(*tmp) *)0)->domain_list )))) | ||
566 | domain_list)for (lock = ((typeof(*lock) *)((char *)((&dom->entrylk_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->domain_list ))), tmp = ((typeof(*lock) *)((char *)(lock->domain_list.next )-(unsigned long)(&((typeof(*lock) *)0)->domain_list)) ); &lock->domain_list != (&dom->entrylk_list); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->domain_list. next)-(unsigned long)(&((typeof(*tmp) *)0)->domain_list )))) { | ||
567 | if (lock->trans != trans) | ||
568 | continue; | ||
569 | |||
570 | list_del_init (&lock->domain_list); | ||
571 | |||
572 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("releasing lock on held by " "{transport=%p}" ,trans); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 574, GF_LOG_TRACE, "releasing lock on held by " "{transport=%p}" ,trans); } while (0) | ||
573 | "releasing lock on held by "do { do { if (0) printf ("releasing lock on held by " "{transport=%p}" ,trans); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 574, GF_LOG_TRACE, "releasing lock on held by " "{transport=%p}" ,trans); } while (0) | ||
574 | "{transport=%p}",trans)do { do { if (0) printf ("releasing lock on held by " "{transport=%p}" ,trans); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 574, GF_LOG_TRACE, "releasing lock on held by " "{transport=%p}" ,trans); } while (0); | ||
575 | |||
576 | GF_FREE ((char *)lock->basename)__gf_free ((char *)lock->basename); | ||
577 | GF_FREE (lock)__gf_free (lock); | ||
578 | } | ||
579 | |||
580 | __grant_blocked_entry_locks (this, pinode, dom, &granted); | ||
581 | |||
582 | } | ||
583 | |||
584 | pthread_mutex_unlock (&pinode->mutex); | ||
585 | |||
586 | list_for_each_entry_safe (lock, tmp, &released, blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&released)->next )-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))), tmp = ((typeof(*lock) *)((char *)(lock->blocked_locks .next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&released); lock = tmp , tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks.next )-(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks) ))) { | ||
Within the expansion of the macro 'list_for_each_entry_safe':
| |||
587 | list_del_init (&lock->blocked_locks); | ||
588 | |||
589 | STACK_UNWIND_STRICT (entrylk, lock->frame, -1, EAGAIN, NULL)do { fop_entrylk_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!lock-> frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack", "entrylk.c", __FUNCTION__, 589, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_entrylk_cbk_t )lock->frame ->ret; _parent = lock->frame->parent; pthread_spin_lock (&lock->frame->root->stack_lock); { _parent-> ref_count--; } pthread_spin_unlock (&lock->frame->root ->stack_lock); old_THIS = (*__glusterfs_this_location()); ( *__glusterfs_this_location()) = _parent->this; lock->frame ->complete = _gf_true; lock->frame->unwind_from = __FUNCTION__ ; if (lock->frame->this->ctx->measure_latency) gf_latency_end (lock->frame); fn (_parent, lock->frame->cookie, _parent ->this, -1, 11, ((void*)0)); (*__glusterfs_this_location() ) = old_THIS; } while (0); | ||
590 | |||
591 | GF_FREE ((char *)lock->basename)__gf_free ((char *)lock->basename); | ||
592 | GF_FREE (lock)__gf_free (lock); | ||
593 | |||
594 | } | ||
595 | |||
596 | list_for_each_entry_safe (lock, tmp, &granted, blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&granted)->next )-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))), tmp = ((typeof(*lock) *)((char *)(lock->blocked_locks .next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&granted); lock = tmp , tmp = ((typeof(*tmp) *)((char *)(tmp->blocked_locks.next )-(unsigned long)(&((typeof(*tmp) *)0)->blocked_locks) ))) { | ||
597 | list_del_init (&lock->blocked_locks); | ||
598 | |||
599 | STACK_UNWIND_STRICT (entrylk, lock->frame, 0, 0, NULL)do { fop_entrylk_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!lock-> frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack", "entrylk.c", __FUNCTION__, 599, GF_LOG_CRITICAL, "!frame" ); } while (0); break; } fn = (fop_entrylk_cbk_t )lock->frame ->ret; _parent = lock->frame->parent; pthread_spin_lock (&lock->frame->root->stack_lock); { _parent-> ref_count--; } pthread_spin_unlock (&lock->frame->root ->stack_lock); old_THIS = (*__glusterfs_this_location()); ( *__glusterfs_this_location()) = _parent->this; lock->frame ->complete = _gf_true; lock->frame->unwind_from = __FUNCTION__ ; if (lock->frame->this->ctx->measure_latency) gf_latency_end (lock->frame); fn (_parent, lock->frame->cookie, _parent ->this, 0, 0, ((void*)0)); (*__glusterfs_this_location()) = old_THIS; } while (0); | ||
600 | |||
601 | GF_FREE ((char *)lock->basename)__gf_free ((char *)lock->basename); | ||
602 | GF_FREE (lock)__gf_free (lock); | ||
603 | } | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | /* Common entrylk code called by pl_entrylk and pl_fentrylk */ | ||
609 | int | ||
610 | pl_common_entrylk (call_frame_t *frame, xlator_t *this, | ||
611 | const char *volume, inode_t *inode, const char *basename, | ||
612 | entrylk_cmd cmd, entrylk_type type, loc_t *loc, fd_t *fd) | ||
613 | { | ||
614 | int32_t op_ret = -1; | ||
615 | int32_t op_errno = 0; | ||
616 | |||
617 | void * transport = NULL((void*)0); | ||
618 | |||
619 | pl_inode_t * pinode = NULL((void*)0); | ||
620 | int ret = -1; | ||
621 | pl_entry_lock_t *unlocked = NULL((void*)0); | ||
622 | char unwind = 1; | ||
623 | |||
624 | pl_dom_list_t *dom = NULL((void*)0); | ||
625 | |||
626 | pinode = pl_inode_get (this, inode); | ||
627 | if (!pinode) { | ||
628 | op_errno = ENOMEM12; | ||
629 | goto out; | ||
630 | } | ||
631 | |||
632 | dom = get_domain (pinode, volume); | ||
633 | if (!dom){ | ||
634 | op_errno = ENOMEM12; | ||
635 | goto out; | ||
636 | } | ||
637 | |||
638 | entrylk_trace_in (this, frame, volume, fd, loc, basename, cmd, type); | ||
639 | |||
640 | transport = frame->root->trans; | ||
641 | |||
642 | if (frame->root->lk_owner.len == 0) { | ||
643 | /* | ||
644 | this is a special case that means release | ||
645 | all locks from this transport | ||
646 | */ | ||
647 | |||
648 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("Releasing locks for transport %p", transport ); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 649, GF_LOG_TRACE, "Releasing locks for transport %p", transport ); } while (0) | ||
649 | "Releasing locks for transport %p", transport)do { do { if (0) printf ("Releasing locks for transport %p", transport ); } while (0); _gf_log (this->name, "entrylk.c", __FUNCTION__ , 649, GF_LOG_TRACE, "Releasing locks for transport %p", transport ); } while (0); | ||
650 | |||
651 | release_entry_locks_for_transport (this, pinode, dom, transport); | ||
652 | op_ret = 0; | ||
653 | |||
654 | goto out; | ||
655 | } | ||
656 | |||
657 | switch (cmd) { | ||
658 | case ENTRYLK_LOCK: | ||
659 | pthread_mutex_lock (&pinode->mutex); | ||
660 | { | ||
661 | ret = __lock_name (pinode, basename, type, | ||
662 | frame, dom, this, 0); | ||
663 | } | ||
664 | pthread_mutex_unlock (&pinode->mutex); | ||
665 | |||
666 | op_errno = -ret; | ||
667 | if (ret < 0) { | ||
668 | if (ret == -EAGAIN11) | ||
669 | unwind = 0; | ||
670 | else | ||
671 | unwind = 1; | ||
672 | goto out; | ||
673 | } else { | ||
674 | op_ret = 0; | ||
675 | op_errno = 0; | ||
676 | unwind = 1; | ||
677 | goto out; | ||
678 | } | ||
679 | |||
680 | break; | ||
681 | |||
682 | case ENTRYLK_LOCK_NB: | ||
683 | unwind = 1; | ||
684 | pthread_mutex_lock (&pinode->mutex); | ||
685 | { | ||
686 | ret = __lock_name (pinode, basename, type, | ||
687 | frame, dom, this, 1); | ||
688 | } | ||
689 | pthread_mutex_unlock (&pinode->mutex); | ||
690 | |||
691 | if (ret < 0) { | ||
692 | op_errno = -ret; | ||
693 | goto out; | ||
694 | } | ||
695 | |||
696 | break; | ||
697 | |||
698 | case ENTRYLK_UNLOCK: | ||
699 | pthread_mutex_lock (&pinode->mutex); | ||
700 | { | ||
701 | unlocked = __unlock_name (dom, basename, type); | ||
702 | } | ||
703 | pthread_mutex_unlock (&pinode->mutex); | ||
704 | |||
705 | if (unlocked) | ||
706 | grant_blocked_entry_locks (this, pinode, unlocked, dom); | ||
707 | |||
708 | break; | ||
709 | |||
710 | default: | ||
711 | gf_log (this->name, GF_LOG_ERROR,do { do { if (0) printf ("Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com", cmd); } while (0) ; _gf_log (this->name, "entrylk.c", __FUNCTION__, 713, GF_LOG_ERROR , "Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com" , cmd); } while (0) | ||
712 | "Unexpected case in entrylk (cmd=%d). Please file"do { do { if (0) printf ("Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com", cmd); } while (0) ; _gf_log (this->name, "entrylk.c", __FUNCTION__, 713, GF_LOG_ERROR , "Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com" , cmd); } while (0) | ||
713 | "a bug report at http://bugs.gluster.com", cmd)do { do { if (0) printf ("Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com", cmd); } while (0) ; _gf_log (this->name, "entrylk.c", __FUNCTION__, 713, GF_LOG_ERROR , "Unexpected case in entrylk (cmd=%d). Please file" "a bug report at http://bugs.gluster.com" , cmd); } while (0); | ||
714 | goto out; | ||
715 | } | ||
716 | |||
717 | op_ret = 0; | ||
718 | out: | ||
719 | pl_update_refkeeper (this, inode); | ||
720 | if (unwind) { | ||
721 | entrylk_trace_out (this, frame, volume, fd, loc, basename, | ||
722 | cmd, type, op_ret, op_errno); | ||
723 | |||
724 | STACK_UNWIND_STRICT (entrylk, frame, op_ret, op_errno, NULL)do { fop_entrylk_cbk_t fn = ((void*)0); call_frame_t *_parent = ((void*)0); xlator_t *old_THIS = ((void*)0); if (!frame) { do { do { if (0) printf ("!frame"); } while (0); _gf_log ("stack" , "entrylk.c", __FUNCTION__, 724, GF_LOG_CRITICAL, "!frame"); } while (0); break; } fn = (fop_entrylk_cbk_t )frame->ret ; _parent = frame->parent; pthread_spin_lock (&frame-> root->stack_lock); { _parent->ref_count--; } pthread_spin_unlock (&frame->root->stack_lock); old_THIS = (*__glusterfs_this_location ()); (*__glusterfs_this_location()) = _parent->this; frame ->complete = _gf_true; frame->unwind_from = __FUNCTION__ ; if (frame->this->ctx->measure_latency) gf_latency_end (frame); fn (_parent, frame->cookie, _parent->this, op_ret , op_errno, ((void*)0)); (*__glusterfs_this_location()) = old_THIS ; } while (0); | ||
725 | } else { | ||
726 | entrylk_trace_block (this, frame, volume, fd, loc, basename, | ||
727 | cmd, type); | ||
728 | } | ||
729 | |||
730 | |||
731 | return 0; | ||
732 | } | ||
733 | |||
734 | /** | ||
735 | * pl_entrylk: | ||
736 | * | ||
737 | * Locking on names (directory entries) | ||
738 | */ | ||
739 | |||
740 | int | ||
741 | pl_entrylk (call_frame_t *frame, xlator_t *this, | ||
742 | const char *volume, loc_t *loc, const char *basename, | ||
743 | entrylk_cmd cmd, entrylk_type type) | ||
744 | { | ||
745 | |||
746 | pl_common_entrylk (frame, this, volume, loc->inode, basename, cmd, type, loc, NULL((void*)0)); | ||
747 | |||
748 | return 0; | ||
749 | } | ||
750 | |||
751 | |||
752 | /** | ||
753 | * pl_fentrylk: | ||
754 | * | ||
755 | * Locking on names (directory entries) | ||
756 | */ | ||
757 | |||
758 | int | ||
759 | pl_fentrylk (call_frame_t *frame, xlator_t *this, | ||
760 | const char *volume, fd_t *fd, const char *basename, | ||
761 | entrylk_cmd cmd, entrylk_type type) | ||
762 | { | ||
763 | |||
764 | pl_common_entrylk (frame, this, volume, fd->inode, basename, cmd, type, NULL((void*)0), fd); | ||
765 | |||
766 | return 0; | ||
767 | } | ||
768 | |||
769 | |||
770 | int32_t | ||
771 | __get_entrylk_count (xlator_t *this, pl_inode_t *pl_inode) | ||
772 | { | ||
773 | int32_t count = 0; | ||
774 | pl_entry_lock_t *lock = NULL((void*)0); | ||
775 | pl_dom_list_t *dom = NULL((void*)0); | ||
776 | |||
777 | list_for_each_entry (dom, &pl_inode->dom_list, inode_list)for (dom = ((typeof(*dom) *)((char *)((&pl_inode->dom_list )->next)-(unsigned long)(&((typeof(*dom) *)0)->inode_list ))); &dom->inode_list != (&pl_inode->dom_list); dom = ((typeof(*dom) *)((char *)(dom->inode_list.next)-(unsigned long)(&((typeof(*dom) *)0)->inode_list)))) { | ||
778 | list_for_each_entry (lock, &dom->entrylk_list, domain_list)for (lock = ((typeof(*lock) *)((char *)((&dom->entrylk_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->domain_list ))); &lock->domain_list != (&dom->entrylk_list) ; lock = ((typeof(*lock) *)((char *)(lock->domain_list.next )-(unsigned long)(&((typeof(*lock) *)0)->domain_list)) )) { | ||
779 | count++; | ||
780 | } | ||
781 | |||
782 | list_for_each_entry (lock, &dom->blocked_entrylks, blocked_locks)for (lock = ((typeof(*lock) *)((char *)((&dom->blocked_entrylks )->next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks ))); &lock->blocked_locks != (&dom->blocked_entrylks ); lock = ((typeof(*lock) *)((char *)(lock->blocked_locks. next)-(unsigned long)(&((typeof(*lock) *)0)->blocked_locks )))) { | ||
783 | count++; | ||
784 | } | ||
785 | |||
786 | } | ||
787 | |||
788 | return count; | ||
789 | } | ||
790 | |||
791 | int32_t | ||
792 | get_entrylk_count (xlator_t *this, inode_t *inode) | ||
793 | { | ||
794 | pl_inode_t *pl_inode = NULL((void*)0); | ||
795 | uint64_t tmp_pl_inode = 0; | ||
796 | int ret = 0; | ||
797 | int32_t count = 0; | ||
798 | |||
799 | ret = inode_ctx_get (inode, this, &tmp_pl_inode)inode_ctx_get2(inode,this,&tmp_pl_inode,0); | ||
800 | if (ret != 0) { | ||
801 | goto out; | ||
802 | } | ||
803 | |||
804 | pl_inode = (pl_inode_t *)(long) tmp_pl_inode; | ||
805 | |||
806 | pthread_mutex_lock (&pl_inode->mutex); | ||
807 | { | ||
808 | count = __get_entrylk_count (this, pl_inode); | ||
809 | } | ||
810 | pthread_mutex_unlock (&pl_inode->mutex); | ||
811 | |||
812 | out: | ||
813 | return count; | ||
814 | } |