Bug Summary

File:xlators/protocol/client/src/client-lk.c
Location:line 224, column 3
Description:Null pointer passed as an argument to a 'nonnull' parameter

Annotated Source Code

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
16static void
17__insert_and_merge (clnt_fd_ctx_t *fdctx, client_posix_lock_t *lock);
18
19static 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
39static int
40dump_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
58int
59dump_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
96static 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 */
106static client_posix_lock_t *
107add_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 */
127static int
128locks_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
140static void
141__delete_client_lock (client_posix_lock_t *lock)
142{
143 list_del_init (&lock->list);
144}
145
146/* Destroy a posix_lock */
147static void
148__destroy_client_lock (client_posix_lock_t *lock)
149{
150 GF_FREE (lock)__gf_free (lock);
151}
152
153/* Subtract two locks */
154struct _values {
155 client_posix_lock_t *locks[3];
156};
157
158/* {big} must always be contained inside {small} */
159static struct _values
160subtract_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) {
1
Taking false branch
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) {
2
Taking true branch
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));
3
Null pointer passed as an argument to a 'nonnull' parameter
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
236static 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
250static 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
258static 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
332static void
333client_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
344static void
345destroy_client_lock (client_posix_lock_t *lock)
346{
347 GF_FREE (lock)__gf_free (lock);
348}
349
350int32_t
351delete_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
393out:
394 return ret;
395}
396
397int32_t
398delete_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
430int32_t
431client_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
456static client_posix_lock_t *
457new_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
484out:
485 return new_lock;
486}
487
488void
489client_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
498int
499client_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
533out:
534 return ret;
535
536}
537
538int32_t
539client_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
559out:
560
561 return ret;
562}
563
564int32_t
565is_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}