File: | xlators/protocol/client/src/client-lk.c |
Location: | line 191, column 3 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | |||
2 | Copyright (c) 2008-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 | ||||
11 | #include "common-utils.h" | |||
12 | #include "xlator.h" | |||
13 | #include "client.h" | |||
14 | #include "lkowner.h" | |||
15 | ||||
16 | static void | |||
17 | __insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock); | |||
18 | ||||
19 | static void | |||
20 | __dump_client_lock (client_posix_lock_t *lock) | |||
21 | { | |||
22 | xlator_t *this = NULL((void*)0); | |||
23 | ||||
24 | this = THIS(*__glusterfs_this_location()); | |||
25 | ||||
26 | gf_log (this->name, GF_LOG_INFO,do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
27 | "{fd=%p}"do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
28 | "{%s lk-owner:%s %"PRId64" - %"PRId64"}"do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
29 | "{start=%"PRId64" end=%"PRId64"}",do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
30 | lock->fd,do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
31 | lock->fl_type == F_WRLCK ? "Write-Lock" : "Read-Lock",do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
32 | lkowner_utoa (&lock->owner),do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
33 | lock->user_flock.l_start,do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
34 | lock->user_flock.l_len,do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
35 | lock->fl_start,do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0) | |||
36 | lock->fl_end)do { do { if (0) printf ("{fd=%p}" "{%s lk-owner:%s %""ll" "d" " - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock ->fd, lock->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa (&lock->owner), lock->user_flock.l_start, lock-> user_flock.l_len, lock->fl_start, lock->fl_end); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 36 , GF_LOG_INFO, "{fd=%p}" "{%s lk-owner:%s %""ll" "d"" - %""ll" "d""}" "{start=%""ll" "d"" end=%""ll" "d""}", lock->fd, lock ->fl_type == 1 ? "Write-Lock" : "Read-Lock", lkowner_utoa ( &lock->owner), lock->user_flock.l_start, lock->user_flock .l_len, lock->fl_start, lock->fl_end); } while (0); | |||
37 | } | |||
38 | ||||
39 | static int | |||
40 | dump_client_locks_fd (clnt_fd_ctx_t *fdctx) | |||
41 | { | |||
42 | client_posix_lock_t *lock = NULL((void*)0); | |||
43 | int count = 0; | |||
44 | ||||
45 | pthread_mutex_lock (&fdctx->mutex); | |||
46 | { | |||
47 | list_for_each_entry (lock, &fdctx->lock_list, list)for (lock = ((typeof(*lock) *)((char *)((&fdctx->lock_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->list ))); &lock->list != (&fdctx->lock_list); lock = ((typeof(*lock) *)((char *)(lock->list.next)-(unsigned long )(&((typeof(*lock) *)0)->list)))) { | |||
48 | __dump_client_lock (lock); | |||
49 | count++; | |||
50 | } | |||
51 | } | |||
52 | pthread_mutex_unlock (&fdctx->mutex); | |||
53 | ||||
54 | return count; | |||
55 | ||||
56 | } | |||
57 | ||||
58 | int | |||
59 | dump_client_locks (inode_t *inode) | |||
60 | { | |||
61 | fd_t *fd = NULL((void*)0); | |||
62 | clnt_conf_t *conf = NULL((void*)0); | |||
63 | xlator_t *this = NULL((void*)0); | |||
64 | clnt_fd_ctx_t *fdctx = NULL((void*)0); | |||
65 | ||||
66 | int total_count = 0; | |||
67 | int locks_fd_count = 0; | |||
68 | ||||
69 | this = THIS(*__glusterfs_this_location()); | |||
70 | conf = this->private; | |||
71 | ||||
72 | LOCK (&inode->lock)pthread_spin_lock (&inode->lock); | |||
73 | { | |||
74 | list_for_each_entry (fd, &inode->fd_list, inode_list)for (fd = ((typeof(*fd) *)((char *)((&inode->fd_list)-> next)-(unsigned long)(&((typeof(*fd) *)0)->inode_list) )); &fd->inode_list != (&inode->fd_list); fd = ( (typeof(*fd) *)((char *)(fd->inode_list.next)-(unsigned long )(&((typeof(*fd) *)0)->inode_list)))) { | |||
75 | locks_fd_count = 0; | |||
76 | ||||
77 | pthread_mutex_lock (&conf->lock); | |||
78 | { | |||
79 | fdctx = this_fd_get_ctx (fd, this); | |||
80 | } | |||
81 | pthread_mutex_unlock (&conf->lock); | |||
82 | ||||
83 | if (fdctx) | |||
84 | locks_fd_count = dump_client_locks_fd (fdctx); | |||
85 | ||||
86 | total_count += locks_fd_count; | |||
87 | } | |||
88 | ||||
89 | } | |||
90 | UNLOCK (&inode->lock)pthread_spin_unlock (&inode->lock); | |||
91 | ||||
92 | return total_count; | |||
93 | ||||
94 | } | |||
95 | ||||
96 | static off_t | |||
97 | __get_lock_length (off_t start, off_t end) | |||
98 | { | |||
99 | if (end == LLONG_MAX9223372036854775807LL) | |||
100 | return 0; | |||
101 | else | |||
102 | return (end - start + 1); | |||
103 | } | |||
104 | ||||
105 | /* Add two locks */ | |||
106 | static client_posix_lock_t * | |||
107 | add_locks (client_posix_lock_t *l1, client_posix_lock_t *l2) | |||
108 | { | |||
109 | client_posix_lock_t *sum = NULL((void*)0); | |||
110 | ||||
111 | sum = GF_CALLOC (1, sizeof (*sum), gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (*sum), gf_client_mt_clnt_lock_t); | |||
112 | if (!sum) | |||
113 | return NULL((void*)0); | |||
114 | ||||
115 | sum->fl_start = min (l1->fl_start, l2->fl_start)((l1->fl_start)<(l2->fl_start)?(l1->fl_start):(l2 ->fl_start)); | |||
116 | sum->fl_end = max (l1->fl_end, l2->fl_end)((l1->fl_end)>(l2->fl_end)?(l1->fl_end):(l2->fl_end )); | |||
117 | ||||
118 | sum->user_flock.l_start = sum->fl_start; | |||
119 | sum->user_flock.l_len = __get_lock_length (sum->fl_start, | |||
120 | sum->fl_end); | |||
121 | ||||
122 | return sum; | |||
123 | } | |||
124 | ||||
125 | ||||
126 | /* Return true if the locks overlap, false otherwise */ | |||
127 | static int | |||
128 | locks_overlap (client_posix_lock_t *l1, client_posix_lock_t *l2) | |||
129 | { | |||
130 | /* | |||
131 | Note: | |||
132 | FUSE always gives us absolute offsets, so no need to worry | |||
133 | about SEEK_CUR or SEEK_END | |||
134 | */ | |||
135 | ||||
136 | return ((l1->fl_end >= l2->fl_start) && | |||
137 | (l2->fl_end >= l1->fl_start)); | |||
138 | } | |||
139 | ||||
140 | static void | |||
141 | __delete_client_lock (client_posix_lock_t *lock) | |||
142 | { | |||
143 | list_del_init (&lock->list); | |||
144 | } | |||
145 | ||||
146 | /* Destroy a posix_lock */ | |||
147 | static void | |||
148 | __destroy_client_lock (client_posix_lock_t *lock) | |||
149 | { | |||
150 | GF_FREE (lock)__gf_free (lock); | |||
151 | } | |||
152 | ||||
153 | /* Subtract two locks */ | |||
154 | struct _values { | |||
155 | client_posix_lock_t *locks[3]; | |||
156 | }; | |||
157 | ||||
158 | /* {big} must always be contained inside {small} */ | |||
159 | static struct _values | |||
160 | subtract_locks (client_posix_lock_t *big, client_posix_lock_t *small) | |||
161 | { | |||
162 | struct _values v = { .locks = {0, 0, 0} }; | |||
163 | ||||
164 | if ((big->fl_start == small->fl_start) && | |||
165 | (big->fl_end == small->fl_end)) { | |||
166 | /* both edges coincide with big */ | |||
167 | v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
168 | gf_client_mt_clnt_lock_t )__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
169 | GF_ASSERT (v.locks[0])do { if (!(v.locks[0])) { do { do { if (0) printf ("Assertion failed: " "v.locks[0]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 169, GF_LOG_ERROR, "Assertion failed: " "v.locks[0]" ); } while (0); } } while (0); | |||
170 | memcpy (v.locks[0], big, sizeof (client_posix_lock_t)); | |||
171 | v.locks[0]->fl_type = small->fl_type; | |||
172 | } | |||
173 | else if ((small->fl_start > big->fl_start) && | |||
| ||||
174 | (small->fl_end < big->fl_end)) { | |||
175 | /* both edges lie inside big */ | |||
176 | v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
177 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
178 | GF_ASSERT (v.locks[0])do { if (!(v.locks[0])) { do { do { if (0) printf ("Assertion failed: " "v.locks[0]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 178, GF_LOG_ERROR, "Assertion failed: " "v.locks[0]" ); } while (0); } } while (0); | |||
179 | v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
180 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
181 | GF_ASSERT (v.locks[1])do { if (!(v.locks[1])) { do { do { if (0) printf ("Assertion failed: " "v.locks[1]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 181, GF_LOG_ERROR, "Assertion failed: " "v.locks[1]" ); } while (0); } } while (0); | |||
182 | v.locks[2] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
183 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
184 | GF_ASSERT (v.locks[2])do { if (!(v.locks[2])) { do { do { if (0) printf ("Assertion failed: " "v.locks[2]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 184, GF_LOG_ERROR, "Assertion failed: " "v.locks[2]" ); } while (0); } } while (0); | |||
185 | ||||
186 | memcpy (v.locks[0], big, sizeof (client_posix_lock_t)); | |||
187 | v.locks[0]->fl_end = small->fl_start - 1; | |||
188 | v.locks[0]->user_flock.l_len = __get_lock_length (v.locks[0]->fl_start, | |||
189 | v.locks[0]->fl_end); | |||
190 | ||||
191 | memcpy (v.locks[1], small, sizeof (client_posix_lock_t)); | |||
| ||||
192 | memcpy (v.locks[2], big, sizeof (client_posix_lock_t)); | |||
193 | v.locks[2]->fl_start = small->fl_end + 1; | |||
194 | v.locks[2]->user_flock.l_start = small->fl_end + 1; | |||
195 | } | |||
196 | /* one edge coincides with big */ | |||
197 | else if (small->fl_start == big->fl_start) { | |||
198 | v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
199 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
200 | GF_ASSERT (v.locks[0])do { if (!(v.locks[0])) { do { do { if (0) printf ("Assertion failed: " "v.locks[0]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 200, GF_LOG_ERROR, "Assertion failed: " "v.locks[0]" ); } while (0); } } while (0); | |||
201 | v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
202 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
203 | GF_ASSERT (v.locks[1])do { if (!(v.locks[1])) { do { do { if (0) printf ("Assertion failed: " "v.locks[1]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 203, GF_LOG_ERROR, "Assertion failed: " "v.locks[1]" ); } while (0); } } while (0); | |||
204 | ||||
205 | memcpy (v.locks[0], big, sizeof (client_posix_lock_t)); | |||
206 | v.locks[0]->fl_start = small->fl_end + 1; | |||
207 | v.locks[0]->user_flock.l_start = small->fl_end + 1; | |||
208 | ||||
209 | memcpy (v.locks[1], small, sizeof (client_posix_lock_t)); | |||
210 | } | |||
211 | else if (small->fl_end == big->fl_end) { | |||
212 | v.locks[0] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
213 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
214 | GF_ASSERT (v.locks[0])do { if (!(v.locks[0])) { do { do { if (0) printf ("Assertion failed: " "v.locks[0]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 214, GF_LOG_ERROR, "Assertion failed: " "v.locks[0]" ); } while (0); } } while (0); | |||
215 | v.locks[1] = GF_CALLOC (1, sizeof (client_posix_lock_t),__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ) | |||
216 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (client_posix_lock_t), gf_client_mt_clnt_lock_t ); | |||
217 | GF_ASSERT (v.locks[1])do { if (!(v.locks[1])) { do { do { if (0) printf ("Assertion failed: " "v.locks[1]"); } while (0); _gf_log_callingfn ("", "client-lk.c" , __FUNCTION__, 217, GF_LOG_ERROR, "Assertion failed: " "v.locks[1]" ); } while (0); } } while (0); | |||
218 | ||||
219 | memcpy (v.locks[0], big, sizeof (client_posix_lock_t)); | |||
220 | v.locks[0]->fl_end = small->fl_start - 1; | |||
221 | v.locks[0]->user_flock.l_len = __get_lock_length (v.locks[0]->fl_start, | |||
222 | v.locks[0]->fl_end); | |||
223 | ||||
224 | memcpy (v.locks[1], small, sizeof (client_posix_lock_t)); | |||
225 | } | |||
226 | else { | |||
227 | /* LOG-TODO : decide what more info is required here*/ | |||
228 | gf_log ("client-protocol", GF_LOG_CRITICAL,do { do { if (0) printf ("Unexpected case in subtract_locks. Please send " "a bug report to gluster-devel@nongnu.org"); } while (0); _gf_log ("client-protocol", "client-lk.c", __FUNCTION__, 230, GF_LOG_CRITICAL , "Unexpected case in subtract_locks. Please send " "a bug report to gluster-devel@nongnu.org" ); } while (0) | |||
229 | "Unexpected case in subtract_locks. Please send "do { do { if (0) printf ("Unexpected case in subtract_locks. Please send " "a bug report to gluster-devel@nongnu.org"); } while (0); _gf_log ("client-protocol", "client-lk.c", __FUNCTION__, 230, GF_LOG_CRITICAL , "Unexpected case in subtract_locks. Please send " "a bug report to gluster-devel@nongnu.org" ); } while (0) | |||
230 | "a bug report to gluster-devel@nongnu.org")do { do { if (0) printf ("Unexpected case in subtract_locks. Please send " "a bug report to gluster-devel@nongnu.org"); } while (0); _gf_log ("client-protocol", "client-lk.c", __FUNCTION__, 230, GF_LOG_CRITICAL , "Unexpected case in subtract_locks. Please send " "a bug report to gluster-devel@nongnu.org" ); } while (0); | |||
231 | } | |||
232 | ||||
233 | return v; | |||
234 | } | |||
235 | ||||
236 | static void | |||
237 | __delete_unlck_locks (clnt_fd_ctx_t *fdctx) | |||
238 | { | |||
239 | client_posix_lock_t *l = NULL((void*)0); | |||
240 | client_posix_lock_t *tmp = NULL((void*)0); | |||
241 | ||||
242 | list_for_each_entry_safe (l, tmp, &fdctx->lock_list, list)for (l = ((typeof(*l) *)((char *)((&fdctx->lock_list)-> next)-(unsigned long)(&((typeof(*l) *)0)->list))), tmp = ((typeof(*l) *)((char *)(l->list.next)-(unsigned long)( &((typeof(*l) *)0)->list))); &l->list != (& fdctx->lock_list); l = tmp, tmp = ((typeof(*tmp) *)((char * )(tmp->list.next)-(unsigned long)(&((typeof(*tmp) *)0) ->list)))) { | |||
243 | if (l->fl_type == F_UNLCK2) { | |||
244 | __delete_client_lock (l); | |||
245 | __destroy_client_lock (l); | |||
246 | } | |||
247 | } | |||
248 | } | |||
249 | ||||
250 | static void | |||
251 | __insert_lock (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock) | |||
252 | { | |||
253 | list_add_tail (&lock->list, &fdctx->lock_list); | |||
254 | ||||
255 | return; | |||
256 | } | |||
257 | ||||
258 | static void | |||
259 | __insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock) | |||
260 | { | |||
261 | client_posix_lock_t *conf = NULL((void*)0); | |||
262 | client_posix_lock_t *t = NULL((void*)0); | |||
263 | client_posix_lock_t *sum = NULL((void*)0); | |||
264 | int i = 0; | |||
265 | struct _values v = { .locks = {0, 0, 0} }; | |||
266 | ||||
267 | list_for_each_entry_safe (conf, t, &fdctx->lock_list, list)for (conf = ((typeof(*conf) *)((char *)((&fdctx->lock_list )->next)-(unsigned long)(&((typeof(*conf) *)0)->list ))), t = ((typeof(*conf) *)((char *)(conf->list.next)-(unsigned long)(&((typeof(*conf) *)0)->list))); &conf->list != (&fdctx->lock_list); conf = t, t = ((typeof(*t) *) ((char *)(t->list.next)-(unsigned long)(&((typeof(*t) * )0)->list)))) { | |||
268 | if (!locks_overlap (conf, lock)) | |||
269 | continue; | |||
270 | ||||
271 | if (is_same_lkowner (&conf->owner, &lock->owner)) { | |||
272 | if (conf->fl_type == lock->fl_type) { | |||
273 | sum = add_locks (lock, conf); | |||
274 | ||||
275 | sum->fd = lock->fd; | |||
276 | ||||
277 | __delete_client_lock (conf); | |||
278 | __destroy_client_lock (conf); | |||
279 | ||||
280 | __destroy_client_lock (lock); | |||
281 | __insert_and_merge (fdctx, sum); | |||
282 | ||||
283 | return; | |||
284 | } else { | |||
285 | sum = add_locks (lock, conf); | |||
286 | ||||
287 | sum->fd = conf->fd; | |||
288 | sum->owner = conf->owner; | |||
289 | ||||
290 | v = subtract_locks (sum, lock); | |||
291 | ||||
292 | __delete_client_lock (conf); | |||
293 | __destroy_client_lock (conf); | |||
294 | ||||
295 | __delete_client_lock (lock); | |||
296 | __destroy_client_lock (lock); | |||
297 | ||||
298 | __destroy_client_lock (sum); | |||
299 | ||||
300 | for (i = 0; i < 3; i++) { | |||
301 | if (!v.locks[i]) | |||
302 | continue; | |||
303 | ||||
304 | INIT_LIST_HEAD (&v.locks[i]->list)do { (&v.locks[i]->list)->next = (&v.locks[i]-> list)->prev = &v.locks[i]->list; } while (0); | |||
305 | __insert_and_merge (fdctx, | |||
306 | v.locks[i]); | |||
307 | } | |||
308 | ||||
309 | __delete_unlck_locks (fdctx); | |||
310 | return; | |||
311 | } | |||
312 | } | |||
313 | ||||
314 | if (lock->fl_type == F_UNLCK2) { | |||
315 | continue; | |||
316 | } | |||
317 | ||||
318 | if ((conf->fl_type == F_RDLCK0) && (lock->fl_type == F_RDLCK0)) { | |||
319 | __insert_lock (fdctx, lock); | |||
320 | return; | |||
321 | } | |||
322 | } | |||
323 | ||||
324 | /* no conflicts, so just insert */ | |||
325 | if (lock->fl_type != F_UNLCK2) { | |||
326 | __insert_lock (fdctx, lock); | |||
327 | } else { | |||
328 | __destroy_client_lock (lock); | |||
329 | } | |||
330 | } | |||
331 | ||||
332 | static void | |||
333 | client_setlk (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock) | |||
334 | { | |||
335 | pthread_mutex_lock (&fdctx->mutex); | |||
336 | { | |||
337 | __insert_and_merge (fdctx, lock); | |||
338 | } | |||
339 | pthread_mutex_unlock (&fdctx->mutex); | |||
340 | ||||
341 | return; | |||
342 | } | |||
343 | ||||
344 | static void | |||
345 | destroy_client_lock (client_posix_lock_t *lock) | |||
346 | { | |||
347 | GF_FREE (lock)__gf_free (lock); | |||
348 | } | |||
349 | ||||
350 | int32_t | |||
351 | delete_granted_locks_owner (fd_t *fd, gf_lkowner_t *owner) | |||
352 | { | |||
353 | clnt_fd_ctx_t *fdctx = NULL((void*)0); | |||
354 | client_posix_lock_t *lock = NULL((void*)0); | |||
355 | client_posix_lock_t *tmp = NULL((void*)0); | |||
356 | xlator_t *this = NULL((void*)0); | |||
357 | ||||
358 | struct list_head delete_list; | |||
359 | int ret = 0; | |||
360 | int count = 0; | |||
361 | ||||
362 | INIT_LIST_HEAD (&delete_list)do { (&delete_list)->next = (&delete_list)->prev = &delete_list; } while (0); | |||
363 | this = THIS(*__glusterfs_this_location()); | |||
364 | fdctx = this_fd_get_ctx (fd, this); | |||
365 | if (!fdctx) { | |||
366 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("fdctx not valid"); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 367, GF_LOG_WARNING , "fdctx not valid"); } while (0) | |||
367 | "fdctx not valid")do { do { if (0) printf ("fdctx not valid"); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__, 367, GF_LOG_WARNING , "fdctx not valid"); } while (0); | |||
368 | ret = -1; | |||
369 | goto out; | |||
370 | } | |||
371 | ||||
372 | pthread_mutex_lock (&fdctx->mutex); | |||
373 | { | |||
374 | list_for_each_entry_safe (lock, tmp, &fdctx->lock_list, list)for (lock = ((typeof(*lock) *)((char *)((&fdctx->lock_list )->next)-(unsigned long)(&((typeof(*lock) *)0)->list ))), tmp = ((typeof(*lock) *)((char *)(lock->list.next)-(unsigned long)(&((typeof(*lock) *)0)->list))); &lock->list != (&fdctx->lock_list); lock = tmp, tmp = ((typeof(*tmp ) *)((char *)(tmp->list.next)-(unsigned long)(&((typeof (*tmp) *)0)->list)))) { | |||
375 | if (!is_same_lkowner (&lock->owner, owner)) { | |||
376 | list_del_init (&lock->list); | |||
377 | list_add_tail (&lock->list, &delete_list); | |||
378 | count++; | |||
379 | } | |||
380 | } | |||
381 | } | |||
382 | pthread_mutex_unlock (&fdctx->mutex); | |||
383 | ||||
384 | list_for_each_entry_safe (lock, tmp, &delete_list, list)for (lock = ((typeof(*lock) *)((char *)((&delete_list)-> next)-(unsigned long)(&((typeof(*lock) *)0)->list))), tmp = ((typeof(*lock) *)((char *)(lock->list.next)-(unsigned long )(&((typeof(*lock) *)0)->list))); &lock->list != (&delete_list); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->list.next)-(unsigned long)(&((typeof(*tmp) *) 0)->list)))) { | |||
385 | list_del_init (&lock->list); | |||
386 | destroy_client_lock (lock); | |||
387 | } | |||
388 | ||||
389 | /* FIXME: Need to actually print the locks instead of count */ | |||
390 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("Number of locks cleared=%d", count) ; } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__ , 391, GF_LOG_TRACE, "Number of locks cleared=%d", count); } while (0) | |||
391 | "Number of locks cleared=%d", count)do { do { if (0) printf ("Number of locks cleared=%d", count) ; } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__ , 391, GF_LOG_TRACE, "Number of locks cleared=%d", count); } while (0); | |||
392 | ||||
393 | out: | |||
394 | return ret; | |||
395 | } | |||
396 | ||||
397 | int32_t | |||
398 | delete_granted_locks_fd (clnt_fd_ctx_t *fdctx) | |||
399 | { | |||
400 | client_posix_lock_t *lock = NULL((void*)0); | |||
401 | client_posix_lock_t *tmp = NULL((void*)0); | |||
402 | xlator_t *this = NULL((void*)0); | |||
403 | ||||
404 | struct list_head delete_list; | |||
405 | int ret = 0; | |||
406 | int count = 0; | |||
407 | ||||
408 | INIT_LIST_HEAD (&delete_list)do { (&delete_list)->next = (&delete_list)->prev = &delete_list; } while (0); | |||
409 | this = THIS(*__glusterfs_this_location()); | |||
410 | ||||
411 | pthread_mutex_lock (&fdctx->mutex); | |||
412 | { | |||
413 | list_splice_init (&fdctx->lock_list, &delete_list); | |||
414 | } | |||
415 | pthread_mutex_unlock (&fdctx->mutex); | |||
416 | ||||
417 | list_for_each_entry_safe (lock, tmp, &delete_list, list)for (lock = ((typeof(*lock) *)((char *)((&delete_list)-> next)-(unsigned long)(&((typeof(*lock) *)0)->list))), tmp = ((typeof(*lock) *)((char *)(lock->list.next)-(unsigned long )(&((typeof(*lock) *)0)->list))); &lock->list != (&delete_list); lock = tmp, tmp = ((typeof(*tmp) *)((char *)(tmp->list.next)-(unsigned long)(&((typeof(*tmp) *) 0)->list)))) { | |||
418 | list_del_init (&lock->list); | |||
419 | count++; | |||
420 | destroy_client_lock (lock); | |||
421 | } | |||
422 | ||||
423 | /* FIXME: Need to actually print the locks instead of count */ | |||
424 | gf_log (this->name, GF_LOG_TRACE,do { do { if (0) printf ("Number of locks cleared=%d", count) ; } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__ , 425, GF_LOG_TRACE, "Number of locks cleared=%d", count); } while (0) | |||
425 | "Number of locks cleared=%d", count)do { do { if (0) printf ("Number of locks cleared=%d", count) ; } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__ , 425, GF_LOG_TRACE, "Number of locks cleared=%d", count); } while (0); | |||
426 | ||||
427 | return ret; | |||
428 | } | |||
429 | ||||
430 | int32_t | |||
431 | client_cmd_to_gf_cmd (int32_t cmd, int32_t *gf_cmd) | |||
432 | { | |||
433 | int ret = 0; | |||
434 | ||||
435 | if (cmd == F_GETLK12 || cmd == F_GETLK6412) | |||
436 | *gf_cmd = GF_LK_GETLK; | |||
437 | else if (cmd == F_SETLK13 || cmd == F_SETLK6413) | |||
438 | *gf_cmd = GF_LK_SETLK; | |||
439 | else if (cmd == F_SETLKW14 || cmd == F_SETLKW6414) | |||
440 | *gf_cmd = GF_LK_SETLKW; | |||
441 | else if (cmd == F_RESLK_LCK) | |||
442 | *gf_cmd = GF_LK_RESLK_LCK; | |||
443 | else if (cmd == F_RESLK_LCKW) | |||
444 | *gf_cmd = GF_LK_RESLK_LCKW; | |||
445 | else if (cmd == F_RESLK_UNLCK) | |||
446 | *gf_cmd = GF_LK_RESLK_UNLCK; | |||
447 | else if (cmd == F_GETLK_FD) | |||
448 | *gf_cmd = GF_LK_GETLK_FD; | |||
449 | else | |||
450 | ret = -1; | |||
451 | ||||
452 | return ret; | |||
453 | ||||
454 | } | |||
455 | ||||
456 | static client_posix_lock_t * | |||
457 | new_client_lock (struct gf_flock *flock, gf_lkowner_t *owner, | |||
458 | int32_t cmd, fd_t *fd) | |||
459 | { | |||
460 | client_posix_lock_t *new_lock = NULL((void*)0); | |||
461 | ||||
462 | new_lock = GF_CALLOC (1, sizeof (*new_lock),__gf_calloc (1, sizeof (*new_lock), gf_client_mt_clnt_lock_t) | |||
463 | gf_client_mt_clnt_lock_t)__gf_calloc (1, sizeof (*new_lock), gf_client_mt_clnt_lock_t); | |||
464 | if (!new_lock) { | |||
465 | goto out; | |||
466 | } | |||
467 | ||||
468 | INIT_LIST_HEAD (&new_lock->list)do { (&new_lock->list)->next = (&new_lock->list )->prev = &new_lock->list; } while (0); | |||
469 | new_lock->fd = fd; | |||
470 | memcpy (&new_lock->user_flock, flock, sizeof (struct gf_flock)); | |||
471 | ||||
472 | new_lock->fl_type = flock->l_type; | |||
473 | new_lock->fl_start = flock->l_start; | |||
474 | ||||
475 | if (flock->l_len == 0) | |||
476 | new_lock->fl_end = LLONG_MAX9223372036854775807LL; | |||
477 | else | |||
478 | new_lock->fl_end = flock->l_start + flock->l_len - 1; | |||
479 | ||||
480 | new_lock->owner = *owner; | |||
481 | ||||
482 | new_lock->cmd = cmd; /* Not really useful */ | |||
483 | ||||
484 | out: | |||
485 | return new_lock; | |||
486 | } | |||
487 | ||||
488 | void | |||
489 | client_save_number_fds (clnt_conf_t *conf, int count) | |||
490 | { | |||
491 | LOCK (&conf->rec_lock)pthread_spin_lock (&conf->rec_lock); | |||
492 | { | |||
493 | conf->reopen_fd_count = count; | |||
494 | } | |||
495 | UNLOCK (&conf->rec_lock)pthread_spin_unlock (&conf->rec_lock); | |||
496 | } | |||
497 | ||||
498 | int | |||
499 | client_add_lock_for_recovery (fd_t *fd, struct gf_flock *flock, | |||
500 | gf_lkowner_t *owner, int32_t cmd) | |||
501 | { | |||
502 | clnt_fd_ctx_t *fdctx = NULL((void*)0); | |||
503 | xlator_t *this = NULL((void*)0); | |||
504 | client_posix_lock_t *lock = NULL((void*)0); | |||
505 | clnt_conf_t *conf = NULL((void*)0); | |||
506 | ||||
507 | int ret = 0; | |||
508 | ||||
509 | this = THIS(*__glusterfs_this_location()); | |||
510 | conf = this->private; | |||
511 | ||||
512 | pthread_mutex_lock (&conf->lock); | |||
513 | { | |||
514 | fdctx = this_fd_get_ctx (fd, this); | |||
515 | } | |||
516 | pthread_mutex_unlock (&conf->lock); | |||
517 | ||||
518 | if (!fdctx) { | |||
519 | gf_log (this->name, GF_LOG_WARNING,do { do { if (0) printf ("failed to get fd context. sending EBADFD" ); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__ , 520, GF_LOG_WARNING, "failed to get fd context. sending EBADFD" ); } while (0) | |||
520 | "failed to get fd context. sending EBADFD")do { do { if (0) printf ("failed to get fd context. sending EBADFD" ); } while (0); _gf_log (this->name, "client-lk.c", __FUNCTION__ , 520, GF_LOG_WARNING, "failed to get fd context. sending EBADFD" ); } while (0); | |||
521 | ret = -EBADFD77; | |||
522 | goto out; | |||
523 | } | |||
524 | ||||
525 | lock = new_client_lock (flock, owner, cmd, fd); | |||
526 | if (!lock) { | |||
527 | ret = -ENOMEM12; | |||
528 | goto out; | |||
529 | } | |||
530 | ||||
531 | client_setlk (fdctx, lock); | |||
532 | ||||
533 | out: | |||
534 | return ret; | |||
535 | ||||
536 | } | |||
537 | ||||
538 | int32_t | |||
539 | client_dump_locks (char *name, inode_t *inode, | |||
540 | dict_t *dict) | |||
541 | { | |||
542 | int ret = 0; | |||
543 | dict_t *new_dict = NULL((void*)0); | |||
544 | char dict_string[256]; | |||
545 | ||||
546 | GF_ASSERT (dict)do { if (!(dict)) { do { do { if (0) printf ("Assertion failed: " "dict"); } while (0); _gf_log_callingfn ("", "client-lk.c", __FUNCTION__ , 546, GF_LOG_ERROR, "Assertion failed: " "dict"); } while (0 ); } } while (0); | |||
547 | new_dict = dict; | |||
548 | ||||
549 | ret = dump_client_locks (inode); | |||
550 | snprintf (dict_string, 256, "%d locks dumped in log file", ret); | |||
551 | ||||
552 | ret = dict_set_dynstr(new_dict, CLIENT_DUMP_LOCKS"trusted.glusterfs.clientlk-dump", dict_string); | |||
553 | if (ret) { | |||
554 | gf_log (THIS->name, GF_LOG_WARNING,do { do { if (0) printf ("could not set dict with %s", "trusted.glusterfs.clientlk-dump" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "client-lk.c", __FUNCTION__, 555, GF_LOG_WARNING, "could not set dict with %s" , "trusted.glusterfs.clientlk-dump"); } while (0) | |||
555 | "could not set dict with %s", CLIENT_DUMP_LOCKS)do { do { if (0) printf ("could not set dict with %s", "trusted.glusterfs.clientlk-dump" ); } while (0); _gf_log ((*__glusterfs_this_location())->name , "client-lk.c", __FUNCTION__, 555, GF_LOG_WARNING, "could not set dict with %s" , "trusted.glusterfs.clientlk-dump"); } while (0); | |||
556 | goto out; | |||
557 | } | |||
558 | ||||
559 | out: | |||
560 | ||||
561 | return ret; | |||
562 | } | |||
563 | ||||
564 | int32_t | |||
565 | is_client_dump_locks_cmd (char *name) | |||
566 | { | |||
567 | int ret = 0; | |||
568 | ||||
569 | if (strcmp (name, CLIENT_DUMP_LOCKS"trusted.glusterfs.clientlk-dump") == 0) | |||
570 | ret = 1; | |||
571 | ||||
572 | return ret; | |||
573 | } |