File: | xlators/mount/fuse/src/fuse-helpers.c |
Location: | line 498, column 15 |
Description: | Null pointer passed as an argument to a 'nonnull' parameter |
1 | /* | |||||
2 | Copyright (c) 2010-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 | #include "fuse-bridge.h" | |||||
11 | #if defined(GF_SOLARIS_HOST_OS) | |||||
12 | #include <sys/procfs.h> | |||||
13 | #else | |||||
14 | #include <sys/sysctl.h> | |||||
15 | #endif | |||||
16 | ||||||
17 | #ifndef GF_REQUEST_MAXGROUPS16 | |||||
18 | #define GF_REQUEST_MAXGROUPS16 16 | |||||
19 | #endif /* GF_REQUEST_MAXGROUPS */ | |||||
20 | ||||||
21 | static void | |||||
22 | fuse_resolve_wipe (fuse_resolve_t *resolve) | |||||
23 | { | |||||
24 | GF_FREE ((void *)resolve->path)__gf_free ((void *)resolve->path); | |||||
25 | ||||||
26 | GF_FREE ((void *)resolve->bname)__gf_free ((void *)resolve->bname); | |||||
27 | ||||||
28 | GF_FREE ((void *)resolve->resolved)__gf_free ((void *)resolve->resolved); | |||||
29 | ||||||
30 | if (resolve->fd) | |||||
31 | fd_unref (resolve->fd); | |||||
32 | ||||||
33 | loc_wipe (&resolve->resolve_loc); | |||||
34 | ||||||
35 | if (resolve->hint) { | |||||
36 | inode_unref (resolve->hint); | |||||
37 | resolve->hint = 0; | |||||
38 | } | |||||
39 | ||||||
40 | if (resolve->parhint) { | |||||
41 | inode_unref (resolve->parhint); | |||||
42 | resolve->parhint = 0; | |||||
43 | } | |||||
44 | } | |||||
45 | ||||||
46 | ||||||
47 | void | |||||
48 | free_fuse_state (fuse_state_t *state) | |||||
49 | { | |||||
50 | xlator_t *this = NULL((void*)0); | |||||
51 | fuse_private_t *priv = NULL((void*)0); | |||||
52 | uint64_t winds = 0; | |||||
53 | char switched = 0; | |||||
54 | ||||||
55 | this = state->this; | |||||
56 | ||||||
57 | priv = this->private; | |||||
58 | ||||||
59 | loc_wipe (&state->loc); | |||||
60 | ||||||
61 | loc_wipe (&state->loc2); | |||||
62 | ||||||
63 | if (state->xdata) { | |||||
64 | dict_unref (state->xdata); | |||||
65 | state->xdata = (void *)0xaaaaeeee; | |||||
66 | } | |||||
67 | if (state->xattr) | |||||
68 | dict_unref (state->xattr); | |||||
69 | ||||||
70 | if (state->name) { | |||||
71 | GF_FREE (state->name)__gf_free (state->name); | |||||
72 | state->name = NULL((void*)0); | |||||
73 | } | |||||
74 | if (state->fd) { | |||||
75 | fd_unref (state->fd); | |||||
76 | state->fd = (void *)0xfdfdfdfd; | |||||
77 | } | |||||
78 | if (state->finh) { | |||||
79 | GF_FREE (state->finh)__gf_free (state->finh); | |||||
80 | state->finh = NULL((void*)0); | |||||
81 | } | |||||
82 | ||||||
83 | fuse_resolve_wipe (&state->resolve); | |||||
84 | fuse_resolve_wipe (&state->resolve2); | |||||
85 | ||||||
86 | pthread_mutex_lock (&priv->sync_mutex); | |||||
87 | { | |||||
88 | winds = --state->active_subvol->winds; | |||||
89 | switched = state->active_subvol->switched; | |||||
90 | } | |||||
91 | pthread_mutex_unlock (&priv->sync_mutex); | |||||
92 | ||||||
93 | if ((winds == 0) && (switched)) { | |||||
94 | xlator_notify (state->active_subvol, GF_EVENT_PARENT_DOWN, | |||||
95 | state->active_subvol, NULL((void*)0)); | |||||
96 | } | |||||
97 | ||||||
98 | #ifdef DEBUG | |||||
99 | memset (state, 0x90, sizeof (*state)); | |||||
100 | #endif | |||||
101 | GF_FREE (state)__gf_free (state); | |||||
102 | state = NULL((void*)0); | |||||
103 | } | |||||
104 | ||||||
105 | ||||||
106 | fuse_state_t * | |||||
107 | get_fuse_state (xlator_t *this, fuse_in_header_t *finh) | |||||
108 | { | |||||
109 | fuse_state_t *state = NULL((void*)0); | |||||
110 | xlator_t *active_subvol = NULL((void*)0); | |||||
111 | fuse_private_t *priv = NULL((void*)0); | |||||
112 | ||||||
113 | state = (void *)GF_CALLOC (1, sizeof (*state),__gf_calloc (1, sizeof (*state), gf_fuse_mt_fuse_state_t) | |||||
114 | gf_fuse_mt_fuse_state_t)__gf_calloc (1, sizeof (*state), gf_fuse_mt_fuse_state_t); | |||||
115 | if (!state) | |||||
116 | return NULL((void*)0); | |||||
117 | ||||||
118 | state->this = THIS(*__glusterfs_this_location()); | |||||
119 | priv = this->private; | |||||
120 | ||||||
121 | pthread_mutex_lock (&priv->sync_mutex); | |||||
122 | { | |||||
123 | active_subvol = fuse_active_subvol (state->this); | |||||
124 | active_subvol->winds++; | |||||
125 | } | |||||
126 | pthread_mutex_unlock (&priv->sync_mutex); | |||||
127 | ||||||
128 | state->active_subvol = active_subvol; | |||||
129 | state->itable = active_subvol->itable; | |||||
130 | ||||||
131 | state->pool = this->ctx->pool; | |||||
132 | state->finh = finh; | |||||
133 | state->this = this; | |||||
134 | ||||||
135 | LOCK_INIT (&state->lock)pthread_spin_init (&state->lock, 0); | |||||
136 | ||||||
137 | return state; | |||||
138 | } | |||||
139 | ||||||
140 | ||||||
141 | void | |||||
142 | frame_fill_groups (call_frame_t *frame) | |||||
143 | { | |||||
144 | #if defined(GF_LINUX_HOST_OS1) | |||||
145 | char filename[32]; | |||||
146 | char line[4096]; | |||||
147 | char *ptr = NULL((void*)0); | |||||
148 | FILE *fp = NULL((void*)0); | |||||
149 | int idx = 0; | |||||
150 | long int id = 0; | |||||
151 | char *saveptr = NULL((void*)0); | |||||
152 | char *endptr = NULL((void*)0); | |||||
153 | int ret = 0; | |||||
154 | ||||||
155 | ret = snprintf (filename, sizeof filename, "/proc/%d/status", frame->root->pid); | |||||
156 | if (ret >= sizeof filename) | |||||
157 | goto out; | |||||
158 | ||||||
159 | fp = fopen (filename, "r"); | |||||
160 | if (!fp) | |||||
161 | goto out; | |||||
162 | ||||||
163 | while ((ptr = fgets (line, sizeof line, fp))) { | |||||
164 | if (strncmp (ptr, "Groups:", 7) != 0) | |||||
165 | continue; | |||||
166 | ||||||
167 | ptr = line + 8; | |||||
168 | ||||||
169 | for (ptr = strtok_r (ptr, " \t\r\n", &saveptr); | |||||
170 | ptr; | |||||
171 | ptr = strtok_r (NULL((void*)0), " \t\r\n", &saveptr)) { | |||||
172 | errno(*__errno_location ()) = 0; | |||||
173 | id = strtol (ptr, &endptr, 0); | |||||
174 | if (errno(*__errno_location ()) == ERANGE34) | |||||
175 | break; | |||||
176 | if (!endptr || *endptr) | |||||
177 | break; | |||||
178 | frame->root->groups[idx++] = id; | |||||
179 | if (idx == GF_MAX_AUX_GROUPS200) | |||||
180 | break; | |||||
181 | } | |||||
182 | ||||||
183 | frame->root->ngrps = idx; | |||||
184 | break; | |||||
185 | } | |||||
186 | out: | |||||
187 | if (fp) | |||||
188 | fclose (fp); | |||||
189 | #elif defined(GF_SOLARIS_HOST_OS) | |||||
190 | char filename[32]; | |||||
191 | char scratch[128]; | |||||
192 | prcred_t *prcred = (prcred_t *) scratch; | |||||
193 | FILE *fp = NULL((void*)0); | |||||
194 | int ret = 0; | |||||
195 | ||||||
196 | ret = snprintf (filename, sizeof filename, | |||||
197 | "/proc/%d/cred", frame->root->pid); | |||||
198 | ||||||
199 | if (ret < sizeof filename) { | |||||
200 | fp = fopen (filename, "r"); | |||||
201 | if (fp != NULL((void*)0)) { | |||||
202 | if (fgets (scratch, sizeof scratch, fp) != NULL((void*)0)) { | |||||
203 | frame->root->ngrps = MIN(prcred->pr_ngroups, | |||||
204 | GF_REQUEST_MAXGROUPS16); | |||||
205 | } | |||||
206 | fclose (fp); | |||||
207 | } | |||||
208 | } | |||||
209 | #elif defined(CTL_KERN) /* DARWIN and *BSD */ | |||||
210 | /* | |||||
211 | N.B. CTL_KERN is an enum on Linux. (Meaning, if it's not | |||||
212 | obvious, that it's not subject to preprocessor directives | |||||
213 | like '#if defined'.) | |||||
214 | Unlike Linux, on Mac OS and the BSDs it is a #define. We | |||||
215 | could test to see that KERN_PROC is defined, but, barring any | |||||
216 | evidence to the contrary, I think that's overkill. | |||||
217 | We might also test that GF_DARWIN_HOST_OS is defined, why | |||||
218 | limit this to just Mac OS. It's equally valid for the BSDs | |||||
219 | and we do have people building on NetBSD and FreeBSD. | |||||
220 | */ | |||||
221 | int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, frame->root->pid }; | |||||
222 | size_t namelen = sizeof name / sizeof name[0]; | |||||
223 | struct kinfo_proc kp; | |||||
224 | size_t kplen = sizeof(kp); | |||||
225 | int i, ngroups; | |||||
226 | ||||||
227 | if (sysctl(name, namelen, &kp, &kplen, NULL((void*)0), 0) != 0) | |||||
228 | return; | |||||
229 | ngroups = MIN(kp.kp_eproc.e_ucred.cr_ngroups, GF_REQUEST_MAXGROUPS16); | |||||
230 | for (i = 0; i < ngroups; i++) | |||||
231 | frame->root->groups[i] = kp.kp_eproc.e_ucred.cr_groups[i]; | |||||
232 | frame->root->ngrps = ngroups; | |||||
233 | #else | |||||
234 | frame->root->ngrps = 0; | |||||
235 | #endif /* GF_LINUX_HOST_OS */ | |||||
236 | } | |||||
237 | ||||||
238 | /* | |||||
239 | * Get the groups for the PID associated with this frame. If enabled, | |||||
240 | * use the gid cache to reduce group list collection. | |||||
241 | */ | |||||
242 | static void get_groups(fuse_private_t *priv, call_frame_t *frame) | |||||
243 | { | |||||
244 | int i; | |||||
245 | const gid_list_t *gl; | |||||
246 | gid_list_t agl; | |||||
247 | ||||||
248 | if (-1 == priv->gid_cache_timeout) { | |||||
249 | frame->root->ngrps = 0; | |||||
250 | return; | |||||
251 | } | |||||
252 | ||||||
253 | if (!priv->gid_cache_timeout) { | |||||
254 | frame_fill_groups(frame); | |||||
255 | return; | |||||
256 | } | |||||
257 | ||||||
258 | gl = gid_cache_lookup(&priv->gid_cache, frame->root->pid); | |||||
259 | if (gl) { | |||||
260 | frame->root->ngrps = gl->gl_count; | |||||
261 | for (i = 0; i < gl->gl_count; i++) | |||||
262 | frame->root->groups[i] = gl->gl_list[i]; | |||||
263 | gid_cache_release(&priv->gid_cache, gl); | |||||
264 | return; | |||||
265 | } | |||||
266 | ||||||
267 | frame_fill_groups (frame); | |||||
268 | ||||||
269 | agl.gl_id = frame->root->pid; | |||||
270 | agl.gl_count = frame->root->ngrps; | |||||
271 | agl.gl_list = GF_CALLOC(frame->root->ngrps, sizeof(gid_t),__gf_calloc (frame->root->ngrps, sizeof(gid_t), gf_fuse_mt_gids_t ) | |||||
272 | gf_fuse_mt_gids_t)__gf_calloc (frame->root->ngrps, sizeof(gid_t), gf_fuse_mt_gids_t ); | |||||
273 | if (!agl.gl_list) | |||||
274 | return; | |||||
275 | ||||||
276 | for (i = 0; i < frame->root->ngrps; i++) | |||||
277 | agl.gl_list[i] = frame->root->groups[i]; | |||||
278 | ||||||
279 | if (gid_cache_add(&priv->gid_cache, &agl) != 1) | |||||
280 | GF_FREE(agl.gl_list)__gf_free (agl.gl_list); | |||||
281 | } | |||||
282 | ||||||
283 | call_frame_t * | |||||
284 | get_call_frame_for_req (fuse_state_t *state) | |||||
285 | { | |||||
286 | call_pool_t *pool = NULL((void*)0); | |||||
287 | fuse_in_header_t *finh = NULL((void*)0); | |||||
288 | call_frame_t *frame = NULL((void*)0); | |||||
289 | xlator_t *this = NULL((void*)0); | |||||
290 | fuse_private_t *priv = NULL((void*)0); | |||||
291 | ||||||
292 | pool = state->pool; | |||||
293 | finh = state->finh; | |||||
294 | this = state->this; | |||||
295 | priv = this->private; | |||||
296 | ||||||
297 | frame = create_frame (this, pool); | |||||
298 | if (!frame) | |||||
299 | return NULL((void*)0); | |||||
300 | ||||||
301 | if (finh) { | |||||
302 | frame->root->uid = finh->uid; | |||||
303 | frame->root->gid = finh->gid; | |||||
304 | frame->root->pid = finh->pid; | |||||
305 | frame->root->unique = finh->unique; | |||||
306 | set_lk_owner_from_uint64 (&frame->root->lk_owner, | |||||
307 | state->lk_owner); | |||||
308 | } | |||||
309 | ||||||
310 | get_groups(priv, frame); | |||||
311 | ||||||
312 | if (priv && priv->client_pid_set) | |||||
313 | frame->root->pid = priv->client_pid; | |||||
314 | ||||||
315 | frame->root->type = GF_OP_TYPE_FOP; | |||||
316 | ||||||
317 | return frame; | |||||
318 | } | |||||
319 | ||||||
320 | ||||||
321 | inode_t * | |||||
322 | fuse_ino_to_inode (uint64_t ino, xlator_t *fuse) | |||||
323 | { | |||||
324 | inode_t *inode = NULL((void*)0); | |||||
325 | xlator_t *active_subvol = NULL((void*)0); | |||||
326 | ||||||
327 | if (ino == 1) { | |||||
328 | active_subvol = fuse_active_subvol (fuse); | |||||
329 | if (active_subvol) | |||||
330 | inode = active_subvol->itable->root; | |||||
331 | } else { | |||||
332 | inode = (inode_t *) (unsigned long) ino; | |||||
333 | inode_ref (inode); | |||||
334 | } | |||||
335 | ||||||
336 | return inode; | |||||
337 | } | |||||
338 | ||||||
339 | uint64_t | |||||
340 | inode_to_fuse_nodeid (inode_t *inode) | |||||
341 | { | |||||
342 | if (!inode) | |||||
343 | return 0; | |||||
344 | if (__is_root_gfid (inode->gfid)) | |||||
345 | return 1; | |||||
346 | ||||||
347 | return (unsigned long) inode; | |||||
348 | } | |||||
349 | ||||||
350 | ||||||
351 | GF_MUST_CHECK__attribute__((warn_unused_result)) int32_t | |||||
352 | fuse_loc_fill (loc_t *loc, fuse_state_t *state, ino_t ino, | |||||
353 | ino_t par, const char *name) | |||||
354 | { | |||||
355 | inode_t *inode = NULL((void*)0); | |||||
356 | inode_t *parent = NULL((void*)0); | |||||
357 | int32_t ret = -1; | |||||
358 | char *path = NULL((void*)0); | |||||
359 | uuid_t null_gfid = {0,}; | |||||
360 | ||||||
361 | /* resistance against multiple invocation of loc_fill not to get | |||||
362 | reference leaks via inode_search() */ | |||||
363 | ||||||
364 | if (name) { | |||||
365 | parent = loc->parent; | |||||
366 | if (!parent) { | |||||
367 | parent = fuse_ino_to_inode (par, state->this); | |||||
368 | loc->parent = parent; | |||||
369 | if (parent) | |||||
370 | uuid_copy (loc->pargfid, parent->gfid); | |||||
371 | } | |||||
372 | ||||||
373 | inode = loc->inode; | |||||
374 | if (!inode) { | |||||
375 | inode = inode_grep (parent->table, parent, name); | |||||
376 | loc->inode = inode; | |||||
377 | } | |||||
378 | ||||||
379 | ret = inode_path (parent, name, &path); | |||||
380 | if (ret <= 0) { | |||||
381 | gf_log ("glusterfs-fuse", GF_LOG_DEBUG,do { do { if (0) printf ("inode_path failed for %s/%s", (parent )?uuid_utoa (parent->gfid):"0", name); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c", __FUNCTION__, 383, GF_LOG_DEBUG , "inode_path failed for %s/%s", (parent)?uuid_utoa (parent-> gfid):"0", name); } while (0) | |||||
382 | "inode_path failed for %s/%s",do { do { if (0) printf ("inode_path failed for %s/%s", (parent )?uuid_utoa (parent->gfid):"0", name); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c", __FUNCTION__, 383, GF_LOG_DEBUG , "inode_path failed for %s/%s", (parent)?uuid_utoa (parent-> gfid):"0", name); } while (0) | |||||
383 | (parent)?uuid_utoa (parent->gfid):"0", name)do { do { if (0) printf ("inode_path failed for %s/%s", (parent )?uuid_utoa (parent->gfid):"0", name); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c", __FUNCTION__, 383, GF_LOG_DEBUG , "inode_path failed for %s/%s", (parent)?uuid_utoa (parent-> gfid):"0", name); } while (0); | |||||
384 | goto fail; | |||||
385 | } | |||||
386 | loc->path = path; | |||||
387 | } else { | |||||
388 | inode = loc->inode; | |||||
389 | if (!inode) { | |||||
390 | inode = fuse_ino_to_inode (ino, state->this); | |||||
391 | loc->inode = inode; | |||||
392 | if (inode) | |||||
393 | uuid_copy (loc->gfid, inode->gfid); | |||||
394 | } | |||||
395 | ||||||
396 | parent = loc->parent; | |||||
397 | if (!parent) { | |||||
398 | parent = inode_parent (inode, null_gfid, NULL((void*)0)); | |||||
399 | loc->parent = parent; | |||||
400 | if (parent) | |||||
401 | uuid_copy (loc->pargfid, parent->gfid); | |||||
402 | ||||||
403 | } | |||||
404 | ||||||
405 | ret = inode_path (inode, NULL((void*)0), &path); | |||||
406 | if (ret <= 0) { | |||||
407 | gf_log ("glusterfs-fuse", GF_LOG_DEBUG,do { do { if (0) printf ("inode_path failed for %s", (inode) ? uuid_utoa (inode->gfid) : "0"); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 409, GF_LOG_DEBUG, "inode_path failed for %s" , (inode) ? uuid_utoa (inode->gfid) : "0"); } while (0) | |||||
408 | "inode_path failed for %s",do { do { if (0) printf ("inode_path failed for %s", (inode) ? uuid_utoa (inode->gfid) : "0"); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 409, GF_LOG_DEBUG, "inode_path failed for %s" , (inode) ? uuid_utoa (inode->gfid) : "0"); } while (0) | |||||
409 | (inode) ? uuid_utoa (inode->gfid) : "0")do { do { if (0) printf ("inode_path failed for %s", (inode) ? uuid_utoa (inode->gfid) : "0"); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 409, GF_LOG_DEBUG, "inode_path failed for %s" , (inode) ? uuid_utoa (inode->gfid) : "0"); } while (0); | |||||
410 | goto fail; | |||||
411 | } | |||||
412 | loc->path = path; | |||||
413 | } | |||||
414 | ||||||
415 | if (loc->path) { | |||||
416 | loc->name = strrchr (loc->path, '/'); | |||||
417 | if (loc->name) | |||||
418 | loc->name++; | |||||
419 | else | |||||
420 | loc->name = ""; | |||||
421 | } | |||||
422 | ||||||
423 | if ((ino != 1) && (parent == NULL((void*)0))) { | |||||
424 | gf_log ("fuse-bridge", GF_LOG_DEBUG,do { do { if (0) printf ("failed to search parent for %""ll" "d" "/%s (%""ll" "d"")", (ino_t)par, name, (ino_t)ino); } while ( 0); _gf_log ("fuse-bridge", "fuse-helpers.c", __FUNCTION__, 426 , GF_LOG_DEBUG, "failed to search parent for %""ll" "d""/%s (%" "ll" "d"")", (ino_t)par, name, (ino_t)ino); } while (0) | |||||
425 | "failed to search parent for %"PRId64"/%s (%"PRId64")",do { do { if (0) printf ("failed to search parent for %""ll" "d" "/%s (%""ll" "d"")", (ino_t)par, name, (ino_t)ino); } while ( 0); _gf_log ("fuse-bridge", "fuse-helpers.c", __FUNCTION__, 426 , GF_LOG_DEBUG, "failed to search parent for %""ll" "d""/%s (%" "ll" "d"")", (ino_t)par, name, (ino_t)ino); } while (0) | |||||
426 | (ino_t)par, name, (ino_t)ino)do { do { if (0) printf ("failed to search parent for %""ll" "d" "/%s (%""ll" "d"")", (ino_t)par, name, (ino_t)ino); } while ( 0); _gf_log ("fuse-bridge", "fuse-helpers.c", __FUNCTION__, 426 , GF_LOG_DEBUG, "failed to search parent for %""ll" "d""/%s (%" "ll" "d"")", (ino_t)par, name, (ino_t)ino); } while (0); | |||||
427 | ret = -1; | |||||
428 | goto fail; | |||||
429 | } | |||||
430 | ret = 0; | |||||
431 | fail: | |||||
432 | /* this should not happen as inode_path returns -1 when buf is NULL | |||||
433 | for sure */ | |||||
434 | if (path && !loc->path) | |||||
435 | GF_FREE (path)__gf_free (path); | |||||
436 | return ret; | |||||
437 | } | |||||
438 | ||||||
439 | /* Use the same logic as the Linux NFS-client */ | |||||
440 | #define GF_FUSE_SQUASH_INO(ino)((uint32_t) ino) ^ (ino >> 32) ((uint32_t) ino) ^ (ino >> 32) | |||||
441 | ||||||
442 | /* courtesy of folly */ | |||||
443 | void | |||||
444 | gf_fuse_stat2attr (struct iatt *st, struct fuse_attr *fa, gf_boolean_t enable_ino32) | |||||
445 | { | |||||
446 | if (enable_ino32) | |||||
447 | fa->ino = GF_FUSE_SQUASH_INO(st->ia_ino)((uint32_t) st->ia_ino) ^ (st->ia_ino >> 32); | |||||
448 | else | |||||
449 | fa->ino = st->ia_ino; | |||||
450 | ||||||
451 | fa->size = st->ia_size; | |||||
452 | fa->blocks = st->ia_blocks; | |||||
453 | fa->atime = st->ia_atime; | |||||
454 | fa->mtime = st->ia_mtime; | |||||
455 | fa->ctime = st->ia_ctime; | |||||
456 | fa->atimensec = st->ia_atime_nsec; | |||||
457 | fa->mtimensec = st->ia_mtime_nsec; | |||||
458 | fa->ctimensec = st->ia_ctime_nsec; | |||||
459 | fa->mode = st_mode_from_ia (st->ia_prot, st->ia_type); | |||||
460 | fa->nlink = st->ia_nlink; | |||||
461 | fa->uid = st->ia_uid; | |||||
462 | fa->gid = st->ia_gid; | |||||
463 | fa->rdev = makedev (ia_major (st->ia_rdev),gnu_dev_makedev (ia_major (st->ia_rdev), ia_minor (st-> ia_rdev)) | |||||
464 | ia_minor (st->ia_rdev))gnu_dev_makedev (ia_major (st->ia_rdev), ia_minor (st-> ia_rdev)); | |||||
465 | #if FUSE_KERNEL_MINOR_VERSION13 >= 9 | |||||
466 | fa->blksize = st->ia_blksize; | |||||
467 | #endif | |||||
468 | #ifdef GF_DARWIN_HOST_OS | |||||
469 | fa->crtime = (uint64_t)-1; | |||||
470 | fa->crtimensec = (uint32_t)-1; | |||||
471 | fa->flags = 0; | |||||
472 | #endif | |||||
473 | } | |||||
474 | ||||||
475 | void | |||||
476 | gf_fuse_fill_dirent (gf_dirent_t *entry, struct fuse_dirent *fde, gf_boolean_t enable_ino32) | |||||
477 | { | |||||
478 | if (enable_ino32) | |||||
479 | fde->ino = GF_FUSE_SQUASH_INO(entry->d_ino)((uint32_t) entry->d_ino) ^ (entry->d_ino >> 32); | |||||
480 | else | |||||
481 | fde->ino = entry->d_ino; | |||||
482 | ||||||
483 | fde->off = entry->d_off; | |||||
484 | fde->type = entry->d_type; | |||||
485 | fde->namelen = strlen (entry->d_name); | |||||
486 | strncpy (fde->name, entry->d_name, fde->namelen); | |||||
487 | } | |||||
488 | ||||||
489 | static int | |||||
490 | fuse_do_flip_xattr_ns (char *okey, const char *nns, char **nkey) | |||||
491 | { | |||||
492 | int ret = 0; | |||||
493 | char *key = NULL((void*)0); | |||||
494 | ||||||
495 | okey = strchr (okey, '.'); | |||||
496 | GF_ASSERT (okey)do { if (!(okey)) { do { do { if (0) printf ("Assertion failed: " "okey"); } while (0); _gf_log_callingfn ("", "fuse-helpers.c" , __FUNCTION__, 496, GF_LOG_ERROR, "Assertion failed: " "okey" ); } while (0); } } while (0); | |||||
497 | ||||||
498 | key = GF_CALLOC (1, strlen (nns) + strlen(okey) + 1,__gf_calloc (1, strlen (nns) + strlen(okey) + 1, gf_common_mt_char ) | |||||
| ||||||
499 | gf_common_mt_char)__gf_calloc (1, strlen (nns) + strlen(okey) + 1, gf_common_mt_char ); | |||||
500 | if (!key) { | |||||
501 | ret = -1; | |||||
502 | goto out; | |||||
503 | } | |||||
504 | ||||||
505 | strcpy (key, nns); | |||||
506 | strcat (key, okey); | |||||
507 | ||||||
508 | *nkey = key; | |||||
509 | ||||||
510 | out: | |||||
511 | return ret; | |||||
512 | } | |||||
513 | ||||||
514 | static int | |||||
515 | fuse_xattr_alloc_default (char *okey, char **nkey) | |||||
516 | { | |||||
517 | int ret = 0; | |||||
518 | ||||||
519 | *nkey = gf_strdup (okey); | |||||
520 | if (!*nkey) | |||||
521 | ret = -1; | |||||
522 | return ret; | |||||
523 | } | |||||
524 | ||||||
525 | #define PRIV_XA_NS"trusted" "trusted" | |||||
526 | #define UNPRIV_XA_NS"system" "system" | |||||
527 | ||||||
528 | int | |||||
529 | fuse_flip_xattr_ns (fuse_private_t *priv, char *okey, char **nkey) | |||||
530 | { | |||||
531 | int ret = 0; | |||||
532 | gf_boolean_t need_flip = _gf_false; | |||||
533 | ||||||
534 | switch (priv->client_pid) { | |||||
| ||||||
535 | case GF_CLIENT_PID_GSYNCD: | |||||
536 | /* valid xattr(s): *xtime, volume-mark* */ | |||||
537 | gf_log("glusterfs-fuse", GF_LOG_DEBUG, "PID: %d, checking xattr(s): "do { do { if (0) printf ("PID: %d, checking xattr(s): " "volume-mark*, *xtime" , priv->client_pid); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 538, GF_LOG_DEBUG, "PID: %d, checking xattr(s): " "volume-mark*, *xtime", priv->client_pid); } while (0) | |||||
538 | "volume-mark*, *xtime", priv->client_pid)do { do { if (0) printf ("PID: %d, checking xattr(s): " "volume-mark*, *xtime" , priv->client_pid); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 538, GF_LOG_DEBUG, "PID: %d, checking xattr(s): " "volume-mark*, *xtime", priv->client_pid); } while (0); | |||||
539 | if ( (strcmp (okey, UNPRIV_XA_NS"system"".glusterfs.volume-mark") == 0) | |||||
540 | || (fnmatch (UNPRIV_XA_NS"system"".glusterfs.volume-mark.*", okey, FNM_PERIOD(1 << 2)) == 0) | |||||
541 | || (fnmatch (UNPRIV_XA_NS"system"".glusterfs.*.xtime", okey, FNM_PERIOD(1 << 2)) == 0) ) | |||||
542 | need_flip = _gf_true; | |||||
543 | break; | |||||
544 | ||||||
545 | case GF_CLIENT_PID_HADOOP: | |||||
546 | /* valid xattr(s): pathinfo */ | |||||
547 | gf_log("glusterfs-fuse", GF_LOG_DEBUG, "PID: %d, checking xattr(s): "do { do { if (0) printf ("PID: %d, checking xattr(s): " "pathinfo" , priv->client_pid); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 548, GF_LOG_DEBUG, "PID: %d, checking xattr(s): " "pathinfo", priv->client_pid); } while (0) | |||||
548 | "pathinfo", priv->client_pid)do { do { if (0) printf ("PID: %d, checking xattr(s): " "pathinfo" , priv->client_pid); } while (0); _gf_log ("glusterfs-fuse" , "fuse-helpers.c", __FUNCTION__, 548, GF_LOG_DEBUG, "PID: %d, checking xattr(s): " "pathinfo", priv->client_pid); } while (0); | |||||
549 | if (strcmp (okey, UNPRIV_XA_NS"system"".glusterfs.pathinfo") == 0) | |||||
550 | need_flip = _gf_true; | |||||
551 | break; | |||||
552 | } | |||||
553 | ||||||
554 | if (need_flip) { | |||||
555 | gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "flipping %s to "PRIV_XA_NS" equivalent",do { do { if (0) printf ("flipping %s to ""trusted"" equivalent" , okey); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c" , __FUNCTION__, 556, GF_LOG_DEBUG, "flipping %s to ""trusted" " equivalent", okey); } while (0) | |||||
556 | okey)do { do { if (0) printf ("flipping %s to ""trusted"" equivalent" , okey); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c" , __FUNCTION__, 556, GF_LOG_DEBUG, "flipping %s to ""trusted" " equivalent", okey); } while (0); | |||||
557 | ret = fuse_do_flip_xattr_ns (okey, PRIV_XA_NS"trusted", nkey); | |||||
558 | } else { | |||||
559 | /* if we cannot match, continue with what we got */ | |||||
560 | ret = fuse_xattr_alloc_default (okey, nkey); | |||||
561 | } | |||||
562 | ||||||
563 | return ret; | |||||
564 | } | |||||
565 | ||||||
566 | int | |||||
567 | fuse_ignore_xattr_set (fuse_private_t *priv, char *key) | |||||
568 | { | |||||
569 | int ret = 0; | |||||
570 | ||||||
571 | /* don't mess with user namespace */ | |||||
572 | if (fnmatch ("user.*", key, FNM_PERIOD(1 << 2)) == 0) | |||||
573 | goto out; | |||||
574 | ||||||
575 | if (priv->client_pid != GF_CLIENT_PID_GSYNCD) | |||||
576 | goto out; | |||||
577 | ||||||
578 | /* trusted NS check */ | |||||
579 | if (!((fnmatch ("*.glusterfs.*.xtime", key, FNM_PERIOD(1 << 2)) == 0) | |||||
580 | || (fnmatch ("*.glusterfs.volume-mark", | |||||
581 | key, FNM_PERIOD(1 << 2)) == 0) | |||||
582 | || (fnmatch ("*.glusterfs.volume-mark.*", | |||||
583 | key, FNM_PERIOD(1 << 2)) == 0))) | |||||
584 | ret = -1; | |||||
585 | ||||||
586 | out: | |||||
587 | gf_log ("glusterfs-fuse", GF_LOG_DEBUG, "%s setxattr: key [%s], "do { do { if (0) printf ("%s setxattr: key [%s], " " client pid [%d]" , (ret ? "disallowing" : "allowing"), key, priv->client_pid ); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c", __FUNCTION__ , 589, GF_LOG_DEBUG, "%s setxattr: key [%s], " " client pid [%d]" , (ret ? "disallowing" : "allowing"), key, priv->client_pid ); } while (0) | |||||
588 | " client pid [%d]", (ret ? "disallowing" : "allowing"), key,do { do { if (0) printf ("%s setxattr: key [%s], " " client pid [%d]" , (ret ? "disallowing" : "allowing"), key, priv->client_pid ); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c", __FUNCTION__ , 589, GF_LOG_DEBUG, "%s setxattr: key [%s], " " client pid [%d]" , (ret ? "disallowing" : "allowing"), key, priv->client_pid ); } while (0) | |||||
589 | priv->client_pid)do { do { if (0) printf ("%s setxattr: key [%s], " " client pid [%d]" , (ret ? "disallowing" : "allowing"), key, priv->client_pid ); } while (0); _gf_log ("glusterfs-fuse", "fuse-helpers.c", __FUNCTION__ , 589, GF_LOG_DEBUG, "%s setxattr: key [%s], " " client pid [%d]" , (ret ? "disallowing" : "allowing"), key, priv->client_pid ); } while (0); | |||||
590 | ||||||
591 | return ret; | |||||
592 | } |